summaryrefslogtreecommitdiffstats
path: root/contrib/gdb
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1999-05-02 10:18:14 +0000
committerdfr <dfr@FreeBSD.org>1999-05-02 10:18:14 +0000
commit5d522df45b49d6b5cb503e2f69b60e64bb65fa68 (patch)
tree629cd71e4ae6f44cf27c59ccf0a5ffc1b5cc19e1 /contrib/gdb
parent410254a3c8907ce0b5c162217599896af24b3326 (diff)
downloadFreeBSD-src-5d522df45b49d6b5cb503e2f69b60e64bb65fa68.zip
FreeBSD-src-5d522df45b49d6b5cb503e2f69b60e64bb65fa68.tar.gz
Virgin import of gdb-4.18
Diffstat (limited to 'contrib/gdb')
-rw-r--r--contrib/gdb/COPYING7
-rw-r--r--contrib/gdb/COPYING.LIB5
-rw-r--r--contrib/gdb/Makefile.in841
-rw-r--r--contrib/gdb/README15
-rw-r--r--contrib/gdb/config-ml.in624
-rwxr-xr-xcontrib/gdb/config.guess543
-rw-r--r--contrib/gdb/config.if87
-rwxr-xr-xcontrib/gdb/config.sub338
-rwxr-xr-xcontrib/gdb/configure549
-rw-r--r--contrib/gdb/configure.in691
-rw-r--r--contrib/gdb/gdb/COPYING7
-rw-r--r--contrib/gdb/gdb/ChangeLog2117
-rw-r--r--contrib/gdb/gdb/ChangeLog-9595
-rw-r--r--contrib/gdb/gdb/ChangeLog-965116
-rw-r--r--contrib/gdb/gdb/ChangeLog-972855
-rw-r--r--contrib/gdb/gdb/ChangeLog-987122
-rw-r--r--contrib/gdb/gdb/Makefile.in529
-rw-r--r--contrib/gdb/gdb/NEWS273
-rw-r--r--contrib/gdb/gdb/README255
-rw-r--r--contrib/gdb/gdb/TODO3
-rw-r--r--contrib/gdb/gdb/abug-rom.c169
-rw-r--r--contrib/gdb/gdb/acconfig.h86
-rw-r--r--contrib/gdb/gdb/acinclude.m4861
-rw-r--r--contrib/gdb/gdb/aclocal.m41424
-rw-r--r--contrib/gdb/gdb/alpha-nat.c86
-rw-r--r--contrib/gdb/gdb/alpha-tdep.c254
-rw-r--r--contrib/gdb/gdb/annotate.c51
-rw-r--r--contrib/gdb/gdb/annotate.h9
-rw-r--r--contrib/gdb/gdb/arc-tdep.c733
-rw-r--r--contrib/gdb/gdb/arm-tdep.c1642
-rw-r--r--contrib/gdb/gdb/arm-xdep.c287
-rw-r--r--contrib/gdb/gdb/ax-gdb.c1942
-rw-r--r--contrib/gdb/gdb/ax-gdb.h111
-rw-r--r--contrib/gdb/gdb/ax-general.c552
-rw-r--r--contrib/gdb/gdb/ax.h285
-rw-r--r--contrib/gdb/gdb/bcache.c40
-rw-r--r--contrib/gdb/gdb/bcache.h2
-rw-r--r--contrib/gdb/gdb/blockframe.c581
-rw-r--r--contrib/gdb/gdb/breakpoint.c3769
-rw-r--r--contrib/gdb/gdb/breakpoint.h190
-rw-r--r--contrib/gdb/gdb/buildsym.c655
-rw-r--r--contrib/gdb/gdb/buildsym.h256
-rw-r--r--contrib/gdb/gdb/c-exp.tab.c1247
-rw-r--r--contrib/gdb/gdb/c-exp.y229
-rw-r--r--contrib/gdb/gdb/c-lang.c79
-rw-r--r--contrib/gdb/gdb/c-lang.h33
-rw-r--r--contrib/gdb/gdb/c-typeprint.c474
-rw-r--r--contrib/gdb/gdb/c-valprint.c148
-rw-r--r--contrib/gdb/gdb/ch-exp.c141
-rw-r--r--contrib/gdb/gdb/ch-lang.c26
-rw-r--r--contrib/gdb/gdb/ch-lang.h5
-rw-r--r--contrib/gdb/gdb/ch-valprint.c104
-rw-r--r--contrib/gdb/gdb/coff-solib.c5
-rw-r--r--contrib/gdb/gdb/coff-solib.h130
-rw-r--r--contrib/gdb/gdb/coffread.c261
-rw-r--r--contrib/gdb/gdb/command.c190
-rw-r--r--contrib/gdb/gdb/complaints.c5
-rw-r--r--contrib/gdb/gdb/complaints.h7
-rw-r--r--contrib/gdb/gdb/config.in261
-rw-r--r--contrib/gdb/gdb/config/alpha/alpha-linux.mh9
-rw-r--r--contrib/gdb/gdb/config/alpha/alpha-linux.mt3
-rw-r--r--contrib/gdb/gdb/config/alpha/alpha-osf1.mh5
-rw-r--r--contrib/gdb/gdb/config/alpha/alpha-osf1.mt3
-rw-r--r--contrib/gdb/gdb/config/alpha/alpha-osf2.mh5
-rw-r--r--contrib/gdb/gdb/config/alpha/alpha-osf3.mh5
-rw-r--r--contrib/gdb/gdb/config/alpha/nm-linux.h66
-rw-r--r--contrib/gdb/gdb/config/alpha/nm-osf.h56
-rw-r--r--contrib/gdb/gdb/config/alpha/nm-osf2.h54
-rw-r--r--contrib/gdb/gdb/config/alpha/nm-osf3.h26
-rw-r--r--contrib/gdb/gdb/config/alpha/tm-alpha.h479
-rw-r--r--contrib/gdb/gdb/config/alpha/tm-alphalinux.h80
-rw-r--r--contrib/gdb/gdb/config/alpha/xm-alphalinux.h29
-rw-r--r--contrib/gdb/gdb/config/alpha/xm-alphaosf.h27
-rw-r--r--contrib/gdb/gdb/config/i386/cygwin.mh6
-rw-r--r--contrib/gdb/gdb/config/i386/cygwin.mt6
-rw-r--r--contrib/gdb/gdb/config/i386/fbsd.mh2
-rw-r--r--contrib/gdb/gdb/config/i386/fbsd.mt2
-rw-r--r--contrib/gdb/gdb/config/i386/go32.mh1
-rw-r--r--contrib/gdb/gdb/config/i386/i386aix.mh2
-rw-r--r--contrib/gdb/gdb/config/i386/i386dgux.mh5
-rw-r--r--contrib/gdb/gdb/config/i386/i386gnu.mh13
-rw-r--r--contrib/gdb/gdb/config/i386/i386m3.mh4
-rw-r--r--contrib/gdb/gdb/config/i386/i386mk.mh4
-rw-r--r--contrib/gdb/gdb/config/i386/i386mk.mt2
-rw-r--r--contrib/gdb/gdb/config/i386/i386sco5.mh4
-rw-r--r--contrib/gdb/gdb/config/i386/i386sco5.mt3
-rw-r--r--contrib/gdb/gdb/config/i386/i386sol2.mh7
-rw-r--r--contrib/gdb/gdb/config/i386/i386sol2.mt2
-rw-r--r--contrib/gdb/gdb/config/i386/i386v4.mh5
-rw-r--r--contrib/gdb/gdb/config/i386/i386v42mp.mh11
-rw-r--r--contrib/gdb/gdb/config/i386/i386v42mp.mt3
-rw-r--r--contrib/gdb/gdb/config/i386/linux.mh8
-rw-r--r--contrib/gdb/gdb/config/i386/linux.mt4
-rw-r--r--contrib/gdb/gdb/config/i386/nbsd.mh2
-rw-r--r--contrib/gdb/gdb/config/i386/ncr3000.mh5
-rw-r--r--contrib/gdb/gdb/config/i386/nm-fbsd.h3
-rw-r--r--contrib/gdb/gdb/config/i386/nm-i386sco.h6
-rw-r--r--contrib/gdb/gdb/config/i386/nm-i386sco5.h22
-rw-r--r--contrib/gdb/gdb/config/i386/nm-i386sol2.h35
-rw-r--r--contrib/gdb/gdb/config/i386/nm-i386v.h2
-rw-r--r--contrib/gdb/gdb/config/i386/nm-i386v4.h5
-rw-r--r--contrib/gdb/gdb/config/i386/nm-i386v42mp.h22
-rw-r--r--contrib/gdb/gdb/config/i386/nm-linux.h21
-rw-r--r--contrib/gdb/gdb/config/i386/nm-symmetry.h1
-rw-r--r--contrib/gdb/gdb/config/i386/tm-cygwin.h127
-rw-r--r--contrib/gdb/gdb/config/i386/tm-fbsd.h32
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386.h12
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386bsd.h4
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386nw.h2
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386os9k.h4
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386sco5.h62
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386sol2.h64
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386v.h6
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386v4.h2
-rw-r--r--contrib/gdb/gdb/config/i386/tm-i386v42mp.h44
-rw-r--r--contrib/gdb/gdb/config/i386/tm-linux.h5
-rw-r--r--contrib/gdb/gdb/config/i386/windows.mh17
-rw-r--r--contrib/gdb/gdb/config/i386/xm-cygwin.h34
-rw-r--r--contrib/gdb/gdb/config/i386/xm-i386bsd.h3
-rw-r--r--contrib/gdb/gdb/config/i386/xm-i386m3.h5
-rw-r--r--contrib/gdb/gdb/config/i386/xm-i386mach.h5
-rw-r--r--contrib/gdb/gdb/config/i386/xm-i386mk.h2
-rw-r--r--contrib/gdb/gdb/config/i386/xm-i386v4.h10
-rw-r--r--contrib/gdb/gdb/config/i386/xm-linux.h12
-rw-r--r--contrib/gdb/gdb/config/i386/xm-windows.h35
-rw-r--r--contrib/gdb/gdb/configure5194
-rw-r--r--contrib/gdb/gdb/configure.host162
-rw-r--r--contrib/gdb/gdb/configure.in827
-rw-r--r--contrib/gdb/gdb/configure.tgt282
-rw-r--r--contrib/gdb/gdb/copying.awk8
-rw-r--r--contrib/gdb/gdb/copying.c10
-rw-r--r--contrib/gdb/gdb/core-aout.c54
-rw-r--r--contrib/gdb/gdb/core-regset.c10
-rw-r--r--contrib/gdb/gdb/core-sol2.c8
-rw-r--r--contrib/gdb/gdb/corefile.c156
-rw-r--r--contrib/gdb/gdb/corelow.c202
-rw-r--r--contrib/gdb/gdb/cp-valprint.c312
-rw-r--r--contrib/gdb/gdb/cpu32bug-rom.c104
-rw-r--r--contrib/gdb/gdb/cxux-nat.c4
-rw-r--r--contrib/gdb/gdb/dbxread.c610
-rw-r--r--contrib/gdb/gdb/dcache.c90
-rw-r--r--contrib/gdb/gdb/defs.h476
-rw-r--r--contrib/gdb/gdb/demangle.c169
-rw-r--r--contrib/gdb/gdb/dink32-rom.c198
-rw-r--r--contrib/gdb/gdb/doc/ChangeLog267
-rw-r--r--contrib/gdb/gdb/doc/GDBvn.texi2
-rw-r--r--contrib/gdb/gdb/doc/HPPA-cfg.texi114
-rw-r--r--contrib/gdb/gdb/doc/LRS197
-rw-r--r--contrib/gdb/gdb/doc/Makefile.in81
-rw-r--r--contrib/gdb/gdb/doc/agentexpr.texi839
-rw-r--r--contrib/gdb/gdb/doc/all-cfg.texi16
-rw-r--r--contrib/gdb/gdb/doc/configure862
-rw-r--r--contrib/gdb/gdb/doc/configure.in11
-rw-r--r--contrib/gdb/gdb/doc/gdb.texinfo2650
-rw-r--r--contrib/gdb/gdb/doc/gdbint.texinfo3836
-rw-r--r--contrib/gdb/gdb/doc/refcard.tex32
-rw-r--r--contrib/gdb/gdb/doc/remote.texi217
-rw-r--r--contrib/gdb/gdb/doc/stabs.texinfo121
-rw-r--r--contrib/gdb/gdb/dwarf2read.c5865
-rw-r--r--contrib/gdb/gdb/dwarfread.c152
-rw-r--r--contrib/gdb/gdb/elfread.c141
-rw-r--r--contrib/gdb/gdb/eval.c359
-rw-r--r--contrib/gdb/gdb/exec.c293
-rw-r--r--contrib/gdb/gdb/expprint.c485
-rw-r--r--contrib/gdb/gdb/expression.h26
-rw-r--r--contrib/gdb/gdb/f-exp.tab.c243
-rw-r--r--contrib/gdb/gdb/f-exp.y10
-rw-r--r--contrib/gdb/gdb/f-lang.c155
-rw-r--r--contrib/gdb/gdb/f-lang.h6
-rw-r--r--contrib/gdb/gdb/f-typeprint.c26
-rw-r--r--contrib/gdb/gdb/f-valprint.c61
-rw-r--r--contrib/gdb/gdb/findvar.c420
-rw-r--r--contrib/gdb/gdb/fork-child.c473
-rw-r--r--contrib/gdb/gdb/fr30-tdep.c552
-rw-r--r--contrib/gdb/gdb/frame.h134
-rw-r--r--contrib/gdb/gdb/gdb-stabs.h16
-rw-r--r--contrib/gdb/gdb/gdb.16
-rw-r--r--contrib/gdb/gdb/gdb_string.h34
-rw-r--r--contrib/gdb/gdb/gdbarch.c360
-rw-r--r--contrib/gdb/gdb/gdbarch.h118
-rw-r--r--contrib/gdb/gdb/gdbcmd.h8
-rw-r--r--contrib/gdb/gdb/gdbcore.h22
-rw-r--r--contrib/gdb/gdb/gdbinit.in18
-rw-r--r--contrib/gdb/gdb/gdbserver/Makefile.in44
-rw-r--r--contrib/gdb/gdb/gdbserver/configure.in245
-rw-r--r--contrib/gdb/gdb/gdbserver/gdbreplay.c3
-rw-r--r--contrib/gdb/gdb/gdbserver/low-hppabsd.c6
-rw-r--r--contrib/gdb/gdb/gdbserver/low-linux.c47
-rw-r--r--contrib/gdb/gdb/gdbserver/low-sim.c289
-rw-r--r--contrib/gdb/gdb/gdbserver/low-sparc.c2
-rw-r--r--contrib/gdb/gdb/gdbserver/remote-utils.c102
-rw-r--r--contrib/gdb/gdb/gdbserver/server.c43
-rw-r--r--contrib/gdb/gdb/gdbserver/server.h62
-rw-r--r--contrib/gdb/gdb/gdbserver/utils.c3
-rw-r--r--contrib/gdb/gdb/gdbthread.h121
-rw-r--r--contrib/gdb/gdb/gdbtypes.c1302
-rw-r--r--contrib/gdb/gdb/gdbtypes.h434
-rw-r--r--contrib/gdb/gdb/gnu-nat.c811
-rw-r--r--contrib/gdb/gdb/gnu-nat.h32
-rw-r--r--contrib/gdb/gdb/gnu-regex.c6626
-rw-r--r--contrib/gdb/gdb/gnu-regex.h727
-rw-r--r--contrib/gdb/gdb/hp-psymtab-read.c2381
-rw-r--r--contrib/gdb/gdb/hp-symtab-read.c3988
-rw-r--r--contrib/gdb/gdb/hpread.h150
-rw-r--r--contrib/gdb/gdb/hpux-thread.c641
-rw-r--r--contrib/gdb/gdb/i386-stub.c38
-rw-r--r--contrib/gdb/gdb/i386-tdep.c114
-rw-r--r--contrib/gdb/gdb/i386aix-nat.c6
-rw-r--r--contrib/gdb/gdb/i386b-nat.c3
-rw-r--r--contrib/gdb/gdb/i386gnu-nat.c29
-rw-r--r--contrib/gdb/gdb/i386ly-tdep.c1
-rw-r--r--contrib/gdb/gdb/i386m3-nat.c6
-rw-r--r--contrib/gdb/gdb/i386mach-nat.c4
-rw-r--r--contrib/gdb/gdb/i386v-nat.c29
-rw-r--r--contrib/gdb/gdb/i386v4-nat.c25
-rw-r--r--contrib/gdb/gdb/i387-tdep.c6
-rw-r--r--contrib/gdb/gdb/infcmd.c306
-rw-r--r--contrib/gdb/gdb/inferior.h183
-rw-r--r--contrib/gdb/gdb/inflow.c67
-rw-r--r--contrib/gdb/gdb/infptrace.c240
-rw-r--r--contrib/gdb/gdb/infrun.c2243
-rw-r--r--contrib/gdb/gdb/inftarg.c768
-rw-r--r--contrib/gdb/gdb/infttrace.c5674
-rw-r--r--contrib/gdb/gdb/irix4-nat.c5
-rw-r--r--contrib/gdb/gdb/irix5-nat.c484
-rw-r--r--contrib/gdb/gdb/jv-exp.tab.c2351
-rw-r--r--contrib/gdb/gdb/jv-exp.y1466
-rw-r--r--contrib/gdb/gdb/jv-lang.c1088
-rw-r--r--contrib/gdb/gdb/jv-lang.h67
-rw-r--r--contrib/gdb/gdb/jv-typeprint.c339
-rw-r--r--contrib/gdb/gdb/jv-valprint.c526
-rw-r--r--contrib/gdb/gdb/language.c85
-rw-r--r--contrib/gdb/gdb/language.h30
-rw-r--r--contrib/gdb/gdb/lynx-nat.c15
-rw-r--r--contrib/gdb/gdb/m2-exp.tab.c210
-rw-r--r--contrib/gdb/gdb/m2-exp.y2
-rw-r--r--contrib/gdb/gdb/m2-lang.c17
-rw-r--r--contrib/gdb/gdb/m2-lang.h2
-rw-r--r--contrib/gdb/gdb/m2-valprint.c12
-rw-r--r--contrib/gdb/gdb/m3-nat.c100
-rw-r--r--contrib/gdb/gdb/m32r-rom.c650
-rw-r--r--contrib/gdb/gdb/m32r-stub.c1685
-rw-r--r--contrib/gdb/gdb/m32r-tdep.c745
-rw-r--r--contrib/gdb/gdb/m68k-stub.c6
-rw-r--r--contrib/gdb/gdb/m68k-tdep.c4
-rw-r--r--contrib/gdb/gdb/m68klinux-nat.c155
-rw-r--r--contrib/gdb/gdb/m68knbsd-nat.c2
-rw-r--r--contrib/gdb/gdb/m88k-tdep.c25
-rw-r--r--contrib/gdb/gdb/main.c311
-rw-r--r--contrib/gdb/gdb/maint.c81
-rw-r--r--contrib/gdb/gdb/mdebugread.c486
-rw-r--r--contrib/gdb/gdb/mem-break.c121
-rw-r--r--contrib/gdb/gdb/minsyms.c105
-rw-r--r--contrib/gdb/gdb/mipsread.c39
-rw-r--r--contrib/gdb/gdb/mon960-rom.c224
-rw-r--r--contrib/gdb/gdb/monitor.c1175
-rw-r--r--contrib/gdb/gdb/monitor.h272
-rw-r--r--contrib/gdb/gdb/mpw-config.in1
-rw-r--r--contrib/gdb/gdb/mpw-make.sed31
-rw-r--r--contrib/gdb/gdb/nindy-tdep.c3
-rw-r--r--contrib/gdb/gdb/nlm/Makefile.in17
-rw-r--r--contrib/gdb/gdb/nlm/configure314
-rw-r--r--contrib/gdb/gdb/nlm/configure.in4
-rw-r--r--contrib/gdb/gdb/nlmread.c59
-rw-r--r--contrib/gdb/gdb/ns32k-tdep.c95
-rw-r--r--contrib/gdb/gdb/ns32km3-nat.c16
-rw-r--r--contrib/gdb/gdb/ns32knbsd-nat.c353
-rw-r--r--contrib/gdb/gdb/objfiles.c249
-rw-r--r--contrib/gdb/gdb/objfiles.h76
-rw-r--r--contrib/gdb/gdb/ocd.c1444
-rw-r--r--contrib/gdb/gdb/ocd.h139
-rw-r--r--contrib/gdb/gdb/op50-rom.c118
-rw-r--r--contrib/gdb/gdb/os9kread.c75
-rw-r--r--contrib/gdb/gdb/osfsolib.c47
-rw-r--r--contrib/gdb/gdb/parse.c384
-rw-r--r--contrib/gdb/gdb/parser-defs.h7
-rw-r--r--contrib/gdb/gdb/partial-stab.h84
-rw-r--r--contrib/gdb/gdb/ppc-bdm.c387
-rw-r--r--contrib/gdb/gdb/ppcbug-rom.c109
-rw-r--r--contrib/gdb/gdb/printcmd.c577
-rw-r--r--contrib/gdb/gdb/procfs.c3163
-rw-r--r--contrib/gdb/gdb/pyr-tdep.c100
-rw-r--r--contrib/gdb/gdb/pyr-xdep.c12
-rw-r--r--contrib/gdb/gdb/remote-adapt.c140
-rw-r--r--contrib/gdb/gdb/remote-array.c144
-rw-r--r--contrib/gdb/gdb/remote-bug.c104
-rw-r--r--contrib/gdb/gdb/remote-d10v.c228
-rw-r--r--contrib/gdb/gdb/remote-e7000.c538
-rw-r--r--contrib/gdb/gdb/remote-eb.c95
-rw-r--r--contrib/gdb/gdb/remote-es.c234
-rw-r--r--contrib/gdb/gdb/remote-est.c105
-rw-r--r--contrib/gdb/gdb/remote-hms.c205
-rw-r--r--contrib/gdb/gdb/remote-mips.c1550
-rw-r--r--contrib/gdb/gdb/remote-mm.c102
-rw-r--r--contrib/gdb/gdb/remote-nindy.c138
-rw-r--r--contrib/gdb/gdb/remote-nrom.c110
-rw-r--r--contrib/gdb/gdb/remote-os9k.c128
-rw-r--r--contrib/gdb/gdb/remote-rdi.c973
-rw-r--r--contrib/gdb/gdb/remote-rdp.c417
-rw-r--r--contrib/gdb/gdb/remote-sds.c1206
-rw-r--r--contrib/gdb/gdb/remote-sim.c735
-rw-r--r--contrib/gdb/gdb/remote-st.c124
-rw-r--r--contrib/gdb/gdb/remote-udi.c111
-rw-r--r--contrib/gdb/gdb/remote-utils.c22
-rw-r--r--contrib/gdb/gdb/remote-vx.c171
-rw-r--r--contrib/gdb/gdb/remote-vx29k.c2
-rw-r--r--contrib/gdb/gdb/remote.c2268
-rw-r--r--contrib/gdb/gdb/scm-exp.c19
-rw-r--r--contrib/gdb/gdb/scm-lang.c28
-rw-r--r--contrib/gdb/gdb/scm-lang.h6
-rw-r--r--contrib/gdb/gdb/scm-tags.h4
-rw-r--r--contrib/gdb/gdb/scm-valprint.c38
-rw-r--r--contrib/gdb/gdb/ser-e7kpc.c138
-rw-r--r--contrib/gdb/gdb/ser-go32.c1
-rw-r--r--contrib/gdb/gdb/ser-mac.c3
-rw-r--r--contrib/gdb/gdb/ser-ocd.c209
-rw-r--r--contrib/gdb/gdb/ser-tcp.c45
-rw-r--r--contrib/gdb/gdb/ser-unix.c94
-rw-r--r--contrib/gdb/gdb/serial.c198
-rw-r--r--contrib/gdb/gdb/serial.h19
-rw-r--r--contrib/gdb/gdb/sol-thread.c1673
-rw-r--r--contrib/gdb/gdb/solib.c274
-rw-r--r--contrib/gdb/gdb/solib.h145
-rw-r--r--contrib/gdb/gdb/somread.c403
-rw-r--r--contrib/gdb/gdb/somsolib.c1066
-rw-r--r--contrib/gdb/gdb/somsolib.h126
-rw-r--r--contrib/gdb/gdb/source.c324
-rw-r--r--contrib/gdb/gdb/srec.h7
-rw-r--r--contrib/gdb/gdb/stabsread.c1742
-rw-r--r--contrib/gdb/gdb/stabsread.h36
-rw-r--r--contrib/gdb/gdb/stack.c693
-rw-r--r--contrib/gdb/gdb/symfile.c1503
-rw-r--r--contrib/gdb/gdb/symfile.h107
-rw-r--r--contrib/gdb/gdb/symmisc.c233
-rw-r--r--contrib/gdb/gdb/symtab.c2320
-rw-r--r--contrib/gdb/gdb/symtab.h313
-rw-r--r--contrib/gdb/gdb/target.c981
-rw-r--r--contrib/gdb/gdb/target.h541
-rw-r--r--contrib/gdb/gdb/terminal.h17
-rw-r--r--contrib/gdb/gdb/thread.c359
-rw-r--r--contrib/gdb/gdb/top.c626
-rw-r--r--contrib/gdb/gdb/top.h25
-rw-r--r--contrib/gdb/gdb/tracepoint.c2780
-rw-r--r--contrib/gdb/gdb/tracepoint.h137
-rw-r--r--contrib/gdb/gdb/tui/ChangeLog121
-rw-r--r--contrib/gdb/gdb/tui/Makefile182
-rw-r--r--contrib/gdb/gdb/tui/Makefile.in168
-rw-r--r--contrib/gdb/gdb/tui/tui.c830
-rw-r--r--contrib/gdb/gdb/tui/tui.h120
-rw-r--r--contrib/gdb/gdb/tui/tuiCommand.c215
-rw-r--r--contrib/gdb/gdb/tui/tuiCommand.h24
-rw-r--r--contrib/gdb/gdb/tui/tuiData.c1624
-rw-r--r--contrib/gdb/gdb/tui/tuiData.h302
-rw-r--r--contrib/gdb/gdb/tui/tuiDataWin.c400
-rw-r--r--contrib/gdb/gdb/tui/tuiDataWin.h29
-rw-r--r--contrib/gdb/gdb/tui/tuiDisassem.c343
-rw-r--r--contrib/gdb/gdb/tui/tuiDisassem.h22
-rw-r--r--contrib/gdb/gdb/tui/tuiGeneralWin.c469
-rw-r--r--contrib/gdb/gdb/tui/tuiGeneralWin.h31
-rw-r--r--contrib/gdb/gdb/tui/tuiIO.c734
-rw-r--r--contrib/gdb/gdb/tui/tuiIO.h43
-rw-r--r--contrib/gdb/gdb/tui/tuiLayout.c1410
-rw-r--r--contrib/gdb/gdb/tui/tuiLayout.h15
-rw-r--r--contrib/gdb/gdb/tui/tuiRegs.c1210
-rw-r--r--contrib/gdb/gdb/tui/tuiRegs.h28
-rw-r--r--contrib/gdb/gdb/tui/tuiSource.c465
-rw-r--r--contrib/gdb/gdb/tui/tuiSource.h27
-rw-r--r--contrib/gdb/gdb/tui/tuiSourceWin.c1098
-rw-r--r--contrib/gdb/gdb/tui/tuiSourceWin.h74
-rw-r--r--contrib/gdb/gdb/tui/tuiStack.c554
-rw-r--r--contrib/gdb/gdb/tui/tuiStack.h22
-rw-r--r--contrib/gdb/gdb/tui/tuiWin.c1650
-rw-r--r--contrib/gdb/gdb/tui/tuiWin.h28
-rw-r--r--contrib/gdb/gdb/typeprint.c27
-rw-r--r--contrib/gdb/gdb/typeprint.h6
-rw-r--r--contrib/gdb/gdb/utils.c1348
-rw-r--r--contrib/gdb/gdb/v850-tdep.c884
-rw-r--r--contrib/gdb/gdb/valarith.c102
-rw-r--r--contrib/gdb/gdb/valops.c1597
-rw-r--r--contrib/gdb/gdb/valprint.c832
-rw-r--r--contrib/gdb/gdb/valprint.h12
-rw-r--r--contrib/gdb/gdb/value.h111
-rw-r--r--contrib/gdb/gdb/values.c409
-rw-r--r--contrib/gdb/gdb/xcoffread.c182
-rw-r--r--contrib/gdb/gdb/xcoffsolib.c13
-rw-r--r--contrib/gdb/gdb/xcoffsolib.h12
-rwxr-xr-xcontrib/gdb/move-if-change17
387 files changed, 141599 insertions, 20882 deletions
diff --git a/contrib/gdb/COPYING b/contrib/gdb/COPYING
index a43ea21..60549be 100644
--- a/contrib/gdb/COPYING
+++ b/contrib/gdb/COPYING
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
- Appendix: How to Apply These Terms to Your New Programs
+ How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -305,7 +305,8 @@ the "copyright" line and a pointer to where the full notice is found.
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.
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
Also add information on how to contact you by electronic and paper mail.
diff --git a/contrib/gdb/COPYING.LIB b/contrib/gdb/COPYING.LIB
index eb685a5..161a3d1 100644
--- a/contrib/gdb/COPYING.LIB
+++ b/contrib/gdb/COPYING.LIB
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -464,7 +464,8 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail.
diff --git a/contrib/gdb/Makefile.in b/contrib/gdb/Makefile.in
index 60a8025..6465ee1 100644
--- a/contrib/gdb/Makefile.in
+++ b/contrib/gdb/Makefile.in
@@ -1,6 +1,7 @@
#
# Makefile for directory with subdirs to build.
-# Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation
+# Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+# Free Software Foundation
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,16 +21,25 @@
srcdir = .
prefix = /usr/local
-
exec_prefix = $(prefix)
-bindir = $(exec_prefix)/bin
-libdir = $(exec_prefix)/lib
+
+bindir=${exec_prefix}/bin
+sbindir=${exec_prefix}/sbin
+libexecdir=${exec_prefix}/libexec
+datadir=${prefix}/share
+sysconfdir=${prefix}/etc
+sharedstatedir=${prefix}/com
+localstatedir=${prefix}/var
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+oldincludedir=/usr/include
+infodir=${prefix}/info
+mandir=${prefix}/man
+
tooldir = $(exec_prefix)/$(target)
program_transform_name =
-datadir = $(prefix)/lib
-mandir = $(prefix)/man
man1dir = $(mandir)/man1
man2dir = $(mandir)/man2
man3dir = $(mandir)/man3
@@ -41,15 +51,20 @@ man8dir = $(mandir)/man8
man9dir = $(mandir)/man9
infodir = $(prefix)/info
includedir = $(prefix)/include
-docdir = $(datadir)/doc
+# Directory in which the compiler finds executables, libraries, etc.
+libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(gcc_version)
GDB_NLM_DEPS =
SHELL = /bin/sh
-INSTALL = $${srcroot}/install.sh -c
-INSTALL_PROGRAM = $(INSTALL)
+# INSTALL_PROGRAM_ARGS is changed by configure.in to use -x for a
+# cygwin host.
+INSTALL_PROGRAM_ARGS =
+
+INSTALL = $(SHELL) $$s/install-sh -c
+INSTALL_PROGRAM = $(INSTALL) $(INSTALL_PROGRAM_ARGS)
+INSTALL_SCRIPT = $(INSTALL)
INSTALL_DATA = $(INSTALL) -m 644
-INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)'
INSTALL_DOSREL = install-dosrel-fake
@@ -64,19 +79,22 @@ HOST_CC = $(CC_FOR_BUILD)
HOST_PREFIX =
HOST_PREFIX_1 = loser-
-# We don't specify -g -O because many compilers don't support -g -O,
-# and/or -O is broken in and of itself.
+# These flag values are normally overridden by the configure script.
CFLAGS = -g
+CXXFLAGS = -g -O2
+
LIBCFLAGS = $(CFLAGS)
CFLAGS_FOR_TARGET = $(CFLAGS)
+LDFLAGS_FOR_TARGET =
LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARGET)
PICFLAG =
PICFLAG_FOR_TARGET =
-CXX = gcc
+CHILLFLAGS = $(CFLAGS)
+CHILL_LIB = -lchill
+CXX = c++
# Use -O2 to stress test the compiler.
-CXXFLAGS = -g -O2
LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates
CXXFLAGS_FOR_TARGET = $(CXXFLAGS)
LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates
@@ -84,25 +102,43 @@ LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates
RANLIB = ranlib
DLLTOOL = dlltool
+WINDRES = windres
NM = nm
+
+LD = ld
+
# Not plain GZIP, since gzip looks there for extra command-line options.
GZIPPROG = gzip
# These values are substituted by configure.
DEFAULT_YACC = yacc
DEFAULT_LEX = lex
+DEFAULT_M4 = m4
+
+BISON = `if [ -f $$r/bison/bison ] ; then \
+ echo $$r/bison/bison -L $$s/bison/ ; \
+ else \
+ echo bison ; \
+ fi`
+
+YACC = `if [ -f $$r/bison/bison ] ; then \
+ echo $$r/bison/bison -y -L $$s/bison/ ; \
+ elif [ -f $$r/byacc/byacc ] ; then \
+ echo $$r/byacc/byacc ; \
+ else \
+ echo ${DEFAULT_YACC} ; \
+ fi`
-BISON = bison -y
LEX = `if [ -f $$r/flex/flex ] ; \
then echo $$r/flex/flex ; \
else echo ${DEFAULT_LEX} ; fi`
M4 = `if [ -f $$r/m4/m4 ] ; \
then echo $$r/m4/m4 ; \
- else echo m4 ; fi`
+ else echo ${DEFAULT_M4} ; fi`
-MAKEINFO = `if [ -f $$r/texinfo/makeinfo/makeinfo ] ; \
+MAKEINFO = `if [ -f $$r/texinfo/makeinfo/Makefile ] ; \
then echo $$r/texinfo/makeinfo/makeinfo ; \
else echo makeinfo ; fi`
@@ -115,8 +151,8 @@ EXPECT = `if [ -f $$r/expect/expect ] ; \
then echo $$r/expect/expect ; \
else echo expect ; fi`
-RUNTEST = `if [ -f $${srcroot}/dejagnu/runtest ] ; \
- then echo $${srcroot}/dejagnu/runtest ; \
+RUNTEST = `if [ -f $$s/dejagnu/runtest ] ; \
+ then echo $$s/dejagnu/runtest ; \
else echo runtest ; fi`
@@ -130,10 +166,13 @@ OTHERS =
# This is set by the configure script to the list of directories which
# should be built using the target tools.
-TARGET_CONFIGDIRS = libiberty libgloss newlib libio librx libstdc++ libg++ winsup
+
+
+TARGET_CONFIGDIRS = libiberty libgloss $(SPECIAL_LIBS) newlib libio librx libstdc++ libg++ winsup opcodes bsp libstub cygmon
# Target libraries are put under this directory:
-TARGET_SUBDIR = . # Changed by configure to $(target_alias) if cross.
+# Changed by configure to $(target_alias) if cross.
+TARGET_SUBDIR = .
# This is set by the configure script to the arguments passed to configure.
CONFIG_ARGUMENTS =
@@ -152,18 +191,31 @@ REALLY_SET_LIB_PATH = \
export $(RPATH_ENVVAR);
ALL = all.normal
-INSTALL_TARGET = install-dirs \
+INSTALL_TARGET = installdirs \
+ install-gcc \
$(INSTALL_MODULES) \
$(INSTALL_TARGET_MODULES) \
$(INSTALL_X11_MODULES) \
- install-gcc \
$(INSTALL_DOSREL)
+INSTALL_TARGET_CROSS = installdirs \
+ install-gcc-cross \
+ $(INSTALL_MODULES) \
+ $(INSTALL_TARGET_MODULES) \
+ $(INSTALL_X11_MODULES) \
+ $(INSTALL_DOSREL)
CC_FOR_TARGET = ` \
- if [ -f $$r/gcc/Makefile ] ; then \
+ if [ -f $$r/gcc/xgcc ] ; then \
if [ -f $$r/$(TARGET_SUBDIR)/newlib/Makefile ] ; then \
- echo $$r/gcc/xgcc -B$$r/gcc/ -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $${srcroot}/newlib/libc/include -nostdinc; \
+ case "$(target_canonical)" in \
+ i[3456]86-*-cygwin*) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -B$$r/$(TARGET_SUBDIR)/newlib/ -L$$r/$(TARGET_SUBDIR)/winsup -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/winsup/include -idirafter $$s/newlib/libc/include -idirafter $$s/newlib/libc/sys/cygwin -idirafter $$s/newlib/libc/sys/cygwin32 -nostdinc; \
+ ;; \
+ *) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/newlib/libc/include -nostdinc; \
+ ;; \
+ esac \
else \
echo $$r/gcc/xgcc -B$$r/gcc/; \
fi; \
@@ -175,11 +227,34 @@ CC_FOR_TARGET = ` \
fi; \
fi`
+# If CC_FOR_TARGET is not overriden on the command line, then this
+# variable is passed down to the gcc Makefile, where it is used to
+# build libgcc2.a. We define it here so that it can itself be
+# overridden on the command line.
+GCC_FOR_TARGET = $$r/gcc/xgcc -B$$r/gcc/
+
+CHILL_FOR_TARGET = ` \
+ if [ -f $$r/gcc/xgcc ] ; then \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -L$$r/gcc/ch/runtime/; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(CC); \
+ else \
+ t='$(program_transform_name)'; echo gcc | sed -e 's/x/x/' $$t; \
+ fi; \
+ fi`
CXX_FOR_TARGET = ` \
- if [ -f $$r/gcc/Makefile ] ; then \
+ if [ -f $$r/gcc/xgcc ] ; then \
if [ -f $$r/$(TARGET_SUBDIR)/newlib/Makefile ] ; then \
- echo $$r/gcc/xgcc -B$$r/gcc/ -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $${srcroot}/newlib/libc/include -nostdinc; \
+ case "$(target_canonical)" in \
+ i[3456]86-*-cygwin*) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -B$$r/$(TARGET_SUBDIR)/newlib/ -L$$r/$(TARGET_SUBDIR)/winsup -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/winsup/include -idirafter $$s/newlib/libc/include -idirafter $$s/newlib/libc/sys/cygwin -idirafter $$s/newlib/libc/sys/cygwin32 -nostdinc; \
+ ;; \
+ *) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/newlib/libc/include -nostdinc; \
+ ;; \
+ esac \
else \
echo $$r/gcc/xgcc -B$$r/gcc/; \
fi; \
@@ -187,13 +262,13 @@ CXX_FOR_TARGET = ` \
if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
echo $(CXX); \
else \
- t='$(program_transform_name)'; echo gcc | sed -e 's/x/x/' $$t; \
+ t='$(program_transform_name)'; echo c++ | sed -e 's/x/x/' $$t; \
fi; \
fi`
AS_FOR_TARGET = ` \
- if [ -f $$r/gas/as.new ] ; then \
- echo $$r/gas/as.new ; \
+ if [ -f $$r/gas/as-new ] ; then \
+ echo $$r/gas/as-new ; \
else \
if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
echo $(AS); \
@@ -203,8 +278,8 @@ AS_FOR_TARGET = ` \
fi`
LD_FOR_TARGET = ` \
- if [ -f $$r/ld/ld.new ] ; then \
- echo $$r/ld/ld.new ; \
+ if [ -f $$r/ld/ld-new ] ; then \
+ echo $$r/ld/ld-new ; \
else \
if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
echo $(LD); \
@@ -224,6 +299,17 @@ DLLTOOL_FOR_TARGET = ` \
fi; \
fi`
+WINDRES_FOR_TARGET = ` \
+ if [ -f $$r/binutils/windres ] ; then \
+ echo $$r/binutils/windres ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(WINDRES); \
+ else \
+ t='$(program_transform_name)'; echo windres | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
AR_FOR_TARGET = ` \
if [ -f $$r/binutils/ar ] ; then \
echo $$r/binutils/ar ; \
@@ -247,8 +333,8 @@ RANLIB_FOR_TARGET = ` \
fi`
NM_FOR_TARGET = ` \
- if [ -f $$r/binutils/nm.new ] ; then \
- echo $$r/binutils/nm.new ; \
+ if [ -f $$r/binutils/nm-new ] ; then \
+ echo $$r/binutils/nm-new ; \
else \
if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
echo $(NM); \
@@ -257,6 +343,18 @@ NM_FOR_TARGET = ` \
fi; \
fi`
+# The first rule in the file had better be this one. Don't put any above it.
+# This lives here to allow makefile fragments to contain dependencies.
+all: all.normal
+.PHONY: all
+
+# These can be overridden by config/mt-*.
+# The _TARGET_ is because they're specified in mt-foo.
+# The _HOST_ is because they're programs that run on the host.
+EXTRA_TARGET_HOST_ALL_MODULES =
+EXTRA_TARGET_HOST_INSTALL_MODULES =
+EXTRA_TARGET_HOST_CHECK_MODULES =
+
#### host and target specific makefile fragments come in here.
###
@@ -271,16 +369,18 @@ BASE_FLAGS_TO_PASS = \
"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
"CFLAGS=$(CFLAGS)" \
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "CHILLFLAGS=$(CHILLFLAGS)" \
+ "CHILL_FOR_TARGET=$(CHILL_FOR_TARGET)" \
+ "CHILL_LIB=$(CHILL_LIB)" \
"CXX_FOR_BUILD=$(CXX_FOR_BUILD)" \
"CXXFLAGS=$(CXXFLAGS)" \
"CXXFLAGS_FOR_TARGET=$(CXXFLAGS_FOR_TARGET)" \
"CXX_FOR_TARGET=$(CXX_FOR_TARGET)" \
"DLLTOOL_FOR_TARGET=$(DLLTOOL_FOR_TARGET)" \
- "GCC_FOR_TARGET=$(CC_FOR_TARGET)" \
"INSTALL=$(INSTALL)" \
"INSTALL_DATA=$(INSTALL_DATA)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
- "INSTALL_XFORM=$(INSTALL_XFORM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
"LDFLAGS=$(LDFLAGS)" \
"LEX=$(LEX)" \
"LD_FOR_TARGET=$(LD_FOR_TARGET)" \
@@ -289,19 +389,39 @@ BASE_FLAGS_TO_PASS = \
"LIBCXXFLAGS=$(LIBCXXFLAGS)" \
"LIBCXXFLAGS_FOR_TARGET=$(LIBCXXFLAGS_FOR_TARGET)" \
"M4=$(M4)" \
+ "MAKE=$(MAKE)" \
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
- "PICFLAG=$(PICFLAG)" \
- "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
"RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET)" \
+ "RPATH_ENVVAR=$(RPATH_ENVVAR)" \
"SHELL=$(SHELL)" \
"EXPECT=$(EXPECT)" \
"RUNTEST=$(RUNTEST)" \
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
- "YACC=$(BISON)" \
+ "TARGET_SUBDIR=$(TARGET_SUBDIR)" \
+ "WINDRES_FOR_TARGET=$(WINDRES_FOR_TARGET)" \
+ "YACC=$(YACC)" \
+ "bindir=$(bindir)" \
+ "datadir=$(datadir)" \
"exec_prefix=$(exec_prefix)" \
+ "includedir=$(includedir)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "libexecdir=$(libexecdir)" \
+ "lispdir=$(lispdir)" \
+ "localstatedir=$(localstatedir)" \
+ "mandir=$(mandir)" \
+ "oldincludedir=$(oldincludedir)" \
"prefix=$(prefix)" \
- "tooldir=$(tooldir)"
+ "sbindir=$(sbindir)" \
+ "sharedstatedir=$(sharedstatedir)" \
+ "sysconfdir=$(sysconfdir)" \
+ "tooldir=$(tooldir)" \
+ "gxx_include_dir=$(gxx_include_dir)" \
+ "gcc_version=$(gcc_version)" \
+ "gcc_version_trigger=$(gcc_version_trigger)" \
+ "target_alias=$(target_alias)" \
+ "libsubdir=$(libsubdir)"
# Flags to pass down to most sub-makes, in which we're building with
# the host environment.
@@ -312,9 +432,10 @@ EXTRA_HOST_FLAGS = \
'CC=$(CC)' \
'CXX=$(CXX)' \
'DLLTOOL=$(DLLTOOL)' \
+ 'LD=$(LD)' \
'NM=$(NM)' \
- 'RANLIB=$(RANLIB)'
-
+ 'RANLIB=$(RANLIB)' \
+ 'WINDRES=$(WINDRES)'
FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS)
@@ -346,8 +467,8 @@ EXTRA_TARGET_FLAGS = \
'LIBCFLAGS=$$(LIBCFLAGS_FOR_TARGET)' \
'LIBCXXFLAGS=$$(LIBCXXFLAGS_FOR_TARGET)' \
'NM=$$(NM_FOR_TARGET)' \
- 'PICFLAG=$$(PICFLAG_FOR_TARGET)' \
- 'RANLIB=$$(RANLIB_FOR_TARGET)'
+ 'RANLIB=$$(RANLIB_FOR_TARGET)' \
+ 'WINDRES=$$(WINDRES_FOR_TARGET)'
TARGET_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS)
@@ -358,7 +479,7 @@ TARGET_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS)
# The HOST_* variables are a special case, which are used for the gcc
# cross-building scheme.
EXTRA_GCC_FLAGS = \
- 'AR=$$(AR_FOR_TARGET)' \
+ 'AR=$(AR)' \
'AS=$(AS)' \
'CC=$(CC)' \
'CXX=$(CXX)' \
@@ -367,49 +488,68 @@ EXTRA_GCC_FLAGS = \
'HOST_PREFIX=$(HOST_PREFIX)' \
'HOST_PREFIX_1=$(HOST_PREFIX_1)' \
'NM=$(NM)' \
- 'RANLIB=$$(RANLIB_FOR_TARGET)' \
- `if test x"$(LANGUAGES)" != x; then echo "LANGUAGES=$(LANGUAGES)"; fi` \
- `if test x"$(STMP_FIXPROTO)" != x; then echo "STMP_FIXPROTO=$(STMP_FIXPROTO)"; fi` \
- `if test x"$(LIMITS_H_TEST)" != x; then echo "LIMITS_H_TEST=$(LIMITS_H_TEST)"; fi` \
- `if test x"$(LIBGCC1_TEST)" != x; then echo "LIBGCC1_TEST=$(LIBGCC1_TEST)"; fi` \
- `if test x"$(LIBGCC2_CFLAGS)" != x; then echo "LIBGCC2_CFLAGS=$(LIBGCC2_CFLAGS)"; fi` \
- `if test x"$(LIBGCC2_INCLUDES)" != x; then echo "LIBGCC2_INCLUDES=$(LIBGCC2_INCLUDES)"; fi` \
- `if test x"$(ENQUIRE)" != x; then echo "ENQUIRE=$(ENQUIRE)"; fi` \
- `if test x"$(BOOT_CFLAGS)" != x; then echo "BOOT_CFLAGS=$(BOOT_CFLAGS)"; fi`
+ 'RANLIB=$(RANLIB)' \
+ 'WINDRES=$$(WINDRES_FOR_TARGET)' \
+ "GCC_FOR_TARGET=$(GCC_FOR_TARGET)" \
+ "`echo 'LANGUAGES=$(LANGUAGES)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'STMP_FIXPROTO=$(STMP_FIXPROTO)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIMITS_H_TEST=$(LIMITS_H_TEST)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC1_TEST=$(LIBGCC1_TEST)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC2_CFLAGS=$(LIBGCC2_CFLAGS)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC2_DEBUG_CFLAGS=$(LIBGCC2_DEBUG_CFLAGS)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC2_INCLUDES=$(LIBGCC2_INCLUDES)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'ENQUIRE=$(ENQUIRE)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'BOOT_CFLAGS=$(BOOT_CFLAGS)' | sed -e s/.*=$$/XFOO=/`"
GCC_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_GCC_FLAGS)
# This is a list of the targets for all of the modules which are compiled
# using $(FLAGS_TO_PASS).
ALL_MODULES = \
+ all-apache \
+ all-ash \
all-autoconf \
+ all-automake \
+ all-bash \
all-bfd \
all-binutils \
+ all-bison \
all-byacc \
- all-cvs \
+ all-bzip2 \
+ all-cvssrc \
+ all-db \
all-dejagnu \
all-diff \
all-dosutils \
all-etc \
all-fileutils \
+ all-findutils \
all-find \
all-flex \
all-gas \
all-gawk \
+ all-gettext \
+ all-gnuserv \
all-gprof \
all-grep \
all-grez \
all-gzip \
all-hello \
all-indent \
+ all-inet \
+ all-intl \
all-ispell \
+ all-itcl \
all-ld \
+ all-libgui \
all-libiberty \
+ all-libtool \
all-m4 \
all-make \
all-mmalloc \
all-opcodes \
all-patch \
+ all-perl \
all-prms \
all-rcs \
all-readline \
@@ -421,50 +561,68 @@ ALL_MODULES = \
all-sim \
all-tar \
all-tcl \
+ all-tcl8.1 \
all-texinfo \
all-textutils \
all-tgas \
all-time \
all-uudecode \
- all-wdiff
+ all-wdiff \
+ all-zip \
+ $(EXTRA_TARGET_HOST_ALL_MODULES)
# This is a list of the check targets for all of the modules which are
# compiled using $(FLAGS_TO_PASS).
-# This is a list of the check targets for all of the modules which are
-# compiled using $(FLAGS_TO_PASS).
#
# The list is in two parts. The first lists those tools which
# are tested as part of the host's native tool-chain, and not
# tested in a cross configuration.
NATIVE_CHECK_MODULES = \
+ check-bison \
check-byacc \
- check-flex
+ check-flex \
+ check-zip
CROSS_CHECK_MODULES = \
+ check-apache \
+ check-ash \
check-autoconf \
+ check-automake \
+ check-bash \
check-bfd \
check-binutils \
- check-cvs \
+ check-bzip2 \
+ check-cvssrc \
+ check-db \
check-dejagnu \
check-diff \
check-etc \
check-fileutils \
+ check-findutils \
check-find \
check-gas \
check-gawk \
+ check-gettext \
+ check-gnuserv \
check-gprof \
check-grep \
check-gzip \
check-hello \
check-indent \
+ check-inet \
+ check-intl \
check-ispell \
+ check-itcl \
check-ld \
+ check-libgui \
check-libiberty \
+ check-libtool \
check-m4 \
check-make \
check-mmcheckoc \
check-opcodes \
check-patch \
+ check-perl \
check-prms \
check-rcs \
check-readline \
@@ -480,41 +638,65 @@ CROSS_CHECK_MODULES = \
check-tgas \
check-time \
check-uudecode \
- check-wdiff
+ check-wdiff \
+ $(EXTRA_TARGET_HOST_CHECK_MODULES)
CHECK_MODULES=$(NATIVE_CHECK_MODULES) $(CROSS_CHECK_MODULES)
# This is a list of the install targets for all of the modules which are
# compiled using $(FLAGS_TO_PASS).
+# We put install-opcodes before install-binutils because the installed
+# binutils might be on PATH, and they might need the shared opcodes
+# library.
+# We put install-tcl before install-itcl because itcl wants to run a
+# program on installation which uses the Tcl libraries.
INSTALL_MODULES = \
+ install-apache \
+ install-ash \
install-autoconf \
+ install-automake \
+ install-bash \
install-bfd \
+ install-bzip2 \
+ install-opcodes \
install-binutils \
+ install-bison \
install-byacc \
- install-cvs \
+ install-cvssrc \
+ install-db \
install-dejagnu \
install-diff \
install-dosutils \
install-etc \
install-fileutils \
+ install-findutils \
install-find \
install-flex \
install-gas \
install-gawk \
+ install-gettext \
+ install-gnuserv \
install-gprof \
install-grep \
install-grez \
install-gzip \
install-hello \
install-indent \
+ install-inet \
+ install-intl \
install-ispell \
+ install-tcl \
+ install-tcl8.1 \
+ install-itcl \
install-ld \
+ install-libgui \
install-libiberty \
+ install-libtool \
install-m4 \
install-make \
install-mmalloc \
- install-opcodes \
install-patch \
+ install-perl \
install-prms \
install-rcs \
install-readline \
@@ -524,12 +706,13 @@ INSTALL_MODULES = \
install-shellutils \
install-sim \
install-tar \
- install-tcl \
install-textutils \
install-tgas \
install-time \
install-uudecode \
- install-wdiff
+ install-wdiff \
+ install-zip \
+ $(EXTRA_TARGET_HOST_INSTALL_MODULES)
# This is a list of the targets for all of the modules which are compiled
# using $(X11_FLAGS_TO_PASS).
@@ -539,18 +722,23 @@ ALL_X11_MODULES = \
all-gdb \
all-expect \
all-gash \
+ all-guile \
all-tclX \
- all-tk
+ all-tk \
+ all-tk8.1 \
+ all-tix
# This is a list of the check targets for all of the modules which are
# compiled using $(X11_FLAGS_TO_PASS).
CHECK_X11_MODULES = \
check-emacs \
check-gdb \
+ check-guile \
check-expect \
check-gash \
check-tclX \
- check-tk
+ check-tk \
+ check-tix
# This is a list of the install targets for all the modules which are
# compiled using $(X11_FLAGS_TO_PASS).
@@ -558,10 +746,13 @@ INSTALL_X11_MODULES = \
install-emacs \
install-emacs19 \
install-gdb \
+ install-guile \
install-expect \
install-gash \
install-tclX \
- install-tk
+ install-tk \
+ install-tk8.1 \
+ install-tix
# This is a list of the targets for all of the modules which are compiled
# using $(TARGET_FLAGS_TO_PASS).
@@ -571,10 +762,15 @@ ALL_TARGET_MODULES = \
all-target-librx \
all-target-libg++ \
all-target-newlib \
+ all-target-libtermcap \
all-target-winsup \
all-target-libgloss \
all-target-libiberty \
- all-target-examples
+ all-target-gperf \
+ all-target-examples \
+ all-target-libstub \
+ all-target-bsp \
+ all-target-cygmon
# This is a list of the configure targets for all of the modules which
# are compiled using the target tools.
@@ -584,10 +780,15 @@ CONFIGURE_TARGET_MODULES = \
configure-target-librx \
configure-target-libg++ \
configure-target-newlib \
+ configure-target-libtermcap \
configure-target-winsup \
configure-target-libgloss \
configure-target-libiberty \
- configure-target-examples
+ configure-target-gperf \
+ configure-target-examples \
+ configure-target-libstub \
+ configure-target-bsp \
+ configure-target-cygmon
# This is a list of the check targets for all of the modules which are
# compiled using $(TARGET_FLAGS_TO_PASS).
@@ -597,7 +798,8 @@ CHECK_TARGET_MODULES = \
check-target-libg++ \
check-target-newlib \
check-target-winsup \
- check-target-libiberty
+ check-target-libiberty \
+ check-target-gperf
# This is a list of the install targets for all of the modules which are
# compiled using $(TARGET_FLAGS_TO_PASS).
@@ -606,20 +808,112 @@ INSTALL_TARGET_MODULES = \
install-target-libstdc++ \
install-target-libg++ \
install-target-newlib \
+ install-target-libtermcap \
install-target-winsup \
install-target-libgloss \
- install-target-libiberty
-
-# The first rule in the file had better be this one. Don't put any above it.
-all: all.normal
-.PHONY: all
+ install-target-libiberty \
+ install-target-bsp \
+ install-target-gperf
+
+# This is a list of the targets for which we can do a clean-{target}.
+CLEAN_MODULES = \
+ clean-apache \
+ clean-ash \
+ clean-autoconf \
+ clean-automake \
+ clean-bash \
+ clean-bfd \
+ clean-binutils \
+ clean-bison \
+ clean-byacc \
+ clean-bzip2 \
+ clean-cvssrc \
+ clean-db \
+ clean-dejagnu \
+ clean-diff \
+ clean-dosutils \
+ clean-etc \
+ clean-fileutils \
+ clean-findutils \
+ clean-find \
+ clean-flex \
+ clean-gas \
+ clean-gawk \
+ clean-gettext \
+ clean-gnuserv \
+ clean-gprof \
+ clean-grep \
+ clean-grez \
+ clean-gzip \
+ clean-hello \
+ clean-indent \
+ clean-inet \
+ clean-intl \
+ clean-ispell \
+ clean-itcl \
+ clean-ld \
+ clean-libgui \
+ clean-libiberty \
+ clean-libtool \
+ clean-m4 \
+ clean-make \
+ clean-mmalloc \
+ clean-opcodes \
+ clean-patch \
+ clean-perl \
+ clean-prms \
+ clean-rcs \
+ clean-readline \
+ clean-release \
+ clean-recode \
+ clean-sed \
+ clean-send-pr \
+ clean-shellutils \
+ clean-sim \
+ clean-tar \
+ clean-tcl \
+ clean-texinfo \
+ clean-textutils \
+ clean-tgas \
+ clean-time \
+ clean-uudecode \
+ clean-wdiff \
+ clean-zip
+
+# All of the target modules that can be cleaned
+CLEAN_TARGET_MODULES = \
+ clean-target-libio \
+ clean-target-libstdc++ \
+ clean-target-librx \
+ clean-target-libg++ \
+ clean-target-newlib \
+ clean-target-winsup \
+ clean-target-libgloss \
+ clean-target-libiberty \
+ clean-target-gperf \
+ clean-target-examples \
+ clean-target-libstub \
+ clean-target-bsp \
+ clean-target-cygmon
+
+# All of the x11 modules that can be cleaned
+CLEAN_X11_MODULES = \
+ clean-emacs \
+ clean-emacs19 \
+ clean-gdb \
+ clean-expect \
+ clean-gash \
+ clean-guile \
+ clean-tclX \
+ clean-tk \
+ clean-tix
# The target built for a native build.
.PHONY: all.normal
all.normal: \
$(ALL_MODULES) \
- $(ALL_TARGET_MODULES) \
$(ALL_X11_MODULES) \
+ $(ALL_TARGET_MODULES) \
all-gcc
# Do a target for all the subdirectories. A ``make do-X'' will do a
@@ -643,7 +937,7 @@ DO_X = \
$(DO_X):
@target=`echo $@ | sed -e 's/^do-//'`; \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
for i in $(SUBDIRS) -dummy-; do \
if [ -f ./$$i/Makefile ]; then \
@@ -659,31 +953,31 @@ $(DO_X):
done; \
;; \
esac ; \
- export AR AS CC CXX NM RANLIB DLLTOOL; \
+ export AR AS CC CXX LD NM RANLIB DLLTOOL WINDRES; \
if (cd ./$$i; \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
- "CC=$${CC}" "CXX=$${CXX}" "NM=$${NM}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
- "DLLTOOL=$${DLLTOOL}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
$${target}); \
then true; else exit 1; fi; \
else true; fi; \
done
@target=`echo $@ | sed -e 's/^do-//'`; \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
for i in $(TARGET_CONFIGDIRS) -dummy-; do \
if [ -f $(TARGET_SUBDIR)/$$i/Makefile ]; then \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'|"`; \
done; \
- export AR AS CC CXX NM RANLIB DLLTOOL; \
+ export AR AS CC CXX LD NM RANLIB DLLTOOL WINDRES; \
if (cd $(TARGET_SUBDIR)/$$i; \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
- "CC=$${CC}" "CXX=$${CXX}" "NM=$${NM}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
- "DLLTOOL=$${DLLTOOL}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
$${target}); \
then true; else exit 1; fi; \
else true; fi; \
@@ -698,17 +992,20 @@ info: do-info
installcheck: do-installcheck
dvi: do-dvi
+# Make sure makeinfo is built before we do a `make info'.
+do-info: all-texinfo
+
install-info: do-install-info dir.info
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
if [ -f dir.info ] ; then \
$(INSTALL_DATA) dir.info $(infodir)/dir.info ; \
else true ; fi
local-clean:
- -rm -f *.a TEMP errs core *.o *~ \#* TAGS *.E
+ -rm -f *.a TEMP errs core *.o *~ \#* TAGS *.E *.log
local-distclean:
- -rm -f Makefile config.status
+ -rm -f Makefile config.status config.cache mh-frag mt-frag
-if [ "$(TARGET_SUBDIR)" != "." ]; then \
rm -rf $(TARGET_SUBDIR); \
else true; fi
@@ -724,6 +1021,34 @@ maintainer-clean: local-maintainer-clean do-maintainer-clean local-clean
maintainer-clean: local-distclean
realclean: maintainer-clean
+# This rule is used to clean specific modules.
+.PHONY: $(CLEAN_MODULES) $(CLEAN_X11_MODULES) clean-gcc
+$(CLEAN_MODULES) $(CLEAN_X11_MODULES) clean-gcc:
+ @dir=`echo $@ | sed -e 's/clean-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) clean); \
+ else \
+ true; \
+ fi
+
+.PHONY: $(CLEAN_TARGET_MODULES)
+$(CLEAN_TARGET_MODULES):
+ @dir=`echo $@ | sed -e 's/clean-target-//'`; \
+ rm -f $(TARGET_SUBDIR)/$${dir}/multilib.out $(TARGET_SUBDIR)/$${dir}/tmpmulti.out; \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/$${dir}; $(MAKE) $(TARGET_FLAGS_TO_PASS) clean); \
+ else \
+ true; \
+ fi
+
+clean-target: $(CLEAN_TARGET_MODULES)
+
# Check target.
.PHONY: check
@@ -732,10 +1057,32 @@ check: $(CHECK_MODULES) \
$(CHECK_X11_MODULES) \
check-gcc
+# Automated reporting of test results.
+
+warning.log: build.log
+ $(srcdir)/contrib/warn_summary build.log > $@
+
+mail-report.log:
+ if test x'$(BOOT_CFLAGS)' != x''; then \
+ BOOT_CFLAGS='$(BOOT_CFLAGS)'; export BOOT_CFLAGS; \
+ fi; \
+ $(srcdir)/contrib/test_summary -t >$@
+ chmod +x $@
+ echo If you really want to send e-mail, run ./$@ now
+
+mail-report-with-warnings.log: warning.log
+ if test x'$(BOOT_CFLAGS)' != x''; then \
+ BOOT_CFLAGS='$(BOOT_CFLAGS)'; export BOOT_CFLAGS; \
+ fi; \
+ $(srcdir)/contrib/test_summary -t -i warning.log >$@
+ chmod +x $@
+ echo If you really want to send e-mail, run ./$@ now
+
# Installation targets.
-.PHONY: install uninstall source-vault binary-vault vault-install
+.PHONY: install install-cross uninstall source-vault binary-vault vault-install
install: $(INSTALL_TARGET)
+install-cross: $(INSTALL_TARGET_CROSS)
uninstall:
@echo "the uninstall target is not supported in this tree"
@@ -766,11 +1113,16 @@ install.all: install-no-fixedincludes
true ; \
fi
+# inet-install is used because the I*Net wants DejaGNU installed but
+# not built. Similarly, gzip is built but not installed.
+inet-install:
+ $(MAKE) INSTALL_MODULES="`echo $(INSTALL_MODULES) | sed -e 's/install-dejagnu//' -e 's/install-gzip//'`" install
+
# install-no-fixedincludes is used because Cygnus can not distribute
# the fixed header files.
.PHONY: install-no-fixedincludes
install-no-fixedincludes: \
- install-dirs \
+ installdirs \
$(INSTALL_MODULES) \
$(INSTALL_TARGET_MODULES) \
$(INSTALL_X11_MODULES) \
@@ -789,7 +1141,7 @@ gcc-no-fixedincludes:
touch gcc/stmp-fixinc gcc/include/fixed; \
rm -f gcc/stmp-headers gcc/stmp-int-hdrs; \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd` ; export srcroot; \
+ s=`cd $(srcdir); pwd` ; export s; \
$(SET_LIB_PATH) \
(cd ./gcc; \
$(MAKE) $(GCC_FLAGS_TO_PASS) install); \
@@ -797,6 +1149,7 @@ gcc-no-fixedincludes:
mv gcc/tmp-include gcc/include 2>/dev/null; \
else true; fi
+
# This rule is used to build the modules which use FLAGS_TO_PASS. To
# build a target all-X means to cd to X and make all.
#
@@ -808,7 +1161,7 @@ $(ALL_MODULES) all-gui all-libproc:
@dir=`echo $@ | sed -e 's/all-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) all); \
else \
@@ -825,7 +1178,7 @@ $(NATIVE_CHECK_MODULES):
dir=`echo $@ | sed -e 's/check-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) check); \
else \
@@ -837,7 +1190,7 @@ $(CROSS_CHECK_MODULES):
@dir=`echo $@ | sed -e 's/check-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) check); \
else \
@@ -847,11 +1200,11 @@ $(CROSS_CHECK_MODULES):
# This rule is used to install the modules which use FLAGS_TO_PASS.
# To build a target install-X means to cd to X and make install.
.PHONY: $(INSTALL_MODULES)
-$(INSTALL_MODULES): install-dirs
+$(INSTALL_MODULES): installdirs
@dir=`echo $@ | sed -e 's/install-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) install); \
else \
@@ -863,13 +1216,33 @@ $(INSTALL_MODULES): install-dirs
.PHONY: $(CONFIGURE_TARGET_MODULES)
$(CONFIGURE_TARGET_MODULES):
@dir=`echo $@ | sed -e 's/configure-target-//'`; \
- if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ if [ -d $(TARGET_SUBDIR)/$${dir} ]; then \
+ r=`pwd`; export r; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/$${dir}/tmpmulti.out 2> /dev/null; \
+ if [ -s $(TARGET_SUBDIR)/$${dir}/tmpmulti.out ]; then \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/multilib.out ]; then \
+ if cmp $(TARGET_SUBDIR)/$${dir}/multilib.out $(TARGET_SUBDIR)/$${dir}/tmpmulti.out > /dev/null; then \
+ rm -f $(TARGET_SUBDIR)/$${dir}/tmpmulti.out; \
+ else \
+ echo "Multilibs changed for $${dir}, reconfiguring"; \
+ rm -f $(TARGET_SUBDIR)/$${dir}/multilib.out $(TARGET_SUBDIR)/$${dir}/Makefile; \
+ mv $(TARGET_SUBDIR)/$${dir}/tmpmulti.out $(TARGET_SUBDIR)/$${dir}/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/$${dir}/tmpmulti.out $(TARGET_SUBDIR)/$${dir}/multilib.out; \
+ fi; \
+ fi; \
+ fi; exit 0 # break command into two pieces
+ @dir=`echo $@ | sed -e 's/configure-target-//'`; \
+ if [ ! -d $(TARGET_SUBDIR) ]; then \
+ true; \
+ elif [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
true; \
elif echo " $(TARGET_CONFIGDIRS) " | grep " $${dir} " >/dev/null 2>&1; then \
if [ -d $(srcdir)/$${dir} ]; then \
[ -d $(TARGET_SUBDIR)/$${dir} ] || mkdir $(TARGET_SUBDIR)/$${dir};\
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
AR="$(AR_FOR_TARGET)"; export AR; \
AS="$(AS_FOR_TARGET)"; export AS; \
@@ -879,8 +1252,10 @@ $(CONFIGURE_TARGET_MODULES):
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
+ LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
NM="$(NM_FOR_TARGET)"; export NM; \
RANLIB="$(RANLIB_FOR_TARGET)"; export RANLIB; \
+ WINDRES="$(WINDRES_FOR_TARGET)"; export WINDRES; \
echo Configuring in $(TARGET_SUBDIR)/$${dir}; \
cd $(TARGET_SUBDIR)/$${dir}; \
case $(srcdir) in \
@@ -894,7 +1269,7 @@ $(CONFIGURE_TARGET_MODULES):
esac; \
if [ "$(srcdir)" = "." ] ; then \
if [ "$(TARGET_SUBDIR)" != "." ] ; then \
- if $(SHELL) $${srcroot}/symlink-tree $${topdir}/$${dir} "no-such-file" ; then \
+ if $(SHELL) $$s/symlink-tree $${topdir}/$${dir} "no-such-file" ; then \
if [ -f Makefile ]; then \
if $(MAKE) distclean; then \
true; \
@@ -914,17 +1289,26 @@ $(CONFIGURE_TARGET_MODULES):
libsrcdir="."; \
else \
srcdiroption="--srcdir=$${topdir}/$${dir}"; \
- libsrcdir="$${srcroot}/$${dir}"; \
+ libsrcdir="$$s/$${dir}"; \
fi; \
if [ -f $${libsrcdir}/configure ] ; then \
- $(SHELL) $${libsrcdir}/configure \
+ rm -f no-such-file skip-this-dir; \
+ CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
$(CONFIG_ARGUMENTS) $${srcdiroption} \
--with-target-subdir="$(TARGET_SUBDIR)"; \
else \
- $(SHELL) $${srcroot}/configure \
+ rm -f no-such-file skip-this-dir; \
+ CONFIG_SITE=no-such-file $(SHELL) $$s/configure \
$(CONFIG_ARGUMENTS) $${srcdiroption} \
--with-target-subdir="$(TARGET_SUBDIR)"; \
fi; \
+ if [ -f skip-this-dir ] ; then \
+ sh skip-this-dir; \
+ rm -f skip-this-dir; \
+ cd ..; rmdir $${dir} || true; \
+ else \
+ true; \
+ fi; \
else \
true; \
fi; \
@@ -939,7 +1323,7 @@ $(ALL_TARGET_MODULES):
@dir=`echo $@ | sed -e 's/all-target-//'`; \
if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $(TARGET_SUBDIR)/$${dir}; $(MAKE) $(TARGET_FLAGS_TO_PASS) all); \
else \
@@ -953,7 +1337,7 @@ $(CHECK_TARGET_MODULES):
@dir=`echo $@ | sed -e 's/check-target-//'`; \
if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $(TARGET_SUBDIR)/$${dir};$(MAKE) $(TARGET_FLAGS_TO_PASS) check);\
else \
@@ -964,11 +1348,11 @@ $(CHECK_TARGET_MODULES):
# TARGET_FLAGS_TO_PASS. To build a target install-X means to cd to X
# and make install.
.PHONY: $(INSTALL_TARGET_MODULES)
-$(INSTALL_TARGET_MODULES): install-dirs
+$(INSTALL_TARGET_MODULES): installdirs
@dir=`echo $@ | sed -e 's/install-target-//'`; \
if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $(TARGET_SUBDIR)/$${dir}; \
$(MAKE) $(TARGET_FLAGS_TO_PASS) install); \
@@ -983,7 +1367,7 @@ $(ALL_X11_MODULES):
@dir=`echo $@ | sed -e 's/all-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; \
$(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) all); \
@@ -998,7 +1382,7 @@ $(CHECK_X11_MODULES):
@dir=`echo $@ | sed -e 's/check-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; \
$(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) check); \
@@ -1009,11 +1393,11 @@ $(CHECK_X11_MODULES):
# This rule is used to install the modules which use X11_FLAGS_TO_PASS.
# To build a target install-X means to cd to X and make install.
.PHONY: $(INSTALL_X11_MODULES)
-$(INSTALL_X11_MODULES):
+$(INSTALL_X11_MODULES): installdirs
@dir=`echo $@ | sed -e 's/install-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; \
$(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) install); \
@@ -1026,29 +1410,70 @@ $(INSTALL_X11_MODULES):
all-gcc:
@if [ -f ./gcc/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) all); \
else \
true; \
fi
-.PHONY: all-bootstrap
-all-bootstrap:
- @if [ -f ./gcc/Makefile ] ; then \
- r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
- $(SET_LIB_PATH) \
- (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) bootstrap); \
- else \
- true; \
- fi
+# Building GCC uses some tools for rebuilding "source" files
+# like texinfo, bison/byacc, etc. So we must depend on those.
+#
+# While building GCC, it may be necessary to run various target
+# programs like the assembler, linker, etc. So we depend on
+# those too.
+#
+# In theory, on an SMP all those dependencies can be resolved
+# in parallel.
+#
+.PHONY: bootstrap bootstrap-lean bootstrap2 bootstrap2-lean bootstrap3 bootstrap3-lean bootstrap4 bootstrap4-lean
+bootstrap bootstrap-lean bootstrap2 bootstrap2-lean bootstrap3 bootstrap3-lean bootstrap4 bootstrap4-lean: all-texinfo all-bison all-byacc all-binutils all-gas all-ld
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Bootstrapping the compiler"; \
+ cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) $@
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ case "$@" in \
+ *bootstrap4-lean ) \
+ msg="Comparing stage3 and stage4 of the compiler"; \
+ compare=compare3-lean ;; \
+ *bootstrap4 ) msg="Comparing stage3 and stage4 of the compiler"; \
+ compare=compare3 ;; \
+ *-lean ) msg="Comparing stage2 and stage3 of the compiler"; \
+ compare=compare-lean ;; \
+ * ) msg="Comparing stage2 and stage3 of the compiler"; \
+ compare=compare ;; \
+ esac; \
+ $(SET_LIB_PATH) \
+ echo "$$msg"; \
+ cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) $$compare
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd` ; export s; \
+ $(SET_LIB_PATH) \
+ echo "Building runtime libraries"; \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) all
+
+.PHONY: cross
+cross: all-texinfo all-bison all-byacc all-binutils all-gas all-ld
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Building the C and C++ compiler"; \
+ cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) LANGUAGES="c c++"
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd` ; export s; \
+ $(SET_LIB_PATH) \
+ echo "Building runtime libraries"; \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) all LANGUAGES="c c++"
.PHONY: check-gcc
check-gcc:
@if [ -f ./gcc/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) check); \
else \
@@ -1059,23 +1484,32 @@ check-gcc:
install-gcc:
@if [ -f ./gcc/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) install); \
else \
true; \
fi
-
+.PHONY: install-gcc-cross
+install-gcc-cross:
+ @if [ -f ./gcc/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) LANGUAGES="c c++" install); \
+ else \
+ true; \
+ fi
# EXPERIMENTAL STUFF
# This rule is used to install the modules which use FLAGS_TO_PASS.
# To build a target install-X means to cd to X and make install.
.PHONY: install-dosrel
-install-dosrel: install-dirs info
+install-dosrel: installdirs info
@dir=`echo $@ | sed -e 's/install-//'`; \
if [ -f ./$${dir}/Makefile ] ; then \
r=`pwd`; export r; \
- srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ s=`cd $(srcdir); pwd`; export s; \
$(SET_LIB_PATH) \
(cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) install); \
else \
@@ -1086,57 +1520,84 @@ install-dosrel-fake:
# This is a list of inter-dependencies among modules.
-all-autoconf: all-m4
-all-bfd:
-all-binutils: all-libiberty all-opcodes all-bfd all-flex all-byacc
+all-apache:
+all-ash:
+all-autoconf: all-m4 all-texinfo
+all-automake: all-m4 all-texinfo
+all-bash:
+all-bfd: all-libiberty all-intl
+all-binutils: all-libiberty all-opcodes all-bfd all-flex all-bison all-byacc all-intl
+all-bison: all-texinfo
+configure-target-bsp: $(ALL_GCC)
+all-target-bsp: configure-target-bsp all-gas all-ld all-gcc
all-byacc:
-all-cvs:
+all-bzip2:
+all-cvssrc:
+configure-target-cygmon: $(ALL_GCC)
+all-target-cygmon: configure-target-cygmon all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio all-target-libstub
+all-db:
all-dejagnu: all-tcl all-expect all-tk
all-diff: all-libiberty
all-emacs:
-all-emacs19: all-byacc
+all-emacs19: all-bison all-byacc
all-etc:
configure-target-examples: $(ALL_GCC)
all-target-examples: configure-target-examples
all-expect: all-tcl all-tk
all-fileutils: all-libiberty
+all-findutils:
all-find:
-all-flex: all-libiberty all-byacc
-all-gas: all-libiberty all-opcodes all-bfd
+all-flex: all-libiberty all-bison all-byacc
+all-gas: all-libiberty all-opcodes all-bfd all-intl
all-gash: all-tcl
all-gawk:
ALL_GCC = all-gcc
-all-gcc: all-libiberty all-byacc all-binutils all-gas all-ld
-all-bootstrap: all-libiberty all-byacc all-binutils all-gas all-ld
-GDB_TK = all-tk all-tcl
-all-gdb: all-libiberty all-opcodes all-bfd all-mmalloc all-readline all-byacc all-sim $(gdbnlmrequirements) $(GDB_TK)
-all-gprof: all-libiberty all-bfd all-opcodes
-all-grep: all-libiberty
+all-gcc: all-bison all-byacc all-binutils all-gas all-ld
+all-bootstrap: all-libiberty all-bison all-byacc all-binutils all-gas all-ld
+GDB_TK = all-tk all-tcl all-itcl all-tix all-libgui
+all-gdb: all-libiberty all-opcodes all-bfd all-mmalloc all-readline all-bison all-byacc all-sim $(gdbnlmrequirements) $(GDB_TK)
+all-gettext:
+all-gnuserv:
+configure-target-gperf: $(ALL_GCC)
+all-target-gperf: configure-target-gperf all-target-libiberty all-target-libstdc++
+all-gprof: all-libiberty all-bfd all-opcodes all-intl
all-grez: all-libiberty all-bfd all-opcodes
all-gui: all-gdb all-libproc all-target-librx
+all-guile:
all-gzip: all-libiberty
all-hello: all-libiberty
all-indent:
+all-inet: all-tcl all-send-pr all-perl
+all-intl:
all-ispell: all-emacs19
-all-ld: all-libiberty all-bfd all-opcodes all-byacc all-flex
+all-itcl: all-tcl all-tk all-tcl8.1 all-tk8.1
+all-ld: all-libiberty all-bfd all-opcodes all-bison all-byacc all-flex all-intl
configure-target-libg++: $(ALL_GCC) configure-target-librx
all-target-libg++: configure-target-libg++ all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio all-target-librx all-target-libstdc++
configure-target-libgloss: $(ALL_GCC)
all-target-libgloss: configure-target-libgloss configure-target-newlib
configure-target-libio: $(ALL_GCC)
all-target-libio: configure-target-libio all-gas all-ld all-gcc all-target-libiberty all-target-newlib
+check-target-libio: all-target-libstdc++
+all-libgui: all-tcl all-tk all-tcl8.1 all-tk8.1 all-itcl
all-libiberty:
configure-target-librx: $(ALL_GCC) configure-target-newlib
all-target-librx: configure-target-librx
configure-target-libstdc++: $(ALL_GCC)
all-target-libstdc++: configure-target-libstdc++ all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio
+configure-target-libstub: $(ALL_GCC)
+all-target-libstub: configure-target-libstub
+all-libtool:
all-m4: all-libiberty
all-make: all-libiberty
all-mmalloc:
configure-target-newlib: $(ALL_GCC)
+configure-target-libtermcap: $(ALL_GCC)
all-target-newlib: configure-target-newlib all-binutils all-gas all-gcc
+all-target-libtermcap: configure-target-libtermcap all-binutils all-gas all-gcc
all-opcodes: all-bfd all-libiberty
all-patch: all-libiberty
+all-perl:
all-prms: all-libiberty
all-rcs:
all-readline:
@@ -1144,46 +1605,35 @@ all-recode: all-libiberty
all-sed: all-libiberty
all-send-pr: all-prms
all-shellutils:
-all-sim: all-libiberty all-bfd all-opcodes
+all-sim: all-libiberty all-bfd all-opcodes all-readline
all-tar: all-libiberty
all-tcl:
+all-tcl8.1:
all-tclX: all-tcl all-tk
all-tk: all-tcl
+all-tk8.1: all-tcl8.1
all-texinfo: all-libiberty
all-textutils:
all-tgas: all-libiberty all-bfd all-opcodes
all-time:
+all-tix: all-tcl all-tk all-tcl8.1 all-tk8.1
all-wdiff:
-all-target-winsup: all-target-newlib all-target-libiberty configure-target-winsup
+all-target-winsup: all-target-newlib all-target-libiberty all-target-libtermcap configure-target-winsup
configure-target-winsup: configure-target-newlib
all-uudecode: all-libiberty
+all-zip:
configure-target-libiberty: $(ALL_GCC)
all-target-libiberty: configure-target-libiberty all-gcc all-ld all-target-newlib
-
+all-target: $(ALL_TARGET_MODULES)
+install-target: $(INSTALL_TARGET_MODULES)
### other supporting targets
MAKEDIRS= \
$(prefix) \
- $(exec_prefix) \
- $(tooldir)
-
-.PHONY: install-dirs
-install-dirs:
- @for i in $(MAKEDIRS) ; do \
- echo Making $$i... ; \
- parent=`echo $$i | sed -e 's@/[^/]*$$@@' | sed -e 's@^$$@/@'`; \
- if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi ; \
- if [ ! -d $$i ] ; then \
- if mkdir $$i ; then \
- true ; \
- else \
- exit 1 ; \
- fi ; \
- else \
- true ; \
- fi ; \
- done
-
+ $(exec_prefix)
+.PHONY: installdirs
+installdirs: mkinstalldirs
+ $(SHELL) $(srcdir)/mkinstalldirs $(MAKEDIRS)
dir.info: do-install-info
if [ -f $(srcdir)/texinfo/gen-info-dir ] ; then \
@@ -1208,7 +1658,7 @@ TAGS: do-TAGS
# with the gnu make, this is done automatically.
-Makefile: Makefile.in configure.in $(host_makefile_frag) $(target_makefile_frag)
+Makefile: Makefile.in configure.in $(host_makefile_frag) $(target_makefile_frag) $(gcc_version_trigger)
$(SHELL) ./config.status
#
@@ -1218,39 +1668,28 @@ Makefile: Makefile.in configure.in $(host_makefile_frag) $(target_makefile_frag)
# ChangeLog omitted because it may refer to files which are not in this
# distribution (perhaps it would be better to include it anyway).
DEVO_SUPPORT= README Makefile.in configure configure.in \
- config.guess config.sub config move-if-change \
- mpw-README mpw-build.in mpw-config.in mpw-configure \
- COPYING COPYING.LIB install.sh config-ml.in symlink-tree
+ config.guess config.if config.sub config move-if-change \
+ mpw-README mpw-build.in mpw-config.in mpw-configure mpw-install \
+ COPYING COPYING.LIB install-sh config-ml.in symlink-tree \
+ mkinstalldirs ltconfig ltmain.sh missing ylwrap
# Files in devo/etc used in any net release.
# ChangeLog omitted because it may refer to files which are not in this
# distribution (perhaps it would be better to include it anyway).
-ETC_SUPPORT= Makefile.in cfg-paper.texi configure.in configure.man \
- configure.texi standards.texi make-stds.texi \
- configure.info* standards.info* cfg-paper.info*
+ETC_SUPPORT= Makefile.in configure configure.in standards.texi \
+ make-stds.texi standards.info*
# When you use `make setup-dirs' or `make taz' you should always redefine
# this macro.
SUPPORT_FILES = list-of-support-files-for-tool-in-question
-# Files where "byacc" (Cygnus version) should be changed to "bison -y" (FSF).
-DISTBISONFILES= binutils/Makefile.in gas/Makefile.in gdb/Makefile.in
.PHONY: taz
taz: $(DEVO_SUPPORT) $(SUPPORT_FILES) \
texinfo/texinfo.tex texinfo/gpl.texinfo texinfo/lgpl.texinfo
- # Make sure "diststuff" files get built properly.
- for f in $(DISTBISONFILES) ; do \
- if [ -r $$f ]; then \
- sed '/^BISON *=.*$$/s/.*/BISON = bison -y/' <$$f >tmp ; \
- mv -f tmp $$f ; \
- else true; fi ; \
- done
- # Take out texinfo from a few places; make simple BISON=bison line.
+ # Take out texinfo from a few places.
sed -e '/^all\.normal: /s/\all-texinfo //' \
-e '/^ install-texinfo /d' \
- -e '/^BISON = /,/^$$/d' \
- -e '/^# BISON:/s/.*/BISON = bison -y/' \
<Makefile.in >tmp
mv -f tmp Makefile.in
#
@@ -1291,29 +1730,40 @@ taz: $(DEVO_SUPPORT) $(SUPPORT_FILES) \
<configure.in >proto-toplev/configure.in
#
mkdir proto-toplev/texinfo
- ln -s ../../texinfo/texinfo.tex proto-toplev/texinfo/
- ln -s ../../texinfo/gpl.texinfo proto-toplev/texinfo/
- ln -s ../../texinfo/lgpl.texinfo proto-toplev/texinfo/
- ln -s ../../texinfo/tex3patch proto-toplev/texinfo/
- chmod og=u `find . -print`
- (VER=`sed <$(TOOL)/Makefile.in -n 's/^VERSION *= *//p'`; \
- echo "==> Making $(TOOL)-$$VER.tar.gz"; \
- rm -f $(TOOL)-$$VER; ln -s proto-toplev $(TOOL)-$$VER; \
- tar cfh - $(TOOL)-$$VER \
- | $(GZIPPROG) -v -9 >$(TOOL)-$$VER.tar.gz )
+ ln -s ../../texinfo/texinfo.tex proto-toplev/texinfo/
+ ln -s ../../texinfo/gpl.texinfo proto-toplev/texinfo/
+ ln -s ../../texinfo/lgpl.texinfo proto-toplev/texinfo/
+ if test -r texinfo/util/tex3patch ; then \
+ mkdir proto-toplev/texinfo/util && \
+ ln -s ../../../texinfo/util/tex3patch proto-toplev/texinfo/util ; \
+ else true; fi
+ chmod -R og=u . || chmod og=u `find . -print`
+ if grep AM_INIT_AUTOMAKE $(TOOL)/configure.in >/dev/null 2>&1; then \
+ ver=`sed < $(TOOL)/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'`; \
+ else \
+ ver=`sed <$(TOOL)/Makefile.in -n 's/^VERSION *= *//p'`; \
+ fi; \
+ $(MAKE) -f Makefile.in do-tar-gz TOOL=$(TOOL) VER=$$ver
+
+do-tar-gz:
+ echo "==> Making $(TOOL)-$(VER).tar.gz"
+ -rm -f $(TOOL)-$(VER)
+ ln -s proto-toplev $(TOOL)-$(VER)
+ tar cfh $(TOOL)-$(VER).tar $(TOOL)-$(VER)
+ $(GZIPPROG) -v -9 $(TOOL)-$(VER).tar
TEXINFO_SUPPORT= texinfo/texinfo.tex texinfo/gpl.texinfo texinfo/lgpl.texinfo
DIST_SUPPORT= $(DEVO_SUPPORT) $(TEXINFO_SUPPORT)
.PHONY: gas.tar.gz
-GAS_SUPPORT_DIRS= bfd include libiberty opcodes
+GAS_SUPPORT_DIRS= bfd include libiberty opcodes intl setup.com makefile.vms
gas.tar.gz: $(DIST_SUPPORT) $(GAS_SUPPORT_DIRS) gas
$(MAKE) -f Makefile.in taz TOOL=gas \
SUPPORT_FILES="$(GAS_SUPPORT_DIRS)"
# The FSF "binutils" release includes gprof and ld.
.PHONY: binutils.tar.gz
-BINUTILS_SUPPORT_DIRS= bfd gas include libiberty opcodes ld gprof
+BINUTILS_SUPPORT_DIRS= bfd gas include libiberty opcodes ld gprof intl setup.com makefile.vms
binutils.tar.gz: $(DIST_SUPPORT) $(BINUTILS_SUPPORT_DIRS) binutils
$(MAKE) -f Makefile.in taz TOOL=binutils \
SUPPORT_FILES="$(BINUTILS_SUPPORT_DIRS) makeall.bat configure.bat"
@@ -1336,7 +1786,7 @@ gnats.tar.gz: $(DIST_SUPPORT) $(GNATS_SUPPORT_DIRS) gnats
SUPPORT_FILES="$(GNATS_SUPPORT_DIRS)"
.PHONY: gdb.tar.gz
-GDB_SUPPORT_DIRS= bfd include libiberty mmalloc opcodes readline sim utils
+GDB_SUPPORT_DIRS= bfd include libiberty mmalloc opcodes readline sim utils intl
gdb.tar.gz: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
$(MAKE) -f Makefile.in taz TOOL=gdb \
SUPPORT_FILES="$(GDB_SUPPORT_DIRS)"
@@ -1362,5 +1812,4 @@ newlib.tar.gz: $(DIST_SUPPORT) $(NEWLIB_SUPPORT_DIRS) newlib
.NOEXPORT:
MAKEOVERRIDES=
-
# end of Makefile.in
diff --git a/contrib/gdb/README b/contrib/gdb/README
index 7ec34b1..eb0e436 100644
--- a/contrib/gdb/README
+++ b/contrib/gdb/README
@@ -4,7 +4,7 @@ This directory contains various GNU compilers, assemblers, linkers,
debuggers, etc., plus their support routines, definitions, and documentation.
If you are receiving this as part of a GDB release, see the file gdb/README.
-If with a gas release, see gas/README; if with a libg++ release,
+If with a binutils release, see binutils/README; if with a libg++ release,
see libg++/README, etc. That'll give you info about this
package -- supported targets, how to use it, how to report bugs, etc.
@@ -19,7 +19,7 @@ To install them (by default in /usr/local/bin, /usr/local/lib, etc),
then do:
make install
-If the configure script can't determine your type of computer, give it
+(If the configure script can't determine your type of computer, give it
the name as an argument, for instance ``./configure sun4''. You can
use the script ``config.sub'' to test whether a name is recognized; if
it is, config.sub translates it to a triplet specifying CPU, vendor,
@@ -30,21 +30,18 @@ explicitly set CC in the environment before running configure, and to
also set CC when running make. For example (assuming sh/bash/ksh):
CC=gcc ./configure
- make CC=gcc
+ make
A similar example using csh:
setenv CC gcc
./configure
- make CC=gcc
-
-See etc/cfg-paper.texi, etc/configure.texi, and/or the README files in
-various subdirectories, for more details.
+ make
Much of the code and documentation enclosed is copyright by
the Free Software Foundation, Inc. See the file COPYING or
COPYING.LIB in the various directories, for a description of the
GNU General Public License terms under which you can copy the files.
-REPORTING BUGS: Again, see gdb/README, gas/README, etc., for info on where and
-how to report problems.
+REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info
+on where and how to report problems.
diff --git a/contrib/gdb/config-ml.in b/contrib/gdb/config-ml.in
new file mode 100644
index 0000000..3a159cf
--- /dev/null
+++ b/contrib/gdb/config-ml.in
@@ -0,0 +1,624 @@
+# Configure fragment invoked in the post-target section for subdirs
+# wanting multilib support.
+#
+# It is advisable to support a few --enable/--disable options to let the
+# user select which libraries s/he really wants.
+#
+# Subdirectories wishing to use multilib should put the following lines
+# in the "post-target" section of configure.in.
+#
+# if [ "${srcdir}" = "." ] ; then
+# if [ "${with_target_subdir}" != "." ] ; then
+# . ${with_multisrctop}../../config-ml.in
+# else
+# . ${with_multisrctop}../config-ml.in
+# fi
+# else
+# . ${srcdir}/../config-ml.in
+# fi
+#
+# See librx/configure.in in the libg++ distribution for an example of how
+# to handle autoconf'd libraries.
+#
+# Things are complicated because 6 separate cases must be handled:
+# 2 (native, cross) x 3 (absolute-path, relative-not-dot, dot) = 6.
+#
+# srcdir=. is special. It must handle make programs that don't handle VPATH.
+# To implement this, a symlink tree is built for each library and for each
+# multilib subdir.
+#
+# The build tree is layed out as
+#
+# ./
+# libg++
+# newlib
+# m68020/
+# libg++
+# newlib
+# m68881/
+# libg++
+# newlib
+#
+# The nice feature about this arrangement is that inter-library references
+# in the build tree work without having to care where you are. Note that
+# inter-library references also work in the source tree because symlink trees
+# are built when srcdir=.
+#
+# Unfortunately, trying to access the libraries in the build tree requires
+# the user to manually choose which library to use as GCC won't be able to
+# find the right one. This is viewed as the lesser of two evils.
+#
+# Configure variables:
+# ${with_target_subdir} = "." for native, or ${target_alias} for cross.
+# Set by top level Makefile.
+# ${with_multisrctop} = how many levels of multilibs there are in the source
+# tree. It exists to handle the case of configuring in the source tree:
+# ${srcdir} is not constant.
+# ${with_multisubdir} = name of multilib subdirectory (eg: m68020/m68881).
+#
+# Makefile variables:
+# MULTISRCTOP = number of multilib levels in source tree (+1 if cross)
+# (FIXME: note that this is different than ${with_multisrctop}. Check out.).
+# MULTIBUILDTOP = number of multilib levels in build tree
+# MULTIDIRS = list of multilib subdirs (eg: m68000 m68020 ...)
+# (only defined in each library's main Makefile).
+# MULTISUBDIR = installed subdirectory name with leading '/' (eg: /m68000)
+# (only defined in each multilib subdir).
+
+# FIXME: Multilib is currently disabled by default for everything other than
+# newlib. It is up to each target to turn on multilib support for the other
+# libraries as desired.
+
+# We have to handle being invoked by both Cygnus configure and Autoconf.
+#
+# Cygnus configure incoming variables:
+# srcdir, subdir, target, arguments
+#
+# Autoconf incoming variables:
+# srcdir, target, ac_configure_args
+#
+# We *could* figure srcdir and target out, but we'd have to do work that
+# our caller has already done to figure them out and requiring these two
+# seems reasonable.
+
+if [ -n "${ac_configure_args}" ]; then
+ Makefile=${ac_file-Makefile}
+ ml_config_shell=${CONFIG_SHELL-/bin/sh}
+ ml_arguments="${ac_configure_args}"
+ ml_realsrcdir=${srcdir}
+else
+ Makefile=${Makefile-Makefile}
+ ml_config_shell=${config_shell-/bin/sh}
+ ml_arguments="${arguments}"
+ if [ -n "${subdir}" -a "${subdir}" != "." ] ; then
+ ml_realsrcdir=${srcdir}/${subdir}
+ else
+ ml_realsrcdir=${srcdir}
+ fi
+fi
+
+# Scan all the arguments and set all the ones we need.
+
+ml_verbose=--verbose
+for option in ${ml_arguments}
+do
+ case $option in
+ --*) ;;
+ -*) option=-$option ;;
+ esac
+
+ case $option in
+ --*=*)
+ optarg=`echo $option | sed -e 's/^[^=]*=//'`
+ ;;
+ esac
+
+ case $option in
+ --disable-*)
+ enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'`
+ eval $enableopt=no
+ ;;
+ --enable-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+ enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $enableopt="$optarg"
+ ;;
+ --norecursion | --no*)
+ ml_norecursion=yes
+ ;;
+ --silent | --sil* | --quiet | --q*)
+ ml_verbose=--silent
+ ;;
+ --verbose | --v | --verb*)
+ ml_verbose=--verbose
+ ;;
+ --with-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+ withopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $withopt="$optarg"
+ ;;
+ --without-*)
+ withopt=`echo ${option} | sed 's:^--::;s:out::;s:-:_:g'`
+ eval $withopt=no
+ ;;
+ esac
+done
+
+# Only do this if --enable-multilib.
+if [ "${enable_multilib}" = yes ]; then
+
+# Compute whether this is the library's top level directory
+# (ie: not a multilib subdirectory, and not a subdirectory like libg++/src).
+# ${with_multisubdir} tells us we're in the right branch, but we could be
+# in a subdir of that.
+# ??? The previous version could void this test by separating the process into
+# two files: one that only the library's toplevel configure.in ran (to
+# configure the multilib subdirs), and another that all configure.in's ran to
+# update the Makefile. It seemed reasonable to collapse all multilib support
+# into one file, but it does leave us with having to perform this test.
+ml_toplevel_p=no
+if [ -z "${with_multisubdir}" ]; then
+ if [ "${srcdir}" = "." ]; then
+ # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}.
+ # ${with_target_subdir} = "." for native, otherwise target alias.
+ if [ "${with_target_subdir}" = "." ]; then
+ if [ -f ${ml_realsrcdir}/../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ else
+ if [ -f ${ml_realsrcdir}/../../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ fi
+ else
+ # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}.
+ if [ -f ${ml_realsrcdir}/../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ fi
+fi
+
+# If this is the library's top level directory, set multidirs to the
+# multilib subdirs to support. This lives at the top because we need
+# `multidirs' set right away.
+
+if [ "${ml_toplevel_p}" = yes ]; then
+
+multidirs=
+for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do
+ dir=`echo $i | sed -e 's/;.*$//'`
+ if [ "${dir}" = "." ]; then
+ true
+ else
+ if [ -z "${multidirs}" ]; then
+ multidirs="${dir}"
+ else
+ multidirs="${multidirs} ${dir}"
+ fi
+ fi
+done
+
+case "${target}" in
+arc-*-elf*)
+ if [ x$enable_biendian != xyes ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *be*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+m68*-*-*)
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68881 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68881* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68000 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68000* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68020 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68020* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+mips*-*-*)
+ if [ x$enable_single_float = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *single* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *el* ) : ;;
+ *eb* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+powerpc*-*-* | rs6000*-*-*)
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powercpu = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ power | */power | */power/* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powerpccpu = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *powerpc* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powerpcos = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-linux* | *mcall-solaris* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mlittle* | *mbig* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_sysv = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-sysv* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_aix = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-aix* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+esac
+
+# Remove extraneous blanks from multidirs.
+# Tests like `if [ -n "$multidirs" ]' require it.
+multidirs=`echo "$multidirs" | sed -e 's/^[ ][ ]*//' -e 's/[ ][ ]*$//' -e 's/[ ][ ]*/ /g'`
+
+# Add code to library's top level makefile to handle building the multilib
+# subdirs.
+
+cat > Multi.tem <<\EOF
+
+# FIXME: There should be an @-sign in front of the `if'.
+# Leave out until this is tested a bit more.
+multi-do:
+ if [ -z "$(MULTIDIRS)" ]; then \
+ true; \
+ else \
+ rootpre=`pwd`/; export rootpre; \
+ srcrootpre=`cd $(srcdir); pwd`/; export srcrootpre; \
+ lib=`echo $${rootpre} | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \
+ compiler="$(CC)"; \
+ for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \
+ dir=`echo $$i | sed -e 's/;.*$$//'`; \
+ if [ "$${dir}" = "." ]; then \
+ true; \
+ else \
+ if [ -d ../$${dir}/$${lib} ]; then \
+ flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
+ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS) $${flags}" \
+ CXXFLAGS="$(CXXFLAGS) $${flags}" \
+ LIBCFLAGS="$(LIBCFLAGS) $${flags}" \
+ LIBCXXFLAGS="$(LIBCXXFLAGS) $${flags}" \
+ LDFLAGS="$(LDFLAGS) $${flags}" \
+ $(DO)); then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ else true; \
+ fi; \
+ fi; \
+ done; \
+ fi
+
+# FIXME: There should be an @-sign in front of the `if'.
+# Leave out until this is tested a bit more.
+multi-clean:
+ if [ -z "$(MULTIDIRS)" ]; then \
+ true; \
+ else \
+ lib=`pwd | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \
+ for dir in Makefile $(MULTIDIRS); do \
+ if [ -f ../$${dir}/$${lib}/Makefile ]; then \
+ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \
+ then true; \
+ else exit 1; \
+ fi; \
+ else true; \
+ fi; \
+ done; \
+ fi
+EOF
+
+cat ${Makefile} Multi.tem > Makefile.tem
+rm -f ${Makefile} Multi.tem
+mv Makefile.tem ${Makefile}
+
+fi # ${ml_toplevel_p} = yes
+
+if [ "${ml_verbose}" = --verbose ]; then
+ echo "Adding multilib support to Makefile in ${ml_realsrcdir}"
+ if [ "${ml_toplevel_p}" = yes ]; then
+ echo "multidirs=${multidirs}"
+ fi
+ echo "with_multisubdir=${with_multisubdir}"
+fi
+
+if [ "${srcdir}" = "." ]; then
+ if [ "${with_target_subdir}" != "." ]; then
+ ml_srcdotdot="../"
+ else
+ ml_srcdotdot=""
+ fi
+else
+ ml_srcdotdot=""
+fi
+
+if [ -z "${with_multisubdir}" ]; then
+ ml_subdir=
+ ml_builddotdot=
+ : # ml_srcdotdot= # already set
+else
+ ml_subdir="/${with_multisubdir}"
+ # The '[^/][^/]*' appears that way to work around a SunOS sed bug.
+ ml_builddotdot=`echo ${with_multisubdir} | sed -e 's:[^/][^/]*:..:g'`/
+ if [ "$srcdir" = "." ]; then
+ ml_srcdotdot=${ml_srcdotdot}${ml_builddotdot}
+ else
+ : # ml_srcdotdot= # already set
+ fi
+fi
+
+if [ "${ml_toplevel_p}" = yes ]; then
+ ml_do='$(MAKE)'
+ ml_clean='$(MAKE)'
+else
+ ml_do=true
+ ml_clean=true
+fi
+
+# TOP is used by newlib and should not be used elsewhere for this purpose.
+# MULTI{SRC,BUILD}TOP are the proper ones to use. MULTISRCTOP is empty
+# when srcdir != builddir. MULTIBUILDTOP is always some number of ../'s.
+# FIXME: newlib needs to be updated to use MULTI{SRC,BUILD}TOP so we can
+# delete TOP. Newlib may wish to continue to use TOP for its own purposes
+# of course.
+# MULTIDIRS is non-empty for the cpu top level Makefile (eg: newlib/Makefile)
+# and lists the subdirectories to recurse into.
+# MULTISUBDIR is non-empty in each cpu subdirectory's Makefile
+# (eg: newlib/h8300h/Makefile) and is the installed subdirectory name with
+# a leading '/'.
+# MULTIDO is used for targets like all, install, and check where
+# $(FLAGS_TO_PASS) augmented with the subdir's compiler option is needed.
+# MULTICLEAN is used for the *clean targets.
+#
+# ??? It is possible to merge MULTIDO and MULTICLEAN into one. They are
+# currently kept separate because we don't want the *clean targets to require
+# the existence of the compiler (which MULTIDO currently requires) and
+# therefore we'd have to record the directory options as well as names
+# (currently we just record the names and use --print-multi-lib to get the
+# options).
+
+sed -e "s:^TOP[ ]*=[ ]*\([./]*\)[ ]*$:TOP = ${ml_builddotdot}\1:" \
+ -e "s:^MULTISRCTOP[ ]*=.*$:MULTISRCTOP = ${ml_srcdotdot}:" \
+ -e "s:^MULTIBUILDTOP[ ]*=.*$:MULTIBUILDTOP = ${ml_builddotdot}:" \
+ -e "s:^MULTIDIRS[ ]*=.*$:MULTIDIRS = ${multidirs}:" \
+ -e "s:^MULTISUBDIR[ ]*=.*$:MULTISUBDIR = ${ml_subdir}:" \
+ -e "s:^MULTIDO[ ]*=.*$:MULTIDO = $ml_do:" \
+ -e "s:^MULTICLEAN[ ]*=.*$:MULTICLEAN = $ml_clean:" \
+ ${Makefile} > Makefile.tem
+rm -f ${Makefile}
+mv Makefile.tem ${Makefile}
+
+# If this is the library's top level, configure each multilib subdir.
+# This is done at the end because this is the loop that runs configure
+# in each multilib subdir and it seemed reasonable to finish updating the
+# Makefile before going on to configure the subdirs.
+
+if [ "${ml_toplevel_p}" = yes ]; then
+
+# We must freshly configure each subdirectory. This bit of code is
+# actually partially stolen from the main configure script. FIXME.
+
+if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then
+
+ if [ "${ml_verbose}" = --verbose ]; then
+ echo "Running configure in multilib subdirs ${multidirs}"
+ echo "pwd: `pwd`"
+ fi
+
+ ml_origdir=`pwd`
+ ml_libdir=`echo $ml_origdir | sed -e 's,^.*/,,'`
+ # cd to top-level-build-dir/${with_target_subdir}
+ cd ..
+
+ for ml_dir in ${multidirs}; do
+
+ if [ "${ml_verbose}" = --verbose ]; then
+ echo "Running configure in multilib subdir ${ml_dir}"
+ echo "pwd: `pwd`"
+ fi
+
+ if [ -d ${ml_dir} ]; then true; else mkdir ${ml_dir}; fi
+ if [ -d ${ml_dir}/${ml_libdir} ]; then true; else mkdir ${ml_dir}/${ml_libdir}; fi
+
+ # Eg: if ${ml_dir} = m68000/m68881, dotdot = ../../
+ dotdot=../`echo ${ml_dir} | sed -e 's|[^/]||g' -e 's|/|../|g'`
+
+ case ${srcdir} in
+ ".")
+ echo Building symlink tree in `pwd`/${ml_dir}/${ml_libdir}
+ if [ "${with_target_subdir}" != "." ]; then
+ ml_unsubdir="../"
+ else
+ ml_unsubdir=""
+ fi
+ (cd ${ml_dir}/${ml_libdir};
+ ../${dotdot}${ml_unsubdir}symlink-tree ../${dotdot}${ml_unsubdir}${ml_libdir} "")
+ if [ -f ${ml_dir}/${ml_libdir}/Makefile ]; then
+ if [ x"${MAKE}" = x ]; then
+ (cd ${ml_dir}/${ml_libdir}; make distclean)
+ else
+ (cd ${ml_dir}/${ml_libdir}; ${MAKE} distclean)
+ fi
+ fi
+ ml_newsrcdir="."
+ ml_srcdiroption=
+ multisrctop=${dotdot}
+ ;;
+ *)
+ case "${srcdir}" in
+ /*) # absolute path
+ ml_newsrcdir=${srcdir}
+ ;;
+ *) # otherwise relative
+ ml_newsrcdir=${dotdot}${srcdir}
+ ;;
+ esac
+ ml_srcdiroption="-srcdir=${ml_newsrcdir}"
+ multisrctop=
+ ;;
+ esac
+
+ case "${progname}" in
+ /*) ml_recprog=${progname} ;;
+ *) ml_recprog=${dotdot}${progname} ;;
+ esac
+
+ # FIXME: POPDIR=${PWD=`pwd`} doesn't work here.
+ ML_POPDIR=`pwd`
+ cd ${ml_dir}/${ml_libdir}
+
+ if [ -f ${ml_newsrcdir}/configure ]; then
+ ml_recprog=${ml_newsrcdir}/configure
+ fi
+ if eval ${ml_config_shell} ${ml_recprog} \
+ --with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \
+ ${ml_arguments} ${ml_srcdiroption} ; then
+ true
+ else
+ exit 1
+ fi
+
+ cd ${ML_POPDIR}
+
+ done
+
+ cd ${ml_origdir}
+fi
+
+fi # ${ml_toplevel_p} = yes
+fi # ${enable_multilib} = yes
diff --git a/contrib/gdb/config.guess b/contrib/gdb/config.guess
index c3c4e79..3263584 100755
--- a/contrib/gdb/config.guess
+++ b/contrib/gdb/config.guess
@@ -1,6 +1,6 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -51,15 +51,55 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- alpha:OSF1:[VX]*:*)
- # After 1.2, OSF1 uses "V1.3" for uname -r.
- # After 4.x, OSF1 uses "X4.x" for uname -r.
- echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VX]//'`
- exit 0 ;;
alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo alpha-dec-osf${UNAME_RELEASE}
- exit 0 ;;
+ cat <<EOF >dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
@@ -69,21 +109,58 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
- Pyramid*:OSx*:*:*)
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
- sun4*:SunOS:5.*:*)
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
- echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -103,25 +180,81 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
- mips:*:4*:UMIPS)
- echo mips-mips-riscos4sysv
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
- mips:*:5*:RISCos)
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy \
+ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
@@ -138,8 +271,8 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`uname -p`
- if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88100 ] ; then
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
@@ -165,10 +298,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i[34]86:AIX:*:*)
+ i?86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
@@ -213,7 +346,7 @@ EOF
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -227,12 +360,48 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
- 9000/[3478]??:HP-UX:*:*)
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
- 9000/8?? ) HP_ARCH=hppa1.0 ;;
+ 9000/[678][0-9][0-9] )
+
+ sed 's/^ //' << EOF >dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy`
+ rm -f dummy.c dummy
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -279,6 +448,13 @@ EOF
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
@@ -306,64 +482,219 @@ EOF
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
- CRAY*C90:*:*:*)
- echo c90-cray-unicos${UNAME_RELEASE}
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
- i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ if test -x /usr/bin/objformat; then
+ if test "elf" = "`/usr/bin/objformat`"; then
+ echo ${UNAME_MACHINE}-unknown-freebsdelf`echo${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+ exit 0
+ fi
+ fi
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
- i*:CYGWIN*:*)
- echo i386-unknown-cygwin32
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:[Cc][Yy][Gg][Ww][Ii][Nn]*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin32
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
*:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
- if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
- echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
- echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
- echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
- echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
- echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
- elif test "${UNAME_MACHINE}" = "alpha" ; then
- echo alpha-unknown-linux ; exit 0
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc)
+ # Determine Lib Version
+ cat >dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ ${CC-cc} dummy.c -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.c dummy
+ echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
else
- # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
- # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
- test ! -d /usr/lib/ldscripts/. \
- && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
+#include <features.h>
main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
#ifdef __ELF__
- printf ("%s-unknown-linux\n", argv[1]);
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
#else
- printf ("%s-unknown-linuxaout\n", argv[1]);
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
@@ -373,32 +704,63 @@ EOF
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
- i[34]86:DYNIX/ptx:4*:*)
+ i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0 ;;
- i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
- i[34]86:*:3.2:*)
+ i?86:*:5:7*)
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+# 5.0.4c returns "Pent II". 5.0.5 returns PentII
+ (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
- echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
+ (/bin/uname -X|egrep '^Machine.*PentII' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pent II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
- echo ${UNAME_MACHINE}-unknown-sysv32
+ echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
Intel:Mach:3*:*)
- echo i386-unknown-mach3
+ echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
@@ -414,28 +776,36 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
- M680[234]0:*:R3V[567]*:*)
+ M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
- uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3 && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- uname -p 2>/dev/null | grep 86 >/dev/null \
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
- m680[234]0:LynxOS:2.[23]*:*)
- echo m68k-lynx-lynxos${UNAME_RELEASE}
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
- i[34]86:LynxOS:2.[23]*:*)
- echo i386-lynx-lynxos${UNAME_RELEASE}
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
- TSUNAMI:LynxOS:2.[23]*:*)
- echo sparc-lynx-lynxos${UNAME_RELEASE}
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
- rs6000:LynxOS:2.[23]*:*)
- echo rs6000-lynx-lynxos${UNAME_RELEASE}
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
@@ -448,16 +818,41 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
- R3000:*System_V*:*:*)
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -501,7 +896,7 @@ main ()
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
@@ -518,7 +913,7 @@ main ()
#endif
#if defined (__386BSD__)
- printf ("i386-unknown-bsd\n"); exit (0);
+ printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
diff --git a/contrib/gdb/config.if b/contrib/gdb/config.if
new file mode 100644
index 0000000..bcc0269
--- /dev/null
+++ b/contrib/gdb/config.if
@@ -0,0 +1,87 @@
+#! /dev/null
+# Don't call it directly. This shell script fragment is called to
+# determine:
+#
+# 1. libstcxx_interface: the interface name for libstdc++.
+# 2. cxx_interface: the interface name for c++.
+# 3. libc_interface: the interface name for libc.
+#
+
+# Get the top level src dir.
+if [ -z "${topsrcdir}" -a -z "${top_srcdir}" ]
+then
+ echo "Undefined top level src dir: topsrcdir and top_srcdir are empty" >&2
+ exit 1
+fi
+
+if [ -n "${topsrcdir}" ]
+then
+ if_topsrcdir=${topsrcdir}
+else
+ if_topsrcdir=${top_srcdir}
+fi
+
+if [ -f ${if_topsrcdir}/libstdc++/Makefile.in ]; then
+# We check libstdc++ for libstdcxx_interface.
+libstdcxx_interface=`grep "^INTERFACE" ${if_topsrcdir}/libstdc++/Makefile.in | sed 's/INTERFACE[ ]*=[ ]*\(.*\)/\1/'`
+else
+libstdcxx_interface=
+fi
+
+if [ -f ${if_topsrcdir}/gcc/cp/Makefile.in ]; then
+# We check gcc/cp for cxx_interface.
+cxx_interface=`grep "^INTERFACE" ${if_topsrcdir}/gcc/cp/Makefile.in | sed 's/INTERFACE[ ]*=[ ]*\(.*\)/\1/'`
+else
+cxx_interface=
+fi
+
+# The trickiest part is libc_interface.
+if [ -z "${libc_interface}" ]
+then
+ case ${target_os} in
+ *linux*libc1*|*linux*libc5*)
+ case ${target_alias} in
+ *alpha*|*powerpc*)
+ libc_interface=-libc5.9-
+ ;;
+ *)
+ libc_interface=-libc5-
+ ;;
+ esac
+ ;;
+ *linux*gnu*)
+ # We have to work harder to figure it out.
+ if [ ${target_alias} = ${build_alias} ]
+ then
+ dummy=if$$
+ cat >$dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ printf("%d\n", __GLIBC_MINOR__);
+ return 0;
+}
+EOF
+ ${CC-cc} $dummy.c -o $dummy 2>/dev/null
+ if [ "$?" = 0 ]
+ then
+ libc_interface=-libc6.`./$dummy`-
+ rm -f $dummy.c $dummy
+ else
+ # It should never happen.
+ echo "Cannot find the GNU C library minor version number." >&2
+ rm -f $dummy.c $dummy
+ exit 1
+ fi
+ else
+ # Cross compiling. Assume glibc 2.1.
+ libc_interface=-libc6.1-
+ fi
+ ;;
+ *)
+ libc_interface=-
+ ;;
+ esac
+fi
diff --git a/contrib/gdb/config.sub b/contrib/gdb/config.sub
index c462f8a..3ce1136 100755
--- a/contrib/gdb/config.sub
+++ b/contrib/gdb/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
+# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -41,6 +41,8 @@
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
@@ -62,11 +64,33 @@ case $1 in
;;
esac
-# Separate what the user gave into CPU-COMPANY and OS (if any).
-basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-if [ $basic_machine != $1 ]
-then os=`echo $1 | sed 's/.*-/-/'`
-else os=; fi
+# CYGNUS LOCAL marketing-names
+# Here we handle any "marketing" names - translating them to
+# standard triplets
+case $1 in
+ mips-tx39-elf)
+ set mipstx39-unknown-elf
+ ;;
+ *)
+ ;;
+esac
+# END CYGNUS LOCAL marketing-names
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
@@ -81,7 +105,8 @@ case $os in
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
os=
basic_machine=$1
;;
@@ -89,10 +114,6 @@ case $os in
os=
basic_machine=$1
;;
- -apple*) # CYGNUS LOCAL
- os=
- basic_machine=$1
- ;;
-scout) # CYGNUS LOCAL
;;
-wrs) # CYGNUS LOCAL
@@ -103,34 +124,37 @@ case $os in
os=-hiuxwe2
;;
-sco5)
- os=sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
@@ -150,16 +174,27 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
- tahoe | i[3456]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
- | arme[lb] | pyramid \
- | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
- | alpha | we32k | ns16k | clipper | i370 | sh \
- | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
- | pdp11 | mips64el | mips64orion | mips64orionel \
- | sparc | sparclet | sparclite | sparc64)
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 \
+ | tron | a29k | 580 | i960 | h8300 \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | alpha | alphaev[45678] | alphaev56 | alphapca5[67] \
+ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp11 \
+ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+ | mipstx39 | mipstx39el \
+ | sparc | sparclet | sparclite | sparc64 | sparc86x | v850 \
+ | c4x)
basic_machine=$basic_machine-unknown
;;
- m88110 | m680[01234]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
+ m88110 | m680[012346]0 | m683?2 | m68360 | m5200 | z8k | v70 \
+ | h8500 | w65 | fr30) # CYGNUS LOCAL
+ basic_machine=$basic_machine-unknown
+ ;;
+ strongarm) # CYGNUS LOCAL nickc/strongarm
+ basic_machine=$basic_machine-unknown
+ ;;
+ thumb)
basic_machine=$basic_machine-unknown
;;
mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith/vr4300
@@ -168,27 +203,85 @@ case $basic_machine in
mips64vr4100 | mips64vr4100el) # CYGNUS LOCAL jsmith/vr4100
basic_machine=$basic_machine-unknown
;;
+ mips64vr5000 | mips64vr5000el) # CYGNUS LOCAL ian/vr5000
+ basic_machine=$basic_machine-unknown
+ ;;
+ mips16)
+ basic_machine=$basic_machine-unknown
+ ;;
+ tic30) # CYGNUS LOCAL ian/tic30
+ basic_machine=$basic_machine-unknown
+ ;;
+ c30) # CYGNUS LOCAL ian/tic30
+ basic_machine=tic30-unknown
+ ;;
+
+ v850e) # CYGNUS LOCAL jtc/v850
+ basic_machine=$basic_machine-unknown
+ ;;
+ v850ea) # CYGNUS LOCAL jtc/v850
+ basic_machine=$basic_machine-unknown
+ ;;
+ d10v)
+ basic_machine=$basic_machine-unknown
+ ;;
+ d30v) # CYGNUS LOCAL hunt/d30v
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
- | sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
- | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
- | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
- | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
- | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-*)
- ;;
- m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-*) # CYGNUS LOCAL
- ;;
+ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+ | xmp-* | ymp-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* \
+ | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+ | alpha-* | alphaev[45678]-* | alphaev56-* | alphapca5[67]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* \
+ | xps100-* | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | sparcv9-* | sparc86x-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-* \
+ | fr30-*) # CYGNUS LOCAL
+ ;;
+ m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-* | d10v-*) # CYGNUS LOCAL
+ ;;
+ strongarm-*) # CYGNUS LOCAL nickc/strongarm
+ ;;
+ thumb-*) # CYGNUS LOCAL angela/thumb
+ ;;
+ v850-*) # CYGNUS LOCAL
+ ;;
+ v850e-*) # CYGNUS LOCAL
+ ;;
+ v850ea-*) # CYGNUS LOCAL
+ ;;
+ d30v-*) # CYGNUS LOCAL
+ ;;
mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith/vr4300
;;
mips64vr4100-* | mips64vr4100el-*) # CYGNUS LOCAL jsmith/vr4100
;;
+ mips16-*) # CYGNUS LOCAL krk/mips16
+ ;;
+ tic30-*) # CYGNUS LOCAL ian/tic30
+ ;;
+ c30-*) # CYGNUS LOCAL ian/tic30
+ basic_machine=tic30-unknown
+ ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd) # CYGNUS LOCAL
@@ -226,9 +319,9 @@ case $basic_machine in
amiga | amiga-*)
basic_machine=m68k-cbm
;;
- amigados)
+ amigaos | amigados)
basic_machine=m68k-cbm
- os=-amigados
+ os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-cbm
@@ -242,10 +335,6 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
- arm | armel | armeb)
- basic_machine=arm-arm
- os=-aout
- ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -282,6 +371,10 @@ case $basic_machine in
basic_machine=cray2-cray
os=-unicos
;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
crds | unos)
basic_machine=m68k-crds
;;
@@ -379,18 +472,39 @@ case $basic_machine in
basic_machine=hppa1.1-hp
os=-proelf
;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
- hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ hp9k6[0-9][0-9] | hp6[0-9][0-9] )
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9] )
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9] )
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | \
+ hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893 )
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679] )
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
+ hppa-next)
+ os=-nextstep3
+ ;;
hppaosf) # CYGNUS LOCAL
basic_machine=hppa1.1-hp
os=-osf
@@ -400,20 +514,20 @@ case $basic_machine in
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[3456]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
- i[3456]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
- i[3456]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
- i[3456]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach) # CYGNUS LOCAL
@@ -428,6 +542,10 @@ case $basic_machine in
basic_machine=i386-unknown
os=-go32
;;
+ i386-mingw32 | mingw32)
+ basic_machine=i386-unknown
+ os=-mingw32
+ ;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -456,6 +574,14 @@ case $basic_machine in
miniframe)
basic_machine=m68000-convergent
;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -519,7 +645,7 @@ case $basic_machine in
basic_machine=i960-intel
os=-nindy
;;
- mon960)
+ mon960) # CYGNUS LOCAL
basic_machine=i960-intel
os=-mon960
;;
@@ -551,25 +677,23 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
- pentium | p5)
- basic_machine=i586-intel
+ pentium | p5 | k5 | nexen)
+ basic_machine=i586-pc
;;
- pentiumpro | p6)
- basic_machine=i686-intel
+ pentiumpro | p6 | k6 | 6x86)
+ basic_machine=i686-pc
;;
- pentium-* | p5-*)
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- pentiumpro-* | p6-*)
+ pentiumpro-* | p6-* | k6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- k5)
- # We don't have specific support for AMD's K5 yet, so just call it a Pentium
- basic_machine=i586-amd
- ;;
- nexen)
- # We don't have specific support for Nexgen yet, so just call it a Pentium
- basic_machine=i586-nexgen
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@@ -672,6 +796,12 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -695,6 +825,9 @@ case $basic_machine in
basic_machine=vax-dec
os=-vms
;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -739,7 +872,11 @@ case $basic_machine in
basic_machine=hppa1.1-oki
;;
mips)
- basic_machine=mips-mips
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
;;
romp)
basic_machine=romp-ibm
@@ -756,7 +893,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sparc)
+ sparc | sparcv9)
basic_machine=sparc-sun
;;
cydra)
@@ -774,6 +911,10 @@ case $basic_machine in
pmac | pmac-mpw) # CYGNUS LOCAL
basic_machine=powerpc-apple
;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
@@ -797,6 +938,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -804,38 +947,46 @@ case $os in
-solaris)
os=-solaris2
;;
- -unixware* | svr4*)
+ -svr4*)
os=-sysv4
;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
-gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux|'`
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* | -aof* \
- | -nindy* | -mon960* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
- | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -cygwin32* | -pe* | -psos*)
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
# CYGNUS LOCAL
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -proelf | -os9* \
- | -macos* | -mpw* | -magic*)
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mon960* | -lnews* )
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
# END CYGNUS LOCAL
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
@@ -952,12 +1103,18 @@ case $basic_machine in
mips*-cisco) # CYGNUS LOCAL
os=-elf
;;
+ mips*-*) # CYGNUS LOCAL
+ os=-elf
+ ;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
+ *-be)
+ os=-beos
+ ;;
*-ibm)
os=-aix
;;
@@ -980,7 +1137,7 @@ case $basic_machine in
os=-sysv
;;
*-cbm)
- os=-amigados
+ os=-amigaos
;;
*-dg)
os=-dgux
@@ -1030,6 +1187,9 @@ case $basic_machine in
*-masscomp)
os=-rtu
;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
*-rom68k) # CYGNUS LOCAL
os=-coff
;;
@@ -1057,18 +1217,18 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
- -bosx*) # CYGNUS LOCAL
- vendor=bull
- ;;
- -lynxos*)
- vendor=lynx
- ;;
-aix*)
vendor=ibm
;;
+ -beos*)
+ vendor=be
+ ;;
-hpux*)
vendor=hp
;;
+ -mpeix*)
+ vendor=hp
+ ;;
-hiux*)
vendor=hitachi
;;
@@ -1090,7 +1250,7 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
- -vxworks*)
+ -vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
diff --git a/contrib/gdb/configure b/contrib/gdb/configure
index f284be1..a63a3fb 100755
--- a/contrib/gdb/configure
+++ b/contrib/gdb/configure
@@ -3,7 +3,8 @@
### WARNING: this file contains embedded tabs. Do not run untabify on this file.
# Configuration script
-# Copyright (C) 1988, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
+# Copyright (C) 1988, 90, 91, 92, 93, 94, 95, 96, 1997
+# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -47,20 +48,25 @@ Makefile=Makefile
Makefile_in=Makefile.in
arguments=
build_alias=
-cache_file=
+cache_file=config.cache
cache_file_option=
configdirs=
+extraconfigdirs=
+diroptions=
exec_prefix=
exec_prefixoption=
fatal=
floating_point=default
gas=default
+gcc_version=
+gcc_version_trigger=
host_alias=NOHOST
host_makefile_frag=
moveifchange=
norecursion=
other_options=
package_makefile_frag=
+package_makefile_rules_frag=
prefix=/usr/local
progname=
program_prefix=
@@ -69,7 +75,7 @@ program_suffix=
program_suffixoption=
program_transform_name=
program_transform_nameoption=
-redirect=">/dev/null"
+redirect=
removing=
site=
site_makefile_frag=
@@ -80,11 +86,54 @@ subdirs=
target_alias=NOTARGET
target_makefile_frag=
undefs=NOUNDEFS
-version="$Revision: 1.222.4.1 $"
+version="$Revision: 1.270 $"
x11=default
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
### we might need to use some other shell than /bin/sh for running subshells
-#
+
+### If we are on Windows, search for the shell. This will permit people
+### to not have /bin/sh, but to be able to see /SOME/PATH/sh configure
+### without also having to set CONFIG_SHELL. This code will work when
+### using bash, which sets OSTYPE.
+case "${OSTYPE}" in
+*win32*)
+ if [ x${CONFIG_SHELL} = x ]; then
+ if [ ! -f /bin/sh ]; then
+ if [ x${SHELL} != x ] && [ -f ${SHELL} ]; then
+ CONFIG_SHELL=${SHELL}
+ export CONFIG_SHELL
+ else
+ for prog in sh sh.exe bash bash.exe; do
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/$prog; then
+ CONFIG_SHELL=$dir/$prog
+ export CONFIG_SHELL
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ test -n "${CONFIG_SHELL}" && break
+ done
+ fi
+ fi
+ fi
+ ;;
+esac
+
config_shell=${CONFIG_SHELL-/bin/sh}
NO_EDIT="This file was generated automatically by configure. Do not edit."
@@ -157,6 +206,10 @@ do
# Now, process the options
case $option in
+ --bi*)
+ bindir=$optarg
+ diroptions="$diroptions --bindir=$optarg"
+ ;;
--build* | --bu*)
case "$build_alias" in
"") build_alias=$optarg ;;
@@ -168,6 +221,10 @@ do
--cache*)
cache_file=$optarg
;;
+ --da*)
+ datadir=$optarg
+ diroptions="$diroptions --datadir=$optarg"
+ ;;
--disable-*)
enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'`
eval $enableopt=no
@@ -201,6 +258,30 @@ do
;;
esac
;;
+ --inc*)
+ includedir=$optarg
+ diroptions="$diroptions --includedir=$optarg"
+ ;;
+ --inf*)
+ infodir=$optarg
+ diroptions="$diroptions --infodir=$optarg"
+ ;;
+ --libd*)
+ libdir=$optarg
+ diroptions="$diroptions --libdir=$optarg"
+ ;;
+ --libe*)
+ libexecdir=$optarg
+ diroptions="$diroptions --libexecdir=$optarg"
+ ;;
+ --lo*)
+ localstatedir=$optarg
+ diroptions="$diroptions --localstatedir=$optarg"
+ ;;
+ --ma*)
+ mandir=$optarg
+ diroptions="$diroptions --mandir=$optarg"
+ ;;
--nfp | --nf*)
floating_point=no
floating_pointoption="--nfp"
@@ -208,6 +289,10 @@ do
--norecursion | --no*)
norecursion=yes
;;
+ --ol*)
+ oldincludedir=$optarg
+ diroptions="$diroptions --oldincludedir=$optarg"
+ ;;
--prefix* | --pre*)
prefix=$optarg
prefixoption="--prefix=$optarg"
@@ -228,6 +313,14 @@ do
--rm)
removing=--rm
;;
+ --sb*)
+ sbindir=$optarg
+ diroptions="$diroptions --sbindir=$optarg"
+ ;;
+ --sh*)
+ sharedstatedir=$optarg
+ diroptions="$diroptions --sharedstatedir=$optarg"
+ ;;
--silent | --sil* | --quiet | --q*)
redirect=">/dev/null"
verbose=--silent
@@ -246,6 +339,10 @@ do
--srcdir* | --sr*)
srcdir=$optarg
;;
+ --sy*)
+ sysconfdir=$optarg
+ diroptions="$diroptions --sysconfdir=$optarg"
+ ;;
--target* | --ta*)
case $target_alias in
NOTARGET) target_alias=$optarg ;;
@@ -286,9 +383,6 @@ do
;;
--x-i* | --x-l*) other_options="$other_options $orig_option"
;;
- --bi* | --sb* | --li* | --da* | --sy* | --sh* | --lo* | --in* | --ol* | --ma*)
- # These options were added to autoconf for emacs.
- ;;
--*)
echo "configure: Unrecognized option: \"$orig_option\"; use --help for usage." >&2
exit 1
@@ -340,7 +434,7 @@ case "${fatal}" in
# Neither --host option nor undefs were present.
# Call config.guess.
guesssys=`echo ${progname} | sed 's/configure$/config.guess/'`
- if host_alias=`${guesssys}`
+ if host_alias=`${config_shell} ${guesssys}`
then
# If the string we are going to use for
# the target is a prefix of the string
@@ -424,9 +518,11 @@ fi
configsub=`echo ${progname} | sed 's/configure$/config.sub/'`
moveifchange=`echo ${progname} | sed 's/configure$/move-if-change/'`
+topsrcdir=`cd \`dirname ${progname}\`; pwd`
+
# this is a hack. sun4 must always be a valid host alias or this will fail.
-if ${configsub} sun4 >/dev/null 2>&1 ; then
+if ${config_shell} ${configsub} sun4 >/dev/null 2>&1 ; then
true
else
echo '***' cannot find config.sub. 1>&2
@@ -434,7 +530,7 @@ else
fi
touch config.junk
-if ${moveifchange} config.junk config.trash ; then
+if ${config_shell} ${moveifchange} config.junk config.trash ; then
true
else
echo '***' cannot find move-if-change. 1>&2
@@ -480,12 +576,35 @@ case "${srcdir}" in
fi
esac
+
# default exec_prefix
case "${exec_prefixoption}" in
"") exec_prefix="\$(prefix)" ;;
*) ;;
esac
+# Define the trigger file to make sure configure will re-run whenever
+# the gcc version number changes.
+if [ "${with_gcc_version_trigger+set}" = set ]; then
+ gcc_version_trigger="$with_gcc_version_trigger"
+ gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${with_gcc_version_trigger}`
+else
+ # If gcc's sources are available, define the trigger file.
+ if [ -f ${topsrcdir}/gcc/version.c ] ; then
+ gcc_version_trigger=${topsrcdir}/gcc/version.c
+ gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}`
+ case "$arguments" in
+ *--with-gcc-version-trigger=$gcc_version_trigger* )
+ ;;
+ * )
+ # Make sure configure.in knows about this.
+ arguments="--with-gcc-version-trigger=$gcc_version_trigger $arguments"
+ ;;
+ esac
+ withoptions="--with-gcc-version-trigger=$gcc_version_trigger $withoptions"
+ fi
+fi
+
### break up ${srcdir}/configure.in.
case "`grep '^# per\-host:' ${srcdir}/configure.in`" in
"")
@@ -508,7 +627,7 @@ case "`grep '^# per\-host:' ${srcdir}/configure.in`" in
eval exec ${config_shell} ${srcdir}/configure ${verbose} \
${buildopt} --host=${host_alias} --target=${target_alias} \
${prefixoption} ${tmpdiroption} ${exec_prefixoption} \
- ${srcdiroption} \
+ ${srcdiroption} ${diroptions} \
${program_prefixoption} ${program_suffixoption} \
${program_transform_nameoption} ${site_option} \
${withoptions} ${withoutoptions} \
@@ -559,8 +678,24 @@ fi
### do common part of configure.in
+# If the language specific compiler does not exist, but the "gcc" directory does,
+# we will skip this directory; in this case the sub-directory's common part
+# of configure.in will create a small shell script "skip-this-dir" containing
+# commands to completely clean up any temporary or created files.
+
. ${tmpfile}.com
+if test -f skip-this-dir; then
+ # Perform the same cleanup as the trap handler, minus the "exit 1" of course,
+ # and reset the trap handler.
+ trap 0
+ rm -f Makefile* ${tmpfile}.com ${tmpfile}.tgt ${tmpfile}.hst ${tmpfile}.pos
+ # Execute the final clean-up actions
+ ${config_shell} skip-this-dir
+ # and stop configuring this directory.
+ exit 0
+fi
+
# some sanity checks on configure.in
case "${srctrigger}" in
"")
@@ -573,9 +708,9 @@ esac
case "${build_alias}" in
"")
if result=`${config_shell} ${configsub} ${host_alias}` ; then
- build_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
- build_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
- build_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+ build_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+ build_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+ build_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
build=${build_cpu}-${build_vendor}-${build_os}
build_alias=${host_alias}
fi
@@ -583,9 +718,9 @@ case "${build_alias}" in
*)
if result=`${config_shell} ${configsub} ${build_alias}` ; then
buildopt="--build=${build_alias}"
- build_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
- build_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
- build_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+ build_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+ build_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+ build_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
build=${build_cpu}-${build_vendor}-${build_os}
else
echo "Unrecognized build system name ${build_alias}." 1>&2
@@ -600,9 +735,9 @@ else
echo "Unrecognized host system name ${host_alias}." 1>&2
exit 1
fi
-host_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+host_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
host=${host_cpu}-${host_vendor}-${host_os}
. ${tmpfile}.hst
@@ -613,9 +748,9 @@ else
echo "Unrecognized target system name ${target_alias}." 1>&2
exit 1
fi
-target_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-target_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-target_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+target_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
target=${target_cpu}-${target_vendor}-${target_os}
. ${tmpfile}.tgt
@@ -670,26 +805,46 @@ fi
# If CC and CXX are not set in the environment, and the Makefile
# exists, try to extract them from it. This is to handle running
# ./config.status by hand.
-if [ -z "${CC}" -a -r Makefile ]; then
+if [ -z "${CC}" ] && [ -r Makefile ]; then
sed -n -e ':loop
/\\$/ N
-/\\$/ b loop
s/\\\n//g
+t loop
/^CC[ ]*=/ s/CC[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
CC=`tail -1 Makefile.cc`
rm -f Makefile.cc
fi
-if [ -z "${CXX}" -a -r Makefile ]; then
+if [ -z "${CFLAGS}" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^CFLAGS[ ]*=/ s/CFLAGS[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CFLAGS=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+if [ -z "${CXX}" ] && [ -r Makefile ]; then
sed -n -e ':loop
/\\$/ N
-/\\$/ b loop
s/\\\n//g
+t loop
/^CXX[ ]*=/ s/CXX[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
CXX=`tail -1 Makefile.cc`
rm -f Makefile.cc
fi
+if [ -z "${CXXFLAGS}" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^CXXFLAGS[ ]*=/ s/CXXFLAGS[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CXXFLAGS=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
# Generate a default definition for YACC. This is used if the makefile can't
# locate bison or byacc in objdir.
@@ -709,6 +864,25 @@ do
test -n "$DEFAULT_YACC" && break
done
+# Generate a default definition for M4. This is used if the makefile can't
+# locate m4 in objdir.
+
+for prog in gm4 gnum4 m4
+do
+ set dummy $prog; tmp=$2
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/$tmp; then
+ DEFAULT_M4="$prog"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ test -n "$DEFAULT_M4" && break
+done
+
# Generate a default definition for LEX. This is used if the makefile can't
# locate flex in objdir.
@@ -734,16 +908,17 @@ if [ "${build}" != "${host}" ]; then
tools="AR AR_FOR_TARGET AS AS_FOR_TARGET BISON CC_FOR_BUILD"
tools="${tools} CC_FOR_TARGET CXX_FOR_TARGET"
- tools="${tools} DLLTOOL DLLTOOL_FOR_TARGET HOST_PREFIX"
+ tools="${tools} DLLTOOL DLLTOOL_FOR_TARGET GCC_FOR_TARGET HOST_PREFIX"
tools="${tools} HOST_PREFIX_1 LD LD_FOR_TARGET LEX MAKEINFO NM"
tools="${tools} NM_FOR_TARGET RANLIB RANLIB_FOR_TARGET"
+ tools="${tools} WINDRES WINDRES_FOR_TARGET YACC"
for var in ${tools}; do
- if [ -z "`eval 'echo $'"${var}"`" -a -r Makefile ]; then
+ if [ -z "`eval 'echo $'"${var}"`" ] && [ -r Makefile ]; then
sed -n -e ':loop
/\\$/ N
-/\\$/ b loop
s/\\\n//g
+t loop
/^'"${var}"'[ ]*=/ s/'"${var}"'[ ]*=[ ]*\(.*\)/\1/p' \
< Makefile > Makefile.v
t=`tail -1 Makefile.v`
@@ -758,13 +933,17 @@ s/\\\n//g
AR_FOR_TARGET=${AR_FOR_TARGET-${target_alias}-ar}
AS=${AS-${host_alias}-as}
AS_FOR_TARGET=${AS_FOR_TARGET-${target_alias}-as}
+ BISON=${BISON-bison}
CC=${CC-${host_alias}-gcc}
- CXX=${CXX-${host_alias}-gcc}
+ CFLAGS=${CFLAGS-"-g -O2"}
+ CXX=${CXX-${host_alias}-c++}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
CC_FOR_TARGET=${CC_FOR_TARGET-${target_alias}-gcc}
- CXX_FOR_TARGET=${CXX_FOR_TARGET-${target_alias}-gcc}
+ CXX_FOR_TARGET=${CXX_FOR_TARGET-${target_alias}-c++}
DLLTOOL=${DLLTOOL-${host_alias}-dlltool}
DLLTOOL_FOR_TARGET=${DLLTOOL_FOR_TARGET-${target_alias}-dlltool}
+ GCC_FOR_TARGET=${GCC_FOR_TARGET-${CC_FOR_TARGET-${target_alias}-gcc}}
HOST_PREFIX=${build_alias}-
HOST_PREFIX_1=${build_alias}-
LD=${LD-${host_alias}-ld}
@@ -774,26 +953,30 @@ s/\\\n//g
NM_FOR_TARGET=${NM_FOR_TARGET-${target_alias}-nm}
RANLIB=${RANLIB-${host_alias}-ranlib}
RANLIB_FOR_TARGET=${RANLIB_FOR_TARGET-${target_alias}-ranlib}
+ WINDRES=${WINDRES-${host_alias}-windres}
+ WINDRES_FOR_TARGET=${WINDRES_FOR_TARGET-${target_alias}-windres}
- if [ -z "${BISON}" ]; then
+ if [ -z "${YACC}" ]; then
IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
for dir in $PATH; do
test -z "$dir" && dir=.
- if test -f $dir/byacc; then
- BISON=byacc
+ if test -f $dir/bison; then
+ YACC="bison -y"
break
fi
- if test -f $dir/bison; then
- BISON=bison
+ if test -f $dir/byacc; then
+ YACC=byacc
break
fi
if test -f $dir/yacc; then
- BISON=yacc
+ YACC=yacc
break
fi
done
IFS="$save_ifs"
- BISON=${BISON-bison}
+ if [ -z "${YACC}" ]; then
+ YACC="bison -y"
+ fi
fi
if [ -z "${LEX}" ]; then
@@ -821,6 +1004,7 @@ s/\\\n//g
export LD
export NM
export RANLIB
+ export WINDRES
else
# If CC is still not set, try to get gcc.
if [ -z "${CC}" ]; then
@@ -828,31 +1012,51 @@ else
for dir in $PATH; do
test -z "$dir" && dir=.
if test -f $dir/gcc; then
- CC="gcc -O2"
+ CC="gcc"
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC} -g -c conftest.c 2>&1`"; then
+ CFLAGS=${CFLAGS-"-g -O2"}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
+ else
+ CFLAGS=${CFLAGS-"-O2"}
+ CXXFLAGS=${CXXFLAGS-"-O2"}
+ fi
+ rm -f conftest*
break
fi
done
IFS="$save_ifs"
CC=${CC-cc}
+ else
+ if test -z "${CFLAGS}"; then
+ # Here CC is set but CFLAGS is not. Use a quick hack to use -O2 if CC
+ # is set to a version of gcc.
+ case "${CC}" in
+ *gcc)
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC} -g -c conftest.c 2>&1`"; then
+ CFLAGS=${CFLAGS-"-g -O2"}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
+ else
+ CFLAGS=${CFLAGS-"-O2"}
+ CXXFLAGS=${CXXFLAGS-"-O2"}
+ fi
+ rm -f conftest*
+ ;;
+ esac
+ fi
fi
- CXX=${CXX-"gcc"}
+ CXX=${CXX-"c++"}
+ CFLAGS=${CFLAGS-"-g"}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
fi
export CC
export CXX
+export CFLAGS
+export CXXFLAGS
-case "$host" in
- *go32*)
- enable_gdbtk=no ;;
-esac
-
-# Determine whether gdb needs tk/tcl or not.
-if [ "$enable_gdbtk" != "no" ]; then
- GDB_TK="all-tcl all-tk"
-else
- GDB_TK=""
-fi
for subdir in . ${subdirs} ; do
@@ -911,27 +1115,34 @@ for subdir in . ${subdirs} ; do
set ${links}; link=$1; shift; links=$*
if [ ! -r ${srcdir}/${file} ] ; then
+ if [ ! -r ${file} ] ; then
+
echo '***' "${progname}: cannot create a link \"${link}\"," 1>&2
echo '***' "since the file \"${srcdir}/${file}\" does not exist." 1>&2
exit 1
+ else
+ srcfile=${file}
+ fi
+ else
+ srcfile=${srcdir}/${file}
fi
${remove} -f ${link}
# Make a symlink if possible, otherwise try a hard link
- if ${symbolic_link} ${srcdir}/${file} ${link} >/dev/null 2>&1 ; then
+ if ${symbolic_link} ${srcfile} ${link} >/dev/null 2>&1 ; then
true
else
# We need to re-remove the file because Lynx leaves a
# very strange directory there when it fails an NFS symlink.
${remove} -r -f ${link}
- ${hard_link} ${srcdir}/${file} ${link}
+ ${hard_link} ${srcfile} ${link}
fi
if [ ! -r ${link} ] ; then
- echo '***' "${progname}: unable to link \"${link}\" to \"${srcdir}/${file}\"." 1>&2
+ echo '***' "${progname}: unable to link \"${link}\" to \"${srcfile}\"." 1>&2
exit 1
fi
- echo "Linked \"${link}\" to \"${srcdir}/${file}\"."
+ echo "Linked \"${link}\" to \"${srcfile}\"."
done
# Create a .gdbinit file which runs the one in srcdir
@@ -957,88 +1168,101 @@ EOF
# been somewhat optimized and is perhaps a bit twisty.
# code is order so as to try to sed the smallest input files we know.
+ # so do these separately because I don't trust the order of sed -e expressions.
- # the four makefile fragments MUST end up in the resulting Makefile in this order:
- # package, target, host, and site. so do these separately because I don't trust the
- # order of sed -e expressions.
+ # the five makefile fragments MUST end up in the resulting Makefile in this order:
+ # package macros, target, host, site, and package rules.
if [ -f ${srcdir}/${subdir}/${Makefile_in} ] ; then
- # Conditionalize for this site from "Makefile.in" (or whatever it's called) into Makefile.tem
- rm -f ${subdir}/Makefile.tem
- case "${site}" in
+ # Conditionalize the makefile for this package from "Makefile.in" (or whatever it's called) into Makefile.tem.
+ rm -f ${subdir}/${Makefile}.tem
+ case "${package_makefile_rules_frag}" in
"") cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem ;;
*)
+ if [ ! -f ${package_makefile_rules_frag} ] ; then
+ package_makefile_rules_frag=${srcdir}/${package_makefile_rules_frag}
+ fi
+ if [ -f ${package_makefile_rules_frag} ] ; then
+ sed -e "/^####/ r ${package_makefile_rules_frag}" ${srcdir}/${subdir}/${Makefile_in} > ${Makefile}.tem
+ else
+ echo '***' Expected package makefile rules fragment \"${package_makefile_rules_frag}\" 1>&2
+ echo '***' is missing in ${PWD=`pwd`}. 1>&2
+ cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem
+ fi
+ esac
+ # working copy now in ${Makefile}.tem
+
+ # Conditionalize for this site.
+ rm -f ${Makefile}
+ case "${site}" in
+ "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ *)
site_makefile_frag=${srcdir}/config/ms-${site}
if [ -f ${site_makefile_frag} ] ; then
- sed -e "/^####/ r ${site_makefile_frag}" ${srcdir}/${subdir}/${Makefile_in} \
- > ${subdir}/Makefile.tem
+ sed -e "/^####/ r ${site_makefile_frag}" ${subdir}/Makefile.tem \
+ > ${Makefile}
else
- cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem
+ mv ${subdir}/Makefile.tem ${Makefile}
site_makefile_frag=
fi
;;
esac
- # working copy now in ${subdir}/Makefile.tem
+ # working copy now in ${Makefile}
# Conditionalize the makefile for this host.
- rm -f ${Makefile}
+ rm -f ${subdir}/Makefile.tem
case "${host_makefile_frag}" in
- "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ "") mv ${Makefile} ${subdir}/Makefile.tem ;;
*)
if [ ! -f ${host_makefile_frag} ] ; then
host_makefile_frag=${srcdir}/${host_makefile_frag}
fi
if [ -f ${host_makefile_frag} ] ; then
- sed -e "/^####/ r ${host_makefile_frag}" ${subdir}/Makefile.tem > ${Makefile}
+ sed -e "/^####/ r ${host_makefile_frag}" ${Makefile} > ${subdir}/Makefile.tem
else
echo '***' Expected host makefile fragment \"${host_makefile_frag}\" 1>&2
echo '***' is missing in ${PWD=`pwd`}. 1>&2
- mv ${subdir}/Makefile.tem ${Makefile}
+ mv ${Makefile} ${subdir}/Makefile.tem
fi
esac
- # working copy now in ${Makefile}
+ # working copy now in ${subdir)/Makefile.tem
# Conditionalize the makefile for this target.
- rm -f ${subdir}/Makefile.tem
+ rm -f ${Makefile}
case "${target_makefile_frag}" in
- "") mv ${Makefile} ${subdir}/Makefile.tem ;;
+ "") mv ${subdir}/Makefile.tem ${Makefile} ;;
*)
if [ ! -f ${target_makefile_frag} ] ; then
target_makefile_frag=${srcdir}/${target_makefile_frag}
fi
if [ -f ${target_makefile_frag} ] ; then
- sed -e "/^####/ r ${target_makefile_frag}" ${Makefile} > ${subdir}/Makefile.tem
+ sed -e "/^####/ r ${target_makefile_frag}" ${subdir}/Makefile.tem > ${Makefile}
else
- mv ${Makefile} ${subdir}/Makefile.tem
+ mv ${subdir}/Makefile.tem ${Makefile}
target_makefile_frag=
fi
;;
esac
- # real copy now in ${subdir}/Makefile.tem
+ # working copy now in ${Makefile}
- # Conditionalize the makefile for this package.
- rm -f ${Makefile}
+ # Emit the default values of this package's macros.
+ rm -f ${subdir}/Makefile.tem
case "${package_makefile_frag}" in
- "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ "") mv ${Makefile} ${subdir}/Makefile.tem ;;
*)
if [ ! -f ${package_makefile_frag} ] ; then
package_makefile_frag=${srcdir}/${package_makefile_frag}
fi
if [ -f ${package_makefile_frag} ] ; then
- sed -e "/^####/ r ${package_makefile_frag}" ${subdir}/Makefile.tem > ${Makefile}
- rm -f ${subdir}/Makefile.tem
+ sed -e "/^####/ r ${package_makefile_frag}" ${Makefile} > ${subdir}/Makefile.tem
else
- echo '***' Expected package makefile fragment \"${package_makefile_frag}\" 1>&2
+ echo '***' Expected package makefile fragment \"${package_makefile_rules_frag}\" 1>&2
echo '***' is missing in ${PWD=`pwd`}. 1>&2
- mv ${subdir}/Makefile.tem ${Makefile}
+ mv ${Makefile} ${subdir}/Makefile.tem
fi
esac
- # working copy now in ${Makefile}
-
- mv ${Makefile} ${subdir}/Makefile.tem
-
# real copy now in ${subdir}/Makefile.tem
# prepend warning about editting, and a bunch of variables.
@@ -1091,43 +1315,118 @@ EOF
echo site_makefile_frag = ${invsubdir}${site_makefile_frag} >>${Makefile}
fi
+ # provide a proper gxx_include_dir to all subdirs.
+ # Note, if you change the default, make sure to fix both here
+ # and in the gcc subdirectory.
+ # Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
+ gxx_include_dir=
+ if test -n "${with_gxx_include_dir}"; then
+ case "${with_gxx_include_dir}" in
+ yes )
+ echo "configure: error: bad value ${withval} given for g++ include directory" 1>&2
+ exit 1
+ ;;
+ no )
+ ;;
+ * )
+ gxx_include_dir=${with_gxx_include_dir}
+ ;;
+ esac
+ fi
+ if test x${gxx_include_dir} = x; then
+ if test x${enable_version_specific_runtime_libs} = xyes; then
+ echo gxx_include_dir = '${libsubdir}/include/g++' >> ${Makefile}
+ else
+ . ${topsrcdir}/config.if
+ echo gxx_include_dir = '${prefix}/include/g++'-${libstdcxx_interface} >> ${Makefile}
+ fi
+ else
+ echo gxx_include_dir = ${gxx_include_dir} >> ${Makefile}
+ fi
+
+ # record if we want to build shared libs.
+ if test -z "${enable_shared}"; then
+ echo enable_shared = no >> ${Makefile}
+ else
+ echo enable_shared = ${enable_shared} >> ${Makefile}
+ fi
+ # record if we want to rumtime library stuff installed in libsubdir.
+ if test -z "${enable_version_specific_runtime_libs}"; then
+ echo enable_version_specific_runtime_libs = no >> ${Makefile}
+ else
+ echo enable_version_specific_runtime_libs = ${enable_version_specific_runtime_libs} >> ${Makefile}
+ fi
+
+ # Emit a macro which describes the file containing gcc's
+ # version number.
+ echo gcc_version_trigger = ${gcc_version_trigger} >> ${Makefile}
+ # And emit a macro defining gcc's version number.
+ echo gcc_version = ${gcc_version} >> ${Makefile}
+
# reset prefix, exec_prefix, srcdir, SUBDIRS, NONSUBDIRS,
# remove any form feeds.
if [ -z "${subdirs}" ]; then
- rm -f ${subdir}/Makefile.tem2
+ rm -f ${subdir}/Makefile.tm2
sed -e "s:^SUBDIRS[ ]*=.*$:SUBDIRS = ${configdirs}:" \
-e "s:^NONSUBDIRS[ ]*=.*$:NONSUBDIRS = ${noconfigdirs}:" \
- ${subdir}/Makefile.tem > ${subdir}/Makefile.tem2
+ ${subdir}/Makefile.tem > ${subdir}/Makefile.tm2
rm -f ${subdir}/Makefile.tem
- mv ${subdir}/Makefile.tem2 ${subdir}/Makefile.tem
- fi
- sed -e "s:^prefix[ ]*=.*$:prefix = ${prefix}:" \
- -e "s:^exec_prefix[ ]*=.*$:exec_prefix = ${exec_prefix}:" \
+ mv ${subdir}/Makefile.tm2 ${subdir}/Makefile.tem
+ fi
+ sed -e "s|^prefix[ ]*=.*$|prefix = ${prefix}|" \
+ -e "s|^exec_prefix[ ]*=.*$|exec_prefix = ${exec_prefix}|" \
+ -e "s|^bindir[ ]*=.*$|bindir = ${bindir}|" \
+ -e "s|^sbindir[ ]*=.*$|sbindir = ${sbindir}|" \
+ -e "s|^libexecdir[ ]*=.*$|libexecdir = ${libexecdir}|" \
+ -e "s|^datadir[ ]*=.*$|datadir = ${datadir}|" \
+ -e "s|^sysconfdir[ ]*=.*$|sysconfdir = ${sysconfdir}|" \
+ -e "s|^sharedstatedir[ ]*=.*$|sharedstatedir = ${sharedstatedir}|" \
+ -e "s|^localstatedir[ ]*=.*$|localstatedir = ${localstatedir}|" \
+ -e "s|^libdir[ ]*=.*$|libdir = ${libdir}|" \
+ -e "s|^includedir[ ]*=.*$|includedir = ${includedir}|" \
+ -e "s|^oldincludedir[ ]*=.*$|oldincludedir = ${oldincludedir}|" \
+ -e "s|^infodir[ ]*=.*$|infodir = ${infodir}|" \
+ -e "s|^mandir[ ]*=.*$|mandir = ${mandir}|" \
-e "/^CC[ ]*=/{
:loop1
/\\\\$/ N
- /\\\\$/ b loop1
s/\\\\\\n//g
+ t loop1
s%^CC[ ]*=.*$%CC = ${CC}%
}" \
-e "/^CXX[ ]*=/{
:loop2
/\\\\$/ N
- /\\\\$/ b loop2
s/\\\\\\n//g
+ t loop2
s%^CXX[ ]*=.*$%CXX = ${CXX}%
}" \
- -e "s:^SHELL[ ]*=.*$:SHELL = ${config_shell}:" \
- -e "s:^GDB_TK[ ]*=.*$:GDB_TK = ${GDB_TK}:" \
- -e "s:^srcdir[ ]*=.*$:srcdir = ${makesrcdir}:" \
+ -e "/^CFLAGS[ ]*=/{
+ :loop3
+ /\\\\$/ N
+ s/\\\\\\n//g
+ t loop3
+ s%^CFLAGS[ ]*=.*$%CFLAGS = ${CFLAGS}%
+ }" \
+ -e "/^CXXFLAGS[ ]*=/{
+ :loop4
+ /\\\\$/ N
+ s/\\\\\\n//g
+ t loop4
+ s%^CXXFLAGS[ ]*=.*$%CXXFLAGS = ${CXXFLAGS}%
+ }" \
+ -e "s|^SHELL[ ]*=.*$|SHELL = ${config_shell}|" \
+ -e "s|^srcdir[ ]*=.*$|srcdir = ${makesrcdir}|" \
-e "s/ //" \
-e "s:^program_prefix[ ]*=.*$:program_prefix = ${program_prefix}:" \
-e "s:^program_suffix[ ]*=.*$:program_suffix = ${program_suffix}:" \
-e "s:^program_transform_name[ ]*=.*$:program_transform_name = ${program_transform_name}:" \
- -e "s:^tooldir[ ]*=.*$:tooldir = ${tooldir}:" \
+ -e "s|^tooldir[ ]*=.*$|tooldir = ${tooldir}|" \
-e "s:^DEFAULT_YACC[ ]*=.*$:DEFAULT_YACC = ${DEFAULT_YACC}:" \
-e "s:^DEFAULT_LEX[ ]*=.*$:DEFAULT_LEX = ${DEFAULT_LEX}:" \
+ -e "s:^DEFAULT_M4[ ]*=.*$:DEFAULT_M4 = ${DEFAULT_M4}:" \
${subdir}/Makefile.tem >> ${Makefile}
+
# If this is a Canadian Cross, preset the values of many more
# tools.
@@ -1202,27 +1501,41 @@ ${progname}" ${arguments} "
if [ -r ${subdir}/config.back ] ; then
mv -f ${subdir}/config.back ${subdir}/config.status
fi
- ${moveifchange} ${subdir}/config.new ${subdir}/config.status
+ ${config_shell} ${moveifchange} ${subdir}/config.new ${subdir}/config.status
;;
*) rm -f ${Makefile} ${subdir}/config.status ${links} ;;
esac
done
-# If there are subdirectories, then recur.
-if [ -z "${norecursion}" -a -n "${configdirs}" ] ; then
- for configdir in ${configdirs} ; do
+# If there are subdirectories, then recur.
+if [ -z "${norecursion}" ] && [ -n "${configdirs}" ] ; then
+ for configdir in ${configdirs} ${extraconfigdirs} ; do
+
+ # If configdir contains ',' it is
+ # srcdir,builddir,target_alias
+ # These come from extraconfigdirs.
+ case ${configdir} in
+ *,*)
+ eval `echo ${configdir} | sed -e 's/\([^,]*\),\([^,]*\),\(.*\)/cfg_dir=\1 bld_dir=\2 tgt_alias=\3/'`
+ ;;
+ *)
+ cfg_dir=${configdir}
+ bld_dir=${configdir}
+ tgt_alias=${target_alias}
+ ;;
+ esac
- if [ -d ${srcdir}/${configdir} ] ; then
+ if [ -d ${srcdir}/${cfg_dir} ] ; then
eval echo Configuring ${configdir}... ${redirect}
case "${srcdir}" in
".") ;;
*)
- if [ ! -d ./${configdir} ] ; then
- if mkdir ./${configdir} ; then
+ if [ ! -d ./${bld_dir} ] ; then
+ if mkdir ./${bld_dir} ; then
true
else
- echo '***' "${progname}: could not make ${PWD=`pwd`}/${configdir}" 1>&2
+ echo '***' "${progname}: could not make ${PWD=`pwd`}/${bld_dir}" 1>&2
exit 1
fi
fi
@@ -1230,17 +1543,21 @@ if [ -z "${norecursion}" -a -n "${configdirs}" ] ; then
esac
POPDIR=${PWD=`pwd`}
- cd ${configdir}
+ cd ${bld_dir}
### figure out what to do with srcdir
case "${srcdir}" in
".") newsrcdir=${srcdir} ;; # no -srcdir option. We're building in place.
/*) # absolute path
- newsrcdir=${srcdir}/${configdir}
+ newsrcdir=${srcdir}/${cfg_dir}
+ srcdiroption="--srcdir=${newsrcdir}"
+ ;;
+ ?:*) # absolute path on win32
+ newsrcdir=${srcdir}/${cfg_dir}
srcdiroption="--srcdir=${newsrcdir}"
;;
*) # otherwise relative
- newsrcdir=../${srcdir}/${configdir}
+ newsrcdir=../${srcdir}/${cfg_dir}
srcdiroption="--srcdir=${newsrcdir}"
;;
esac
@@ -1252,6 +1569,9 @@ if [ -z "${norecursion}" -a -n "${configdirs}" ] ; then
/*) # absolute path
cache_file_option="--cache-file=${cache_file}"
;;
+ ?:*) # absolute path on win32
+ cache_file_option="--cache-file=${cache_file}"
+ ;;
*) # relative path
cache_file_option="--cache-file=../${cache_file}"
;;
@@ -1263,18 +1583,19 @@ if [ -z "${norecursion}" -a -n "${configdirs}" ] ; then
elif [ -f ${newsrcdir}/configure.in ] ; then
case "${progname}" in
/*) recprog=${progname} ;;
+ ?:*) recprog=${progname} ;;
*) recprog=../${progname} ;;
esac
else
- eval echo No configuration information in ${configdir} ${redirect}
+ eval echo No configuration information in ${cfg_dir} ${redirect}
recprog=
fi
### The recursion line is here.
if [ ! -z "${recprog}" ] ; then
- if eval ${config_shell} ${recprog} ${verbose} ${buildopt} --host=${host_alias} --target=${target_alias} \
+ if eval ${config_shell} ${recprog} ${verbose} ${buildopt} --host=${host_alias} --target=${tgt_alias} \
${prefixoption} ${tmpdiroption} ${exec_prefixoption} \
- ${srcdiroption} ${program_prefixoption} ${program_suffixoption} ${program_transform_nameoption} ${site_option} ${withoptions} ${withoutoptions} ${enableoptions} ${disableoptions} ${floating_pointoption} ${cache_file_option} ${removing} ${other_options} ${redirect} ; then
+ ${srcdiroption} ${diroptions} ${program_prefixoption} ${program_suffixoption} ${program_transform_nameoption} ${site_option} ${withoptions} ${withoutoptions} ${enableoptions} ${disableoptions} ${floating_pointoption} ${cache_file_option} ${removing} ${other_options} ${redirect} ; then
true
else
echo Configure in `pwd` failed, exiting. 1>&2
diff --git a/contrib/gdb/configure.in b/contrib/gdb/configure.in
index fd35114..eb7fc71 100644
--- a/contrib/gdb/configure.in
+++ b/contrib/gdb/configure.in
@@ -1,3 +1,4 @@
+#! /bin/bash
##############################################################################
## This file is a shell script fragment that supplies the information
@@ -13,6 +14,23 @@
## For more information on these two systems, check out the documentation
## for 'Autoconf' (autoconf.texi) and 'Configure' (configure.texi).
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999
+# Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
##############################################################################
### To add a new directory to the tree, first choose whether it is a target
@@ -24,26 +42,27 @@
# these libraries are used by various programs built for the host environment
#
-host_libs="mmalloc libiberty opcodes bfd readline gash tcl tk tclX"
+host_libs="intl mmalloc libiberty opcodes bfd readline gash db tcl tk tcl8.1 tk8.1 tclX itcl tix libgui"
if [ "${enable_gdbgui}" = "yes" ] ; then
host_libs="${host_libs} libgui"
fi
# these tools are built for the host environment
-#
-host_tools="byacc flex bison binutils ld gas gcc gdb make patch
- prms send-pr gprof gdbtest tgas etc expect dejagnu sim
- m4 autoconf ispell grep diff rcs cvs fileutils shellutils
- textutils wdiff find emacs emacs19 uudecode hello tar gzip indent
- recode release sed utils"
-
+# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
+# know that we are building the simulator.
+host_tools="byacc flex bison binutils ld gas gcc sim gdb make patch prms send-pr gprof gdbtest tgas etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool ispell grep diff rcs cvssrc fileutils shellutils time textutils wdiff find emacs emacs19 uudecode hello tar gzip indent recode release sed utils guile perl apache inet gawk findutils snavigator libtool gettext zip"
# these libraries are built for the target environment, and are built after
# the host libraries and the host tools (which may be a cross compiler)
#
-target_libs="target-libiberty target-libgloss target-newlib target-libio target-librx target-libstdc++ target-libg++"
-
+target_libs="target-libiberty \
+ target-libgloss \
+ target-newlib \
+ target-libio \
+ target-librx \
+ target-libstdc++ \
+ target-libg++"
# these tools are built using the target libs, and are intended to run only
# in the target environment
@@ -52,7 +71,7 @@ target_libs="target-libiberty target-libgloss target-newlib target-libio target-
# list belongs in this list. those programs are also very likely
# candidates for the "native_only" list which follows
#
-target_tools="target-examples target-groff"
+target_tools="target-examples target-groff target-gperf"
################################################################################
@@ -64,13 +83,13 @@ target_tools="target-examples target-groff"
# directories to be built in the native environment only
#
-native_only="autoconf cvs emacs emacs19 fileutils find grep gzip hello
- indent ispell m4 rcs recode sed shellutils tar textutils gash
- uudecode wdiff gprof target-groff"
+# This must be a single line because of the way it is searched by grep in
+# the code below.
+native_only="autoconf automake libtool cvssrc emacs emacs19 fileutils find gawk gettext grep gzip hello indent ispell m4 rcs recode sed shellutils tar textutils gash uudecode wdiff gprof target-groff guile perl apache inet time ash bash bzip2 prms snavigator gnuserv target-gperf"
# directories to be built in a cross environment only
#
-cross_only="target-libiberty target-libgloss target-newlib"
+cross_only="target-libgloss target-newlib target-cygmon target-opcodes target-libstub"
## All tools belong in one of the four categories, and are assigned above
## We assign ${configdirs} this way to remove all embedded newlines. This
@@ -94,45 +113,132 @@ appdirs=""
# Work in distributions that contain no compiler tools, like Autoconf.
if [ -d ${srcdir}/config ]; then
case "${host}" in
- m68k-hp-hpux*) host_makefile_frag=config/mh-hp300 ;;
- m68k-apollo-sysv*) host_makefile_frag=config/mh-apollo68 ;;
- m68k-apollo-bsd*) host_makefile_frag=config/mh-a68bsd ;;
- m68k-*-linux*) host_makefile_frag=config/mh-linux ;;
- m88k-dg-dgux*) host_makefile_frag=config/mh-dgux ;;
- m88k-harris-cxux*) host_makefile_frag=config/mh-cxux ;;
- m88k-motorola-sysv*) host_makefile_frag=config/mh-delta88;;
- mips*-dec-ultrix*) host_makefile_frag=config/mh-decstation ;;
- mips*-nec-sysv4*) host_makefile_frag=config/mh-necv4 ;;
- mips*-sgi-irix[56]*) host_makefile_frag=config/mh-irix5 ;;
- mips*-sgi-irix4*) host_makefile_frag=config/mh-irix4 ;;
- mips*-sgi-irix3*) host_makefile_frag=config/mh-sysv ;;
- mips*-*-sysv4*) host_makefile_frag=config/mh-sysv4 ;;
- mips*-*-sysv*) host_makefile_frag=config/mh-riscos ;;
- i[345]86-ncr-sysv4.3) host_makefile_frag=config/mh-ncrsvr43 ;;
- i[345]86-ncr-sysv4*) host_makefile_frag=config/mh-ncr3000 ;;
- i[345]86-*-sco3.2v5*) host_makefile_frag=config/mh-sysv ;;
- i[345]86-*-sco*) host_makefile_frag=config/mh-sco ;;
- i[345]86-*-isc*) host_makefile_frag=config/mh-sysv ;;
- i[345]86-*-linux*) host_makefile_frag=config/mh-linux ;;
- i[345]86-*-solaris2*) host_makefile_frag=config/mh-sysv4 ;;
- i[345]86-*-aix*) host_makefile_frag=config/mh-aix386 ;;
- i[345]86-*-go32*) host_makefile_frag=config/mh-go32 ;;
- vax-*-ultrix2*) host_makefile_frag=config/mh-vaxult2 ;;
- *-*-solaris2*) host_makefile_frag=config/mh-solaris ;;
- m68k-sun-sunos*) host_makefile_frag=config/mh-sun3 ;;
- *-hp-hpux[78]*) host_makefile_frag=config/mh-hpux8 ;;
- *-hp-hpux*) host_makefile_frag=config/mh-hpux ;;
- *-*-hiux*) host_makefile_frag=config/mh-hpux ;;
- rs6000-*-lynxos*) host_makefile_frag=config/mh-lynxrs6k ;;
- *-*-lynxos*) host_makefile_frag=config/mh-lynxos ;;
- *-*-sysv4*) host_makefile_frag=config/mh-sysv4 ;;
- *-*-sysv*) host_makefile_frag=config/mh-sysv ;;
+ m68k-hp-hpux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hp300"
+ ;;
+ m68k-apollo-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-apollo68"
+ ;;
+ m68k-apollo-bsd*)
+ host_makefile_frag="${host_makefile_frag} config/mh-a68bsd"
+ ;;
+ m88k-dg-dgux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-dgux"
+ ;;
+ m88k-harris-cxux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-cxux"
+ ;;
+ m88k-motorola-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-delta88"
+ ;;
+ mips*-dec-ultrix*)
+ host_makefile_frag="${host_makefile_frag} config/mh-decstation"
+ ;;
+ mips*-nec-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-necv4"
+ ;;
+ mips*-sgi-irix6*)
+ host_makefile_frag="${host_makefile_frag} config/mh-irix6"
+ ;;
+ mips*-sgi-irix5*)
+ host_makefile_frag="${host_makefile_frag} config/mh-irix5"
+ ;;
+ mips*-sgi-irix4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-irix4"
+ ;;
+ mips*-sgi-irix3*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+ mips*-*-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv4"
+ ;;
+ mips*-*-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-riscos"
+ ;;
+ i[3456]86-*-sysv5*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv5"
+ ;;
+ i[3456]86-*-dgux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-dgux386"
+ ;;
+ i[3456]86-ncr-sysv4.3*)
+ host_makefile_frag="${host_makefile_frag} config/mh-ncrsvr43"
+ ;;
+ i[3456]86-ncr-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-ncr3000"
+ ;;
+ i[3456]86-*-sco3.2v5*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+ i[3456]86-*-sco*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sco"
+ ;;
+ i[3456]86-*-udk*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv5"
+ ;;
+ i[3456]86-*-isc*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+ i[3456]86-*-solaris2*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv4"
+ ;;
+ i[3456]86-*-aix*)
+ host_makefile_frag="${host_makefile_frag} config/mh-aix386"
+ ;;
+ i[3456]86-*-go32*)
+ host_makefile_frag="${host_makefile_frag} config/mh-go32"
+ ;;
+ i[3456]86-*-msdosdjgpp*)
+ host_makefile_frag="${host_makefile_frag} config/mh-go32"
+ ;;
+ *-cygwin*)
+ host_makefile_frag="${host_makefile_frag} config/mh-cygwin"
+ ;;
+ *-mingw32*)
+ host_makefile_frag="${host_makefile_frag} config/mh-mingw32"
+ ;;
+ *-windows*)
+ host_makefile_frag="${host_makefile_frag} config/mh-windows"
+ ;;
+ vax-*-ultrix2*)
+ host_makefile_frag="${host_makefile_frag} config/mh-vaxult2"
+ ;;
+ *-*-solaris2*)
+ host_makefile_frag="${host_makefile_frag} config/mh-solaris"
+ ;;
+ m68k-sun-sunos*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sun3"
+ ;;
+ *-hp-hpux[78]*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hpux8"
+ ;;
+ *-hp-hpux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hpux"
+ ;;
+ *-*-hiux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hpux"
+ ;;
+ rs6000-*-lynxos*)
+ host_makefile_frag="${host_makefile_frag} config/mh-lynxrs6k"
+ ;;
+ *-*-lynxos*)
+ host_makefile_frag="${host_makefile_frag} config/mh-lynxos"
+ ;;
+ *-*-aix4.[3456789]* | *-*-aix[56789].*)
+ host_makefile_frag="${host_makefile_frag} config/mh-aix43"
+ ;;
+ *-*-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv4"
+ ;;
+ *-*-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
esac
fi
# If we aren't going to be using gcc, see if we can extract a definition
# of CC from the fragment.
-if [ -z "${CC}" -a "${build}" = "${host}" ]; then
+if [ -z "${CC}" ] && [ "${build}" = "${host}" ]; then
IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
found=
for dir in $PATH; do
@@ -143,7 +249,7 @@ if [ -z "${CC}" -a "${build}" = "${host}" ]; then
fi
done
IFS="$save_ifs"
- if [ -z "${found}" -a -n "${host_makefile_frag}" -a -f "${srcdir}/${host_makefile_frag}" ]; then
+ if [ -z "${found}" ] && [ -n "${host_makefile_frag}" ] && [ -f "${srcdir}/${host_makefile_frag}" ]; then
xx=`sed -n -e 's/^[ ]*CC[ ]*=[ ]*\(.*\)$/\1/p' < ${srcdir}/${host_makefile_frag}`
if [ -n "${xx}" ] ; then
CC=$xx
@@ -155,37 +261,90 @@ fi
# Well, we don't yet, but we will.
if false && [ "${host}" = "${target}" ] && [ x${enable_shared} = x ]; then
case "${target}" in
- alpha-dec-osf*) enable_shared=yes ;;
+ alpha*-dec-osf*) enable_shared=yes ;;
+ alpha*-*-linux*) enable_shared=yes ;;
mips-sgi-irix5*) enable_shared=yes ;;
*) enable_shared=no ;;
esac
fi
-if [ x${enable_shared} = xyes ]; then
- waugh=
+case "${enable_shared}" in
+ yes) shared=yes ;;
+ no) shared=no ;;
+ "") shared=no ;;
+ *) shared=yes ;;
+esac
+
+if [ x${shared} = xyes ]; then
case "${host}" in
- hppa*) waugh=config/mh-papic ;;
- i[345]86-*) waugh=config/mh-x86pic ;;
- sparc64-*) waugh=config/mh-sparcpic ;;
- *) waugh=config/mh-${host_cpu}pic ;;
+ hppa*)
+ host_makefile_frag="${host_makefile_frag} config/mh-papic"
+ ;;
+ i[3456]86-*-cygwin*)
+ # We don't want -fPIC on Cygwin.
+ ;;
+ i[3456]86-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-x86pic"
+ ;;
+ sparc64-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sparcpic"
+ ;;
+ powerpc*-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-ppcpic"
+ ;;
+ alpha*-*-linux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-elfalphapic"
+ ;;
+ *)
+ if test -f ${srcdir}/config/mh-${host_cpu}pic; then
+ host_makefile_frag="${host_makefile_frag} config/mh-${host_cpu}pic"
+ fi
+ ;;
esac
- if [ -f ${srcdir}/${waugh} ]; then
- if [ -n "${host_makefile_frag}" ] ; then
- cat ${srcdir}/${host_makefile_frag} > mh-frag
- cat ${srcdir}/${waugh} >> mh-frag
- host_makefile_frag=mh-frag
- else
- host_makefile_frag=${waugh}
- fi
- fi
+fi
+
+rm -f mh-frag
+if [ -n "${host_makefile_frag}" ] ; then
+ for f in ${host_makefile_frag}
+ do
+ cat ${srcdir}/$f >> mh-frag
+ done
+ host_makefile_frag=mh-frag
fi
# per-target:
case "${target}" in
- v810*) target_makefile_frag=config/mt-v810 ;;
- i[345]86-*-netware*) target_makefile_frag=config/mt-netware ;;
- powerpc-*-netware*) target_makefile_frag=config/mt-netware ;;
+ v810*)
+ target_makefile_frag="${target_makefile_frag} config/mt-v810"
+ ;;
+ i[3456]86-*-netware*)
+ target_makefile_frag="${target_makefile_frag} config/mt-netware"
+ ;;
+ powerpc-*-netware*)
+ target_makefile_frag="${target_makefile_frag} config/mt-netware"
+ ;;
+ *-*-linux-gnu)
+ target_makefile_frag="${target_makefile_frag} config/mt-linux"
+ ;;
+esac
+
+# If --enable-target-optspace always use -Os instead of -O2 to build
+# the target libraries, similarly if it is not specified, use -Os
+# on selected platforms.
+case "${enable_target_optspace}:${target}" in
+ yes:*)
+ target_makefile_frag="${target_makefile_frag} config/mt-ospace"
+ ;;
+ # CYGNUS LOCAL d10v, d30v, fr30
+ :m32r-* | :d10v-* | :d30v-* | :fr30-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-ospace"
+ ;;
+ no:* | :*)
+ ;;
+ *)
+ echo "*** bad value \"${enable_target_optspace}\" for --enable-target-optspace flag; ignored" 1>&2
+ ;;
esac
skipdirs=
@@ -200,7 +359,7 @@ case ${with_x} in
yes | "") # the default value for this tree is that X11 is available
;;
no)
- skipdirs="${skipdirs} tk gash"
+ skipdirs="${skipdirs} tk libgui gash"
;;
*)
echo "*** bad value \"${with_x}\" for -with-x flag; ignored" 1>&2
@@ -219,22 +378,25 @@ if [ x"${host}" = x"${target}" ] ; then
# that are in the 'cross only' list
skipdirs="${skipdirs} ${cross_only}"
is_cross_compiler=no
- target_subdir=.
else
# similarly, don't build the targets in the 'native only'
# list when building a cross compiler
skipdirs="${skipdirs} ${native_only}"
is_cross_compiler=yes
- target_subdir=${target_alias}
- if [ ! -d ${target_subdir} ] ; then
- if mkdir ${target_subdir} ; then true
- else
- echo "'*** could not make ${PWD=`pwd`}/${target_subdir}" 1>&2
- exit 1
- fi
- fi
fi
+# We always want to use the same name for this directory, so that dejagnu
+# can reliably find it.
+target_subdir=${target_alias}
+
+if [ ! -d ${target_subdir} ] ; then
+ if mkdir ${target_subdir} ; then true
+ else
+ echo "'*** could not make ${PWD=`pwd`}/${target_subdir}" 1>&2
+ exit 1
+ fi
+fi
+
copy_dirs=
# Handle --with-headers=XXX. The contents of the named directory are
@@ -287,7 +449,9 @@ fi
# Default to using --with-stabs for certain targets.
if [ x${with_stabs} = x ]; then
case "${target}" in
- mips*-*-* | alpha*-*-osf* | i[345]86*-*-sysv4* | i[345]86*-*-unixware*)
+ mips*-*-irix6*)
+ ;;
+ mips*-*-* | alpha*-*-osf*)
with_stabs=yes;
withoptions="${withoptions} --with-stabs"
;;
@@ -309,7 +473,7 @@ while [ $# != 0 ]; do
:
else
echo >config.temp
- ${srcdir}/install.sh -c -m 644 config.temp $2/COPIED
+ ${srcdir}/install-sh -c -m 644 config.temp $2/COPIED
fi
# Copy the directory, assuming we have tar.
@@ -328,8 +492,12 @@ done
# Configure extra directories which are host specific
case "${host}" in
- i[345]86-*-go32*)
+ i[3456]86-*-go32*)
configdirs="$configdirs dosrel" ;;
+ i[3456]86-*-mingw32*)
+ configdirs="$configdirs dosrel" ;;
+ *-cygwin*)
+ configdirs="$configdirs libtermcap dosrel" ;;
esac
# Remove more programs from consideration, based on the host or
@@ -339,46 +507,132 @@ esac
noconfigdirs=""
case "${host}" in
- i[345]86-*-vsta)
- noconfigdirs="tcl expect dejagnu make texinfo bison patch flex byacc send-pr gprof uudecode dejagnu diff"
+ i[3456]86-*-vsta)
+ noconfigdirs="tcl expect dejagnu make texinfo bison patch flex byacc send-pr gprof uudecode dejagnu diff guile perl apache inet itcl tix db snavigator gnuserv gettext"
;;
- i[345]86-*-go32)
- noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr gprof uudecode dejagnu diff"
+ i[3456]86-*-go32* | i[3456]86-*-msdosdjgpp*)
+ noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl apache inet itcl tix db snavigator gnuserv gettext"
+ ;;
+ i[3456]86-*-mingw32*)
+ # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl apache inet itcl tix db snavigator gnuserv"
+ noconfigdirs="expect dejagnu cvs autoconf automake send-pr gprof rcs guile perl texinfo apache inet libtool"
;;
- *-*-cygwin32)
- noconfigdirs="patch diff make tk tcl expect dejagnu cvs autoconf texinfo bison send-pr gprof rcs"
+ *-*-cygwin*)
+ noconfigdirs="autoconf automake send-pr gprof rcs guile perl texinfo apache inet"
+ ;;
+ *-*-windows*)
+# This is only used to build WinGDB...
+# note that powerpc-eabi depends on sim configured before gdb.
+ configdirs="bfd libiberty opcodes readline sim gdb"
+ target_configdirs=
+ ;;
+ *-*-netbsd*)
+ noconfigdirs="rcs"
;;
ppc*-*-pe)
- noconfigdirs="patch diff make tk tcl expect dejagnu cvs autoconf texinfo bison send-pr gprof rcs"
+ noconfigdirs="patch diff make tk tcl expect dejagnu cvssrc autoconf automake texinfo bison send-pr gprof rcs guile perl apache inet itcl tix db snavigator gnuserv"
;;
esac
case "${target}" in
*-*-netware)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-librx target-newlib target-libiberty"
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-librx target-newlib target-libiberty target-libgloss"
+ ;;
+ *-*-rtems*)
+ noconfigdirs="$noconfigdirs target-libgloss"
;;
*-*-vxworks*)
- noconfigdirs="$noconfigdirs target-newlib"
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
;;
- alpha-dec-osf*)
+ alpha*-dec-osf*)
# ld works, but does not support shared libraries. emacs doesn't
- # work. newlib is not 64 bit ready. I'm not sure about fileutils or grep.
+ # work. newlib is not 64 bit ready. I'm not sure about fileutils.
# gas doesn't generate exception information.
- noconfigdirs="$noconfigdirs gas ld emacs fileutils grep target-newlib"
+ noconfigdirs="$noconfigdirs gas ld emacs fileutils target-newlib target-libgloss"
+ ;;
+ alpha*-*-*vms*)
+ noconfigdirs="$noconfigdirs gdb ld target-newlib target-libgloss"
+ ;;
+ alpha*-*-linux*)
+ # newlib is not 64 bit ready
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ # linux has rx in libc
+ skipdirs="$skipdirs target-librx"
;;
alpha*-*-*)
# newlib is not 64 bit ready
- noconfigdirs="$noconfigdirs target-newlib"
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ ;;
+ arc-*-*)
+ noconfigdirs="$noconfigdirs target-libgloss"
;;
arm-*-pe*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ arm-*-coff*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ arm-*-elf*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ arm-*-oabi*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ c4x-*-*)
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ ;;
+ thumb-*-coff)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+# CYGNUS LOCAL clm/arm-elf
+ thumb-*-elf)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ thumb-*-oabi)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+# END CYGNUS LOCAL
+# CYGNUS LOCAL nickc/strongarm
+ strongarm-*-elf)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ strongarm-*-coff)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+# END CYGNUS LOCAL
+ thumb-*-pe) # CYGNUS LOCAL nickc/thumb
+ noconfigdirs="$noconfigdirs target-libgloss"
;;
arm-*-riscix*)
- noconfigdirs="$noconfigdirs ld"
+ noconfigdirs="$noconfigdirs ld target-libgloss"
+ ;;
+ d10v-*-*)
+ noconfigdirs="$noconfigdirs target-librx target-libg++ target-libstdc++ target-libio target-libgloss"
;;
+# CYGNUS LOCAL d30v
+ d30v-*-*)
+ ;;
+# END CYGNUS LOCAL
+# CYGNUS LOCAL fr30
+ fr30-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+# END CYGNUS LOCAL
h8300*-*-* | \
h8500-*-*)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx"
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
;;
hppa*-*-*elf* | \
hppa*-*-lites*)
@@ -394,115 +648,198 @@ case "${target}" in
esac
noconfigdirs="$noconfigdirs ld shellutils"
;;
- i[345]86-*-go32)
+ i[3456]86-*-coff | i[3456]86-*-elf)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ i[3456]86-*-go32* | i[3456]-*-msdosdjgpp*)
# but don't build gdb
noconfigdirs="$noconfigdirs gdb target-libg++ target-libstdc++ target-libio target-librx"
;;
- *-*-cygwin32)
+ *-*-linux*)
+ # linux has rx in libc
+ skipdirs="$skipdirs target-librx"
+ ;;
+ i[3456]86-*-mingw32*)
+ target_configdirs="$target_configdirs target-mingw"
+ noconfigdirs="$noconfigdirs expect target-libgloss"
- # make/glob's configure uses some AC_TRY_RUN type tests
- target_configdirs="$target_configdirs target-winsup"
- noconfigdirs="$noconfigdirs tcl tk expect make"
+ # Can't build gdb for mingw32 if not native.
+ case "${host}" in
+ i[3456]86-*-mingw32) ;; # keep gdb tcl tk expect etc.
+ *) noconfigdirs="$noconfigdirs gdb tcl tk expect itcl tix db snavigator gnuserv"
+ ;;
+ esac
+ ;;
+ *-*-cygwin*)
+ target_configdirs="$target_configdirs target-libtermcap target-winsup"
+ noconfigdirs="$noconfigdirs target-libgloss"
# always build newlib.
skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
- # Can't build gdb for cygwin32 if not native.
- case "${host}:${build}" in
- *-*-cygwin32 | *-*-cygwin32:*-*-cygwin32) ;; # keep gdb
- *) noconfigdirs="$noconfigdirs gdb"
+ # Can't build gdb for Cygwin if not native.
+ case "${host}" in
+ *-*-cygwin*) ;; # keep gdb tcl tk expect etc.
+ *) noconfigdirs="$noconfigdirs gdb tcl tk expect itcl tix libgui db snavigator gnuserv"
+ ;;
esac
-
;;
- i[345]86-*-pe)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx"
+ i[3456]86-*-pe)
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
;;
- i[345]86-*-sco3.2v5*)
+ i[3456]86-*-sco3.2v5*)
# The linker does not yet know about weak symbols in COFF,
# and is not configured to handle mixed ELF and COFF.
- noconfigdirs="$noconfigdirs gprof ld"
+ noconfigdirs="$noconfigdirs ld target-libgloss"
;;
- i[345]86-*-sco*)
- noconfigdirs="$noconfigdirs gprof"
+ i[3456]86-*-sco*)
+ noconfigdirs="$noconfigdirs gprof target-libgloss"
;;
- i[345]86-*-solaris2*)
- # The linker does static linking correctly, but the Solaris C library
- # has bugs such that some important functions won't work when statically
- # linked. (See man pages for getpwuid, for example.)
- noconfigdirs="$noconfigdirs ld"
+ i[3456]86-*-solaris2*)
+ noconfigdirs="$noconfigdirs target-libgloss"
;;
- i[345]86-*-sysv4*)
+ i[3456]86-*-sysv4*)
# The SYSV4 C compiler doesn't handle Emacs correctly
case "${CC}" in
"" | cc*) noconfigdirs="$noconfigdirs emacs emacs19" ;;
*) ;;
esac
# but that's okay since emacs doesn't work anyway
- noconfigdirs="$noconfigdirs emacs emacs19"
+ noconfigdirs="$noconfigdirs emacs emacs19 target-libgloss"
+ ;;
+ m68k-*-*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ mn10200-*-*)
+ noconfigdirs="$noconfigdirs"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ mn10300-*-*)
+ noconfigdirs="$noconfigdirs"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
;;
powerpc-*-aix*)
# copied from rs6000-*-* entry
- noconfigdirs="$noconfigdirs gprof cvs"
+ noconfigdirs="$noconfigdirs gprof cvssrc target-libgloss"
+ # This is needed until gcc and ld are fixed to work together.
+ use_gnu_ld=no
;;
powerpc*-*-winnt* | powerpc*-*-pe* | ppc*-*-pe)
target_configdirs="$target_configdirs target-winsup"
- noconfigdirs="$noconfigdirs gdb tcl tk make expect"
+ noconfigdirs="$noconfigdirs gdb tcl tk make expect target-libgloss itcl tix db snavigator gnuserv"
# always build newlib.
skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
;;
+ # This is temporary until we can link against shared libraries
+ powerpcle-*-solaris*)
+ noconfigdirs="$noconfigdirs gdb sim make tcl tk expect itcl tix db snavigator gnuserv"
+ ;;
+ powerpc-*-eabi)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
rs6000-*-lynxos*)
# The CVS server code doesn't work on the RS/6000
# Newlib makes problems for libg++ in crosses.
- noconfigdirs="$noconfigdirs target-newlib gprof cvs"
+ noconfigdirs="$noconfigdirs target-newlib gprof cvssrc"
+ ;;
+ rs6000-*-aix*)
+ noconfigdirs="$noconfigdirs gprof"
+ # This is needed until gcc and ld are fixed to work together.
+ use_gnu_ld=no
;;
rs6000-*-*)
noconfigdirs="$noconfigdirs gprof"
;;
m68k-apollo-*)
- noconfigdirs="$noconfigdirs ld binutils gprof"
+ noconfigdirs="$noconfigdirs ld binutils gprof target-libgloss"
;;
mips*-*-irix5*)
# The GNU linker does not support shared libraries.
# emacs is emacs 18, which does not work on Irix 5 (emacs19 does work)
- noconfigdirs="$noconfigdirs ld gprof emacs"
+ noconfigdirs="$noconfigdirs ld gprof emacs target-libgloss"
+ ;;
+ mips*-*-irix6*)
+ # The GNU assembler and linker do not support IRIX 6.
+ # emacs is emacs 18, which does not work on Irix 5 (emacs19 does work)
+ noconfigdirs="$noconfigdirs ld gas gprof emacs target-libgloss"
;;
mips*-dec-bsd*)
- noconfigdirs="$noconfigdirs gprof"
+ noconfigdirs="$noconfigdirs gprof target-libgloss"
;;
mips*-*-bsd*)
- noconfigdirs="$noconfigdirs gprof"
+ noconfigdirs="$noconfigdirs gprof target-libgloss"
;;
+ mipstx39-*-*)
+ noconfigdirs="$noconfigdirs gprof" # same as generic mips
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ ;;
mips*-*-*)
noconfigdirs="$noconfigdirs gprof"
;;
romp-*-*)
- noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes"
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss"
;;
sh-*-*)
case "${host}" in
- i[345]86-*-vsta) ;; # don't add gprof back in
- i[345]86-*-go32) ;; # don't add gprof back in
+ i[3456]86-*-vsta) ;; # don't add gprof back in
+ i[3456]86-*-go32*) ;; # don't add gprof back in
+ i[3456]86-*-msdosdjgpp*) ;; # don't add gprof back in
*) skipdirs=`echo " ${skipdirs} " | sed -e 's/ gprof / /'` ;;
esac
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ sparc-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ sparc64-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ sparclite-*-*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
;;
sparc-*-sunos4*)
if [ x${is_cross_compiler} != xno ] ; then
- noconfigdirs="$noconfigdirs gdb gdbtest target-newlib"
+ noconfigdirs="$noconfigdirs gdb gdbtest target-newlib target-libgloss"
else
use_gnu_ld=no
fi
;;
v810-*-*)
- noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libio target-libg++ target-libstdc++ opcodes"
+ noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libio target-libg++ target-libstdc++ opcodes target-libgloss"
+ ;;
+ v850-*-*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ v850e-*-*) # CYGNUS LOCAL v850e
+ noconfigdirs="$noconfigdirs target-libgloss"
;;
+ v850ea-*-*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;; # END CYGNUS LOCAL
vax-*-vms)
- noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes"
+ noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes target-libgloss"
;;
vax-*-*)
- noconfigdirs="$noconfigdirs target-newlib"
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
;;
*-*-lynxos*)
# Newlib makes problems for libg++ in crosses.
- noconfigdirs="$noconfigdirs target-newlib"
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
;;
*-*-macos* | \
*-*-mpw*)
@@ -511,19 +848,13 @@ case "${target}" in
;;
esac
-# targets that need a second pass
-case "${target}" in
- *-gm-magic*)
- noconfigdirs="$noconfigdirs libgloss"
- ;;
+# If we aren't building newlib, then don't build libgloss, since libgloss
+# depends upon some newlib header files.
+case "${noconfigdirs}" in
+ *target-libgloss*) ;;
+ *target-newlib*) noconfigdirs="$noconfigdirs target-libgloss" ;;
esac
-# If we are building a Canadian Cross, discard tools that can not be built
-# using a cross compiler. FIXME: These tools should be fixed.
-if [ "${build}" != "${host}" ]; then
- noconfigdirs="$noconfigdirs expect dejagnu make texinfo diff"
-fi
-
# Make sure we don't let GNU ld be added if we didn't want it.
if [ x$with_gnu_ld = xno ]; then
use_gnu_ld=no
@@ -587,12 +918,12 @@ fi
# Deconfigure all subdirectories, in case we are changing the
# configuration from one where a subdirectory is supported to one where it
# is not.
-if [ -z "${norecursion}" -a -n "${configdirs}" ]; then
+if [ -z "${norecursion}" ] && [ -n "${configdirs}" ]; then
for i in `echo ${configdirs} | sed -e s/target-//g` ; do
rm -f $i/Makefile
done
fi
-if [ -z "${norecursion}" -a -n "${target_configdirs}" ]; then
+if [ -z "${norecursion}" ] && [ -n "${target_configdirs}" ]; then
for i in `echo ${target_configdirs} | sed -e s/target-//g` ; do
rm -f ${target_subdir}/$i/Makefile
done
@@ -660,14 +991,45 @@ if [ x${use_gnu_ld} = x ] ; then
fi
fi
-if [ x${enable_shared} = xyes ]; then
+# If using newlib, add --with-newlib to the withoptions so that gcc/configure
+# can detect this case.
+
+if [ x${with_newlib} != xno ] && echo " ${target_configdirs} " | grep " target-newlib " > /dev/null 2>&1 && [ -d ${srcdir}/newlib ] ; then
+ with_newlib=yes
+ withoptions="$withoptions --with-newlib"
+fi
+
+if [ x${shared} = xyes ]; then
case "${target}" in
- hppa*) target_makefile_frag=config/mt-papic ;;
- i[345]86-*) target_makefile_frag=config/mt-x86pic ;;
- *) target_makefile_frag=config/mt-${target_cpu}pic ;;
+ hppa*)
+ target_makefile_frag="${target_makefile_frag} config/mt-papic"
+ ;;
+ i[3456]86-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-x86pic"
+ ;;
+ powerpc*-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-ppcpic"
+ ;;
+ alpha*-*-linux*)
+ target_makefile_frag="${target_makefile_frag} config/mt-elfalphapic"
+ ;;
+ *)
+ if test -f ${srcdir}/config/mt-${target_cpu}pic; then
+ target_makefile_frag="${target_makefile_frag} config/mt-${target_cpu}pic"
+ fi
+ ;;
esac
fi
+rm -f mt-frag
+if [ -n "${target_makefile_frag}" ] ; then
+ for f in ${target_makefile_frag}
+ do
+ cat ${srcdir}/$f >> mt-frag
+ done
+ target_makefile_frag=mt-frag
+fi
+
# post-target:
# Make sure that the compiler is able to generate an executable. If it
@@ -676,7 +1038,7 @@ fi
# can be created. At this point the main configure script has set CC.
echo "int main () { return 0; }" > conftest.c
${CC} -o conftest ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} conftest.c
-if [ $? = 0 ] && [ -s conftest ]; then
+if [ $? = 0 ] && [ -s conftest -o -s conftest.exe ]; then
:
else
echo 1>&2 "*** The command '${CC} -o conftest ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} conftest.c' failed."
@@ -689,7 +1051,8 @@ rm -f conftest*
# The Solaris /usr/ucb/cc compiler does not appear to work.
case "${host}" in
sparc-sun-solaris2*)
- if [ "`/usr/bin/which ${CC-cc}`" = "/usr/ucb/cc" ] ; then
+ CCBASE="`echo ${CC-cc} | sed 's/ .*$//'`"
+ if [ "`/usr/bin/which $CCBASE`" = "/usr/ucb/cc" ] ; then
could_use=
[ -d /opt/SUNWspro/bin ] && could_use="/opt/SUNWspro/bin"
if [ -d /opt/cygnus/bin ] ; then
@@ -715,7 +1078,7 @@ esac
# If --enable-shared was set, we must set LD_LIBRARY_PATH so that the
# binutils tools will find libbfd.so.
-if [ "${enable_shared}" = "yes" ]; then
+if [ "${shared}" = "yes" ]; then
sed -e 's/^SET_LIB_PATH[ ]*=.*$/SET_LIB_PATH = $(REALLY_SET_LIB_PATH)/' \
Makefile > Makefile.tem
rm -f Makefile
@@ -723,7 +1086,7 @@ if [ "${enable_shared}" = "yes" ]; then
case "${host}" in
*-*-hpux*)
- sed -e 's/RPATH_ENVVAR[ ]*=.*$/RPATH_ENVVAR = SHLIB_PATH/' \
+ sed -e 's/^RPATH_ENVVAR[ ]*=.*$/RPATH_ENVVAR = SHLIB_PATH/' \
Makefile > Makefile.tem
rm -f Makefile
mv -f Makefile.tem Makefile
@@ -734,9 +1097,10 @@ fi
# Record target_configdirs and the configure arguments in Makefile.
target_configdirs=`echo "${target_configdirs}" | sed -e 's/target-//g'`
targargs=`echo "${arguments}" | \
- sed -e 's/--norecursion//' \
+ sed -e 's/--no[^ ]*//' \
-e 's/--cache[a-z-]*=[^ ]*//' \
-e 's/--ho[a-z-]*=[^ ]*//' \
+ -e 's/--bu[a-z-]*=[^ ]*//' \
-e 's/--ta[a-z-]*=[^ ]*//'`
# Passing a --with-cross-host argument lets the target libraries know
@@ -748,7 +1112,18 @@ if [ x${is_cross_compiler} = xyes ]; then
targargs="--with-cross-host=${host_alias} ${targargs}"
fi
-targargs="--host=${target_alias} ${targargs}"
+# Default to --enable-multilib.
+if [ x${enable_multilib} = x ]; then
+ targargs="--enable-multilib ${targargs}"
+fi
+
+# Pass --with-newlib if appropriate. Note that target_configdirs has
+# changed from the earlier setting of with_newlib.
+if [ x${with_newlib} != xno ] && echo " ${target_configdirs} " | grep " newlib " > /dev/null 2>&1 && [ -d ${srcdir}/newlib ] ; then
+ targargs="--with-newlib ${targargs}"
+fi
+
+targargs="--host=${target_alias} --build=${build_alias} ${targargs}"
sed -e "s:^TARGET_CONFIGDIRS[ ]*=.*$:TARGET_CONFIGDIRS = ${target_configdirs}:" \
-e "s%^CONFIG_ARGUMENTS[ ]*=.*$%CONFIG_ARGUMENTS = ${targargs}%" \
-e "s%^TARGET_SUBDIR[ ]*=.*$%TARGET_SUBDIR = ${target_subdir}%" \
diff --git a/contrib/gdb/gdb/COPYING b/contrib/gdb/gdb/COPYING
index a43ea21..60549be 100644
--- a/contrib/gdb/gdb/COPYING
+++ b/contrib/gdb/gdb/COPYING
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
- Appendix: How to Apply These Terms to Your New Programs
+ How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -305,7 +305,8 @@ the "copyright" line and a pointer to where the full notice is found.
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.
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
Also add information on how to contact you by electronic and paper mail.
diff --git a/contrib/gdb/gdb/ChangeLog b/contrib/gdb/gdb/ChangeLog
index 0ee1d9c..0ae5117 100644
--- a/contrib/gdb/gdb/ChangeLog
+++ b/contrib/gdb/gdb/ChangeLog
@@ -1,1414 +1,1115 @@
-Mon Apr 22 20:17:01 1996 Fred Fish <fnf@cygnus.com>
-
- * Makefile.in (VERSION): Bump version number to 4.16
- * NEWS: Update for 4.16 release.
-
-Fri Apr 12 21:39:42 1996 Fred Fish <fnf@cygnus.com>
-
- * Makefile.in (VERSION): Bump version to 4.15.86
- * README: Update for 4.16 release.
- * configure.in (AC_CHECK_FUNCS): Also check for sbrk.
- * configure: Regenerate with autoconf.
- * config.in: Regenerate with autoheader.
- * main.c (main): Only use sbrk() when HAVE_SBRK is defined.
- * top.c (command_loop): Ditto.
-
-Thu Apr 11 17:51:58 1996 Fred Fish <fnf@cygnus.com>
-
- From: Miles Bader <miles@gnu.ai.mit.edu>
- * configure.in (AC_CHECK_HEADERS): check for endian.h.
- Use AC_CHECK_TOOL to find AR & RANLIB. Add AC_PROG_AWK.
- Add host & target cases for i[345]86-*-gnu*.
- * config.in: Regenerate with autoheader.
- * configure: Regenerate with autoconf.
- * Makefile.in (AR, AWK): Set from corresponding autoconf substs.
- (init.c): Don't scan mig-generated files.
- * defs.h (endian.h): Include if HAVE_ENDIAN_H defined.
- * config/nm-m3.h (ATTACH_NO_WAIT): Define.
- * infcmd.c (attach_command): Use "#ifndef ATTACH_NO_WAIT"
- rather than "#ifndef MACH".
-
-Mon Apr 8 12:53:56 1996 Fred Fish <fnf@cygnus.com>
-
- * Makefile.in (scm-exp.o, scm-lang.o, scm-valprint.o): Add targets and
- dependencies.
- * scm-lang.c (gdb_string.h): Include.
- * objfiles.c (add_to_objfile_sections): Cast second arg of obstack_grow
- call to correct type (char *).
- * cp-valprint.c (cp_print_static_field): Ditto.
- * somsolib.c (som_solib_create_inferior_hook): Add a declaration
- for external find_unwind_entry function (from hppa-tdep.c).
- * remote-pa.c (remote_write_bytes, remote_read_bytes): Change
- type of second arg to "char *" to be type compatible with
- dcache.
- (remote_wait): Cast second arg to strtol to correct type.
- * hppa-tdep.c (compare_unwind_entries): Change argument types to
- "const void *" to be type compatible with qsort, and then
- assign to local args prior to use.
-
-Sun Apr 7 22:34:29 1996 Fred Fish <fnf@cygnus.com>
-
- From: Miles Bader <miles@gnu.ai.mit.edu>
- * gnu-nat.c, gnu-nat.h, msg.defs, exc_request.defs, i386gnu-nat.c,
- msg_reply.defs, notify.defs, process_reply.defs, reply_mig_hack.awk,
- config/nm-gnu.h, config/i386/{i386gnu.mh, i386gnu.mt, nm-gnu.h,
- m-i386gnu.h, xm-i386gnu.h}: New files for GNU hurd.
-
-Sun Apr 7 13:32:41 1996 Fred Fish <fnf@cygnus.com>
-
- * configure.in (case host): Add i386sco5 host.
- * configure: Regenerate.
-
- From: Robert Lipe <robertl@dgii.com>
- Add support for SCO OpenServer 5 (a.k.a. 3.2v5*) This
- target is an SVR3.2 with COFF, ELF, and shared libes, but
- no /proc.
- * config/i386/i386sco5.mh: New file.
- * config/i386/nm-i386sco5.h: New file.
-
-Sat Apr 6 08:55:22 1996 Fred Fish <fnf@cygnus.com>
-
- * bcache.c (bcache): When size of chunk to cache is exactly equal to
- BCACHE_MAXLENGTH, stash chunk as unique copy.
-
-Sat Apr 6 00:46:26 1996 Fred Fish <fnf@cygnus.com>
-
- * symfile.c (INLINE_ADD_PSYMBOL): Remove ifdef.
- (add_psymbol_to_list): Add an arg for passing CORE_ADDR values and
- use it, rather than calling add_psymbol_addr_to_list.
- (add_psymbol_addr_to_list): Delete.
- (add_psymbol_to_list): Make psymbol static to avoid random data in
- gaps due to alignment of structure members.
- * symfile.h (INLINE_ADD_PSYMBOL, ADD_PSYMBOL_TO_LIST,
- ADD_PSYMBOL_ADDR_TO_LIST): Remove. Real world tests show no
- performance improvements by inlining via complicated macros and
- they just make gdb larger and harder to maintain.
- * dwarfread.c (add_enum_psymbol): Replace ADD_PSYMBOL_TO_LIST
- and/or ADD_PSYMBOL_ADDR_TO_LIST macro(s) with call to
- add_psymbol_to_list with appropriate long or CORE_ADDR args.
- (add_partial_symbol): Ditto.
- * partial-stab.h: Ditto.
- * os9kread.c (read_os9k_psymtab): Ditto
- * mdebugread.c (parse_partial_symbols): Ditto.
- (handle_psymbol_enumerators): Ditto.
- (demangle.h): Include.
- * hpread.c (hpread_build_psymtabs): Ditto.
- (hpread_build_psymtabs): Ditto.
- (demangle.h): Include
-
-Thu Apr 4 17:59:58 1996 Fred Fish <fnf@cygnus.com>
-
- * configure.in: Check for setpgid function.
- * config.in: Regenerate with autoheader.
- * configure: Regenerate with autoconf.
- * inflow.c (_initialize_inflow): Only try to use _SC_JOB_CONTROL
- if it is actually defined.
- (gdb_setpgid): Use HAVE_SETPGID.
- * ch-exp.c: Change include of <string.h> to "gdb_string.h".
- * c-exp.y: Ditto.
- * f-exp.y: Ditto.
- * m2-exp.y: Ditto.
- * c-exp.y: Include <ctype.h>.
- * serial.c: Ditto.
- * config/m68k/nm-news.h: Add typedef for pid_t which is
- apparently missing from <sys/types.h>. Enclose entire
- file in NM_NEWS_H ifndef and define when included.
- * config/mips/nm-news-mips.h: Ditto.
- * config/m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL,
- REGISTER_CONVERT_TO_RAW): Change name of temporary variable.
-
-Thu Apr 4 17:17:53 1996 Fred Fish <fnf@cygnus.com>
-
- * symmisc.c (print_objfile_statistics): Print memory used by
- psymbol cache obstack.
-
-Mon Apr 1 16:31:00 1996 Stan Shebs <shebs@andros.cygnus.com>
-
- * mpw-make.sed: Change references to config.h to be in objdir,
- edit out rules to rebuild config.h.
-
-Mon Apr 1 08:32:23 1996 Fred Fish <fnf@cygnus.com>
-
- * hppa-tdep.c (hppa_pop_frame): Call clear_proceed_status before
- proceeding.
-
-Sun Mar 31 16:15:43 1996 Fred Fish <fnf@cygnus.com>
-
- * hppah-nat.c (store_inferior_registers, store_inferior_registers,
- fetch_register, child_xfer_memory): Use call_ptrace function supplied
- by infptrace.c rather than calling ptrace directly.
-
-Sat Mar 30 11:00:22 1996 Fred Fish <fnf@cygnus.com>
-
- * configure.in: Check whether printf family supports printing
- long doubles or not and define PRINTF_HAS_LONG_DOUBLE if so.
- * acconfig.h: Provide default undef for PRINTF_HAS_LONG_DOUBLE.
- * configure: Regenerate.
- * valprint.c (print_floating): Use PRINTF_HAS_LONG_DOUBLE.
- * c-exp.y (parse_number): Use PRINTF_HAS_LONG_DOUBLE.
- * configure.in: Fix have_gregset and have_fpregset autoconf
- variable names so that they match the pattern required to
- cache them.
-
-Fri Mar 29 21:53:14 1996 Fred Fish <fnf@cygnus.com>
-
- * core-aout.c (fetch_core_registers): Cast core_reg_size to int
- before testing against reg_ptr.
- * eval.c (evaluate_subexp_standard): Cast type of
- TYPE_FN_FIELD_VOFFSET to int.
- * findvar.c (extract_signed_integer, extract_unsigned_integer,
- extract_long_unsigned_integer): Cast type of sizeof to int.
- * values.c (unpack_field_as_long, modify_field): Ditto.
- * valops.c (value_assign, call_function_by_hand): Ditto.
- * infcmd.c (do_registers_info): Ditto.
- * ser-tcp.c (tcp_open): Ditto
- * remote.c (putpkt): Ditto.
- * dcache.c (dcache_peek): Ditto.
- * dcache.c (dcache_poke): Ditto.
- * m2-exp.y (yylex): Ditto.
- * gnu-regex.c (re_match_2): Ditto.
- * f-lang.c (ADD_BF_SYMNUM, saved_bf_list_end, tmp_bf_ptr): Ifdef
- out unused macro definition and variables.
- * inftarg.c (proc_wait): Move from main.c to here, and make static.
- * valprint.c (val_print_string): Change bufsize from int to unsigned.
- * main.c (wait.h): Include
- * top.c (command_line_input): Remove unused variable "c".
- * f-typeprint.c (f_type_print_varspec_prefix): Add missing enum
- value TYPE_CODE_TYPEDEF to switch statement.
- (f_type_print_varspec_suffix): Add missing enum value
- TYPE_CODE_TYPEDEF to switch statement.
- * ch-exp.c (parse_primval): Add remaining enumeration values to
- switch statement, with no specific action.
- (ch_lex): Add LOC_UNRESOLVED in switch statement.
- (pushback_token): Ifdef out, since code using it is ifdef'd out.
- * stabsread.c (cleanup_undefined_types): Remove unused label
- "badtype".
- * objfiles.h (print_symbol_bcache_statistics): Add prototype.
- * maint.c (objfiles.h): Include.
- (maintenance_print_statistics): Remove unused variable "temp".
- * minsyms.c (lookup_minimal_symbol_solib_trampoline): Remove
- unused variable "found_file_symbol".
- * m2-exp.y (yylex): Add LOC_UNRESOLVED case to switch.
- * language.c (lang_bool_type): Use existing function local type
- variable rather than create block local variables.
- * solib.c (disable_break): Enclose in ifndef SVR4_SHARED_LIBS.
- * infptrace.c (wait.h, command.h): Include.
- * ser-tcp.c (gdb_string.h): Include
- * i386-tdep.c (codestream_seek): Change "place" to CORE_ADDR.
- (i386_get_frame_setup): Change "pc" from int to CORE_ADDR.
- * command.c (complete_on_enum): Make assignment used as truth value
- explictly check against NULL.
- (wait.h): Include.
- * infrun.c (wait_for_inferior): Ifdef out prologue_pc since code
- that uses it is ifdef'd out.
- * parser-defs.h: Add prototype for write_dollar_variable.
- * infrun.c: Add prototype for write_pc_pid.
- * breakpoint.h: Add prototype for re_enable_breakpoints_in_shlibs.
- * symmisc.c (bcache.h): Include.
- * bcache.h: Add prototype for print_bcache_statistics.
- * symfile.c: Include <time.h>.
- * printcmd.c (print_scalar_formatted): Change len to unsigned int.
- * valarith.c (value_equal): Cast result of TYPE_LENGTH to int.
- * valarith.c (value_binop): Change result_len, promoted_len1,
- and promoted_len2 to unsigned int.
- * valarith.c (value_subscripted_rvalue): Change elt_offs and
- elt_size to unsigned int.
- * valops.c (value_array): Change typelength to unsigned int.
- (destructor_name_p): Change len to unsigned int.
- * scm-lang.h (scm_parse): Add prototype for scm_unpack.
- * symfile.c (decrement_reading_symtab): Change return type to void.
- * valarith.c (value_subscript): Remove unused variable "word".
- (value_subscript): Remove unused variable "tint".
- * valops.c (auto_abandon): Ifdef out, since code using it is also
- ifdef'd out.
- * eval.c (init_array_element): Remove unused variable "val".
- * Makefile.in (values.o): Depends on scm-lang.h.
- (command.o): Depends upon wait_h.
- (ser-tcp.o): Depends upon gdb_string.h.
- (infptrace.o): Depends upon wait_h and command_h.
- (maint.o): Depends on objfiles.h and symfile.h.
- * values.c (allocate_repeat_value): Remove unused variable
- "element_type".
- (scm-lang.h): Include.
- * breakpoint.c (create_longjmp_breakpoint): Enclose in
- GET_LONGJMP_TARGET define, unused otherwise.
- * config/i386/nm-linux.h: Add prototypes for i386_insert_watchpoint,
- i386_remove_watchpoint and i386_stopped_by_watchpoint.
-
-Thu Mar 28 06:51:26 1996 Fred Fish <fnf@cygnus.com>
+1999-04-07 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * GDB 4.18 released.
- * valops.c (value_assign): Make copy of internal variable value
- before returning it as a new value, since it is owned by the
- internal variable and will be freed along with it.
+1999-04-06 Jim Blandy <jimb@zwingli.cygnus.com>
-Wed Mar 27 12:54:55 1996 Fred Fish <fnf@cygnus.com>
+ * README: Change revision numbers in text to "4.18".
+ * Makefile.in (VERSION): Set to 4.18.
- From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
- * breakpoint.c (breakpoint_re_set_one): Keep temporary
- breakpoints bp_until, bp_finish, bp_watchpoint_cope, bp_call_dummy
- and bp_step_resume in case breakpoint_re_set_one is called due
- to a step over a dlopen call.
- * infrun.c (wait_for_inferior): Always remove breakpoints from
- inferior in BPSTAT_WHAT_CHECK_SHLIBS case.
+1999-04-06 Stan Shebs <shebs@andros.cygnus.com>
+
+ * solib.c (clear_solib): Don't call disable_breakpoints_in_shlibs,
+ this breaks rerunning on sun4 native.
+
+1999-04-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Incorporate suggestions from David Taylor and Jason Molenda.
-Tue Mar 26 13:15:32 1996 Fred Fish <fnf@cygnus.com>
+1999-04-02 Jim Blandy <jimb@zwingli.cygnus.com>
- * Makefile.in (VERSION): Bump version to 4.15.85
+ * README: Note that GDB requires an ANSI C compiler, and explain
+ how to get GCC.
- * config/mips/tm-mips.h (COERCE_FLOAT_TO_DOUBLE): Only prefer
- non-prototyped case over prototyped case for C.
- * config/pa/tm-hppa.h (COERCE_FLOAT_TO_DOUBLE): Ditto.
+ * README: Update.
+ It says we provide HTML documentation, but we don't.
+ The instructions for building the .info files were wrong.
+ It didn't mention that texinfo.tex was provided with GDB.
+ It didn't mention the intl, texinfo, etc, or util directories.
+ (Perhaps util would be best left unmentioned.)
+ It didn't mention the --enable-build-warnings flag, or the --host
+ flag.
+ It didn't mention remote-array.c or remote-d10v.c.
+ It had an old address for reporting bugs. It's now gdb@gnu.org.
+ It mentioned xxgdb, which is obsolete, but didn't mention DDD.
-Sat Mar 23 15:50:47 1996 Fred Fish <fnf@cygnus.com>
+ * config/sparc/nm-linux.h: Don't redefine PT_ATTACH to use the
+ deprecated PTRACE_SUNATTACH compatibility commands. The
+ definitions from <sys/ptrace.h> are fine.
- * os9kread.c (os9k_process_one_symbol): Note nonportable
- assumption that an int can hold a char *.
+1999-04-01 Stan Shebs <shebs@andros.cygnus.com>
- * bcache.h (struct hashlink): Wrap data[] inside union with
- double to force longest alignment.
- (BCACHE_DATA): New macro to access data[].
- (BCACHE_ALIGNMENT): New macro to get offset to data[].
- * bcache.c (lookup_cache, bcache): Use BCACHE_DATA to get
- address of cached data. Use BCACHE_ALIGNMENT to compute
- amount of space to allocate for each hashlink struct.
+ * NEWS: Add more notes about user-visible changes.
-Sat Mar 23 12:14:02 1996 Fred Fish <fnf@cygnus.com>
+1999-04-01 Jim Blandy <jimb@zwingli.cygnus.com>
- * ch-lang.c (evaluate_subexp_chill): Fix typo.
+ Fix for cross-debugging on an AIX host from Johanna Svenningsson:
+ * ax-gdb.h (enum axs_lvalue_kind): Remove trailing comma from enum.
+ * ax.h (enum agent_op, enum agent_flaws): Same.
+ * tracepoint.h (enum actionline_type): Same.
+ * config/xm-aix4.h: Add declaration for termdef.
-Thu Mar 21 08:27:19 1996 Fred Fish <fnf@cygnus.com>
+1999-03-31 Stan Shebs <shebs@andros.cygnus.com>
- * Makefile.in (VERSION): Bump version to 4.15.3
+ * jv-lang.h (dynamics_objfile): Remove decl, conflicts with static
+ decl in jv-lang.c.
-Thu Mar 21 10:56:41 1996 Ian Lance Taylor <ian@cygnus.com>
+1999-03-31 Jim Blandy <jimb@zwingli.cygnus.com>
- * config.in: Rename from config.h.in.
- * configure.in: Call AC_CONFIG_HEADER with config.h:config.in.
- Change CONFIG_HEADERS test in AC_OUTPUT accordingly.
- * configure: Rebuild.
- * Makefile.in (stamp-h): Depend upon config.in, not config.h.in.
- Set CONFIG_HEADERS to config.h:config.in.
+ Mon Mar 29 14:40:44 1999 David Taylor <taylor@ryobi.cygnus.com>
-Tue Mar 19 12:47:51 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ * valops.c (search_struct_field): revert HP merge change
+ to this function -- it causes messages to be printed about
+ member class ambiguity when the compiler is happy.
+ (search_struct_field_aux): delete -- added as part of HP merge
+ change; with aforementioned change it is no longer called.
- * partial-stab.h (case N_ENDM): Finish current partial symbol
- table for Solaris 2 cc.
+1999-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
-Tue Mar 19 10:39:15 1996 Jeffrey A Law (law@cygnus.com)
+ Merged change from Keith Seitz:
+
+ 1999-03-16 Keith Seitz <keiths@cygnus.com>
- * rs6000-nat.c (exec_one_dummy_insn): Don't clobber the
- PC in the registers array. From Peter Schauer.
+ * remote.c (reomte_binary_checked): New file global.
+ (check_binary_download): New function to check if
+ stub supports binary downloading that works with
+ stubs that are not eight bit clean.
+ (remote_write_bytes): Check for binary download capability
+ and use it if available.
+ Remove references to global remote_binary_length. What a hack.
+ (putpkt_binary): New function.
+ (putpkt): Call putpkt_binary.
+ Use xor to escape trouble characters.
+ * m32r-stub.c (bin2mem): Follow escape char convention change.
-Mon Mar 18 13:47:09 1996 Fred Fish <fnf@cygnus.com>
+ Applied patch from Stu Grossman:
- * symfile.c (reread_symbols): Reinitialize bcache struct
- members to zero using memset. Also use memset to reinit
- global_psymbols and static_psymbols, rather than explicitly
- resetting each structure member.
+ Mon Feb 22 12:32:19 1999 Per Bothner <bothner@cygnus.com>
-Sat Mar 16 19:47:36 1996 Fred Fish <fnf@cygnus.com>
+ * jv-valprint.c (java_val_print): Restore line that somehow got lost.
- * configure.in: Add fragment to create stamp-h.
-
- From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
- * configure.in (AC_CHECK_HEADERS): Check for link.h.
- * configure: Regenerate with autoconf.
- * config.h.in: Regenerate with autoheader.
- * config/i386/nm-linux.h: Include solib.h only if HAVE_LINK_H
- is defined.
- * solib.c: Exclude most of the code if HAVE_LINK_H is not defined.
- * config/i386/linux.mh: Reinstate XM_CLIBS, it is needed for
- older a.out based systems.
-
-Sat Mar 16 16:45:43 1996 Fred Fish <fnf@cygnus.com>
-
- * config.h.in: New file.
- * acconfig.h: New file, for autoheader.
- * configure.in (AC_CONFIG_HEADER): Add, generate config.h.
- * configure: Regenerate.
- * Makefile.in (defs_h): Add config.h
- (distclean): Remove config.h and stamp-h during distclean.
- (config.h, stamp-h): New targets to remake config.h when necessary.
- * defs.h (config.h): Include before any other includes or defines.
- * i386-tdep.c (gdb_string.h): Move include after include of defs.h.
- * i386v4-nat.c (defs.h): Include before testing HAVE_SYS_PROCFS_H.
+1999-03-24 Stan Shebs <shebs@andros.cygnus.com>
-Sat Mar 16 14:55:27 1996 Fred Fish <fnf@cygnus.com>
+ * Makefile (VERSION): Bump to 4.17.87.
- From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
- * Makefile.in (INSTALLED_LIBS): Make sure that @LIBS@ will not
- result in an empty line, to work around a bug in native Ultrix 4.4
- and OSF/1-3.2C make.
+ Attempt to sort out SCO-related configs.
+ * configure.host (i[3456]86-*-sysv4.2*): Use instead of
+ i[3456]86-*-sysv4.2MP and i[3456]86-*-sysv4.2uw2*.
+ (i[3456]86-*-sysv5*): Recognize.
+ * configure.tgt (i[3456]86-*-sco3.2v5*, i[3456]86-*-sco3.2v4*):
+ Recognize.
-Sat Mar 16 13:33:17 1996 Fred Fish <fnf@cygnus.com>
+Wed Mar 24 01:01:27 1999 Andrew Cagney <cagney@sludge.cygnus.com>
- * configure.in: Add gdbserver to configdirs under linux.
- * configure: Regenerate.
+ * rs6000-tdep.c (rs6000_software_single_step): Change SIGNAL to
+ unsigned int.
+
+ From Rodney Brown <rodneybrown@pmsc.com>:
+ * target.h (enum thread_control_capabilities), breakpoint.h (enum
+ bptype), breakpoint.c (enum insertion_state_t): Strict ISO-C
+ doesn't allow trailing comma in enum definition.
-Fri Mar 15 12:06:58 1996 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * config/i386/nm-nbsd.h (FLOAT_INFO): Comment out.
- * config/i386/tm-nbsd.h (NUM_REGS): Define.
-
-Thu Mar 14 10:31:18 1996 Jeffrey A Law (law@cygnus.com)
-
- * solib.c (solib_break_names): Add _r_debug_state for
- vanilla SVR4 implementations. From Peter Schauer.
-
-Mon Mar 11 14:24:57 1996 Dawn Perchik <dawn@critters.cygnus.com>
-
- * mon960-rom.c: New file; support mon960 rom monitor on i960.
- * monitor.c (monitor_debug): Change remotedebug to buffer strings.
- * monitor.c (monitor_open): Add test for flag MO_NO_ECHO_ON_OPEN before
- epecting prompt and echo during open.
- * monitor.c (monitor_stop): Add test for flag MO_SEND_BREAK_ON_OPEN to
- determine if break should be sent as stop command.
- * monitor.h: Add flags MO_NO_ECHO_ON_OPEN and MO_SEND_BREAK_ON_OPEN.
- * i960-tdep.c (mon960_frame_chain_valid): New function for getting
- stack frame on mon960.
- * Makefile.in: Add mon960 files.
- * configure.in: Changed i960-*-coff* and i960-*-elf* to target mon960;
- added i960-nindy-coff* and i960-nindy-elf* for target nindy.
+1999-03-23 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * hppa-tdep.c (pa_register_look_aside): Remove CPU_HPPA_RISC_20
+ check, test for presence of struct save_state_t and the ss_wide
+ member directly.
+ * configure.in: Remove CPU_HPPA_RISC_20 test. Add tests for
+ HAVE_STRUCT_SAVE_STATE_T and HAVE_STRUCT_MEMBER_SS_WIDE.
+ * acconfig.h: Add HAVE_STRUCT_SAVE_STATE_T HAVE_STRUCT_MEMBER_SS_WIDE.
+ * configure, config.in: Regenerated.
+
+Tue Mar 23 17:22:57 1999 Philippe De Muyter <phdm@macqel.be>
+
+ * remote.c, parse.c: Include ctype.h.
+
+Mon Mar 22 13:25:13 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infttrace.c (proc_wait): rename to ptrace_wait.
+
+1999-03-17 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (HAVE_MULTIPLE_PROC_FDS): Don't define for Solaris
+ hosts--gdb doesn't support this yet.
* configure: Regenerated.
- * config/i960/mon960.mt, config/i960/tm-mon960.h: New files;
- support mon960 rom monitor on i960.
-
-Mon Mar 11 11:02:47 1996 Steve Chamberlain <sac@slash.cygnus.com>
-
- With Michael Snyder:
- * i386-tdep.c (skip_trampoline_code): Fix strncmp length.
- * win32-nat.c (CHECK, DEBUG*, debug_*): New.
- (handle_load_dll): Don't reload symbols.
- (handle_exception): Use the DEBUG_* names.
- (child_wait): Add DEBUG_* code.
- (_initialize_inftarg): Add new commands to set debug_ names.
-
-Mon Mar 11 09:19:58 1996 Jeffrey A Law (law@cygnus.com)
-
- * From Peter Schauer:
- * breakpoint.c (insert_breakpoints): Use ALL_BREAKPOINTS_SAFE.
- (bpstat_stop_status): Likewise.
- (remove_solib_event_breakpoints): Likewise.
- (clear_momentary_breakpoints): Likewise.
- (re_enable_breakpoints_in_shlibs): Don't reenable a breakpoint
- if we still can't read the memory for that breakpoint.
- (mention): Add bp_shlib_event case to keep gcc quiet.
+
+Tue Mar 16 01:11:33 1999 Andrew Cagney <cagney@rhino.cygnus.com>
+
+ * target.h (struct target_ops), target.c (debug_to_query),
+ remote.c (pack_hex_byte, remote_query): Promote char parameters to
+ int. Stops compile problems with pedantic ISO-C compilers.
+
+Tue Mar 16 15:29:04 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * jv-lang.c, jv-lang.h (java_primitive_type): Declare argument
+ as int instead of char.
+
+1999-03-15 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Merged changes for binary downloads from Michael Snyder:
-Fri Mar 8 12:08:12 1996 Jeffrey A Law (law@cygnus.com)
+ Fri Mar 12 13:11:48 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
- * breakpoint.h (enum enable): New enum shlib_disabled for
- shared library breakpoints that have been temporarily disabled.
- * breakpoint.c: Handle temporarily disabled shared library
- breakpoints like disabled breakpoints in most places.
- (insert_breakpoints): Use shlib_disabled to indicate
- that an unsettable breakpoint is only temporarily disabled.
- (re_enable_breakpoints_in_shlibs): New function.
- * corelow.c (solib_add_stub): After adding shared libraries,
- try to reenable any temporarily disabled breakpoints.
- * infcmd.c (attach_command): Likewise.
- * infrun.c (wait_for_inferior): Likewise.
+ * remote.c (remote_write_bytes): fix 'X' packet protocol so that it
+ can't overwrite the end of its buffer with escaped characters.
-Fri Mar 8 11:41:25 1996 Ian Lance Taylor <ian@cygnus.com>
+1999-03-12 Jim Blandy <jimb@zwingli.cygnus.com>
- * defs.h (extract_long_unsigned_integer): Declare.
- * findvar.c (extract_long_unsigned_integer): New function.
- * printcmd.c (print_scalar_formatted): Use it.
- * valprint.c (val_print_type_code_int): Likewise.
+ Merged changes for HP/UX 9 from Jason Molenda:
-Thu Mar 7 17:40:50 1996 Stan Shebs <shebs@andros.cygnus.com>
+ 1999-03-08 Jason Molenda (jsm@bugshack.cygnus.com)
- * infcmd.c (do_registers_info): Ignore anonymous registers.
- * sh-tdep.c (set processor): New command to set specific
- processor type.
- (sh_reg_names, sh3_reg_names): Arrays of register names for
- SH and SH3 processors.
- (sh_set_processor_type): New function.
- * sh3-rom.c (sh3_open): Call it.
- (sh3_regname): Add names of all the bank registers.
- (sh3_supply_register): Clean up formatting.
- * config/sh/tm-sh.h (NUM_REGS, NUM_REALREGS): Increase to include
- bank registers.
- (REGISTER_NAMES): Add names of bank registers.
- (FP15_REGNUM): Define.
- (REGISTER_VIRTUAL_TYPE): Use it.
- * monitor.c: Clean up some comments.
+ * infttrace.c (hppa_get_process_events): Removed. Function only
+ usable on HPUX 10 and above. It is not called by any other part
+ of GDB.
+ * hppah-nat.c (hppa_get_process_events): Ditto.
+ (child_pid_to_exec_file): Only call ptrace with PT_GET_PROCESS_PATHNAME
+ if that symbol has been defined.
+ * config/pa/nm-hppah.h: Don't set up prototypes et al for
+ hppa_get_process_events.
-Thu Mar 7 12:09:51 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+ * config/pa/hppahpux.mh (TERM_LIB): Do not initialize, let autoconf
+ determine best library automatically.
+ * config/pa/hpux1020.mh: Ditto.
+ * config/pa/hpux1100.mh: Ditto.
+ * configure.in (TERM_LIB): Also check for libHcurses.
+ * configure: Regenerated.
- * i386b-nat.c: Revert part of Mar 5 change. FreeBSD collapsed the
- s* and t* symbols too.
+ Merged changes to accomodate the Hurd:
+
+ Thu Mar 11 18:05:11 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
-Thu Mar 7 15:18:51 1996 James G. Smith <jsmith@cygnus.co.uk>
+ * infptrace.c (proc_wait): Rename to ptrace_wait.
+ * inftarg.c (child_wait): call ptrace_wait instead of proc_wait.
+ * inferior.h: Declare ptrace_wait instead of proc_wait.
- * symfile.c (generic_load): Avoid division by zero.
+1999-03-11 Jim Blandy <jimb@zwingli.cygnus.com>
-Wed Mar 6 17:57:59 1996 Jeffrey A Law (law@cygnus.com)
+ * Makefile.in (VERSION): click to 4.17.86, for next snapshot.
- * breakpoint.c (bfd_lookup_symbol): Provide for all SVR4 systems,
- not just those with HANDLE_SVR4_EXEC_EMULATORS.
+1999-03-09 Rodney Brown <RodneyBrown@pmsc.com>
- From Peter Schauer:
- * breakpoint.c (internal_breakpoint_number): Move to file scope.
- (create_solib_event_breakpoint): Use an internal breakpoint number.
+ Get working on UnixWare 2.1.1.
+ * acconfig.h: Update for defines for procfs.c.
+ * configure.in: Identify defines for procfs.c.
+ * configure.host: i386-*-sysv4.2uw2* => i386v42mp
+ * configure.tgt: i386-*-sysv4.2uw2* => i386v42mp
+ * configure, config.in: Regenerate.
+ * procfs.c: Rename HAVE_NO_PRRUN_T to HAVE_PRRUN_T (autoconf
+ standard), wrap UNIXWARE difference in THE_PR_LWP macro for
+ legibility.
+ * config/i386/tm-i386v42mp.h: Remove HAVE_PSTATUS_T,
+ HAVE_NO_PRRUN_T; now set by configure.
-Wed Mar 6 00:32:44 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+1999-03-04 Jim Blandy <jimb@zwingli.cygnus.com>
- * valarith.c (value_in): Change builtin_type_chill_bool to
- LA_BOOL_TYPE.
+ Merged changes from Jason Molenda:
+
+ 1999-02-24 Jason Molenda (jsm@bugshack.cygnus.com)
-Tue Mar 5 23:48:36 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+ * configure.in: Set CPU_HPPA_RISC_20 if the host CPU is a PA 2.0
+ processor.
+ * acconfig.h: Add CPU_HPPA_RISC_20
+ * config.in, configure: Regenerated.
+ * hppa-tdep.c (pa_register_look_aside): Only refer to new
+ structure elements if we are on a PA2.0 system.
+ * defs.h: Include limits.h.
- * ch-exp.c (parse_primval): Handle CARD, MAX, MIN.
- (match_string_literal): Handle control sequence.
- (match_character_literal): Deto.
+ Merged changes from Stu Grossman:
+
+ Wed Feb 17 10:10:27 1999 Stu Grossman <grossman@babylon-5.cygnus.com>
- * ch-lang.c (chill_printchar): Change formating of nonprintable
- characters from C'xx' to ^(num).
- (chill_printstr): Deto.
- (value_chill_card, value_chill_max_min): New functions to process
- Chill's CARD, MAX, MIN.
- (evaluate_subexp_chill): Process UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN.
+ * gdbtypes.h (get_discrete_bounds): Remove duplicate decl.
- * expression.h (exp_opcode): Add UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN
- for Chill's CARD, MAX, MIN.
+ * jv-typeprint.c (java_type_print_base): Change fputs => fputs_filtered.
+
+ Mon Jan 25 18:30:57 1999 Per Bothner <bothner@cygnus.com>
+
+ * jv-lang.h (JAVA_OBJECT_SIZE): Change from hard-wired constant.
+ (java_primitive_type_from_name, get_java_object_header_size): Declare.
+ * jv-lang.c (java_class_from_object): Use get_java_object_type.
+ * jv-lang.c: Update Class field names: dtable->vtable,
+ msize->method_count, nfields->field_count, bfsize->size_in_bytes,
+ nmethods->method_count.
+ (type_from_class): Demangle array type names.
+ (java_link_class_type): Array type names are now demangled.
+ (get_java_object_type): If not defined yet, try looking it up.
+ (get_java_object_header_size): New function.
+ (java_primitive_type_from_name): New function.
+ (java_demangled_signature_length, java_demangled_signature_copy): New.
+ (java_demangle_type_signature): Re-implement using above functions.
+ (evaluate_subexp_java): For UNOP_IND, call evaluate_subexp_java
+ to evaluate subexp (not evaluate_subexp_standard).
+ For BINOP_SUBSCRIPT update for new array type naming scheme.
+ * jv-valprint.c (java_value_print): Use java_class_from_object.
+ Update array printing to new array type naming convention.
+ (java_val_print): Doing check_typedef when printing a pointer is
+ is a waste of effort. Also, handle TYPE_CODE_INT, to make sure
+ Java bytes as not printed as C chars.
+
+ Fri Jan 8 16:58:22 1999 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * blockframe.c (find_pc_sect_partial_function): Search full symtabs as
+ a last ditch effort (after the partial & minimal symtabs).
+ * defs.h utils.c: Fixup prototypes for vprintf_filtered,
+ vfprintf_filtered, vfprintf_unfiltered and vprintf_unfiltered to return
+ ints to match their standard equivalents.
+ * defs.h symtab.c top.c: Create skip_prologue_hook to allow Java to
+ control the prologue skipping process.
+ * jv-typeprint.c (java_type_print_base): Remove extern for
+ jv_class_demangle, add new arg for objfile (NULL).
+ * symtab.h: Remove struct sourcevector and struct source. Definately
+ not needed.
+ * values.c (value_virtual_fn_field): Fixes code to handle new vtable
+ debug info format. Patch from marka.
+
+ Wed Dec 16 23:11:25 1998 Stu Grossman <grossman@fencer.cygnus.com>
- * valarith.c (value_in): Add processing of TYPE_CODE_RANGE
- and change return type from builtin_type_int to
- builtin_type_chill_bool.
+ * jv-lang.c (java_class_from_object java_class_is_primitive
+ is_object_type): Change dtable to vtable.
+ * (java_primitive_type): Change arg to type char.
+ * (_initialize_java_language): Make java_char_type be unsigned.
+ * jv-lang.h: Fixup prototypes.
+
+ Mon Dec 7 19:02:15 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * jv-valprint.c (java_value_print): Fix printing of values where
+ run time type != compile time type.
+
+ Fri Dec 4 15:23:38 1998 Stu Grossman <grossman@fencer.cygnus.com>
+
+ * Makefile.in: Whack out m2-typeprint.c.
+ * c-typeprint.c (c_type_print_varspec_suffix) typeprint.h: Make this
+ global. It's needed by Java.
+ * (c_type_print_base): Whack prefix off of qualified method names
+ (names with name spaces).
+ * gdbtypes.h (struct cplus_struct_type): Add bits for Java attributes.
+ Shrink voffset
+ to 16 bits to compensate for added bits above (hopefully this is still
+ enough).
+ * Add new accessor macros (TYPE_FND_FIELD_PUBLIC, ...) for all new
+ attribute bits.
+ * jv-typeprint.c (java_type_print_base): Fix printing of method
+ attributes. Handle JVM style manglings.
+ * (java_print_type): Enable code type print varspec_suffix to allow
+ array indices to print out.
+ * jv-valprint.c (java_val_print): Minor formatting.
+ * m2-lang.c (m2_language_d): Change m2_print_type to c_print_type.
+ * stabsread.c (read_member_functions): Save public and static attributes.
+
+1999-03-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Gary Thomas <gthomas@cygnus.co.uk>:
+ * arm-tdep.c (ARM_LE_BREAKPOINT, ARM_BE_BREAKPOINT,
+ THUMB_LE_BREAKPOINT, THUMB_BE_BREAKPOINT): Use illegal instruction
+ instead of SWI 24.
+ * config/arm/tm-arm.h (CALL_DUMMY): Ditto.
+ (IN_SIGTRAMP): Define.
+
+1999-03-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * configure.in (TERM_LIB): Move the code which sets this to a
+ better place.
+
+1999-02-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ * breakpoint.c (SOLIB_LOADED_LIBRARY_PATHNAME,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_CREATE_CATCH_LOAD_HOOK,
+ SOLIB_CREATE_CATCH_UNLOAD_HOOK): Supply default definitions.
+ * infrun.c (SOLIB_IN_DYNAMIC_LINKER): Ditto.
+
+1999-02-23 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Patch from Jason Molenda (jsm@bugshack.cygnus.com)
+ * configure.in (TERM_LIB): Move checking for TERM_LIB, substituting.
+ * configure, aclocal.m4, config.in: Regenerated.
+
+1999-02-22 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 4.17.85, for the release process.
+
+ Patch from Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+ * breakpoint.c (watch_command_1): Reformat comment.
+
+ Patch from Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+ * c-typeprint.c (c_type_print_base): Reformat comments.
+
+ Patch from Edith Epstein <eepstein@sophia.cygnus.com>:
+ * config/pa/nm-hppah.h: Added prototype declarations for
+ hppa_enable_page_protection_events and
+ hppa_disable_page_protection_events.
+
+ Patch from Edith Epstein <eepstein@sophia.cygnus.com>:
+ * infttrace.c (hppa_insert_hw_watchpoint): Make sure that
+ function always returns a value.
+ (hppa_remove_hw_watchpoint): Make sure that function always
+ returns a value.
+
+ Patch from Edith Epstein <eepstein@sophia.cygnus.com>:
+ * inftarg.c (child_wait): Fixed code that checks whether
+ or not the target program has done a fork/vfork.
+ related_pid does not have a value unless the target
+ program has forked/vforked.
+
+1999-02-22 Jim Blandy <jimb@zwingli.cygnus.com>
-Tue Mar 5 18:54:04 1996 Stan Shebs <shebs@andros.cygnus.com>
+ * tm-h8500.h, i386lynx-nat.c: Removed. These files are long
+ dead; it seems that they only appeared due to some CVS weirdness.
+ If they appear again, we may need to distribute garlic and holy
+ water.
- * config/nm-nbsd.h (link_object, lo_name, etc): Move to here
- from config/nm-nbsd.h.
- * config/sparc/nm-nbsd.h (regs, fp_status, etc): Move to here
- from config/sparc/tm-nbsd.h.
+1999-02-16 Jim Blandy <jimb@zwingli.cygnus.com>
- * config/m68k/nm-hp300hpux.h (FIVE_ARG_PTRACE): Define here
- instead of in config/m68k/xm-hp300hpux.h.
+ * Makefile.in (VERSION): Bump to 4.17.2.
-Tue Mar 5 12:05:35 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+Sun Feb 14 18:21:08 1999 Mark Alexander <marka@cygnus.com>
- * i386b-nat.c, m68knbsd-nat.c (fetch_core_registers): Provide
- implementation for NetBSD systems.
+ * config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
+ coffread.c will correctly handle char or short function parameters.
-Mon Mar 4 23:44:16 1996 Per Bothner <bothner@kalessin.cygnus.com>
+1999-02-11 Jason Molenda (jsm@bugshack.cygnus.com)
- * valarith.c (binop_user_defined_p): Return 0 for BINOP_CONCAT.
- (value_concat): Handle varying strings (add COERCE_VARYING_ARRAY).
+ * configure, aclocal.m4: Regenerate with correct version of aclocal.
- * ch-lang.c (evaluate_subexp_chill case MULTI_SUBSCRIPT): Error
- if "function" is pointer to non-function.
+1999-02-10 Syd Polk <spolk@cygnus.com>
-Mon Mar 4 17:47:03 1996 Stan Shebs <shebs@andros.cygnus.com>
+ * acinclude.m4: Fix for new location of itclConfig.sh and itkConfig.sh.
+ * aclocal.m4: Regnerate.
+ * configure: Regenerate.
- * top.c (print_gdb_version): Update copyright year.
+1999-02-10 Jason Molenda (jsm@bugshack.cygnus.com)
-Mon Mar 4 14:44:54 1996 Jeffrey A Law (law@cygnus.com)
+ * demangle.c: Fix comments to mention "set demangle-style"
+ instead of "set demangle".
+ Run through indent to fix minor indenting problems.
- From Peter Schauer:
- * infrun.c (wait_for_inferior): Remove breakpoints and
- switch terminal settings before calling SOLIB_ADD.
- * solib.c (enable_break, SVR4 variant): Don't map in symbols
- for the dynamic linker, the namespace pollution causes real
- problems.
+Wed Feb 10 17:53:09 1999 Bob Manson <manson@charmed.cygnus.com>
-Sun Mar 3 17:18:57 1996 James G. Smith <jsmith@cygnus.co.uk>
+ * i386-tdep.c (gdb_print_insn_i386): Add missing returns.
- * remote-mips.c (common_breakpoint): Explicitly terminate the
- returned buffer.
+Wed Feb 10 13:17:21 1999 Stan Shebs <shebs@andros.cygnus.com>
-Wed Feb 28 22:32:18 1996 Stan Shebs <shebs@andros.cygnus.com>
+ Declare Gould configuration obsolete:
+ * configure.host, configure.tgt: Comment out Gould configs.
+ * Makefile.in: Comment out Gould-related actions.
+ * gould-xdep.c, gould-tdep.c, config/gould/*: Comment out.
+ * NEWS: Mention obsolete status.
- From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
- * remote.c (remote_detach): Send a command 'D' to the target
- when detaching, update the function's comments.
+1999-02-09 DJ Delorie <dj@cygnus.com>
-Wed Feb 28 15:50:12 1996 Fred Fish <fnf@cygnus.com>
+ * sparcl-tdep.c: UDP download works in cygwin
- * Makefile.in (VERSION): Bump version to 4.15.2 to establish
- baseline for gdb 4.16 rerelease testing.
+1999-02-08 Jason Molenda (jsm@bugshack.cygnus.com)
-Wed Feb 28 13:32:05 1996 Jeffrey A Law (law@cygnus.com)
+ * gnu-regex.c: Check ENABLE_NLS instead of HAVE_LIBINTL_H.
+ * configure.in: Don't check for libintl.h.
+ * configure, config.in: Regenerated.
- * somsolib.c (som_solib_create_inferior_hook): Before returning
- call clear_symtab_users.
+Mon Feb 8 18:10:50 1999 Stan Shebs <shebs@andros.cygnus.com>
-Tue Feb 27 00:04:46 1996 Stu Grossman (grossman@critters.cygnus.com)
+ * NEWS: Mention new X packet and PowerPC variant support.
- * remote-e7000.c (e7000_open): Delete all breakpoints when
- connecting to e7000. Change connect message to allow use of
- monitor.exp in test suite.
- * (e7000_load): Print transfer rate of download.
- * symfile.c (generic_load): Print transfer rate of download.
+1999-02-08 Nick Clifton <nickc@cygnus.com>
-Sun Feb 25 13:58:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+ * configure.host: Add support for StrongARM host.
+ * configure.tgt: Add support for StrongARM target.
- * configure.in (mips*-*-vxworks*): New config.
- * configure: Regenerated.
+Mon Feb 8 12:05:05 1999 David Taylor <taylor@texas.cygnus.com>
- * config/mips/vxmips.mt, config/mips/tm-vxmips.h: New files.
- * remote-vxmips.c (vx_convert_to_virtual, vx_convert_from_virtual):
- Remove, never used.
+ * dsrec.c (make_srec): Cast targ_addr to int in call to sprintf
+ otherwise on big endian machine with a bfd_vma of 64 bits,
+ *everything* gets loaded at location 0.
-Sat Feb 24 12:30:28 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+Mon Feb 7 10:05:43 1999 Frank Ch. Eigler <fche@cygnus.com>
- * partial-stab.h (case N_FUN): Function symbols generated
- by SPARCworks cc have a meaningless zero value, do not update
- pst->textlow if the function symbol value is zero.
+ * infrun.c (wait_for_inferior): Allow SIGTRAP to be "pass"ed
+ to target program.
- * stabsread.c (define_symbol): Initialize SYMBOL_TYPE field
- for function prototype declaration symbols.
+Fri Feb 5 16:46:14 1999 Stan Shebs <shebs@andros.cygnus.com>
-Fri Feb 23 22:33:04 1996 Stu Grossman (grossman@critters.cygnus.com)
+ * NEWS: Add mentions of various new things.
- * remote-e7000.c (e7000_load): New routine to download via the
- network.
- * (e7000_wait): Don't backup PC when we hit a breakpoint.
- Apparantly new sh2 pods get this right...
- * (e7000_ops): Add call to e7000_load.
+Thu Feb 4 00:19:14 1999 Christopher Faylor <cgf@cygnus.com>
-Thu Feb 22 00:52:42 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+ * configure.in: Move termcap determination later in the
+ file to catch setting of cygwin flag.
+ * configure: Regenerate.
- * config/m68k/{nbsd.mh,nbsd.mt,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h},
- m68knbsd-nat.c: New files, support for NetBSD/m68k.
+Wed Feb 3 14:16:38 1999 Christopher Faylor <cgf@cygnus.com>
- * configure.in (m68k-*-netbsd*): New config.
+ * config/i386/cygwin.mh: Move TERMCAP test code to configure.in.
+ * configure.in: Treat libtermcap.a detection as a special case
+ when hosting on cygwin.
+ * configure: Regenerate.
+
+1999-02-03 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_binary_download, remote_binary_length): New
+ static globals for dealing with binary transmissions.
+ (remote_write_bytes): Add support for binary downloads
+ by shadowing the "M" packet with a new "X" packet. This
+ defaults to ON; if the stub does not understand this, it
+ will fall back to using "M".
+ (putpkt): Add support for binary downloading.
+ * monitor.c (monitor_expect): The mon2000 monitor
+ on the MSA2000 will also emit random DC1/DC3 chars.
+ * m32r-stub.c: Change all char's to unsigned char's
+ to support binary downloading.
+ (handle_exception): Add support for binary downloading
+ via a new "X" packet.
+ (getpacket): Do NOT strip eighth bit of incoming chars.
+ Watch out for escaped characters in the incoming stream.
+ (putpacket): Do NOT strip eighth bit of incoming chars.
+ (bin2mem): New function to write binary data directly to
+ memory.
+ * m32r-rom.c: Add new "mon2000" target.
+
+Tue Feb 2 18:40:29 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * hp-psymtab-read.c (hpread_build_psymtabs): Coerce first arg
+ passed to make_cleanup to the correct type.
+ (hpread_quick_traverse): Change fifth arg to call to
+ hpread_end_psymtab to be 0.
+ Compare CURR_MODULE_END to 0 rather than NULL.
+ Get rid of ifdef'ed out code.
+ (scan_procs): Get rid of ifdef'ed out code.
+
+ * somread.c (som_symfile_read): Coerce first argument passed to
+ make_cleanup to the correct type.
+
+Tue Feb 2 17:36:29 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * hp-psymtab-read.c (do_pxdb): New function. Check whether the
+ file needs to be processed by pxdb (an HP debug info massaging
+ tool), if so call it.
+ (hpread_build_psymtabs): Initialize scan_start to 0 and
+ simplify flow of control.
+
+ * somread.c (som_symfile_read): Add call to do_pxdb (),
+ in hp-psymtab-read.c.
+
+ * symfile.c (symbol_file_add): Remove ifdef'ed out HPUX specific
+ code.
+ (symfile_bfd_open): Remove HPUXHPPA ifdef'ed code. Code is now
+ in hp-psymtab-read.c.
+
+1999-02-02 Martin Hunt <hunt@cygnus.com>
+
+ * printcmd.c (print_scalar_formatted): Use strcat to concat all
+ the output together before calling fprintf_filtered().
+
+1999-02-01 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Require autoconf 2.13.
+ (AM_EXEEXT): Replace with new AC_EXEEXT.
+ * acinclude.m4: Move itcl header macros from aclocal.m4 to here.
+ * aclocal.m4: Regenerated.
* configure: Regenerated.
-Wed Feb 21 19:00:21 1996 Fred Fish <fnf@cygnus.com>
+1999-02-01 Jim Blandy <jimb@zwingli.cygnus.com>
- * standalone.c (open, _initialize_standalone): Fix obvious typos
- reported by Martin Pool <martin@citr.uq.oz.au>.
+ Allow PPC users to select which PPC/RS6000 variant they're
+ debugging at run-time. At the moment, the only thing this affects
+ is the set of registers visible.
+ * config/rs6000/tm-rs6000.h (REGISTER_NAME): Define this as a call
+ to the function rs6000_register_name.
+ (rs6000_register_name): Include extern decl.
+ (NUM_REGS): Bump to 183. What's the right way to do this?
+ (FIRST_UISA_SP_REGNUM, LAST_UISA_SP_REGNUM): Renamed from
+ FIRST_SP_REGNUM, LAST_SP_REGNUM.
+ (REGISTER_BYTES): Recompute this.
+ * rs6000-tdep.c: Renamed all uses of FIRST_SP_REGNUM and
+ LAST_SP_REGNUM to FIRST_UISA_SP_REGNUM and LAST_UISA_SP_REGNUM, with
+ some concomitant formatting changes.
+ #include "gdbcmd.h", so we can define commands here.
+ (struct variant): New structure.
+ (COMMON_UISA_REG_NAMES, PPC_UISA_SPR_NAMES, PPC_SEGMENT_REG_NAMES,
+ PPC_32_OEA_SPR_NAMES, num_registers): New macros.
+ (register_names_rs6000, register_names_uisa, register_names_403,
+ register_names_403GC, register_names_505, register_names_860,
+ register_names_601, register_names_602, register_names_603,
+ register_names_604, register_names_750, variants): New variables.
+ (rs6000_register_name, install_variant, find_variant_by_name,
+ install_variant_by_name, list_variants, show_current_variant,
+ set_processor, show_processor): New functions.
+ (_initialize_rs6000_tdep): Define new commands `set processor' and
+ `show processor', and call install_variant_by_name to set the
+ default variant.
+ * rs6000-nat.c: Renamed all uses of FIRST_SP_REGNUM and
+ LAST_SP_REGNUM to FIRST_UISA_SP_REGNUM and LAST_UISA_SP_REGNUM, with
+ some concomitant formatting changes.
+ * configure.in: Accept the `--with-cpu' flag, to specify a default
+ processor variant.
+ * acconfig.h: Provide a blurb for TARGET_CPU_DEFAULT, which is set
+ by configure's `--with-cpu' flag.
+ * config.in, configure: Regenerated.
-Wed Feb 21 14:24:04 1996 Jeffrey A Law (law@cygnus.com)
+Sun Jan 31 15:24:24 1999 Stan Shebs <shebs@andros.cygnus.com>
- * solib.c (solib_create_inferior_hook): Fix thinko.
+ * buildsym.h, buildsym.c: Convert to ANSI-only.
-Tue Feb 20 23:59:19 1996 Jeffrey A Law (law@cygnus.com)
+ * buildsym.h, buildsym.c: Reformat to standard.
- * solib.c (solib_break_names): Define for Solaris and Linux.
- (enable_break): For SVR4 systems, first try to use the debugger
- interfaces in the dynamic linker to track shared library events
- as they happen, then fall back to BKPT_AT_SYMBOL code. Convert
- BKPT_AT_SYMBOL code to use shared library event breakpoints.
- (solib_create_inferior_hook): Simplify BKPT_AT_SYMBOL code,
- it no longer needs to restart/wait on the inferior.
- * symfile.c (find_lowest_section): No longer static.
- * symfile.h (find_lowest_section): Corresponding changes.
+ * buildsym.c (merge_symbol_lists): Remove unused variable.
+ (_initialize_buildsym): Remove, does nothing.
-Tue Feb 20 18:54:08 1996 Fred Fish <fnf@cygnus.com>
+1999-01-31 J.T. Conklin <jtc@redbacknetworks.com>
- * valops.c (COERCE_FLOAT_TO_DOUBLE): Define default value.
- (value_arg_coerce): Use COERCE_FLOAT_TO_DOUBLE.
- * config/alpha/tm-alpha.h (COERCE_FLOAT_TO_DOUBLE): Define to 1.
- * config/mips/tm-mips.h: Ditto.
- * config/pa/tm-hppa.h: Ditto.
- * config/rs6000/tm-rs6000.h: Ditto.
- * config/sparc/tm-sparc.h: Ditto.
-
-Tue Feb 20 17:32:05 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+ * i386-stub.c, m32r-stub.c, m68k-stub.c, sh-stub.c, sparc-stub.c,
+ sparcl-stub, sparclet-stub.c: Change declaration of putDebugChar
+ to include explicit void return type as per documentation. Fix up
+ occasions where stubs erroneously checked return type.
- * config/{i386,ns32k}/nbsd.mh (NATDEPFILES): Remove core-aout.o.
+Sun Jan 31 13:18:33 1999 Stan Shebs <shebs@andros.cygnus.com>
- * config/nm-nbsd.h (FETCH_INFERIOR_REGISTERS): Defined.
- * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG):
- #ifdef'd out definitions --- Causes serious gdb failures on
- the i386. Need to investigate further before enabling.
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * remote.c (remote_query): Fix tipo.
- * i386b-nat.c (fetch_inferior_registers, store_inferior_registers,
- fetch_core_registers): New functions. These functions are defined
- if FETCH_INFERIOR_REGISTERS is set. Registers are fetched/stored
- with ptrace PT_GETREGS/PT_SETREGS.
+Fri Jan 29 15:25:09 1999 Stan Shebs <shebs@andros.cygnus.com>
-Tue Feb 20 16:55:06 1996 Stu Grossman (grossman@critters.cygnus.com)
+ * configure.tgt (v850): Add wildcard to match.
- * findvar.c (extract_floating store_floating): Replace `long
- double' with `DOUBLEST'.
+Fri Jan 29 16:44:01 1999 Edith Epstein <eepstein@sophia.cygnus.com>
-Mon Feb 19 15:25:51 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+ * inferior.h: Ran indent.
- * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG):
- Define.
+ * fork-child.c: Ran indent.
-Mon Feb 19 10:32:05 1996 Jeffrey A Law (law@cygnus.com)
+ * infrun.c : Ran indent.
- * symtab.h (looup_minimal_symbol_solib_trampoline): Declare.
+Fri Jan 29 12:57:34 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
- * breakpoint.h (remove_solib_event_breakpoints): Declare.
- * breakpoint.c (remove_solib_event_breakpoints): New function.
- * somsolib.c (solib_create_inferior_hook): Remove all solib event
- breakpoints before inserting any new ones. Use a solib event
- breakpoint for the breakpoint at "_start".
- Remove extraneous "\n" from calls to warning.
-
- * breakpoint.c (breakpoint_1): Add missing "sigtramp" to bptypes
- name array.
-
-Mon Feb 19 01:09:32 1996 Doug Evans <dje@cygnus.com>
-
- * dwarfread.c (add_partial_symbol): Use ADD_PSYMBOL_ADDR_TO_LIST
- for CORE_ADDR values.
- (new_symbol): Use SYMBOL_VALUE_ADDRESS for CORE_ADDR values.
- * symfile.h (add_psymbol_{,addr}to_list): Add prototypes.
-
-Sun Feb 18 14:37:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
-
- * mipsread.c (mipscoff_symfile_read): Unconditionally add
- alpha coff dynamic symbols for all symbol files. Makes skipping
- over the trampoline code work when stepping from a function in a
- shared library into a function in a different shared library.
-
-Sun Feb 18 09:27:10 1996 Stu Grossman (grossman@cygnus.com)
-
- * config/sparc/tm-sparc.h: Define PS_FLAG_CARRY. Define
- RETURN_VALUE_ON_STACK to return long doubles on the stack.
-
-Sat Feb 17 16:33:11 1996 Fred Fish <fnf@cygnus.com>
-
- * Makefile.in (ch-exp.o): Add dependencies.
- (various): Add gdb_string.h to dependencies that need it.
-
-Sat Feb 17 08:57:50 1996 Fred Fish <fnf@cygnus.com>
-
- * symmisc.c (print_symbol_bcache_statistics): Update description for
- printing byte cache statistics.
-
-Thu Feb 16 16:02:03 1996 Stu Grossman (grossman@cygnus.com)
-
- * Add native support for long double data type.
- * c-exp.y (%union): Change dval to typed_val_float. Use DOUBLEST
- to store actual data. Change types of INT and FLOAT tokens to
- typed_val_int and typed_val_float respectively. Create new token
- DOUBLE_KEYWORD to specify the string `double'. Make production
- for FLOAT use type determined by parse_number. Add production for
- "long double" data type.
- * (parse_number): Use sscanf to parse numbers as float, double or
- long double depending upon the type of typed_val_float.dval. Also
- allow user to specify `f' or `l' suffix to explicitly specify
- float or long double constants. Change typed_val to
- typed_val_int.
- * (yylex): Change typed_val to typed_val_int. Also, scan for
- "double" keyword.
- * coffread.c (decode_base_type): Add support for T_LNGDBL basic
- type.
- * configure, configure.in: Add check for long double support in
- the host compiler.
- * defs.h: Define DOUBLEST appropriatly depending on whether
- HAVE_LONG_DOUBLE (from autoconf) is defined. Also, fix prototypes
- for functions that handle this type.
- * expression.h (union exp_element): doubleconst is now type
- DOUBLEST.
- * m2-exp.y f-exp.y (%union): dval becomes type DOUBLEST.
- * findvar.c (extract_floating): Make return value be DOUBLEST.
- Also, add support for numbers with size of long double.
- * (store_floating): Arg `val' is now type DOUBLEST. Handle all
- floating types.
- * parser-defs.h parse.c (write_exp_elt_dblcst): Arg expelt is now
- DOUBLEST.
- * valarith.c (value_binop): Change temp variables v1, v2 and v to
- type DOUBLEST. Coerce type of result to long double if either op
- was of that type.
- * valops.c (value_arg_coerce): If argument type is bigger than
- double, coerce to long double.
- * (call_function_by_hand): If REG_STRUCT_HAS_ADDR is defined, and
- arg type is float and > 8 bytes, then use pointer-to-object
- calling conventions.
- * valprint.c (print_floating): Arg doub is now type DOUBLEST.
- Use appropriate format and precision to print out floating point
- values.
- * value.h: Fixup prototypes for value_as_double,
- value_from_double, and unpack_double to use DOUBLEST.
- * values.c (record_latest_value): Remove check for invalid
- floats. Allow history to store them so that people may examine
- them in hex if they want.
- * (value_as_double unpack_double): Change return value to DOUBLEST.
- * (value_from_double): Arg `num' is now DOUBLEST.
- * (using_struct_return): Use RETURN_VALUE_ON_STACK macro (target
- specific) to expect certain types to always be returned on the stack.
-
-Fri Feb 16 14:00:54 1996 Fred Fish <fnf@cygnus.com>
-
- * bcache.c, bcache.h: New files to implement a byte cache.
- * Makefile.in (SFILES): Add bcache.c.
- (symtab_h): Add bcache.h.
- (HFILES_NO_SRCDIR): add bcache.h
- (COMMON_OBJS): Add bcache.o
- (bcache.o): New target.
- * dbxread.c (start_psymtab): Make global_syms & static_syms
- type "partial_symbol **".
- * hpread.c (hpread_start_symtab): Ditto.
- * os9kread.c (os9k_start_psymtab): Ditto.
- * stabsread.h (start_psymtab): Ditto.
- * {symfile.c, symfile.h} (start_psymtab_common): Ditto.
- * maint.c (maintenance_print_statistics): Call
- print_symbol_bcache_statistics.
- * objfiles.c (allocate_objfile): Initialize psymbol bcache malloc
- and free pointers.
- * solib.c (allocate_rt_common_objfile): Ditto.
- * symfile.c (reread_symbols): Ditto.
- (free_objfile): Free psymbol bcache when objfile is freed.
- (objfile_relocate): Use new indirect psymbol pointers.
- * objfiles.h (struct objfile): Add psymbol cache.
- * symfile.c (compare_psymbols): Now passed pointers to pointers to
- psymbols.
- (reread_symbols): Free psymbol bcache when freeing other objfile
- resources.
- (add_psymbol_to_list, add_psymbol_addr_to_list): Initialize new
- psymbol using the psymbol bcache.
- (init_psymbol_list): Psymbol lists now contain pointers rather than
- the actual psymbols.
- * symfile.h (psymbol_allocation_list): Psymbol lists now dynamically
- grown arrays of pointers.
- (ADD_PSYMBOL_VT_TO_LIST): Initialize new symbol using the psymbol
- bcache.
- * symmisc.c (print_partial_symbols): Now takes pointer to pointer
- to partial symbol.
- (print_symbol_bcache_statistics): New function to print per objfile
- bcache statistics.
- (print_partial_symbol, print_partial_symbols,
- maintenance_check_symtabs, extend_psymbol_list):
- Account for change to pointer to pointer to partial symbol.
- * symtab.c (find_pc_psymbol, lookup_partial_symbol, decode_line_2,
- make_symbol_completion_list):
- Account for change to pointer to pointer to partial symbol.
- * symtab.h (bcache.h): Include.
- * xcoffread.c (xcoff_start_psymtab): Make global_syms & static_syms
- type "partial_symbol **".
-
-Fri Feb 16 10:02:34 1996 Fred Fish <fnf@cygnus.com>
-
- * dwarfread.c (free_utypes): New function.
- (read_file_scope): Call free_utypes as cleanup, rather than just
- freeing the utypes pointer.
-
-Thu Feb 15 21:40:52 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
-
- * demangle.c (is_cplus_marker): New function, checks if a
- character is one of the commonly used C++ marker characters.
- * defs.h (is_cplus_marker): Add prototype.
- * c-typeprint.c (c_type_print_base), ch-lang.c (chill_demangle),
- cp-valprint.c (cp_print_class_method), mdebugread.c (parse_symbol),
- stabsread.c (define_symbol, read_member_functions, read_struct_fields),
- symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P),
- values.c (vb_match): Use is_cplus_marker instead of comparison
- with CPLUS_MARKER.
-
-Thu Feb 15 18:08:13 1996 Fred Fish <fnf@cygnus.com>
-
- * symfile.h (INLINE_ADD_PSYMBOL): Default this to 0 and possibly
- delete entirely someday.
-
-Thu Feb 15 15:25:34 1996 Stan Shebs <shebs@andros.cygnus.com>
-
- * mpw-make.sed: Edit out makefile rebuild rule.
- (host_alias, target_alias): Comment out instead of deleting.
- (@LIBS@): Edit out references.
-
-Tue Feb 13 22:56:46 1996 Fred Fish <fnf@cygnus.com>
-
- * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
- Use n_psyms in OBJSTAT, not psyms.
-
-Mon Feb 12 15:59:31 1996 Doug Evans <dje@charmed.cygnus.com>
-
- * configure.in (sparclet-*-aout*): New config.
- * configure: Regenerated.
+ * infrun.c (_initialize_infrun): Do not stop or print anything
+ when a SIGWINCH is received.
-Mon Feb 12 14:17:52 1996 Fred Fish <fnf@cygnus.com>
+ * Makefile.in (m2-exp.tab.c): Use YACC not BISON.
+ (f-exp.tab.c): Ditto.
+ (jv-exp.tab.c): Ditto.
+ (c-exp.tab.c): Ditto.
+ (YACC): Define as @YACC@.
- * somsolib.c (som_solib_add): Use xmalloc rather than bare
- unchecked call to malloc.
- * remote-mips.c (pmon_load_fast): ditto.
- * remote-mm.c (mm_open): ditto.
- * hpread.c (hpread_lookup_type): ditto.
- * remote-adapt.c (adapt_open): ditto.
+1999-01-29 Martin Hunt <hunt@cygnus.com>
-Mon Feb 12 13:11:32 1996 Fred Fish <fnf@cygnus.com>
+ Changes from Keith Seitz <keiths@cygnus.com>
+ * valops.c (value_assign): Add calls to register_changed_hook and
+ memory_changed_hook to inform UIs that the user has changed
+ the target's registers/memory.
+ * findvar.c (write_register_gen): Remove call to pc_changed_hook.
+ * defs.h: Remove declaration for pc_changed_hook and
+ add declarations for register_changed_hook and
+ memory_changed_hook.
+ * top.c: Ditto.
- * f-lang.c (allocate_saved_bf_node, allocate_saved_function_node,
- allocate_saved_f77_common_node, allocate_common_entry_node,
- add_common_block): Use xmalloc rather than malloc, some of which
- were unchecked.
- * gnu-regex.c: At same point as other gdb specific changes
- #undef malloc and then #define it to xmalloc.
- * ch-exp.c (growbuf_by_size): Use xmalloc/xrealloc rather than
- bare unchecked calls to malloc/realloc.
- * stabsread.c (dbx_lookup_type): Use xmalloc rather than bare
- unchecked call to malloc.
+1999-01-29 Mark Alexander <marka@cygnus.com>
-Wed Feb 7 11:31:26 1996 Stu Grossman (grossman@cygnus.com)
+ * procfs.c (wait_fd): Handle deleted threads correctly.
- * symtab.c (gdb_mangle_name): Change opname var to be const to
- match return val of cplus_mangle_name.
- * i960-tdep.c: Change arg types of next_insn to match callers.
+1999-01-28 Jason Molenda (jsm@bugshack.cygnus.com)
-Wed Feb 7 07:34:24 1996 Fred Fish <fnf@cygnus.com>
+ * utils.c (init_page_info): Force window size if running under emacs.
- * config/i386/linux.mh (XM_CLIBS, GDBSERVER_LIBS): Remove. These
- apparently aren't needed in any reasonably recent version of
- linux.
+1999-01-27 James Ingham <jingham@cygnus.com>
-Tue Feb 6 21:37:03 1996 Per Bothner <bothner@kalessin.cygnus.com>
+ * typeprint.c (whatis_exp): Remove static declaration.
- * stabsread.c (read_range_type): If !self-subrange and language
- is Chill, assume a true range. If a true_range is a sub_subrange,
- use builtin_type_int for index_type.
+Wed Jan 27 16:50:25 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
-Tue Feb 6 18:38:51 1996 J.T. Conklin <jtc@slave.cygnus.com>
+ * hp-psymtab-read.c: Reformat using indent.
- * nindy-share/nindy.c (say): Use stdarg.h macros when compiling
- with an ANSI compiler.
+Wed Jan 27 13:20:25 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
-Mon Feb 5 18:24:28 1996 Steve Chamberlain <sac@slash.cygnus.com>
+ * hp-psymtab-read.c: Reformat comments, update copyright.
- From Michael_Snyder@NeXT.COM (Michael Snyder):
- * valops.c (value_arg_coerce): Coerce float to double, unless the
- function prototype specifies float.
-
-Mon Feb 5 09:51:55 1996 Tom Tromey <tromey@creche.cygnus.com>
+Tue Jan 26 16:02:47 1999 Mark Alexander <marka@cygnus.com>
- * language.c (set_language_command): Use languages table when
- printing available languages.
+ * v850-tdep.c (v850_generic_reg_names, v850e_reg_names,
+ v850_register_names, v850_processor_type_table): Declare tables
+ and structures for handling differences in register names for
+ v850 and v850e.
+ (struct reg_list): Define new structure for creating tables
+ of register bit masks in v850e instrutions.
+ (handle_prepare, handle_pushm): New helpers for v850_scan_prologue.
+ (v850_scan_prologue): Recognize v850e instructions: callt, prepare,
+ and pushm.
+ (v850_target_architecture_hook): New function to set register
+ names based on current machine.
+ (_initialize_v850_tdep): Set up target_architecture_hook.
+ * config/v850/tm-v850.h (v850_register_names): Declare.
+ (REGISTER_NAME): Define to refer to v850_register_names.
+ (SR0_REGNUM, CTBP_REGNUM): Define.
+ (PS_REGNUM): Redefine in terms of SR0_REGNUM.
-Sat Feb 3 12:22:05 1996 Fred Fish <fnf@cygnus.com>
+Tue Jan 26 18:27:26 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
- Fix problems reported by Hans Verkuil (hans@wyst.hobby.nl):
- * command.c (add_cmd): Add missing initialization for enums member.
- Reorder members to match structure declaration to make it easier to
- tell when one is missing.
- * exec.c (exec_file_command): Fix problem where filename in malloc'd
- memory is referenced after being freed.
+ * Makefile.in (c-exp.tab.c): Use BISON instead of YACC, to pick
+ the correct value from configure output.
+ (jv-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
-Sat Feb 3 03:26:21 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com)
- * dwarfread.c (read_func_scope): Avoid GDB core dumps if
- AT_name tag is missing.
+ * breakpoint.h (ep_is_exception_catchpoint): Add prototype.
+ * frame.h (select_and_print_frame): Add prototype.
+ * stack.c (func_command): Call select_and_print_frame with correct
+ number of arguments. Reformat whitespace.
- * procfs.c (procfs_stopped_by_watchpoint): Fix logic when
- FLTWATCH and FLTKWATCH are defined.
+Tue Jan 26 16:53:54 1999 Fernando Nasser <fnasser@cygnus.com>
- * remote.c (remote_read_bytes): Advance memaddr for transfers,
- return number of bytes transferred for partial reads.
+ * remote.c (remote_query): fix maximum packet size to account for
+ remote_debug use.
+ (putpkt): add comment to alert about extra byte need.
- * top.c (init_signals): Reset SIGTRAP to SIG_DFL.
+Mon Jan 25 19:55:30 1999 Mark Alexander <marka@cygnus.com>
-Fri Feb 2 13:40:50 1996 Steve Chamberlain <sac@slash.cygnus.com>
+ * sh-tdep.c (sh_target_architecture_hook): Return immediately
+ when a matching machine is found.
- * win32-nat.c (mappings): Add ppc registers.
- (child_resume): Turn off step for ppc.
+Fri Jan 22 09:10:35 1999 Mark Alexander <marka@cygnus.com>
-Thu Feb 1 10:29:31 1996 Steve Chamberlain <sac@slash.cygnus.com>
+ * remote-mips.c (mips_initialize): Fix parameters to clear_breakpoint.
+ (common_breakpoint): Restore support for instruction breakpoints
+ on non-LSI targets.
- * config/powerpc/(cygwin32.mh, cygwin32.mt, tm-cygwin32.h,
- xm-cygwin32.h): New.
- * config/i386/(*win32*): Becomes *cygwin32*.
- * configure.in (i[3456]86-*-win32*): Becomes i[3456]86-*-cygwin32.
- (powerpcle-*-cygwin32): New.
- * configure: Regenerate.
- * win32-nat.c (child_create_inferior): Call CreateProcess
- with the right program arg.
+Thu Jan 21 17:16:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
-Thu Feb 1 11:01:10 1996 Jeffrey A Law (law@cygnus.com)
+ * stack.c: Close open comment.
+ * symtab.c (find_pc_sect_line): Ditto.
- * config/pa/tm-hppa.h (SOFT_FLOAT): Provide a default definition.
+Thu Jan 21 17:51:51 1999 Stan Shebs <shebs@andros.cygnus.com>
-Wed Jan 31 19:01:28 1996 Fred Fish <fnf@cygnus.com>
+ * procfs.c (init_procfs_ops): New function, fills in procfs_ops,
+ init only nonzero fields, leave to_require_attach and
+ to_require_detach empty, not needed for /proc systems yet.
+ (_initialize_procfs): Call init_procfs_ops.
- * serial.c: Change fputc/fputs/fprintf to _unfiltered forms.
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * top.c (init_main): Fix tipo in description of the remotetimeout
+ variable.
+ * breakpoint.c (bpstat_stop_status): Handle systems where
+ DECR_PC_AFTER_BREAK != DECR_PC_AFTER_HW_BREAK.
-Wed Jan 31 18:36:27 1996 Stan Shebs <shebs@andros.cygnus.com>
+Thu Jan 21 17:25:46 1999 Mark Alexander <marka@cygnus.com>
- * config/sparc/xm-sun4os4.h (HAVE_TERMIOS): Remove.
+ * mon960-rom.c (_initialize_mon960): Call init_mon960_cmds
+ to fill in mon960_cmds structure properly.
- * config/sparc/xm-sparc.h (HAVE_WAIT_STRUCT): Remove, never used.
+Wed Jan 20 17:53:22 1999 Stan Shebs <shebs@andros.cygnus.com>
- * config/i386/nm-i386mach.h (CHILD_PREPARE_TO_STORE): Move to
- here from config/i386/xm-i386mach.h, fix name.
- * config/i386/nm-sun386.h: Ditto, from config/i386/xm-sun386.h.
- * config/i386/nm-ptx4.h (CHILD_PREPARE_TO_STORE): Move to
- here from config/i386/xm-ptx4.h.
- * config/i386/nm-ptx4.h: Ditto, from config/i386/xm-ptx.h.
- * config/i386/nm-symmetry.h: Ditto, from config/i386/xm-symmetry.h.
- * config/m68k/nm-sun3.h: Ditto, from config/m68k/xm-sun3.h.
- * config/sparc/nm-nbsd.h: Ditto, from config/sparc/xm-nbsd.h.
- * config/sparc/nm-sun4os4: Ditto, from config/sparc/xm-sparc.h.
+ * remote-sds.c (sds_ops): Define only once.
+ (init_sds_ops, sds_command, _initialize_remote_sds): Declare.
+ (init_sds_ops): Init only non-zero fields.
- * config/sparc/nm-sun4sol2.h: New file, renamed from nm-sysv4.h.
- (PRSVADDR_BROKEN): Move here from xm-sun4sol2.h.
- * config/sparc/sun4sol2.mh (NAT_FILE): Update.
+Wed Jan 20 15:45:15 1999 Mark Alexander <marka@cygnus.com>
-Wed Jan 31 17:20:26 1996 Jeffrey A Law (law@cygnus.com)
+ * h8300-tdep.c (original_register_names, h8300h_register_names,
+ h8300_register_names): Define new variables.
+ (set_register_names): New function to set register names based on
+ current CPU type.
+ (h8300_command, h8300h_command, h8300s_command): Call
+ set_register_names.
+ * config/h8300/tm-h8300.h (h8300_register_names): Declare.
+ (REGISTER_NAME): Define to refer to h8300_register_names.
- * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Handle software
- floating point correctly.
- (STORE_RETURN_VALUE): Likewise.
- * config/pa/tm-pro.h (SOFT_FLOAT): define.
+1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
-Wed Jan 31 13:34:52 1996 Fred Fish <fnf@cygnus.com>
+ * sol-thread.c abug-rom.c cpu32bug-rom.c dbug-rom.c m32r-rom.c
+ mac-nat.c mon960-rom.c op50-rom.c ppc-bdm.c remote-adapt.c
+ remote-array.c remote-bug.c remote-e7000.c remote-eb.c remote-es.c
+ remote-est.c remote-hms.c remote-mm.c remote-nindy.c remote-nrom.c
+ remote-os9k.c remote-rdp.c remote-sds.c remote-sim.c remote-st.c
+ remote-udi.c rom68k-rom.c sh3-rom.c sparcl-tdep.c sparclet-rom.c
+ v850ice.c win32-nat.c: cosmetic changes to conform to coding
+ standards.
- * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
- Define to what should be reasonable values. However, apparently
- a bug in linux mmap prevents mapped symbol tables from working.
+1999-01-19 Jim Blandy <jimb@zwingli.cygnus.com>
-Tue Jan 30 18:26:19 1996 Fred Fish <fnf@cygnus.com>
+ Use aclocal to generate GDB's aclocal.m4 script.
+ * acinclude.m4: New file, containing the hand-written local macro
+ definitions that used to be in aclocal.m4. Don't sinclude
+ ../bfd/aclocal.m4 any more; running aclocal in this directory will
+ get us the definitions we need. HOWEVER: Do sinclude
+ ../bfd/acinclude.m4, because we need the definition of
+ BFD_NEED_DECLARATION.
+ * aclocal.m4: Regenerated by aclocal.
+ * configure: Regenerated by autoconf.
- * defs.h (errno.h>: Move #include closer to head of file to solve
- obscure problem with systems that declare perror with const arg, in
- both errno.h and stdio.h, and const is defined away by intervening
- local include.
+Tue Jan 19 10:27:23 1999 David Taylor <taylor@texas.cygnus.com>
-Tue Jan 30 15:41:10 1996 Fred Fish <fnf@cygnus.com>
+ * breakpoint.c (disable_breakpoints_in_shlibs): new parameter,
+ silent, controls whether to print message about removal of shared
+ library breakpoints.
+ * breakpoint.h (disable_breakpoints_in_shlibs): decl updated.
+ * irix5-nat.c (clear_solib): call disable_breakpoints_in_shlibs.
+ * osfsolib.c (clear_solib): ditto.
+ * solib.c (clear_solib): ditto.
+ * somsolib.c (som_solib_restart): update call to
+ disable_breakpoints_in_shlibs.
- From Jon Reeves <reeves@zk3.dec.com>:
- * i386-stub.c (getpacket): Change fprintf stream from "gdb" to stderr.
- (mem_fault_routine): Fix misplaced volatile type qualifier in decl.
+ * target.h (child_post_attach): only declare if CHILD_POST_ATTACH
+ is define.
-Mon Jan 29 19:05:58 1996 Fred Fish <fnf@cygnus.com>
+Tue Jan 19 18:07:11 1999 Andrew Cagney <cagney@b1.cygnus.com>
- * Makefile.in (diststuff): Make all-doc; diststuff target does not
- exist in doc/Makefile.in.
+ * corelow.c (solib_add_stub): Ditto.
+ (core_file_to_sym_file): Cast make_cleanup parameter.
-Mon Jan 29 18:44:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+ * solib.c (symbol_add_stub, solib_map_sections): Change argument
+ to PTR insted of a char*. Matches catch_errors interface.
- * config/m88k/xm-cxux.h (BP_HIT_COUNT): Remove, never used.
+Mon Jan 18 14:01:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
-Mon Jan 29 00:10:35 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+ * remote-array.c (array_open): Don't use fprintf_filtered to send
+ data to the log file.
- * ch-valprint.c (calculate_array_length): New function to
- determine the length of an array type.
- (chill_val_print (case TYPE_CODE_ARRAY)): If the length of an
- array type is zero, call calculate_array_length.
+ * remote-array.c (handle_load_dll): Change argument type to PTR so
+ that it is compatible with catch_errors.
+ * ocd.c (ocd_start_remote): Ditto.
+ * remote-sds.c (sds_start_remote): Ditto.
- * gdbtypes.c (get_discrete_bounds (case TYPE_CODE_ENUM)): The
- values may not be sorted. Scan all entries and set the real lower
- and upper bound.
+ * win32-nat.c (win32_child_thread_alive): Namespace proof
+ child_thread_alive.
+ (init_child_ops): Update.
-Sun Jan 28 15:50:42 1996 Fred Fish <fnf@cygnus.com>
+Mon Jan 18 12:03:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
- * config/xm-linux.h: Move include of solib.h and #define of
- SVR4_SHARED_LIBS from here ...
- * config/nm-linux.h: ...to here.
+ * remote-rdi.c (arm_rdi_open): Set gdb_hostif.hostosarg and
+ gdb_hostif.dbgarg to NULL instead of stdout.
+ (voiddummy, myprint, mywritec): Use gdb_stdout instead of stdout.
-Sat Jan 27 10:34:05 1996 Fred Fish <fnf@cygnus.com>
+Mon Jan 18 16:40:50 1999 Stan Shebs <shebs@andros.cygnus.com>
- * configure.in (AC_CHECK_HEADERS): Check for sys/procfs.h.
- Also check for gregset_t and fpregset_t types.
- * configure: Regenerate.
- * core-regset.c (sys/procfs.h): Only include if HAVE_SYS_PROCFS_H
- is defined.
- (fetch_core_registers): Turn into stub unless both HAVE_GREGSET_T
- and HAVE_FPREGSET_T are defined. These changes allow systems
- like linux that are migrating to /proc support to use a single
- configuration for both new and old versions.
+ * ser-ocd.c (ocd_open): Handle Unix case gracefully.
- * config/i386/linux.mt: Note that this is now for both a.out and
- ELF systems.
- * config/i386/linux.mh (NATDEPFILES): Add solib.o, core-regset.o,
- i386v4-nat.o
- * config/i386/tm-linux.h (tm-sysv4.h): Include.
- * config/i386/xm-linux.h (solib.h): Include
- (SVR4_SHARED_LIBS): Define.
- * i386v4-nat.c: Only compile if HAVE_SYS_PROCFS_H is defined.
- (supply_gregset, fill_gregset): Compile if HAVE_GREGSET_T defined.
- (supply_fpregset, fill_fpregset): Compile if HAVE_FPREGSET_T
- defined.
+ * target.c (dummy_target): Don't initialize statically.
+ (init_dummy_target): New function, fills in dummy_target.
+ (initialize_targets): Use it.
+ * hpux-thread.c (hpux_thread_ops): Don't initialize statically.
+ (init_hpux_thread_ops): New function, fills in hpux_thread_ops.
+ (_initialize_hpux_thread): Use it.
+ * m3-nat.c (m3_ops): Don't initialize statically.
+ (init_m3_ops): New function, fills in m3_ops.
+ (_initialize_m3): Use it.
-Fri Jan 26 13:48:14 1996 Stan Shebs <shebs@andros.cygnus.com>
+1999-01-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
- * config/sparc/xm-sparc.h (NEW_SUN_CORE): Remove, never used.
- * config/i386/xm-sun386.h: Ditto.
- * config/m68k/xm-sun2.h, config/m68k/xm-sun3.h: Ditto.
+ * sol-thread.c: delete compile time initialization of target_ops
+ (_initialize_sol_thread): initialize target_ops at run time.
+ * hpux-thread.c: added target_ops entry.
+ * m3-nat.c: ditto.
-Thu Jan 25 16:05:53 1996 Tom Tromey <tromey@creche.cygnus.com>
+Mon Jan 18 15:19:13 1999 David Taylor <taylor@texas.cygnus.com>
- * Makefile.in (INSTALLED_LIBS, CLIBS): Include @LIBS@.
+ * procfs.c (procfs_ops): delete compile time initialization.
+ (_initialize_procfs): initialize procfs_ops at run time.
+
+Mon Jan 18 12:51:44 1999 Christopher Faylor <cgf@cygnus.com>
-Thu Jan 25 09:22:15 1996 Steve Chamberlain <sac@slash.cygnus.com>
+ * configure.in: Ensure that -luser32 is always linked in
+ for cygwin build.
+ * configure: Regenerated.
- From Greg McGary <gkm@gnu.ai.mit.edu>:
- * dcache.c (dcache_peek, dcache_poke): Advance addr for
- multi-byte I/O.
+Mon Jan 18 08:38:05 1999 Mark Alexander <marka@cygnus.com>
-Thu Jan 25 13:08:51 1996 Doug Evans (dje@cygnus.com)
+ * values.c (value_virtual_fn_field): Clear the pointed-to
+ offset when casting to the base class.
- * infrun.c (normal_stop): Fix test for shared library event.
+Mon Jan 18 10:30:51 1999 David Taylor <taylor@texas.cygnus.com>
-Thu Jan 25 03:26:38 1996 Doug Evans <dje@charmed.cygnus.com>
+ * remote-udi.c (init_udi_ops): change non-existant udi_run_ops to
+ udi_ops; delete NULL initializers.
- * configure.in (sparc64-*-*): Add default host configuration.
- (sparc64-*-solaris2*): Add target configuration.
- * configure: Regenerated.
- * sparc/sp64sol2.mt: New file.
-
-Wed Jan 24 22:31:37 1996 Doug Evans <dje@charmed.cygnus.com>
-
- * Makefile.in (RUNTEST): srcdir renamed to rootsrc.
-
-Wed Jan 24 15:42:24 1996 Tom Tromey <tromey@creche.cygnus.com>
-
- * Makefile.in (lint): Close backquotes.
-
-Wed Jan 24 13:19:10 1996 Fred Fish <fnf@cygnus.com>
-
- * NEWS: Make note of new record and replay feature for
- remote debug sessions.
- * serial.c (gdbcmd.h): Include.
- (serial_logfile, serial_logfp, serial_reading, serial_writing):
- Define here, for remote debug session logging.
- (serial_log_command, serial_logchar, serial_write, serial_readchar):
- New functions for remote debug session logging.
- (serial_open): Open remote debug session log file when needed.
- (serial_close): Close remote debug session log file when needed.
- (_initialize_serial): Add set/show commands for name of remote
- debug session log file.
- * serial.h (serial_readchar): Declare
- (SERIAL_READCHAR): Call serial_readchar().
- (SERIAL_WRITE): Call serial_write().
- (serial_close): Declare as extern.
- (serial_logfile, serial_logfp): Declare.
- * top.c (execute_command): Declare serial_logfp. Log user command
- in remote debug session log if log file is open.
- * remote-array.c (array_wait): #ifdef out echo to gdb_stdout.
- (array_read_inferior_memory): Rewrite to fix memory overwrite bug.
- * remote-array.c (SREC_SIZE): Remove, duplicates define in
- monitor.h.
- * remote-array.c (hexchars, hex2mem): Remove, unused.
- * gdbserver/low-linux.c (store_inferior_registers): Remove
- unnecessary extern declaration of registers[].
- * gdbserver/Makefile.in (all): Add gdbreplay.
- * gdbserver/gdbreplay.c: New file.
- * gdbserver/README: Give example of recording a remote
- debug session with gdb and then replaying it with gdbreplay.
+Mon Jan 18 12:03:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.c (serial_close): gdb_fclose tages gdb_file** arg, not
+ gdb_file*.
+
+ * f-valprint.c, target.c, gdbarch.c: Pass gdb_stderr not stderr.
+
+Mon Jan 18 10:46:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * stack.c (print_frame_info_base): Don't cast call to
+ catch_errors.
+ (print_args_stub): Change char* arg to PTR.
+ * symmisc.c (print_symbol): Ditto.
+ * top.c (quit_cover): Ditto.
+ * remote.c (remote_open_1, remote_start_remote): Ditto.
+ * infrun.c (normal_stop, hook_stop_stub, restore_selected_frame):
+ Ditto.
+
+ * stack.c (backtrace_command): Cast first arg of make_cleanup to
+ make_cleanup_func.
+ * remote.c (remote_kill): Cast putpkt arg to catch_errors_ftype.
+
+Mon Jan 18 08:47:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
-Tue Jan 23 18:02:35 1996 Per Bothner <bothner@kalessin.cygnus.com>
-
- * stabsread.c (rs6000_builtin_type): Make bool type unsigned.
- (read_one_struct_field): Support boolean bitfields.
- * c-valprint.c (c_val_print): Print booleans properly.
-
-Tue Jan 23 18:54:09 1996 Stan Shebs <shebs@andros.cygnus.com>
-
- * remote-vxsparc.c (vx_convert_to_virtual, vx_convert_from_virtual):
- Remove, never used.
- * config/sparc/vxsparc.mt (TDEPFILES): Add remote-vxsparc.o.
-
-Tue Jan 23 14:36:05 1996 Per Bothner <bothner@kalessin.cygnus.com>
-
- * ch-exp.c (parse_tuple): Error if invalid mode.
-
- * value.h (COERCE_ARRAY): Don't coerce enums.
- (COERCE_ENUM): Don't COERCE_REF.
- (COERCE_NUMBER): New macro (same as COERCE_ARRAY then COERCE_ENUM).
- * valops.c (value_assign): Only do COERCE_ARRAY if internalvar (let
- value_cast handle it otherwise); do *not* COERCE_ENUM either way.
- * valarith.c: Use COERCE_NUMBER instead od COEREC_ARRAY.
- Add COERCE_REF before COERCE_ENUM.
- * values.c (value_as_long): Simplify.
-
- * valops.c (value_array): Create internalvar if !c_style_arrays.
-
- * language.c (lang_bool_type): Add Fortran support.
- * eval.c (OP_BOOL): Use LA_BOOL_TYPE.
-
-Tue Jan 23 13:08:26 1996 Jeffrey A Law (law@cygnus.com)
-
- * symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
- All references changed.
- * breakpoint.c (bpstat_what): Add shlib_event to the class types.
- Update state table. Reformat so that it's still readable.
- When we hit the shlib_event breakpoint, set the calss of shlib_event.
- (breakpoint_1): Add "shlib events" as a breakpoint type.
- Print the shlib_event breakpoint like other breakpoints.
- (create_solib_event_breakpoint): New function.
- (breakpoint_re_set_one): Handle solib_event breakpoints.
- * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
- (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
- action.
- (create_solib_event_breakpoint): Declare.
- * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
- (normal_stop): Inform the user when the inferior stoped due
- to a shared library event.
- (_initialize_infrun): Add new set/show variable "stop-on-solib-events"
- to control whether or not gdb continues the inferior or stops it when
- a shared library event occurs.
- * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
- * somsolib.c (TODO list): Update.
- (som_solib_create_inferior_hook): Arrange for gdb to be notified
- when significant shared library events occur.
- * hppa-tdep.c (find_unwind_entry): No longer static.
-
-Tue Jan 23 09:00:48 1996 Doug Evans <dje@charmed.cygnus.com>
-
- * printcmd.c (print_insn): Pass fprintf_unfiltered to
- INIT_DISASSEMBLE_INFO.
-
-Mon Jan 22 16:59:40 1996 Stan Shebs <shebs@andros.cygnus.com>
-
- * remote.c (remotebreak): New GDB variable.
- (remote_break): New global.
- (remote_interrupt): Send a break instead of ^C if remote_break.
- * NEWS: Describe the new variable.
-
-Mon Jan 22 16:24:11 1996 Doug Evans <dje@charmed.cygnus.com>
-
- * sparc-tdep.c (_initialize_sparc_tdep): Always use print_insn_sparc.
-
-Fri Jan 19 07:19:38 1996 Fred Fish <fnf@cygnus.com>
-
- * hp300ux-nat.c (getpagesize): Remove unused function
- fetch_core_registers.
- (hp300ux_core_fns): Remove, is unused.
- (_initialize_core_hp300ux): Remove, is unused.
- (gdbcore.h): Remove #include, no longer needed.
+ * defs.h (catch_errors_ftype): Define.
+ (catch_errors): Replace char* arg with PTR arg.
+ * top.c (catch_errors): Update
+
+ * breakpoint.c (bpstat_stop_status, bpstat_stop_status,
+ delete_breakpoint, breakpoint_re_set): Delete all casts in call to
+ catch_errors.
+ (breakpoint_cond_eval, watchpoint_check,
+ cover_target_enable_exception_callback, breakpoint_re_set_one):
+ Arg is PTR not char*.
-Fri Jan 19 00:59:53 1996 Jeffrey A Law (law@cygnus.com)
+ * breakpoint.c (cover_target_enable_exception_callback): Change
+ type to int. Check for cast values of 0 and -1. Return a result!
+ (insert_breakpoints): Move declaration of SAL and ARGS to where
+ they are used.
+
+1999-01-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
- * rs6000-nat.c (exec_one_dummy_insn): Rework to avoid
- ptrace bug in aix4.1.3 on the rs6000.
+ * remote.c (remote_query): new function - creates proper interface
+ to the remote protocol "q" command.
-Wed Jan 17 13:22:27 1996 Stan Shebs <shebs@andros.cygnus.com>
+Fri Jan 15 17:11:48 EST 1999 Zdenek Radouch (radouch@cygnus.com)
- * remote-hms.c (hms_ops): Add value for to_thread_alive.
- * remote-nindy.c (nindy_ops): Ditto.
- * remote-udi.c (udi_ops): Ditto.
+ * config/fr30/tm-fr30.h: Changed ABI to match GCC change
+ (always use pointer for structs passed by value).
-Tue Jan 16 18:00:35 1996 James G. Smith <jsmith@cygnus.co.uk>
+1999-01-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
- * remote-mips.c (pmon_opn, pmon_wait, pmon_makeb64, pmon_zeroset,
- pmon_checkset, pmon_make_fastrec, pmon_check_ack,
- pmon_load_fast): New functions. Support for the PMON monitor world.
- (common_open): New function to merge support for different monitors.
- (mips_open): Use common_open().
- (mips_send_command): New function.
- (mips_send_packet): Scan out-of-sequence packets.
- (mips_enter_debug, mips_exit_debug): New functions.
- (pmon_ops): New target definition structure.
+ * target.h: added entry for target queries (to_query)
+ target.c: ditto.
+
+Thu Jan 14 18:29:17 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * remote-mm.c (mm_wait): fix stream arg to gdb_flush.
+ * remote-udi.c (udi_wait): fix stream arg to fwrite.
+ * symmisc.c (maintenance_check_symtabs): fix stream argument to
+ print_address_numeric.
+
+Wed Jan 13 19:33:16 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * breakpoint.c (insert_breakpoints): insert cast to eliminate
+ warning.
+
+Wed Jan 13 14:59:02 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infrun.c (set/show scheduler-locking) New command. Set a
+ mode bit that will control how GDB attempts to control thread
+ scheduling for step, continue, etc. (resume): make use of
+ the schedule-locking mode.
+ * target.h (struct target_ops): new field to_has_thread_control.
+ * sol-thread.c: initialize target_ops to_has_thread_control.
+ * procfs.c: ditto.
+ * target.c: ditto.
+ * m3-nat.c: ditto.
+ * remote.c: ditto.
+ * hpux-thread.c: ditto.
+ * thread.c: cull duplicate prototypes. Move prototypes to top.
+ * serial.c: indentation cleanup.
+ * breakpoint.c: add casts to eliminate compiler warnings.
-Tue Jan 16 11:22:58 1996 Stu Grossman (grossman@cygnus.com)
+Tue Jan 12 17:00:00 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * inftarg.c (child_create_inferior): fixed HPUXHPPA specific
+ call to fork_inferior. The shell param is now NULL.
+
+1999-01-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (init_base_monitor_ops): Whitespace cleanup.
+ (_initialize_remote_monitors): Same.
+
+1999-01-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (init_monitor_ops): Initialize the monitor_ops
+ structure if it hasn't already been done.
+
+Tue Jan 12 14:50:10 1999 Stan Shebs <shebs@andros.cygnus.com>
- * Makefile.in (CLIBS): Add LIBS to allow libraries to be
- specified on the make command line (via make LIBS=xxx).
+ * inftarg.c (child_ops): Don't initialize statically.
+ (init_child_ops): New function, fills in child_ops.
+ (_initialize_inftarg): Use it.
+ (child_post_attach): Declare extern.
+ (child_wait): Fix ambiguous parens.
+ (child_attach_to_process): Remove unused local wstatus.
+ (child_insert_fork_catchpoint, child_remove_fork_catchpoint,
+ child_insert_vfork_catchpoint, child_remove_vfork_catchpoint,
+ child_has_forked, child_insert_exec_catchpoint,
+ child_remove_exec_catchpoint): Return a value.
+Mon Jan 11 16:43:44 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
-Fri Jan 12 21:41:58 1996 Jeffrey A Law (law@cygnus.com)
+ * remote.c (remote_wait): Add inferior_pid to thread list only
+ if it is not already there.
- * symtab.c (find_pc_symtab): Don't lose if OBJF_REORDERED
- is set but there are no psymtabs.
+1999-01-11 Jason Molenda (jsm@bugshack.cygnus.com)
-Fri Jan 12 15:56:12 1996 Steve Chamberlain <sac@slash.cygnus.com>
+ * scm-tags.h: Update FSF's address on copyright notice.
+ * ser-e7kpc.c: Same.
+ * gnu-nat.h: Same.
- * dsrec.c (load_srec): Remove unused variable.
- * monitor.c (monitor_expect): Don't expect a ^C to echo.
- * serial.c (serial_open): Add parallel interface.
- * sh3-rom.c (parallel, parallel_in_use): New.
- (sh3_load): If parallel_in_use, download though the
- parallel port.
- (sh3_open): Open parallel port if specified.
- (sh3_close): New function.
- (_inititalize_sh3): Add sh3_close hook and documentation.
- * monitor.c (monitor_close): Export.
- * monitor.h (monitor_close): Add prototype.
+Mon Jan 11 13:45:57 1999 Stu Grossman <grossman@babylon-5.cygnus.com>
-Fri Jan 12 13:11:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+ * dwarf2read.c (dump_die): Change stderr to gdb_stderr.
+ * expprint.c (print_subexp): fprintf => fprintf_unfiltered.
+ * jv-typeprint.c (java_type_print_base): fputs => fputs_filtered.
+ * stack.c (struct function_bounds): Remove superfluous `typedef'.
+ * symfile.c (list_overlays_command): stdout => gdb_stdout.
+ * symmisc.c (maintenance_check_symtabs): stdout => gdb_stdout.
+ * utils.c (print_spaces): Make more efficient.
+
+Mon Jan 11 13:55:51 1999 David Taylor <taylor@texas.cygnus.com>
- From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
- * remote.c (remotetimeout): New GDB variable, use to set the
- remote timeout for reading.
+ * utils (print_spaces): fix arg to strcat; fix formatting.
+Fri Jan 8 11:57:24 1999 Stan Shebs <shebs@andros.cygnus.com>
-Fri Jan 12 07:14:27 1996 Fred Fish <fnf@cygnus.com>
+ * exec.c (exec_ops): Don't initialize statically.
+ (init_exec_ops): New function, fills in exec_ops.
+ (_initialize_exec): Use it.
- * lynx-nat.c, irix4-nat.c, sparc-nat.c: Include gdbcore.h
- to get "struct core_fns" defined.
- * Makefile.in (lynx-nat.o, irix4-nat.o, sparc-nat.o):
- Are dependent upon gdbcore_h.
+Thu Jan 7 17:50:15 EST 1999 Zdenek Radouch (radouch@cygnus.com)
-Thu Jan 11 23:13:24 1996 Per Bothner <bothner@cygnus.com>
+ Beta FR30 port.
+ * fr30-tdep.c
+ * config/fr30/tm-fr30.h
+
+Wed Jan 6 12:28:35 1999 David Taylor <taylor@texas.cygnus.com>
- * symfile.c (decrement_reading_symtab): New function.
- * symfile.c, symtab.h (currently_reading_symtab): New variable.
- * symfile.c (psymtab_to_symtab): Adjust currently_reading_symtab.
- * gdbtypes.c (check_typedef): Don't call lookup_symbol if
- currently_reading_symtab (since that could infinitely recurse).
+ * configure.in: Add an --enable-tui argument. Construct
+ tui/Makefile from tui/Makefile.in. Use AM_PROG_CC_STDC. If we
+ have the GUI, then we need this to process libgui.h.
+ (ENABLE_CFLAGS): define and export BUILD_TUI.
+ (AC_CHECK_HEADERS): Add check for term.h.
+
+ * configure.host (hppa-*-hpux10.20, hppa-*-hpux11.0*): New configs.
+
+ * config.in, configure : regenerated.
+
+ * Makefile.in: Allow the TUI code to be conditionally enabled.
+ (TUI_LIBRARY): New variable, value are set by the configuration
+ script. Set to the empty string when the TUI isn't enabled.
+ (gdb$(GDBEXT)): Use those, instead of referring to all-tui and
+ tui/libtui.a directly.
+ (BUILD_TUI): build the tui -- only when configured with
+ --enable-tui.
+ (YLWRAP): use ylwrap to avoid problems on systems w/o bison.
+ (gdb$(EXEEXT)): make it dependent on BUILD_TUI.
+ (all-tui): remove dependency from phony target.
+ (c-exp.tab.c): use ylwrap instead of bison.
+ (jv-exp.tab.c): ditto.
+ (f-exp.tab.c): ditto.
+ (m2-exp.tab.c): ditto.
+ (ALLDEPFILES): add somread.c, hp-psymtab-read.c, hp-symtab-read.c.
+ (SFILES): remove the above files
+ (COMMON_OBS): remove somread.o
+ (SFILES): Add the tui files to this, so they get included in etags
+ tables.
+ (gdb$(EXEEXT)): Add all-tui to the list of dependencies, and add
+ tui/libtui.a to the link list.
+ (all-tui): New rule, which does a recursive make in the tui
+ subdir.
+ (tui/libtui.a): When recursing, pass down ${FLAGS_TO_PASS}. And
+ don't echo the make command. This is closer to what the other
+ recursions do.
+ (HFILES_NO_SRCDIR): add hpread.h
+ (COMMON_OBS): add hp-psymtab-read.o, hp-symtab-read.o
+ (SFILES): add hp-psymtab-read.c, hp-symtab-read.c add rules for
+ the new files. Remove hpread.c, hpread.o
+ (gdb$(EXEEXT)): Depend on the actual tui library, not on a
+ fictitious target. Since the fictitious target never existed,
+ make would always relink.
+ (tui/libtui.a): Always recurse to make sure the library is up to
+ date.
+
+Wed Jan 6 12:05:12 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c: Pacify --enable-build-warnings, reformat code
+ to conform to standards, fix spelling errors.
+ (ishex, stubhex, record_currthread, etc): Declare.
+ (ishex, stubhex): Declare char arg as int.
+ (pack_string): Comment out, never used but possibly useful.
+ (threadref_to_int, remote_get_threadinfo, etc): Make static.
+
+Wed Jan 6 11:43:32 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Elena Zannoni
+ <ezannoni@cygnus.com> and Edith Epstein <eepstein@cygnus.com> as
+ part of a project to merge in changes made by HP.
+
+ * c-exp.y: use external flag hp_som_som_object_present to decide
+ whether code was compiled by HP's compilers. Add two new C++
+ tokens for true and false.
+ (yylex): check for template name is done differently for the
+ HP/aCC compiler case. Change some of the template processing code
+ for handling HP aCC templates. Handle true and false tokens.
+
+Tue Jan 5 11:13:36 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (record_curthread): Must not modify inferior_pid when
+ called from wait_for_inferior. Instead, if a new thread-id is
+ detected, call add_thread.
+ (MAGIC_NULL_PID): new macro, use instead of the magic number
+ "42000".
+ (remote_find_new_threads): if inferior_pid is unknown, get and use
+ the current thread id.
+ (remote_start_remote): on connecting, attempt to get the current
+ thread id for inferior_pid.
+ (remote_resume): If pid == -1, then resume any-thread (not the
+ current thread specifically). Also some cosmetic fixups.
+
+ * thread.c (info_threads_command): don't initialize current_pid
+ until after call to FIND_NEW_THREADS (which may change inferior_pid).
+ Also some cosmetic fixups.
+ * infrun.c: cosmetic fixups and casts to avoid warnings.
+ * infcmd.c: cosmetic fixups, mainly long lines.
+
+Tue Jan 5 11:55:57 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * target.c (noprocess): terminate sentence with a period.
+ * breakpoint.c (catch_command_1): ditto.
-Thu Jan 11 17:21:25 1996 Per Bothner <bothner@kalessin.cygnus.com>
+ * c-valprint.c (c_value_print): remove hack^2 from HP; it causes
+ testsuite losses with no real gain.
- * stabsread.c (read_struct_type): Trivial simplification.
+ * inferior.h (START_INFERIOR_TRAPS_EXPECTED): restore, but only
+ if tm-*.h hasn't overridden default value.
- * stabsread.c (define-symbol): Use invisible references
- for TYPE_CODE_SET and TYPE_CODE_BITSTRING too.
- * valops.c (call_function_by_hand): Likewise.
- * eval.c (evaluate_subexp_standard): When known, use the formal
- parameter type as the expected type when evaluating arg expressions.
- * ch-lang.c (evaluate_subexp_chill): Likewise (for MULTI_SUBSCRIPT).
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
+ * configure.in: Fix whitespace indentation for --help.
+ * configure: Regenerated.
-Wed Jan 10 16:08:49 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+1999-01-04 Manuel Bouyer <bouyer@antioche.lip6.fr>
- * configure.in, configure: Recognize rs6000-*-aix4*.
- * config/powerpc/xm-aix.h: Reduce to include "xm-aix4.h".
- * config/rs6000/aix4.mh (XM_FILE): Point to xm-aix4.h.
- * config/rs6000/xm-aix4.h: New file.
- * config/xm-aix4.h: New file.
+ * main.c: Add --write command line option, document -w.
+ * gdb.1: Document --write.
-Wed Jan 10 11:25:37 1996 Fred Fish <fnf@cygnus.com>
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
- From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
- * gdbserver/low-linux.c: New file.
- * remote.c (remote_read_bytes): Fix aborts on larger packets.
-
- * config/i386/linux.mh (GDBSERVER_DEPFILES, GDBSERVER_LIBS):
- Define.
- * stabsread.c (define_symbol): If register value is too large,
- tell what it is and what max is.
+ * configure.in: Require autoconf 2.12.1 or higher.
+ * doc/configure.in: Ditto.
+ * nlm/configure.in: Ditto.
+ * rdi-share/configure.in: Ditto.
+ * testsuite/configure.in: Ditto.
+ * doc/Makefile.in: Don't hardcode $(SHELL).
+ * nlm/Makefile.in: Ditto.
+ * rdi-share/Makefile.in: Ditto.
+ * testsuite/Makefile.in: Ditto.
+Mon Jan 4 12:53:03 1999 Stan Shebs <shebs@andros.cygnus.com>
-Tue Jan 9 09:33:53 1996 Jeffrey A Law (law@cygnus.com)
-
- * hpread.c (hpread_build_psymtabs): Finish Jan 4th
- enum namespace -> enum_namespace change.
-
-Tue Jan 9 04:44:47 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
-
- * ch-exp.c (parse_primval): In case ARRAY, add missing
- FORWARD_TOKEN ().
-
-Mon Jan 8 13:29:34 1996 Stan Shebs <shebs@andros.cygnus.com>
-
- * remote-mips.c (mips_receive_header): Recognize \012 instead
- of \n, but write \n when program sends a \012.
- * ser-mac.c (mac_input_buffer): Increase size of buffer.
-
-Mon Jan 8 12:00:40 1996 Jeffrey A Law (law@cygnus.com)
-
- * infptrace.c (initialize_infptrace): Move function out of
- #ifdef conditional; put code within the function inside an
- #ifdef conditional.
-
- * buildsym.c (end_symtab): Remove sort_pending and sort_linevec
- arguments. Sorting is now dependent on OBJF_REORDERED. All
- callers/references changed.
- * dbxread.c (read_ofile_symtab): Correctly determine value for
- last_source_start_addr for reordered executables.
- (process_one_symbol): Handle N_FUN with no name as an end of
- function marker.
- * partial-stab.h (case N_FN, N_TEXT): Don't assume CUR_SYMBOL_VALUE
- is the high text address for a psymtab.
- (case N_SO): Likewise.
- (case N_FUN): Handle N_FUN with no name as an end of function
- marker.
- * minsyms.c (lookup_minimal_symbol_by_pc): Examine all symbols
- at the same address rather than a random subset of them.
- * coffread.c (coff_symfile_init): Set OBJF_REORDERED.
- * elfread.c (elf_symfile_init): Similarly.
- * somread.c (som_symfile_init): Similarly.
- * xcoffread.c (xcoff_symfile_init): Similarly.
-
-Fri Jan 5 17:46:01 1996 Stu Grossman (grossman@cygnus.com)
-
- * stack.c (print_stack_frame print_frame_info) symmisc.c
- (dump_symtab): Change RETURN_MASK_ERROR to RETURN_MASK_ALL so
- that catch_errors doesn't get blindsided by QUIT and lose the
- cleanup chain. This fixes a problem where ^C while in a
- user-defined command sometimes leaves instream NULL and causes a
- segfault in command_loop.
-
-Fri Jan 5 13:59:16 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
-
- * configure.in, configure: Add `-ldl -lw' for Solaris linking.
-
-Fri Jan 5 12:02:00 1996 Steve Chamberlain <sac@slash.cygnus.com>
-
- * config/sh/sh.mt, config/powerpc/*.mt, config/pa/hppapro.mt,
- config/m68k/monitor.mt, config/h8500/h8500.mt, config/h8300/h8300.mt:
- srec.o renamed to dsrec.o.
-
-Thu Jan 4 16:04:54 1996 Stu Grossman (grossman@cygnus.com)
-
- * breakpoint.c (remove_breakpoint): Change error to warning so
- that hardware watchpoint removal problems won't leave breakpoint
- traps in the target.
- * remote-e7000.c (e7000_insert_breakpoint,
- e7000_remove_breakpoint): Use e7000 based breakpoints, not memory
- breakpoints.
- * (e7000_wait): Adjust PC back by two when we see a breakpoint to
- compensate for e7000 maladjustment.
- * sparcl-tdep.c (sparclite_check_watch_resources): Fix logic bug
- which prevented hardware watchpoints from working.
-
-Thu Jan 4 10:44:17 1996 Fred Fish <fnf@cygnus.com>
-
- * infptrace.c (udot_info): New function.
- (PT_*): Define each individually if that one is not defined.
- * rs6000-nat.c (kernel_u_size): New function
- Include <sys/user.h> for "struct user"
- * alpha-nat.c (kernel_u_size): New function.
- Include <sys/user.h> for "struct user"
- * sparc-nat.c (kernel_u_size): New function.
- Include <sys/user.h> for "struct user"
- * i386b-nat.c (kernel_u_size): New function.
- * i386v-nat.c (kernel_u_size): New function.
- * config/i386/nm-fbsd.h (KERNEL_U_SIZE): Define.
- (kernel_u_size): Declare.
- * config/i386/nm-linux.h (KERNEL_U_SIZE): Define.
- (kernel_u_size): Declare.
- * config/sparc/nm-sun4os4.h (KERNEL_U_SIZE): Define.
- (kernel_u_size): Declare.
- * config/alpha/nm-osf2.h (KERNEL_U_SIZE): Define.
- (kernel_u_size): Declare.
- * config/rs6000/nm-rs6000.h (KERNEL_U_SIZE): Define.
- (kernel_u_size): Declare.
-
-Thu Jan 4 11:00:01 1996 steve chamberlain <sac@slash.cygnus.com>
-
- * mdebugread.c (mylookup_symbol): enum namespace becomes
- enum_namespace type.
- * symfile.c (add_psymbol_to_list)
- (add_psymbol_addr_to_list): Ditto.
- * symtab.c (lookup_partial_symbol): Ditto.
- (lookup_symbol): Ditto.
- (lookup_block_symbol): Ditto.
- * win32-nat.c (handle_load_dll): Use incoming dll base.
- (child_wait): Catch DLL load errors.
- (create_child_inferior): Translated between paths correctly.
-
-Wed Jan 3 23:13:53 1996 Fred Fish <fnf@cygnus.com>
-
- * i386v4-nat.c (supply_gregset, fill_gregset): Subtract NUM_FREGS
- from NUM_REGS to get number of general registers that we care about.
- * config/i386/tm-i386.h (REGISTER_BYTES): Define in terms
- of number of general regs and number of floating point regs.
-
-Wed Jan 3 19:49:54 1996 steve chamberlain <sac@slash.cygnus.com>
-
- * config/i386/tm-win32.h (IN_SOLIB_CALL_TRAMPOLINE): New.
- (SKIP_TRAMPOLINE_CODE): New.
- * config/i386/xm-win32.h (CANT_FORK): Deleted.
- (SLASH*) Changed to use unix style slash.
- * symtab.h (namespace enum): becomes typedef to avoid namespace
- collision in C++.
- * infcmd.c (path_command): Use empty string if PATH name not set.
- * i386-tdep.c (skip_trampoline_code): New function.
- * srec.c: Renamed dsrec.c to avoid filename collision.
- * Makefile.in: Cope with renaming.
-
-Wed Jan 3 13:09:04 1996 Fred Fish <fnf@cygnus.com>
+ * remote-vx.c (init_vx_ops, init_vx_run_ops): Remove unneeded
+ inits of new fields, including ref to bogus field.
+ (vx_ops, vx_run_ops): Make static.
- * symmisc.c (print_objfile_statistics): Print memory use statistics
- for objfile psymbol, symbol, and type obstacks.
+Mon Jan 4 15:05:29 1999 David Taylor <taylor@texas.cygnus.com>
-Tue Jan 2 13:41:14 1996 Stan Shebs <shebs@andros.cygnus.com>
+ * inferior.h (START_INFERIOR_TRAPS_EXPECTED): delete,
+ already defined in tm.h.
- * config/mips/nm-irix5.h: Restore.
- (TARGET_HAS_HARDWARE_WATCHPOINTS, etc): Define as for Irix 4;
- from Lee Iverson <leei@ai.sri.com>.
- * config/mips/irix5.mh (NAT_FILE): Use nm-irix5.h.
- * config/mips/irix[345].mh (MUNCH_DEFINE): Remove.
+ * inftarg.c: change <sys/unistd.h> to <unistd.h> and
+ conditionalize its inclusion.
+ * infttrace.c: ditto.
-For older changes see ChangeLog-95
+For older changes see ChangeLog-98
Local Variables:
-mode: indented-text
+mode: change-log
left-margin: 8
fill-column: 74
version-control: never
diff --git a/contrib/gdb/gdb/ChangeLog-95 b/contrib/gdb/gdb/ChangeLog-95
index cdf4dda..2265be8 100644
--- a/contrib/gdb/gdb/ChangeLog-95
+++ b/contrib/gdb/gdb/ChangeLog-95
@@ -3,7 +3,6 @@ Fri Dec 29 16:30:58 1995 Stan Shebs <shebs@andros.cygnus.com>
* symfile.c (find_sym_fns): Add PowerMac to xcoff file recognition
kludge.
-
Fri Dec 22 11:05:59 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* configure.in (gdb_host): Add support for DG/UX running on x86 as
@@ -108,7 +107,6 @@ Mon Dec 11 18:19:16 1995 Stan Shebs <shebs@andros.cygnus.com>
* mac-gdb.r: Fix version resources to use symbolic version strings.
(cfrg): New resource, code fragment for PowerMac.
-
Mon Dec 11 14:13:03 1995 Fred Fish <fnf@amigalib.com>
* dbxread.c (process_one_symbol): When looking at the next
@@ -119,7 +117,7 @@ Mon Dec 11 15:56:55 1995 Per Bothner <bothner@kalessin.cygnus.com>
* eval.c (evaluate_struct_tuple): Fix thinko.
-Mon Dec 11 06:52:02 1995 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+Mon Dec 11 06:52:02 1995 Wilfried Moser <moser@rtl.cygnus.com>
* ch-typeprint.c (chill_type_print_base): Slightly change of printing
of variant structures.
@@ -843,7 +841,8 @@ Fri Oct 27 09:54:07 1995 Stu Grossman (grossman@cygnus.com)
startup. Eliminate sleeps. Clear breakpoints (if using monitor
breakpoints). Re-init frame.
* (mips_detach): Close down target.
- * (mips_wait): Handle return status with registers, or breakpoint stuff.
+ * (mips_wait): Handle return status with registers, or breakpoint
+ * stuff.
* (mips_kill): Add ^C handling.
* (mips_insert_breakpoint mips_remove_breakpoint): Call new
breakpoint stuff if enabled.
@@ -856,7 +855,6 @@ Fri Oct 27 09:54:07 1995 Stu Grossman (grossman@cygnus.com)
user-defined commands to suppress auto-repeat (by hittin return key).
* valops.c: Add start of auto function-call abandonment capability.
-
Thu Oct 26 22:02:27 1995 Stan Shebs <shebs@andros.cygnus.com>
* mpw-config.in: Add support for PowerMac host, add beginnings
@@ -1817,7 +1815,7 @@ Tue Aug 1 11:44:53 1995 J.T. Conklin <jtc@rtl.cygnus.com>
inflow.c, infptrace.c, infrun.c, irix5-nat.c, language.c,
m2-typeprint.c, main.c, mdebugread.c, minsyms.c, mipsread.c,
monitor.c, nlmread.c, objfiles.c, os9kread.c, osfsolib.c, parse.c,
- printcmd.c, procfs.c, regex.c, remote-adapt.c, remote-arc.c,
+ printcmd.c, procfs.c, regex.c, remote-adapt.c,
remote-array.c, remote-bug.c, remote-e7000.c, remote-eb.c,
remote-es.c, remote-hms.c, remote-mm.c, remote-os9k.c,
remote-pa.c, remote-sim.c, remote-st.c, remote-udi.c,
@@ -2237,7 +2235,6 @@ Thu Jul 13 13:42:38 1995 Jeffrey A. Law <law@rtl.cygnus.com>
* m3-nat.c (m3_ops): Likewise.
* monitor.c (monitor_ops): Likewise.
* procfs.c (procfs_ops): Likewise.
- * remote-arc.c (arc_ops): Likewise.
* remote-array.c (array_ops): Likewise.
* remote-e7000.c (e7000_ops): Likewise.
* remote-es.c (es1800_ops, es1800_child_ops): Likewise.
@@ -2551,6 +2548,16 @@ Sat Jun 3 01:54:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
* value.h (struct value): Change `repetitions' field from
`short' to `int' type.
+Fri Jun 2 11:17:23 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc-tdep.c (arc_bfd_mach_type): New static global.
+ (codestream_fill): Handle byte order differences.
+ (setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N".
+ (arc_get_frame_setup): Read it here.
+ (arc_frame_saved_pc): And here.
+ (arc_print_insn): New function.
+ (arc_set_cpu_type): Set arc_bfd_mach_type. Don't set tm_print_insn.
+ (_initialize_arc_tdep): Set tm_print_insn to arc_print_insn.
Wed May 31 12:04:01 1995 J.T. Conklin <jtc@rtl.cygnus.com>
@@ -2884,6 +2891,7 @@ Tue May 2 18:32:24 1995 Stan Shebs <shebs@andros.cygnus.com>
* remote-nrom.c: New file, NetROM target support.
* config/a29k/a29k-udi.mt, config/i960/vxworks960.mt: Use
REMOTE_OBS instead of REMOTE_O.
+ * config/arc/arc.mt: Ditto.
Fri Apr 28 23:30:00 1995 Stu Grossman (grossman@cygnus.com)
@@ -3056,6 +3064,41 @@ Wed Apr 12 14:34:31 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
* xcoffread.c: Call complain() rather than error() or printing a
warning.
+Wed Apr 12 08:15:27 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc-tdep.c: #include "gdbcmd.h".
+ (codestream_seek): Pass CORE_ADDR.
+ (arc_cpu_type, tmp_arc_cpu_type, arc_cpu_type_table): New globals.
+ (debug_pipeline_p): Likewise.
+ (X_...): Instruction field access macros.
+ (BUILD_INSN): Define.
+ (codestream_tell): Allow for stream elements > 1 byte.
+ (codestream_fill): Likewise.
+ (setup_prologue_scan): New function.
+ (arc_get_frame_setup): Call it. Update to current spec
+ regarding prologues. Use BUILD_INSN.
+ (skip_prologue): New argument `frameless_p'. Use BUILD_INSN.
+ (arc_frame_saved_pc): New function.
+ (frame_find_saved_regs): Use BUILD_INSN.
+ (get_insn_type, single_step): New functions.
+ (one_stepped): New global.
+ (arc_set_cpu_type_command, arc_show_cpu_type_command): New functions.
+ (arc_set_cpu_type): New function.
+ (_initialize_arc_tdep): Define new `set' commands `cpu',
+ `displaypipeline', and `debugpipeline'.
+ * arc/tm-arc.h (TARGET_BYTE_ORDER): Delete.
+ (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ (DEFAULT_ARC_CPU_TYPE): Define.
+ (SKIP_PROLOGUE_FRAMELESS_P): Define.
+ (BREAKPOINT): Delete.
+ (BIG_BREAKPOINT, LITTLE_BREAKPOINT): Define.
+ (DECR_PC_AFTER_BREAK): Change to 8.
+ (NO_SINGLE_STEP): Define.
+ (ARC_PC_TO_REAL_ADDRESS): Define.
+ (SAVED_PC_AFTER_CALL): Use it.
+ (NUM_REGS, REGISTER_BYTES): Fix.
+ (FRAME_SAVED_PC): Call arc_frame_saved_pc.
+ (FRAME_LOCALS_ADDRESS): Fix.
Tue Apr 11 16:42:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
@@ -3647,6 +3690,9 @@ Mon Mar 13 15:25:47 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
* alpha-tdep.c (find_proc_desc): If pdr.framereg field is -1, don't
use the PDR, just examine prologues instead.
+Fri Mar 10 16:13:18 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/arc/tm-arc.h: Change arc register names.
Fri Mar 10 02:49:40 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
@@ -3742,9 +3788,9 @@ Tue Mar 7 00:23:47 1995 Stu Grossman (grossman@cygnus.com)
match the IDP monitor. Also, set NUM_REGS to 18 cuz there's no
floating-point for this card.
- * serial.h, ser-go32.c, ser-go32-para.c, ser-mac.c, ser-tcp.c,
- ser-unix.c: Add SERIAL_SETSTOPBITS to set the number of stopbits
- (needed for IDP board?!?!?).
+ * serial.h, ser-go32.c, ser-mac.c, ser-tcp.c, ser-unix.c: Add
+ SERIAL_SETSTOPBITS to set the number of stopbits (needed for IDP
+ board?!?!?).
* defs.h, utils.c, remote-hms.c, remote-pa.c, remote.c: Fix defs
and usage of fputc_unfiltered and putchar_unfiltered. Eliminate
@@ -3901,7 +3947,8 @@ Tue Feb 28 14:38:39 1995 Kung Hsu <kung@mexican.cygnus.com>
* defs.h (SWAP_TARGET_AND_HOST): check endianess at runtime not
compile time.
-
+ * arc-tdep.c (_initialize_arc_tdep): set tm_print_insn according to
+ processor.
* vx-share/ptrace.h: merge in WRS new ptrace requests.
@@ -4147,6 +4194,7 @@ Mon Feb 6 18:50:59 1995 Stan Shebs <shebs@andros.cygnus.com>
* i386-tdep.c (_initialize_i386_tdep): Put void decl on separate
line, so init.c generation works correctly.
+ * arc-tdep.c (_initialize_arc_tdep): Ditto.
Mon Feb 6 14:44:36 1995 Rob Savoye <rob@darkstar.cygnus.com>
@@ -4160,10 +4208,6 @@ Sat Feb 4 13:29:52 1995 Stan Shebs <shebs@andros.cygnus.com>
* config/m68k/est.mt (TDEPFILES): Remove m68k-pinsn.o.
-Fri Feb 3 16:47:31 1995 Kung Hsu <kung@mexican.cygnus.com>
-
- * ser-go32-para.c (dos_read): fix syntax errors.
-
Fri Feb 3 11:19:20 1995 Stu Grossman (grossman@cygnus.com)
* core.c (dis_asm_read_memory), defs.h, top.c: Get rid of
@@ -4190,7 +4234,11 @@ Thu Feb 2 19:02:45 1995 Rob Savoye <rob@darkstar.cygnus.com>
Thu Feb 2 16:11:04 1995 Kung Hsu <kung@mexican.cygnus.com>
- * ser-go32-para.c: new file for go32 parallel port communication.
+ * config/arc/arc.mt: new target makefile for arc processor.
+ * config/arc/tm-arc.h: new target header for arc processor.
+ * config/arc/go32.mh: new go32 host makefile for arc processor.
+ * config/arc/xm-go32.h: new go32 host header for arc processor.
+ * arc-tdep.c: new target dependent codes for arc processor.
Thu Feb 2 13:58:40 1995 Stan Shebs <shebs@andros.cygnus.com>
@@ -4473,21 +4521,6 @@ Wed Jan 25 01:11:21 1995 Jeff Law (law@snake.cs.utah.edu)
* hpread.c (hpread_process_one_debug_symbol): Fix lines garbled
by an ill-advised global search and replace.
-Tue Jan 24 12:10:28 1995 Stu Grossman (grossman@cygnus.com)
-
- * gdbtk.tcl (create_registers_window): Work around a radiobutton
- widget bug to make Options|Natural button work.
-
- * gdbtk.c (gdb_disassemble): Fix problem with source+assembly and
- g++ caused by out-of-order pc's.
- * gdbtk.tcl (files_command): Remove duplicate file names. Also,
- add scrollbar.
-
-Mon Jan 23 17:21:09 1995 Stu Grossman (grossman@cygnus.com)
-
- * gdbtk.tcl: Take .gdbtkinit if it exists. Makes gdbtk match the
- doc!
-
Mon Jan 23 13:11:46 1995 Per Bothner <bothner@kalessin.cygnus.com>
Add support for Chill bitstring literals (e.h. H'FF00').
diff --git a/contrib/gdb/gdb/ChangeLog-96 b/contrib/gdb/gdb/ChangeLog-96
new file mode 100644
index 0000000..760b425
--- /dev/null
+++ b/contrib/gdb/gdb/ChangeLog-96
@@ -0,0 +1,5116 @@
+Tue Dec 31 15:19:32 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: more small register fixes
+
+Tue Dec 31 06:51:43 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/i386/xm-windows.h: Undo previous change to SIGTRAP
+ and SIGQUIT values; it messed up non-MIPS targets.
+ * config/mips/tm-mips.h: Undefine BREAKPOINT, replace
+ with separate LITTLE_BREAKPOINT and BIG_BREAKPOINT definitions;
+ this fixes problem with setting breakpoints in little-endian
+ programs in the simulator.
+
+Mon Dec 30 00:14:06 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * remote-sim.c (gdbsim_open_p): New static local.
+ (gdbsim_open): Call unpush_target if sim open. Set gdbsim_open_p.
+ (gdbsim_close): Only call sim_close if sim open. Reset gdbsim_open_p.
+
+Sun Dec 29 09:15:03 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/i386/xm-windows.h: Make SIGTRAP and SIGQUIT consistent
+ with sim/mips/support.h.
+
+Fri Dec 27 14:53:40 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850-tdep.c (struct pifsr): Add cur_frameoffset field.
+ (v850_scan_prologue): Add debug code #ifdef'ed DEBUG. Support new
+ compiler prologues using register save functions and short store
+ instructions. Add support for functions with large stack frames.
+
+ * config/v850/tm-vm850.h ({R0,R1,R12,EP}_REGNUMS): New register
+ number defintiions for r0, r1, r12, ep.
+ (SAVE{1,2,3}_{START,END}_REGNUM): Register number definitions for
+ the 3 sets of saved registers.
+
+Thu Dec 26 19:56:55 1996 Mark Alexander <marka@cygnus.com>
+
+ * valprint.c (print_longest): Don't lose upper bits
+ of 64-bit values on Windows.
+ * config/i386/xm-windows.h: Leave CC_HAS_LONG_LONG defined,
+ undefine PRINTF_HAS_LONG_LONG, so that 64-bit values will
+ be printed without loss of upper bits.
+
+Thu Dec 26 15:15:21 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/sparc/tm-sparclet.h: make registers ASR15, ASR19 invisible
+ (they're not useful, you can't change, write or even read them)
+
+Thu Dec 26 15:20:48 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/pa/hppahpux.mh (TERMCAP): Always link to libc before
+ libcurses, to avoid picking up broken select() from libcurses
+ on some versions of HPUX.
+
+Thu Dec 26 15:14:41 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sparclet-rom.c: Remove includes of Unix system files.
+ Add function "sparclet_supply_register" so that parse_register_dump
+ will not seg-fault by calling a null function pointer.
+ Remove XMODEM support (unfinished work?).
+ Remove flag "MO_HANDLE_NL", so monitor's output can be read by humans.
+ Add fill command.
+ Remove colon from getreg.resp_delim so PSR register will work.
+ Remove pointer to sparclet_load (downloading SREC's doesn't work).
+ Null out local register names for %g0, all %cc and all %asr regs,
+ since the monitor can't report them. Will return zero instead.
+ * sparclet-stub.c: New -- remote protocol support for sparclet CPU.
+ * config/sparc/tm-sparclet.h: Re-arrange REGISTER_NAMES:
+ Add back %g0 and %psr, add %cc coprocessor regs, add %asr regs.
+ Adjust NUM_REGS and REGISTER_BYTES accordingly
+
+Tue Dec 24 10:27:37 1996 Jeffrey A Law (law@cygnus.com)
+
+ * remote-e7000.c (want_h8300h, want_nopc_h8300h): Renamed
+ from want and want_nopc.
+ (want_h8300s, want_nopc_h8300s): New variables for H8/S register
+ lists.
+ (e7000_fetch_registers): Use H8/300H or H8/S register list string
+ as needed.
+ (e7000_wait): Likewise.
+
+Mon Dec 23 02:25:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (mips_find_saved_regs): If a frame has been
+ interrupted by a signal, figure out whether the registers that
+ the proc_desc claims are saved have been saved yet.
+ (mips_push_dummy_frame): Write dummy frame register after all
+ registers have been saved in the dummy frame. Update comments
+ to reflect the fact that we are now using an AT_ENTRY_POINT
+ call dummy.
+
+Sun Dec 22 15:52:25 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c (d10v_skip_prologue): PR11287. Fix problem where
+ some breakpoints weren't being set.
+
+Sat Dec 21 12:57:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-mips.h (PC_IN_CALL_DUMMY): Removed, the default
+ definition in inferior.h is sufficient.
+ * mips-tdep.c (mips_pc_in_call_dummy): Ditto.
+ (mips_push_arguments): Make sure that the stack is aligned to a
+ multiple of 8 after the arguments are pushed.
+ Structures are always passed by value in the old ABI.
+ Adjust argument register value on big endian targets when passing
+ a value whose length is less than the register size.
+ Write stack arguments with a single write_memory call.
+ (mips_pop_frame): Use frame_saved_regs instead of proc_desc to
+ decide which registers have to be restored.
+
+ * irix5-nat.c (fill_gregset): Sign extend registers before
+ filling in the gregset structure.
+
+Fri Dec 20 11:06:03 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/genmakes: Don't define _DEBUG. This breaks wingdb.
+
+Thu Dec 19 19:42:44 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850-tdep.c (v850_scan_prologue): Deal with -mep shorting
+ register saves by using the ep register.
+
+Thu Dec 19 15:57:16 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-tdep.c (m32r_frame_find_saved_regs): Fix thinko in arg def.
+
+Thu Dec 19 09:38:56 1996 Mark Alexander <marka@cygnus.com>
+
+ * values.c (unpack_double): Make it compile with MSVC++ 2.x.
+ * remote-mips.c (S_IROTH): Define if not defined by stat.h, e.g.
+ when using MSVC++.
+ (common_open): Fix help string.
+
+Wed Dec 18 23:01:32 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Use NewFolderRecursive for installation.
+
+Sat Dec 14 20:50:01 1996 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Handle floating point args.
+ * config/mips/tm-mips.h (FIX_CALL_DUMMY): Define to set up $25
+ correctly for PIC on Irix 5.
+
+Sat Dec 14 09:52:30 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * i386-tdep.c (i386_frame_find_saved_regs): Handle zero return
+ from get_pc_function_start gracefully.
+
+Sat Dec 14 00:43:57 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-exp.y (qualified_name): Replace explicit check for valid
+ destructor name with call to destructor_name_p.
+
+ * c-lang.h, c-typeprint.c (cp_type_print_method_args): Removed,
+ no longer needed.
+
+ * c-typeprint.c (c_type_print_varspec_prefix, c_type_print_base):
+ Replace remaining fprintf_unfiltered calls with their filtered variant.
+ (c_type_print_base): Do not print return type for destructors from
+ template classes.
+ Replace cp_type_print_method_args with cplus_demangle call to get
+ consistent type output for stubbed and unstubbed methods.
+
+ * cp-valprint.c (cp_print_class_method): Replace
+ cp_type_print_method_args with cplus_demangle call to get consistent
+ type output for stubbed and unstubbed methods.
+
+ * gdbtypes.c, gdbtypes.h (get_destructor_fn_field): New function
+ to find the destructor field indices for a type.
+
+ * gdbtypes.h (struct type): Clarify comments for vptr_basetype
+ and arg_types fields.
+ (struct fn_field): Remove args field, no longer used.
+
+ * symtab.c (decode_line_1), valops.c (value_struct_elt,
+ check_field_in): Use get_destructor_fn_field to find the destructor
+ field indices instead of assuming that the compiler passes the member
+ function fields in a specific order.
+
+ * symtab.c (find_methods): Pass NULL instead of SYMBOL_BLOCK_VALUE
+ to lookup_symbol.
+ (list_symbol): Replace cp_type_print_method_args with cplus_demangle
+ call in zapped out code and explain why this code is zapped out.
+
+Thu Dec 12 13:29:14 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/ppc{,le}-sim.mt (SIM): Add the simulator common
+ library ../sim/common/libcommon.a.
+
+Wed Dec 11 11:15:08 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * monitor.c (monitor_load): Add support for load address argument.
+ * dsrec.c: #include <time.h>.
+ (load_srec): New argument load_offset. Print download stats.
+ * srec.h (load_srec): Update prototype.
+ * sh3-rom.c (sh3_load): Update call to load_srec.
+
+Mon Dec 9 17:34:05 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: more small register fixes
+ * mn10300-tdep.c: filled in from another target
+
+Mon Dec 9 17:12:19 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * monitor.c (monitor_insert_breakpoint): Handle bi-endian machines.
+
+Mon Dec 9 15:58:51 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/tm-mips.h: Get rid of call-dummy code.
+ Minor changes to make pre-ANSI compilers happy.
+ * mips-tdep.c: Minor changes to make pre-ANSI compilers happy.
+ (mips_push_arguments): Rewrite to partially support EABI.
+ (mips_pc_in_call_dummy): New function.
+ * infcmd.c: Include symfile.h to get prototype of entry_point_address,
+ which fixes 64-bit sign extension bug on MIPS.
+
+Mon Dec 9 00:14:49 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: fix register names
+ * mn10300-tdep.c: new skeleton tdep for mn10300
+
+Sun Dec 8 18:02:57 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.h: Update some comments.
+ * remote-sim.c (gdb_os_error): New function.
+ (init_callbacks): Fix initializing of gdb_callback. Add gdb_os_error.
+ (gdb_os_printf_filtered): Use gdb_stdout, not stdout.
+
+Sun Dec 8 00:36:31 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix5-nat.c (supply_gregset, fill_gregset): Handle gregsets
+ from O32 and N32 ABI.
+ (xfer_link_map_member): Work around problem with alignments
+ in struct obj when compiling GDB under N32 ABI.
+
+Thu Dec 5 23:30:44 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * d10v-tdep.c: Add support for examination and interpretation
+ of instruction trace buffer.
+ (trace, untrace, info trace, tdisassemble): New commands.
+
+Thu Dec 5 14:06:23 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/sparc/tm-sparclet.h (TARGET_BYTE_ORDER): Undef.
+ (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ (BREAKPOINT): Undef.
+ ({BIG,LITTLE}_BREAKPOINT): Define.
+ (TM_PRINT_INSN_MACH): Redefine for sparclet.
+
+Wed Dec 4 16:34:05 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/mn10300.mt, config/mn10300/tm-mn10300.h: New.
+
+Tue Dec 3 13:02:08 1996 Fred Fish <fnf@ninemoons.com>
+
+ * infptrace.c (store_inferior_registers): Move some common code out
+ to store_register, like fetch_inferior_registers & fetch_register.
+ (store_register): New function, from store_inferior_registers.
+ (fetch_inferior_registers, fetch_register): Minor code tweaks to
+ make {fetch,store}_inferior_registers and {fetch,store}_register
+ routines as similar in structure as possible.
+ (fetch_inferior_registers, store_inferior_registers): Eliminate
+ local variable numregs and just use ARCH_NUM_REGS directly.
+
+Tue Dec 3 11:38:14 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: add macro USE_GENERIC_DUMMY_FRAMES to enable/disable
+ code for generic call_dummy frames.
+ * config/h8300/tm-h8300.h: turn on USE_GENERIC_DUMMY_FRAMES
+ * config/m32r/tm-m32r.h: Ditto.
+ * config/sh/tm-sh.h: Ditto.
+ * config/v850/tm-v850.h: Ditto.
+
+Sun Dec 1 00:41:47 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * vax-tdep.c (vax_print_insn, print_insn_arg): Use info functions
+ for printing. From Valeriy Ushakov <uwe@ptc.spbu.ru>.
+
+Sun Dec 1 00:40:46 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.tgt: Add new mn10300 entry.
+
+Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Add support for Irix 6.2 native O32 and N32 ABI.
+
+ * config.in, configure.in, configure: Check for <objlist.h>.
+ * configure.tgt: Handle mips*-sgi-irix6* like irix5 for now.
+
+ * cp-valprint.c (cp_print_value_fields): Use SYMBOL_VALUE_ADDRESS
+ instead of SYMBOL_BLOCK_VALUE to get the address of a static member.
+
+ * dwarf2read.c: Turn warnings and recoverable errors into complaints,
+ add new complaints where appropriate.
+ gcc -Wall cleanup.
+ (struct line_head): Change line_base from char to int to avoid
+ problems with compilers whose plain char is represented by an
+ unsigned char.
+ (struct partial_die_info): Add is_declaration field.
+ (dwarf2_tmp_obstack): New obstack for allocating temporary storage
+ used during symbol reading.
+ (cu_header_offset): New variable for resolving relative reference
+ dies.
+ (optimized_out, basereg, islocal, frame_base_reg, frame_base_offset):
+ New interface variables for decode_locdesc.
+ (struct dwarf2_pinfo): New structure for communication between
+ psymtab and symtab reading, passed via pst->read_symtab_private.
+ (dwarf2_has_info, dwarf2_build_psymtabs): Accept objects files
+ without line number sections.
+ (dwarf2_build_psymtabs_hard): Initialize temporary obstack
+ for symbol reading.
+ Allocate and initialize pst->read_symtab_private.
+ Relocate pst->textlow and pst->texthigh with baseaddr.
+ (scan_partial_symbols): Do not add DW_AT_declaration symbols
+ to the partial symbol table.
+ Add file scope enumerator symbols to the partial symbol table.
+ Fix typo in highpc computation.
+ If we didn't find a lowpc, set it to highpc to avoid complaints
+ from `maint check.
+ (add_partial_symbol): Relocate symbol values with baseaddr.
+ Add static DW_TAG_subprogram and DW_TAG_variable symbols to the
+ minimal symbol table.
+ Obtain symbol values for DW_TAG_variable symbols from the location
+ descriptor, skip symbols with missing location desciptors.
+ Skip symbols for aggregate types without children.
+ Handle enumerator symbols.
+ (dwarf2_psymtab_to_symtab): Issue symbol reading message if verbose.
+ (psymtab_to_symtab_1): Set local variables from
+ pst->read_symtab_private, set cu_header_offset and baseaddr.
+ Initialize temporary obstack for symbol reading, initialize
+ buildsym and add a cleanup to really_free_pendings.
+ Relocate highpc with baseaddr when calling end_symtab.
+ If the compilation is from a C file generated by language
+ preprocessors, do not set the symtab language if it was already
+ deduced by start_subfile.
+ Removed verbose sorting symbol table message.
+ (process_die): Handle DW_TAG_ptr_to_member_type and
+ DW_TAG_reference_type.
+ Use read_subroutine_type to get the function type for
+ DW_TAG_subprogram before calling read_func_scope.
+ (read_file_scope): Initialize file name to <unknown>, start_subfile
+ expects a non-NULL name.
+ If we didn't find a lowpc, set it to highpc to avoid complaints
+ from finish_symbol.
+ Relocate lowpc and highpc with baseaddr.
+ Get rid of Irix6.2 native cc compile machine prefix in comp_dir.
+ Zero out ftypes for each new compilation unit (may be different
+ language or different objfile).
+ Accept compilation units without line number information, pass
+ comp_dir to decode_lines.
+ (read_func_scope): Initialize function name to <unknown> to avoid
+ core dumps when DW_AT_name is missing.
+ Relocate lowpc and highpc with baseaddr.
+ Handle DW_AT_frame_base, keep result for DW_OP_fbreg operations.
+ Pass function type to new_symbol.
+ (read_lexical_block_scope): Relocate lowpc and highpc with baseaddr.
+ (read_structure_scope): Set TYPE_TAG_NAME, not TYPE_NAME.
+ Handle DW_TAG_class_type.
+ Copy fields to type_obstack, release temporary storage for fields.
+ Don't add symbol if die is a stub die and has no children.
+ Handle C++ static member fields.
+ (read_enumeration): Set TYPE_TAG_NAME, not TYPE_NAME.
+ Copy fields to type_obstack, release temporary storage for fields.
+ Let new_symbol handle the symbol creation for enumerators
+ instead of handcrafting a symbol.
+ Determine signedness of enum type from enumerators.
+ (dwarf_read_array_type): Handle variable length arrays.
+ Use lookup_pointer_type instead of handcrafting a type.
+ Create array type only if a DW_TAG_subrange_type was found.
+ (read_tag_pointer_type, read_tag_reference_type):
+ Use lookup_pointer_type and lookup_reference_type instead
+ of handcrafting a type.
+ (read_tag_ptr_to_member_type): New function to handle
+ DW_TAG_ptr_to_member_type.
+ (read_subroutine_type): Handle parameter dies.
+ Use lookup_function_type instead of handcrafting a type.
+ (read_typedef): Allocate a TYPE_CODE_TYPEDEF type for the typedef.
+ (read_base_type): If the type has a name, use init_type to create
+ a new type instead of second guessing a fundamental type.
+ (read_comp_unit): Reset die reference table before building
+ a new one.
+ (dwarf2_read_section): Read section contents into psymbol_obstack.
+ (dwarf2_read_abbrevs): Handle unterminated abbreviations
+ for a compile unit gracefully.
+ (read_partial_die): Zero partial die before reading its info.
+ Handle DW_AT_declaration.
+ Fix typo in handling of DW_FORM_block4.
+ (read_full_die): Fix typo in handling of DW_FORM_block4.
+ (read_1_signed_byte, read_2_signed_bytes, read_4_signed_bytes):
+ New routines to get signed values from a buffer.
+ (read_n_bytes, read_string): Allocate storage from the temporary
+ obstack. If the host char size permits it, return pointer
+ to buffer instead of allocating storage.
+ (set_cu_language): Handle DW_LANG_Mips_Assembler.
+ (dwarf_attr): Return NULL if reference die for DW_AT_specification
+ or DW_AT_abstract_origin die is not found.
+ (record_minimal_symbol): Removed, replaced with a direct call to
+ prim_record_minimal_symbol, it now handles saving the string itself.
+ (convert_locdesc): Removed, partial symtab reading now uses
+ decode_locdesc.
+ (dwarf_attr): Use dwarf2_get_ref_die_offset to get the absolute
+ offset for the die reference.
+ (dwarf_decode_lines): Complain if the line section info is missing.
+ Use read_1_signed_byte to extract lh.line_base to avoid
+ problems with compilers whose plain char is represented by an
+ unsigned char.
+ Add cleanups for allocated temporary storage.
+ Start a subfile for the first file in the state machine.
+ Fix off by one problem with dirs.dirs access.
+ Use comp_dir when directory index is 0.
+ Support multiple sequences (from Jason Merrill <jason@cygnus.com>).
+ (dwarf2_start_subfile): Try to keep line numbers from identical
+ absolute and relative file names in a common subfile.
+ (new_symbol): Allocate symbol and symbol name on the symbol_obstack.
+ Set SYMBOL_LINE from DW_AT_decl_line if present.
+ Set SYMBOL_TYPE from passed type if not NULL.
+ Change DW_TAG_variable symbol types with missing type entries
+ to a sensible type.
+ Handle optimized_out, offreg and islocal storage classes.
+ Add external symbols with type information whose address isn't
+ known as LOC_UNRESOLVED symbols.
+ Synthesize typedefs for C++ classes, structs, unions and enumerations.
+ Handle DW_TAG_enumerator symbols, complain for unrecognized
+ symbol tags.
+ (die_type): A missing DW_AT_type represents a void type.
+ Use dwarf2_get_ref_die_offset to get the absolute offset for
+ the die reference.
+ (die_containing_type): New function to build type from
+ DW_AT_containing_type attribut.
+ (read_type_die): Handle DW_TAG_ptr_to_member_type.
+ Treat DW_TAG_subprogram like DW_TAG_subroutine_type.
+ (dwarf_base_type): Fix typo with creation of FT_UNSIGNED_SHORT
+ fundamental type.
+ (create_name): Removed, symbol name allocation is now done
+ in new_symbol.
+ (dump_die): Use print_address_numeric to print a CORE_ADDR.
+ (dwarf2_empty_die_ref_table): New function to clear the die
+ reference table.
+ (dwarf2_get_ref_die_offset): New function to get the absolute
+ die offset from a die reference attribute.
+ (decode_locdesc): Complete rewrite using a stack, code mostly
+ borrowed from dwarfread.c:locval.
+ (dwarf_alloc_type): Removed, replaced by direct calls to alloc_type.
+ (dwarf_alloc_block): Allocate block on temporary obstack.
+
+ * elfread.c (elf_symtab_read): When handling Irix dynamic symbols,
+ skip section name symbols and relocate all others.
+ (elf_symfile_read): Build dwarf2 psymtab even if offset is non-zero.
+
+ * irix5-nat.c (fetch_core_registers): Handle core_reg_sect
+ from N32 executables. Call registers_fetched after extracting
+ the registers.
+ (obj_list_variant, struct link_map, LM_OFFSET, LM_ADDR): New
+ definitions to enable support of O32 and N32 format objlists.
+ (struct so_list): New members offset, so_name and lmstart to
+ eliminate dependencies from the objlist format used.
+ (solib_map_sections, symbol_add_stub, solib_add,
+ info_sharedlibrary_command, solib_address, clear_solib): Use
+ so_name and LM_OFFSET.
+ (first_link_map_member): Rewrite to enable support of O32 and N32
+ format objlists.
+ (next_link_map_member, xfer_link_map_member): New functions to
+ support O32 and N32 format objlists.
+ (find_solib): Use first_link_map_member, next_link_map_member and
+ xfer_link_map_member.
+ (solib_create_inferior_hook): Use TARGET_SIGNAL_* instead of
+ host signal numbers.
+
+ * mdebugread.c (parse_partial_symbols, handle_psymbol_enumerators):
+ Pass CORE_ADDR variant to add_psymbol_to_list.
+
+ * mips-tdep.c (heuristic_proc_desc): Stop examining the prologue
+ if we encounter a positive stack adjustment. Handle `move $30,$sp'.
+ Handle `sd reg,offset($sp)' for 32 bit ABIs.
+
+ * symmisc.c (dump_msymbols, print_partial_symbols): Use
+ print_address_numeric to print a SYMBOL_VALUE_ADDRESS.
+ (dump_symtab): Print compilation directory if it is not NULL.
+
+ * valops.c (search_struct_field, value_struct_elt_for_reference):
+ Use SYMBOL_VALUE_ADDRESS instead of SYMBOL_BLOCK_VALUE to get the
+ address of a static member.
+
+Thu Nov 28 00:46:24 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * vax-tdep.c (vax_print_insn): Made static, modified to take
+ disassemble_info as parameter.
+ (_initialize_vax_tdep): New function to initialize tm_print_insn
+ to vax_print_insn.
+
+Wed Nov 27 11:29:06 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: Remove old-style CALL_DUMMY code.
+ * h8300-tdep.c, config/h8300/tm-h8300.h: Ditto.
+ * m32r-tdep.c, config/m32r/tm-m32r.h: Ditto.
+ * sh-tdep.c, config/sh/tm-sh.h: Ditto.
+ * v850-tdep.c, config/v850/tm-v850.h: Ditto.
+
+Wed Nov 27 10:32:14 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.c: DELETE command will not delete CALL_DUMMY breakpoint.
+ * blockframe.c: Add target-independant support for managing
+ CALL_DUMMY frames on the host side.
+ * frame.h: Declarations for generic CALL_DUMMY frame support.
+ * h8300-tdep.c: Add target function calls using generic frame support.
+ * config/h8300/tm-h8300.h: config for generic target function calls.
+ * m32r-tdep.c: Add target function calls using generic frame support.
+ * config/m32r/tm-m32r.h: config for generic target function calls.
+ * sh-tdep.c: Add target function calls using generic frame support.
+ * config/sh/tm-sh.h: config for generic target function calls.
+ * v850-tdep.c: Add target function calls using generic frame support.
+ * config/v850/tm-v850.h: config for generic target function calls.
+ * valops.c: ADD PUSH_RETURN_ADDRESS so that it doesn't have to be
+ done by PUSH_ARGUMENTS when there's no CALL_DUMMY.
+
+Tue Nov 26 19:21:35 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/tm-mips.h (ADDR_BITS_REMOVE, TARGET_READ_SP): Define.
+ (mips_addr_bits_remove): Declare.
+ * mips-tdep.c (mips_push_dummy_frame): Fix heuristic-fence-post
+ errors when hitting breakpoints during inferior function calls
+ in 64-bit programs.
+ (fix_sign_extension): Make public, rename to mips_addr_bits_remove.
+ * utils.c (paddr_nz, preg_nz): New functions, similar to
+ paddr and preg but don't print leading zeroes.
+ * defs.h (paddr_nz, preg_nz): Declare.
+ * remote-mips.c: Use paddr_nz instead of paddr throughout
+ to reduce packet size.
+ (pmon_end_download): Improve timeout error handling.
+
+Tue Nov 26 17:21:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.
+
+Mon Nov 25 13:17:16 1996 Fred Fish <fnf@ninemoons.com>
+
+ From: Paul Eggert <eggert@twinsun.com>
+ * remote-bug.c (wait_strings): Avoid creating a trigraph.
+
+Fri Nov 22 15:55:22 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * valops.c (value_at, value_fetch_lazy): Put in D10V call
+ to fix up address pointers.
+ * values.c (value_from_longest): Removed previous d10v changes.
+ * config/d10v/tm-d10v.h (TARGET_PTR_BIT): Change to 4 bytes.
+
+Fri Nov 22 10:06:19 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/i386/nm-i386v4.h (LOSING_POLL): Define, needed for
+ Unixware 1.1.2.
+
+Thu Nov 21 19:13:58 1996 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c: Replace hard-coded constants with MIPS_INSTLEN.
+ (common_breakpoint): Use paddr instead of %x to print 64-bit values.
+ (heuristic_proc_desc): Add tests for 64-bit instructions.
+ (init_extra_frame_info, mips_push_arguments): Recognize additional
+ registers for EABI.
+ * remote-mips.c: Extend DDB target to allow TFTP downloads.
+ * config/mips/tm-mips.h (MIPS_LAST_ARG_REGNUM, MIPS_NUM_ARG_REGS):
+ Define.
+
+Wed Nov 20 19:09:16 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * infcmd.c (do_registers_info): Call val_print with the
+ virtual buf instead of the raw buf. Needed for REGISTER_CONVERT
+ to work with non-floating point regs.
+
+ * d10v-tdep.c (d10v_skip_prologue): If we have line debugging
+ information, then the end of the prologue should the first
+ assembly instruction of the first source line.
+
+ * values.c (value_from_longest): Put in D10V call to
+ fix up address pointers.
+
+ * config/d10v/tm-d10v.h (REGISTER_VIRTUAL_SIZE): Modified.
+ (REGISTER_VIRTUAL_TYPE): Modified for PC_REGNUM and SP_REGNUM.
+ (REGISTER_CONVERTIBLE): Make PC and SP convertible.
+ (REGISTER_CONVERT_TO_VIRTUAL): Define.
+ (REGISTER_CONVERT_TO_RAW): Define.
+ (D10V_MAKE_DADDR): Define.
+ (D10V_MAKE_IADDR): Define.
+
+Wed Nov 20 16:15:15 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/cygwin32.mh: add MMALLOC_CFLAGS = -I$(MMALLOC_SRC)
+ -DMMCHECK_FORCE=1 so memory checks are loaded for cygwin32 gdb
+
+Wed Nov 20 00:43:09 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * callback.h: Delete, moved to ../include.
+ * callback.c: Delete, moved to ../sim/common.
+ * Makefile.in (SFILES,COMMON_OBJS): Delete callback.[co].
+ (callback.o): Delete rule.
+ * remote-sim.h: No longer include callback.h.
+ (sim_callback_write_stdout): Delete prototype.
+ * remote-sim.c (init_callbacks,end_callbacks): New functions.
+ (gdb_os_write_stdout, gdb_os_printf_filtered): New functions.
+ (gdb_callback, callbacks_initialized): New static globals.
+ (gdbsim_open): Call init_callbacks.
+ (gdbsim_close): Call end_callbacks.
+ (simulator_command): Call init_callbacks.
+
+ * config/h8300/h8300.mt (SIM): Change to ../sim/h8300/libsim.a.
+ * config/h8500/h8500.mt (SIM): Change to ../sim/h8500/libsim.a.
+
+Mon Nov 18 15:58:05 1996 Jim Wilson <wilson@cygnus.com>
+
+ * config/mips/tm-mips.h (FIX_CALL_DUMMY): Change unsigned LONGEST
+ to ULONGEST.
+
+Fri Nov 15 15:34:18 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * procfs.c (wait_fd): Handle EINTR error return from poll
+ by restarting the poll.
+ * defs.h (PIDGET): Define a default version that just
+ returns its argument unchanged.
+ * inflow.c (terminal_init_inferior): Eliminate #ifdef
+ of PIDGET and fold both alternatives into common code.
+ (pass_signal): Use PIDGET for pid passed to kill().
+
+Thu Nov 14 15:54:20 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * utils.c (paddr,preg): Use a static variable initialized to 32
+ instead of doing addr>>32 to eliminate a warning produced by GCC
+ on 32-bit systems.
+
+ * config/d10v/tm-d10v.h (ULONGEST): Define.
+
+Tue Nov 12 12:25:27 1996 Jim Wilson <wilson@cygnus.com>
+
+ * c-typeprint.c (cp_type_print_method_args): Pass -1 for show in
+ recursive call to type_print.
+
+Tue Nov 12 12:18:29 1996 Jim Wilson <wilson@cygnus.com>
+
+ * defs.h (ULONGEST): New macro.
+ * alpha-tdep.c, breakpoint.c, c-exp.y, ch-exp.c, convex-xdep.c,
+ corefile.c, defs.h, f-exp.y, findvar.c, gdbcore.h, m2-exp.y,
+ m88k-tdep.c, printcmd.c, remote-hms.c, remote-mips.c, sparc-tdep.c,
+ valarith.c, valops.c, values.c, config/gould/tm-np1.h,
+ config/mips/tm-mips.h, mswin/prebuilt/gdb/cexptab.c,
+ mswin/prebuilt/gdb/fexptab.c, mswin/prebuilt/gdb/m2exptab.c:
+ Change all occurances of unsigned LONGEST to ULONGEST.
+
+ * configure.host (mips-sgi-irix6): Add.
+
+Tue Nov 12 12:16:40 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sh-tdep.c: Add functionality for target function calls.
+ * config/sh/tm-sh.h: Add support for target function calls.
+
+Tue Nov 12 12:06:58 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c: Add functionality for target function calls.
+ * valops.c: Small change to support target function calls.
+ * config/m32r/tm-m32r.h: Add support for target function calls.
+
+Mon Nov 11 17:15:59 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * defs.h: Modify Nov 11 12:59:00 change so _MSC_VER is checked
+ instead of _WIN32.
+ * win32-nat.c: Fix Nov 11 12:59:00 change (windows.h should
+ be included instead of windefs.h for compilers other than
+ VC++).
+ * mswin/windefs.h: Remove ^Ms and change C++ style comments
+ to C style comments.
+
+Mon Nov 11 14:32:38 1996 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (get_cell): Fix off-by-one bug.
+ * mips-tdep.c (get_frame_pointer, fix_sign_extension):
+ New functions to consolidate common code.
+ (mips_frame_chain, init_extra_frame_info): Use new functions
+ to fix problems with backtrace and finish commands on ddb board.
+
+Mon Nov 11 12:59:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * mips-tdep.c, remote-mips.c, values.c, mdebugread.c,
+ config/mips/tm-mips.h: Add/fix bugs for 64-bit mips support.
+ * defs.h: Cleanup; add prototypes.
+ * corefile.c: Change FIXME #ifdef
+ * win32-nat.c: Include windefs instead of windows.h.
+ * utils.c: Add routines for printing addresses and registers
+ based on type size.
+
+Sat Nov 9 01:05:10 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-tdep.c (heuristic_proc_desc): Stop examining the prologue
+ if we encounter a positive stack adjustment.
+ (find_proc_desc): If heuristic_fence_post is non-zero, use
+ heuristic_proc_start to determine the start of a function before
+ calling heuristic_proc_desc.
+
+ * coffread.c (coff_symtab_read): Change minimal symbol types
+ for C_LABEL symbols from mst_* to mst_file_*.
+
+ * config/m68k/sun3os4.mh (MMALLOC_CFLAGS): Define MMCHECK_FORCE to 1.
+
+ * configure.in: Handle error message from sun3 native ld when
+ configuring HLDFLAGS.
+ * configure: Regenerated with autoconf.
+
+ * c-valprint.c (c_value_print): Adjust value address by VALUE_OFFSET.
+ * cp-valprint.c (cp_print_value): Prevent gdb crashes by making sure
+ that the virtual base pointer from an user object still points to
+ accessible memory.
+
+ * dbxread.c (dbx_symfile_init): Initialize sym_stab_info to
+ clear the recently added header_files fields.
+ (dbx_symfile_finish): Free hfiles[i].vector to avoid storage leak.
+
+Fri Nov 8 14:30:23 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/tm-sh.h: Added a missing comma in middle of
+ REGISTER_NAMES list.
+
+Fri Nov 8 12:29:51 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c: Fix some formatting and comments.
+
+ * remote-sim.c (simulator_command): Set up callbacks before
+ entering the simulator.
+
+Thu Nov 7 15:19:08 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c: Fix some problems with inferior function calls.
+ * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Change dummy to be
+ a pointer to the dummy's stack instead of just a flag.
+
+Tue Nov 5 10:21:02 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c: Improved frame_chain and fn prologue analysis.
+ * config/tm-m32r.h: Add framesize and register to extra_frame_info.
+
+Tue Nov 5 10:08:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/gdbwin.h: Remove bogus definition of CORE_ADDR.
+ * mswin/srcwin.cpp (CSrcScroll1::CSrcScroll1): Initialize depth
+ to fix divide-by-zero problem with clicking on source window.
+
+Mon Nov 4 00:48:37 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/recordit: Fix problem with absolute paths.
+ * mswin/recordit: Fix problem with relative paths.
+
+Sun Nov 3 18:06:42 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/{Makefile.in configure configure.in}: New files for
+ configuring wingdb under Unix.
+
+Sat Nov 2 03:54:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix5-nat.c, osfsolib.c, solib.c (symbol_add_stub): Handle
+ missing or zero-sized .text sections properly.
+ * mdebugread.c: Handle scRConst and scSUndefined storage classes.
+ * stabsread.c (scan_file_globals): Try to resolve symbols
+ for shared libraries from the minimal symbol table of the main
+ executable first.
+
+Fri Nov 1 13:59:28 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Major fixes to support
+ inferior function calls and proper stack backtracing on D10V-EVA
+ board.
+
+Fri Nov 1 10:50:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/linux.mh (NATDEPFILES): Fix up things so that it
+ links.
+ (GDBSERVER_DEPFILES,TERMCAP): Ditto.
+
+ * monitor.c (dev_name,targ_ops): Move static variables before
+ first use, to avoid compiler warnings.
+
+Thu Oct 31 16:37:17 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c: Improved frame_chain and fn prologue analysis.
+ * configure.tgt: Add entry for m32r target.
+ * monitor.h: Add a flag to tell monitor_store_register to use
+ (val, regno) instead of (regno, val).
+ * monitor.c: Make monitor_store_register honor the above flag.
+ Make monitor_exp ignore DC1/DC3 for m32r.
+ Increase buf size in monitor_dump_regs.
+
+Wed Oct 30 18:14:14 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c, m32r-rom.c: New files.
+ * config/m32r/m32r.mt: New file.
+ * config/m32r/tm-m32r.h: New file.
+
+Tue Oct 29 16:56:01 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/xm-cygwin32.h:
+ * config/powerpc/xm-cygwin32.h:
+ add #define LSEEK_NOT_LINEAR so source lines aren't unexpectedly
+ truncated.
+
+Tue Oct 29 18:36:43 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h (TARGET_BYTE_ORDER_SELECTABLE):
+ Define.
+
+Tue Oct 29 14:59:20 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * TODO: Add item suggesting an "info bfd" command.
+
+Tue Oct 29 12:48:04 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c: Snapshot that supports D10V-EVA board.
+
+ * config/d10v/tm-d10v.h (REGISTER_NAMES): Add imap0,imap1,dmap.
+ (TARGET_READ_FP,TARGET_WRITE_FP): Define.
+
+Mon Oct 28 17:34:24 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/genmakes mswin/recordit: New scripts to generate make
+ files for MSVC.
+
+Sun Oct 27 20:18:04 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/{tm-vr5000.h,tm-vr5000el.h,vr5000.mt,vr5000el.mt}:
+ New files.
+ * configure.tgt: Modify cases for vr5000 to use new files.
+
+Sat Oct 26 07:15:14 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/alpha/alpha-osf3.mh (XM_CLIBS): Add -lm for OSF/1-4.0.
+
+ * procfs.c (proc_set_exec_trap): Under Alpha OSF/1-4.0, tracing
+ the entry to the exit system call to detect termination of the
+ inferior stopped working. Trace termination of the inferior via
+ PRFS_STOPTERM instead.
+ (procfs_init_inferior): Do not trace entry to exit system call
+ if PIOCSSPCACT is defined.
+ (procfs_wait): Handle PR_DEAD event, which signals the termination
+ of the inferior if PRFS_STOPTERM is set.
+
+ * mdebugread.c (parse_partial_symbols): Ignore stNil section
+ start address symbols.
+
+ * sparc-tdep.c (get_saved_register): Get saved PC from the
+ frame info if not in innermost frame.
+
+Thu Oct 24 10:51:45 1996 Mark Alexander <marka@cygnus.com>
+
+ * dbxread.c (process_one_symbol): Interpret end-of-function
+ markers correctly; this fixes problem on Vr5000 where all
+ functions in a module had the same address.
+ * configure.in, configure.tgt, configure.host, gdbserver/configure.in:
+ Correct for pc-linux-gnu problem in config.guess.
+ * configure: Regenerate.
+
+Thu Oct 24 10:06:58 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dbxread.c: Don't swap symbols in place, since internal and
+ external forms may have different sizes. Don't assume that an
+ internal_nlist has the same layout as an external_nlist. Create
+ symbol for n_strx element so to hide specifics of nlist from
+ partial-stab.h.
+ * partial-stab.h: Don't reference dbxread symbols directly. Use
+ CUR_SYMBOL_STRX instead.
+ * config/i386/xm-windows.h: Define SIGQUIT and SIGTRAP.
+
+ * config/v850/tm-v850.h: Define PS_REGNUM and TARGET_V850 for
+ MSVC builds.
+ * mswin/gdbwin.c (reg_order): Define register order for V850.
+ * mswin/gui.cpp (CGuiApp::InitInstance): Define target name for
+ V850.
+ * mswin/regdoc.h: Define MAXREGS for V850.
+
+Tue Oct 22 16:28:20 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-tdep.c (scan_prologue): Changes to deal with scheduled
+ prologues correctly. First, prologue end is now defined by
+ presence of a branch, jump or call insn. Second, can no longer
+ fix frame offsets because we may not know the offset until after a
+ register has been saved.
+ * (v850_init_extra_frame_info): Fixup frame offsets here because
+ we have all the info at this time.
+ * (v850_frame_chain): Use new calling convention for scan_prologue.
+
+Tue Oct 22 10:25:29 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Changes to allow stack
+ backtraces and inferior function calls.
+
+Tue Oct 22 10:32:46 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update init.c editing to work with Oct 8 change.
+ (@HLDFLAGS@): Always edit out.
+
+Mon Oct 21 18:17:08 1996 Mark Alexander <marka@cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): Fix 64-bit
+ sign-extension problems in calculating psymtab addresses.
+ * buildsym.c (end_symtab): Use macro to pop context.
+
+Mon Oct 21 14:40:50 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-tdep.c: Cleanup lots of things. Add many comments.
+
+ * v850-tdep.c (v850_init_extra_frame_info v850_frame_chain): Fix
+ sign bugs with scanning prologues. Get a little smarter about
+ calculating the length of uninteresting instructions.
+
+Mon Oct 21 14:01:38 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * top.c: Add new commands "set annotate" and "show annotate".
+
+Sun Oct 20 04:38:39 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * corelow.c (core_close): Clear inferior_pid only if there is
+ an open core_bfd.
+
+ * cp-valprint.c (cp_print_value_fields): Pass correct address
+ to val_print, not 0.
+
+ From Andreas Schwab (schwab@issan.informatik.uni-dortmund.de):
+ * eval.c (evaluate_subexp_standard) [case BINOP_REPEAT]: Chase
+ typedefs before checking for integral type of right operand.
+
+Fri Oct 18 17:26:22 1996 Mark Alexander <marka@cygnus.com>
+
+ * mdebugread.c (parse_symbol): Fix crash when malloc has
+ no type info and void type has no associated pointer type.
+
+Thu Oct 17 18:18:20 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host: New file, host configuration mapping.
+ * configure.tgt: New file, target configuration mapping.
+ * configure.in: Remove host and target mapping.
+ * configure: Rebuild.
+
+Wed Oct 16 17:46:03 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * breakpoint.c (must_shift_inst_regs): New global.
+ (bpstat_stop_status): Change #if uses of DECR_PC_AFTER_BREAK into
+ equivalent expression uses.
+ * infrun.c (wait_for_inferior): Ditto.
+
+Wed Oct 16 01:53:43 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-tdep.c (v850_push_arguments): Use symbolic names for arg
+ registers.
+ * config/v850/tm-v850.h: Change FP to 29. Define arg regs.
+
+Tue Oct 15 16:30:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (init.c): Don't use -s option with grep. It means
+ something different under Digital Unix.
+
+ * buildsym.c (finish_block): Treat LOC_BASEREG_ARG and
+ LOC_LOCAL_ARG as arguments so that GDB will know about function
+ args declared this way. Mostly affects dwarf.
+ * dwarfread.c (decode_die_type): Change default type from int to
+ void. This allows GDB to recognize void functions.
+ * (new_symbol): If AT_PROTOTYPED is present, set a flag in the
+ type structure.
+ * findvar.c (extract_floating store_floating): Clean up comments
+ to reflect reality.
+ * gdbtypes.h: Add TYPE_FLAG_PROTOTYPED so that we can tell if a
+ function has a prototype. Currently, only dwarf supports this.
+ * utils.c (floatformat_from_doublest): Fix logic error with
+ converting from double to float. (It wasn't shifting mant_long if
+ it had a hidden bit.)
+ * v850-tdep.c: Add support for function calling. Fix some
+ problems with debugging code w/o debug symbols.
+ * config/v850/tm-v850.h: Ditto.
+
+Tue Oct 15 18:19:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * utils.c: Always ensure that size_t is defined. Check
+ HAVE_STDDEF_H rather than __STDC__
+ (xmalloc, xrealloc): Use size_t rather than long.
+
+Tue Oct 15 14:24:19 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h: Undefine NO_SINGLE_STEP so targets
+ can use single-step commands.
+
+Sun Oct 13 11:38:25 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.c (define_symbol): If REG_STRUCT_HAS_ADDR is non-zero,
+ follow typedefs before checking TYPE_CODE for structures and unions.
+
+Fri Oct 11 15:43:54 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * frame.h: Move definition of struct frame_saved_regs to before
+ struct frame to make it possible to use frame_saved_regs in
+ EXTRA_FRAME_INFO macro.
+
+ * v850-tdep.c config/v850/tm-v850.h: Lotsa new functions and
+ macros to make frame operations (such as backtrace) work.
+
+Fri Oct 11 14:23:50 1996 Fred Fish <fnf@cygnus.com>
+
+ * dbxread.c (process_one_symbol): Check for null string directly
+ rather than using strcmp against "".
+ * partial-stab.h: Ditto.
+
+Fri Oct 11 12:18:32 1996 Mark Alexander <marka@cygnus.com>
+
+ * gdbserver/{gdbreplay.c,low-linux.c,remote-utils.c,utils.c}:
+ Make it compile on Linux and eliminate some warnings.
+
+Thu Oct 10 16:32:08 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (init.c): Fixup final sed script to work around
+ Linux bug with `p' operator.
+
+Wed Oct 9 18:02:48 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-mips.c: Use the correct name everywhere (DDB) for NEC's
+ VR4300 target.
+ (ddb_ops, pmon_ops): Fix the documentation strings.
+
+Wed Oct 9 07:42:44 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (init.c): Retro HPUX grep lacks -h option. Strip
+ filenames with sed instead.
+
+Tue Oct 8 15:59:44 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h: Remove decls of xmalloc and xrealloc. There is a
+ conflicting definition in libiberty.h.
+
+Tue Oct 8 11:47:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * dbxread.c (dbx_symfile_read): Call free_pending_blocks rather
+ than poking global variable (which is now static).
+ * hpread.c (hpread_build_psymtabs): Ditto.
+ * os9kread.c (os9k_symfile_read): Ditto.
+ * xcoffread.c (xcoff_initial_scan): Ditto.
+
+ * buildsym.h (free_pending_blocks): Declare here.
+ (pending_blocks): Remove declaration of global symbol.
+ (free_pendings): Remove declaration of global symbol.
+ (make_blockvector): Declare here.
+ (record_pending_block): Declare here.
+
+ * dstread.c (make_blockvector): Remove static copy that was old
+ clone of version in buildsym.c.
+ (process_dst_block): Call record_pending_block rather than doing
+ it by hand.
+ (read_dst_symtab): Ditto.
+
+ * buildsym.c (make_blockvector): Make global rather than static,
+ (record_pending_block): New function, code moved from finish_block.
+ (finish_block): Use record_pending_block.
+ (free_pending_blocks): New function.
+ (really_free_pendings): Call free_pending_blocks.
+ (pending_blocks): Make static instead of global.
+ (free_pendings): Make static instead of global.
+
+Tue Oct 8 09:03:22 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/i386/windows.mh config/i386/xm-windows.h:: New config
+ files to support building Wingdb (built under Microsoft build
+ environment).
+
+ * Makefile.in: Add rule for hpux-thread.o (needs special header
+ files).
+ * (SUBDIRS): Remove mswin.
+ * Change procedure for creating init.c. Speeds things up quite a
+ bit.
+ * config.in configure configure.in: Check for select, poll.
+ * Check for OSF header files before including hpux-thread.o.
+ * Don't configure doc or testsuite when building under MSVC.
+ * findvar.c value.h (read_register_pid write_register_pid): Make
+ global. Needed for hppa-tdep.c.
+ * (supply_register): Don't set pid to inferior_pid when supplying
+ registers.
+ * hppa-tdep.c (saved_pc_after_call): frame_saved_pc ->
+ FRAME_SAVED_PC.
+ * (frame_saved_pc): Change name to hppa_frame_saved_pc.
+ * (hppa_pop_frame): Don't use a pid of 0 with target_write_pc.
+ Use write_pc instead, which uses the correct pid.
+ * (target_read_pc target_write_pc): Use read/write_register_pid
+ instead of read/write_register to preserve the pid passed in.
+ * inftarg.c (child_can_run): Add flag child_suppress_run to allow
+ hpux-threads.c to override this as a runnable target.
+ * config/pa/nm-hppah.h: Define target_new_objfile and
+ target_pid_to_str.
+ * config/pa/tm-hppa.h (FRAME_SAVED_PC): Use hppa_frame_saved_pc
+ instead of frame_saved_pc.
+ * config/m68k/tm-m68k.h: Define TARGET_M68K for Wingdb.
+ * config/m68k/tm-monitor.h: Use FRAME_CHAIN_VALID_ALTERNATE, since
+ we can't easily determine the start file bounds with ELF.
+ * config/mips/tm-mips.h: Define TARGET_MIPS for Wingdb.
+ * hpux-thread.c: New file for HPUX/OSF thread support.
+ * osf-share/{README AT386/cma_thread_io.h HP800/cma_thread_io.h
+ RIOS/cma_thread_io.h cma_attr.h cma_deb_core.h cma_debug_client.h
+ cma_errors.h cma_handle.h cma_init.h cma_list.h cma_mutex.h
+ cma_sched.h cma_semaphore_defs.h cma_sequence.h cma_stack.h
+ cma_stack_int.h cma_tcb_defs.h cma_util.h}: New files for OSF
+ thread support.
+
+Sun Oct 6 15:48:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * buildsym.c (finish_block): Change innerblock_anon_complaint to
+ print the addresses as part of the complaint. Add a complaint for
+ cases where the block end address is smaller than the block start
+ address, in case any such conditions slip through our fixup mechanism.
+ * symmisc.c (dump_symtab): Only print blockvector for primary
+ symtabs, to avoid massive duplication of output due to secondary
+ symtabs that point to same blockvector. Also do some minor
+ formatting tweaks.
+
+Mon Oct 7 10:42:32 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ Replace header_files global by per-objfile field.
+ * gdb-stabs.h (struct dbx_symfile_info): Add fields header_files,
+ n_header_files, n_allocated_header_files.
+ * stabsread.h (header_files, n_header_files, n_allocated_header_files):
+ Replace externs by macros HEADER_FILES, N_HEADER_FILES, and
+ N_ALLOCATED_HEADER_FILES.
+ * dbxread.c (dbx_symfile_finish): Free HEADER_FILES.
+ (free_header_files, init_header-files): Don't free/init headerfiles.
+ (various functions): Use macros instead of header_files globals.
+ * stabsread.c (various functions): Likewise.
+
+Sun Oct 6 22:43:06 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2read.c (read_tag_reference_type): New fn.
+ (read_type_die): Call it.
+ (dwarf_attr): Also look in the DIEs referred to by specification
+ or abstract_origin attributes.
+
+Wed Oct 2 22:07:16 1996 Fred Fish <fnf@cygnus.com>
+
+ * inferior.h (IN_SIGTRAMP): Pass pc to SIGTRAMP_START and
+ SIGTRAMP_END.
+ * config/i386/tm-i386os9k.h (SIGTRAMP_START, SIGTRAMP_END):
+ Define with dummy pc arg.
+ * config/m68k/tm-nbsd.h: Ditto.
+ * doc/gdbint.texinfo: Document that SIGTRAMP_START and
+ SIGTRAMP_END are macros that take an single argument.
+
+Mon Sep 30 20:02:45 1996 Fred Fish <fnf@cygnus.com>
+
+ * defs.h: Remove define of PRIVATE_XMALLOC.
+
+Mon Sep 30 15:39:28 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/v850/tm-v850.h: Use distinct register for PC, not EIPC.
+
+Mon Sep 30 11:16:34 1996 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (execute_control_command): Free values from while_control
+ and if_control conditions after evaluation to avoid storage leaks.
+ From Peter Schauer.
+
+Fri Sep 27 17:43:06 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure configure.in: Recognize v850 target.
+ * v850-tdep.c: New file, NEC V850 target support.
+ * config/v850/{v850.mt tm-v850.h}: New files for NEC V850 support.
+
+Fri Sep 27 14:48:15 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Update current_line and
+ current_symtab when stepping continues in the middle of a new line.
+
+Fri Sep 27 10:25:30 1996 Fred Fish <fnf@cygnus.com>
+
+ * top.c (print_gdb_version): Rewrote to comply with new GNU coding
+ standards for the --version option.
+ (print_gnu_advertisement): Remove, now part of print_gdb_version.
+ (show_version): Remove call to print_gnu_advertisement.
+ * top.h (print_gnu_advertisement): Remove prototype.
+ * main.c (print_gdb_help): Move help to static function and
+ add prototype.
+ (main): Call print_gdb_help rather than inlining it.
+ (main): Remove call to print_gnu_advertisement.
+
+Fri Sep 27 13:32:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/d10v/tm-d10v.h (TARGET_{INT,PTR}_BIT): Define.
+ (TARGET_{,LONG_}DOUBLE_BIT): Ditto.
+
+Thu Sep 26 23:10:26 1996 Mark Alexander <marka@cygnus.com>
+
+ * configure.in, config/i386/tm-linux.h: Fix configure
+ problem on older Linux systems that prevented core files
+ from being recognized.
+
+Wed Sep 25 18:31:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dbug-rom.c: New file, support for Motorola's dBUG monitor.
+ * config/m68k/monitor.mt (TDEPFILES): Add it.
+ * NEWS: Mention it.
+
+Mon Sep 23 16:13:50 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/d10v/tm-d10v.h (SAVED_PC_AFTER_CALL): Fixed.
+ Now single-steps correctly.
+ * d10v-tdep.c (d10v_pop_frame): Fixed.
+
+Fri Sep 20 16:10:58 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sh/tm-sh.h (REGISTER_NAMES): Move fp registers to
+ be consistent with GCC.
+ (FPUL_REGNUM, etc): Renumber to match list changes.
+ (ADDR_BITS_REMOVE): Delete.
+ * sh-tdep.c (sh_reg_names, sh3_reg_names, sh3e_reg_names):
+ Rearrange to match REGISTER_NAMES.
+ * sh3-rom.c (sh3_regnames, sh3e_regnames): Ditto.
+
+Thu Sep 19 16:19:01 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c: Stack chain should work now.
+
+Tue Sep 17 18:46:57 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Snapshot.
+
+Tue Sep 17 12:20:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add cases for MIPS 5000 like MIPS 4300.
+ * configure: Rebuild.
+
+Tue Sep 17 12:09:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * ser-e7kpc.c: Added wingdb support for target e7000pc.
+
+Tue Sep 17 10:56:52 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (pmon_wait): DDB PMON does not require forced
+ re-entry back into debug mode.
+
+Mon Sep 16 14:32:58 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (mips_load): Ensure that the PC is explicitly
+ loaded after a load to a DDB PMON system.
+
+Fri Sep 13 12:02:39 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (INTERNAL_LDFLAGS): Add @HLDFLAGS@ to list.
+ (HLDENV): Set to @HLDENV@.
+ (gdb): Prefix link command line with $(HLDENV).
+ * configure.in: Add support to test for --enable-shared and
+ generate appropriate values for HLDFLAGS and HLDENV.
+ * configure: Regenerated with autoconf.
+
+Sun Sep 8 15:26:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * alpha-nat.c (fetch_core_registers): Match Sep 4 gdbcore.h prototype
+ change for core_read_registers in struct core_fns.
+ * core-regset.c (fetch_core_registers): Ditto & add prototype.
+ * core-sol2.c (fetch_core_registers): Ditto & add prototype.
+ * i386aix-nat.c (fetch_core_registers): Ditto & add prototype.
+ * i386b-nat.c (fetch_core_registers): Ditto.
+ * i386mach-nat.c (fetch_core_registers): Ditto & add prototype.
+ * irix4-nat.c (fetch_core_registers): Ditto.
+ * irix5-nat.c (fetch_core_registers): Ditto.
+ * lynx-nat.c (fetch_core_registers): Ditto & add prototype.
+ * m68knbsd-nat.c (fetch_core_registers): Ditto.
+ * mips-nat.c (fetch_core_registers): Ditto & add prototype.
+ * rs6000-nat.c (fetch_core_registers): Ditto.
+ * sparc-nat.c (fetch_core_registers): Ditto.
+ * sun3-nat.c (fetch_core_registers): Ditto & add prototype.
+ * ultra3-nat.c (fetch_core_registers): Ditto & add prototype.
+
+ * alpha-nat.c (register_addr): Match Sep 4 gdbcore.h prototype change.
+ * delta68-nat.c (register_addr): Ditto.
+ * gdbserver/low-linux.c (register_addr): Ditto.
+ * gdbserver/low-hppabsd.c (register_addr): Ditto.
+ * i386m3-nat.c (register_addr): Ditto.
+ * mips-nat.c (register_addr): Ditto.
+ * ultra3-nat.c (register_addr): Ditto.
+
+Sun Sep 8 15:14:00 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * blockframe.c (inside_main_func): Cleanup slightly. Move
+ mainsym def into the block it's used in.
+ * configure.in configure: Allow NATDEPFILES to be recognized in
+ .mh files regardless of whitespace.
+
+ * cpu32bug-rom.c (cpu32bug_cmds): Change load_response string to
+ keep downloads from hanging.
+
+ * remote-wiggler.c: Add support for flash upgrades.
+ * (wiggler_error): Fix message format. Add new error code.
+ * (wiggler_write_byets): Error code is hex. Report errors with
+ proper routine name.
+ * (wiggler_read_byets): Report errors with proper routine name.
+ * (get_packet): Add support for new flash commands.
+ * (wiggler_load): Call clear_symtab_users() to reset things
+ properly after download.
+ * (flash_xfer_memory bdm_update_flash_command): New funxtions to
+ support flash upgrades for Wiggler.
+ * (_initialize_remote_wiggler): Add `bdm update-flash' command.
+
+Fri Sep 6 13:14:13 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * ser-tcp.c: don't include netinet/tcp.h if __CYGWIN32__
+
+Thu Sep 5 17:05:13 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/cygwin32.mh:
+ * config/powerpc/cygwin32.mh: build ser-tcp.o for both hosts
+
+Thu Sep 5 12:09:13 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * value.h (COERCE_REF): Fix previous change.
+ (COERCE_ENUM): Add a check_typedef (this is the real fix).
+
+Thu Sep 5 03:28:30 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard): In case of OP_ARRAY: make a
+ better check of array boundaries.
+
+Thu Sep 5 01:29:42 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure: Update aclocal.m4 and re-run autoconf to get correct
+ defs for BFD stuff.
+ * remote-wiggler.c (wiggler_error): Error codes are hex. Also,
+ fix default message generation.
+
+Wed Sep 4 17:28:40 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in: Add mswin to SUBDIRS. Add rules for
+ mswin/libwingdb.a and remote-wiggler.o.
+ * breakpoint.c (breakpoint_here_p): Clean up bp enabled test.
+ * (breakpoint_inserted_here_p): New func, just like
+ breakpoint_here_p, except it's honest. Honestly.
+ * breakpoint.h: Proto for above.
+ * configure configure.in: Add mswin to configdirs if host is
+ i[3456]86-*-windows.
+ * core-aout.c (fetch_core_registers register_addr) gdbcore.h:
+ Change all vars that can contain addresses to type CORE_ADDR.
+ * findvar.c (supply_register): Allow val to be NULL. This means
+ that regno is unsupported.
+ * (read_pc read_pc_pid write_pc write_pc_pid): Make non-pid forms
+ just call pid forms with inferior_pid so that there's only once
+ place to hack PC's and such.
+ * infrun.c (proceed): Don't skip breakpoints if user changed PC.
+ * remote-wiggler.c: New file. Support for BDM interface from
+ Macraigor Systems.
+ * serial.c: Enhance serial logging capability. Add hex and octal
+ output modes (set remotelogbase {hex|octal|ascii}. Also log
+ breaks, timeouts, errors, and eofs.
+ * serial.h: Redefine SERIAL_SEND_BREAK to go through a wrapper
+ function so that we can log breaks. Don't export serial_logfile
+ or serial_logfp.
+ * top.c (execute_command): Don't test for serial_logfp here.
+ Just call serial_log_comand, and let serial.c sort it out.
+ * valops.c (value_of_variable): Don't attempt to establish frames
+ for static and global variables. This makes things work a bit
+ better if the stack or frame pointer is trashed.
+ * config/m68k/monitor.mt (TDEPFILES): Add remote-wiggler.o.
+ * config/m68k/tm-m68k.h: Define STACK_ALIGN. CPU32 can't hack
+ misaligned stacks during function calls.
+
+Wed Sep 4 13:06:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * terminal.h: Don't use #elif.
+
+Wed Sep 4 06:49:35 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (parse_tuple_element): Allow (*): for array tuples
+ if we have a type.
+
+ * eval.c (evaluate_subexp_standard): In case of OP_ARRAY:
+ check number of args against bounds of array to avoid
+ memory corruption.
+
+ * value.h (COERCE_REF): Do a CHECK_TYPEDEF in case we get
+ a TYPE_CODE_TYPEDEF.
+
+Fri Aug 30 15:07:14 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c: Provide support for DDBVR4300 target board.
+ (ddb_open, ddb_ops): Added.
+ (mips_monitor_type): MON_DDB Added.
+ (mips_enter_debug, mips_exit_debug, mips_initialize,
+ mips_fetch_registers, common_breakpoint, mips_load,
+ _initialize_remote_mips): Updated.
+
+Thu Aug 29 17:00:18 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * nlm/configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+ * nlm/configure: Regenerate.
+
+ * gdbserver/configure.in (i[345]86-*-*): Recognize i686 for
+ pentium pro.
+
+Wed Aug 28 13:11:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: If CY_AC_PATH_TCLCONFIG can't find TCL, don't run
+ CY_AC_LOAD_TCLCONFIG.
+ * configure: Rebuild.
+
+Tue Aug 27 12:40:40 1996 Fred Fish <fnf@cygnus.com>
+
+ * infrun.c (wait_for_inferior): Initialize stop_func_end before calling
+ find_pc_partial_function.
+
+Tue Aug 27 10:17:34 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure: Regenerate again.
+
+Tue Aug 27 04:25:08 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: work around host_alias configure bug.
+ AC_CANONICAL_HOST is called twice (first by AC_CHECK_TOOL
+ and second by AC_CANONICAL_SYSTEM). The second clobbers the
+ previous setting. Circumventing by moving the second check
+ to before the first.
+ * configure: regenerated
+
+Mon Aug 26 18:36:54 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/d10v/d10v.mt: New file.
+ * config/d10v/tm-d10v.h: New file.
+ * configure.in: New target D10V.
+ * d10v-tdep.c: New file.
+
+Sun Aug 25 00:09:47 1996 Fred Fish <fnf@rtl.cygnus.com>
+
+ * rs6000-tdep.c: Fix typo in comment.
+ * valops.c (call_function_by_hand): Set using_gcc to 2
+ for code compiled without -g, per comment in code.
+ * config/a29k/tm-a29k.h (STACK_ALIGN): Add comment.
+ * config/sparc/tm-sparc.h (STACK_ALIGN): Add comment.
+ * config/sparc/tm-sp64.h (STACK_ALIGN): Add comment.
+ * config/pyr/tm-pyr.h (STACK_ALIGN): Add comment.
+ * config/m88k/tm-m88k.h (STACK_ALIGN): Add comment.
+ * config/pa/tm-hppa.h (PUSH_ARGUMENTS): Enclose args in ()'s.
+ (STACK_ALIGN): Add comment, move to be with other associated
+ macros, and document.
+ * config/mips/tm-mips.h (PUSH_ARGUMENTS): Enclose args in ()'s.
+ (STACK_ALIGN): Remove completely, handled by PUSH_ARGUMENTS.
+ * config/alpha/tm-alpha.h (PUSH_ARGUMENTS): Enclose args in ()'s.
+ * config/rs6000/tm-rs6000.h (STACK_ALIGN): Remove completely,
+ handled by PUSH_ARGUMENTS.
+ (PUSH_ARGUMENTS): Enclose args in ()'s.
+
+Fri Aug 23 13:55:05 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Try to reenable shared library
+ breakpoints even if auto_solib_load is not set.
+
+Wed Aug 21 16:31:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * valprint.c (print_longest): Test for CC_HAS_LONG_LONG as well as
+ PRINTF_HAS_LONG_LONG.
+ * expprint.c (dump_expression): Ditto.
+ * configure.in: Fix check for long long support in compiler to
+ use a function body, not a nested function.
+ * configure: Rebuild with autoconf.
+
+Tue Aug 20 17:59:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4: Include ../bfd/aclocal.m4.
+ * configure.in: Add stdlib.h to AC_CHECK_HEADERS. Call
+ BFD_NEED_DECLARATION on malloc, realloc, and free.
+ * acconfig.h: Add NEED_DECLARATION_MALLOC,
+ NEED_DECLARATION_REALLOC, and NEED_DECLARATION_FREE.
+ * configure, config.in: Rebuild.
+ * defs.h: Include <stddef.h> and <stdlib.h> based on HAVE_*_H
+ rather than __STDC__. Only declare malloc, realloc, and free if
+ NEED_DECLARATION_* is defined.
+
+Tue Aug 20 15:37:03 1996 Fred Fish <fnf@cygnus.com>
+
+ * solib.c (_initialize_solib): Add missing '\' chars at ends of
+ strings that continue on next line.
+ (enable_break): Replace "return 0" with setting success to zero
+ and letting normal return handle the return.
+
+Sat Aug 17 14:16:23 1996 Fred Fish <fnf@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Make sure sp and struct_addr
+ are properly aligned.
+
+Fri Aug 16 17:54:26 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_fix_call_dummy): Add full set of arguments.
+ * config/rs6000/tm-rs6000.h (FIX_CALL_DUMMY): Pass all arguments
+ to function, declare function correctly.
+
+Fri Aug 16 17:24:35 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * symtab.h: changed namespace to _namespace for compiling under
+ MFC v4.0.
+
+Fri Aug 16 13:52:21 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update for various recent changes, add some
+ comments.
+
+Fri Aug 16 15:47:36 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/rs6000/tm-rs6000.h (FIX_CALL_DUMMY): Cast args to be an
+ integer for type correctness.
+
+Fri Aug 16 15:15:37 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/mips/{vr4300.mt, vr4300el.mt} (SIM): Add -lm when
+ simulator is included.
+
+Thu Aug 15 13:44:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * findvar.c (write_register_pid): Only needed when TARGET_WRITE_PC
+ is not defined.
+ (read_register_pid): Only needed when TARGET_READ_PC is not
+ defined.
+ * hppa-tdep.c (frame_saved_pc): Remove prototype.
+ * infptrace.c (udot_info): Prototype when CHILD_XFER_MEMORY is
+ not defined.
+ * config/xm-aix4.h (aix_resizewindow): Convert old style decl
+ to prototype.
+ * xcoffsolib.c (command.h): Include for needed prototypes.
+
+Wed Aug 14 17:54:19 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/i386/cygwin32.mh: Set NAT_FILE to nm-empty.h to make
+ native work.
+
+Wed Aug 14 02:03:42 1996 Fred Fish <fnf@cygnus.com>
+
+ From Blair MacIntyre <bm@cs.columbia.edu>:
+ * hppa-tdep.c (hppa_fix_call_dummy): Use MSYMBOL_TYPE rather
+ than SYMBOL_TYPE on msymbols.
+ * somsolib.c (som_solib_create_inferior_hook): Ditto.
+
+ * Makefile.in (init.c): Generate with prototypes.
+
+ * config/pa/tm-hppa.h (frame_saved_pc): Add prototype.
+ * config/rs6000/xm-rs6000.h (aix_resizewindow): Ditto.
+ * config/rs6000/tm-rs6000.h (frame_initial_stack_address): Ditto.
+ (pc_load_segment_name): Ditto.
+ (pop_frame): Ditto.
+ (extract_return_value): Ditto.
+ (is_magic_function_pointer): Ditto.
+ (push_dummy_frame): Ditto.
+ (fix_call_dummy): Ditto.
+ (push_arguments): Ditto.
+ (skip_trampoline_code): Ditto.
+ (aix_process_linenos): Ditto.
+
+ * config/m68k/tm-cisco.h (get_longjmp_target): Add prototype.
+ * config/m68k/tm-es1800.h: Ditto.
+ * config/m68k/tm-vx68.h: Ditto.
+ * config/m68k/tm-sun3.h: Ditto.
+ * config/m68k/tm-m68kv4.h: Ditto.
+
+Tue Aug 13 23:04:36 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/nm-mips.h (get_longjmp_target): Add prototype.
+ * config/mips/nm-irix3.h (get_longjmp_target): Add prototype.
+ * remote-mips.c (mips_read_processor_type): Remove prototype.
+ * mips-tdep.c (gdb_print_insn_mips): Add prototype and make static.
+ * irix5-nat.c (fetch_core_registers): Add prototype.
+
+Mon Aug 12 21:23:44 1996 Fred Fish <fnf@cygnus.com>
+
+ * remote-pa.c (boot_board): Add dummy params to make type compatible
+ for passing to add_com.
+ * scm-exp.c (scm_lreadr): Ensure svalue is not used uninitialized.
+ * buildsym.c (compare_line_numbers): Change function to match
+ prototype and also what qsort expects.
+
+Mon Aug 12 19:19:00 1996 Mark Alexander <marka@cygnus.com>
+
+ * remote.c: Make remote_write_size public.
+ * sh-tdep.c (_initialize_sh_tdep): Set remote_write_size to 300
+ to prevent packet errors with some versions of CMON.
+
+Mon Aug 12 16:20:58 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h: Define CONST_PTR as blank if compiling with Microsoft
+ C, else it's `const'.
+ * c-lang.c c-lang.h ch-lang.c f-lang.c language.c m2-lang.c
+ scm-lang.c: Microsoft C can't hack const pointers. Use CONST_PTR
+ macro instead.
+ * configure configure.in defs.h: Use AC_C_CONST to figure out if
+ the compiler supports const. Gets rid of some cruft in defs.h.
+ * dwarf2read.c: <string.h> -> "gdb_string.h"
+ * remote-sim.c: Add prototypes. Fix call to gdbsim_kill.
+ * sparcl-tdep.c (download): Add prototypes to write_routine and
+ start_routine args.
+
+ * mswin/gdbwin.c: Don't include both varargs.h AND stdarg.h. Get
+ rid of varargs.h Include string.h.
+ * (gdbwin_update gdbwin_fputs regs_changed_f bpt_changed_f
+ update): Fix prototypes, fix calls.
+ * (update): Return value for catch_errors.
+ * (run_execute_command togdb_command_from_tty togdb_command):
+ Cleanup catching of errors from calls to execute_command. Also,
+ dup command string to avoid modifying const strings.
+ * (togdb_breakinfo_i_init togdb_breakinfo_i_next): Use 0 instead
+ of NULL when see if b->address isn't set.
+ * (bi_disable_bpt bi_enable_bpt bi_delete_all
+ bi_delete_breakpoint): Add arg to calls to update.
+ * (gui_command): Add prototype.
+ * (mswin_query): Fix prototype.
+ * (_initialize_gdbwin): Dup string to avoid modifying const.
+ * (info_path togdb_get_info_path): Remove const from decls cuz
+ this can't be const (it points at malloc'ed memory).
+ * (togdb_searchpath): Remove const from path. Dup string to
+ avoid modifying const strings.
+ * rindex -> strrchr.
+ * (gdbwin_list_symbols): Regexp param is const.
+ * Fix lots of refs to psymtabs to deref correct pointers.
+ * (togdb_set_breakpoint_sal): Call set_breakpoint_sal with sal,
+ not &sal.
+ * mswin/gdbwin.h (togdb_searchpath togdb_get_info_path
+ toget_set_info_path): Fix prototypes to match reality.
+ * mswin/gui.cpp: Define _beginthreadex and _endthreadex routines
+ with proper prototypes.
+ * mswin/iface.cpp (gdbwin_fputs): Define with correct number of args.
+ * mswin/ser-win32s.c: Fix defs of min and max.
+ * mswin/serdll32.c (OpenComm16): Make cbInQueue and cbOutQueue be
+ USHORT.
+ * (WriteComm16): Change lpBug from LPVOID to LPCSTR.
+ * mswin/serdll32.h: Fix prototypes for OpenComm16 and WriteComm16.
+
+Sun Aug 11 20:54:16 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * main.c (main): Make sure command loop is used with cygwin32.
+ * terminal.h: Allow cygwin32 to use termios.h.
+
+Fri Aug 9 12:42:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * somread.c (som_symtab_read): Handle secondary definition
+ symbols (aka weak symbols).
+
+ * config/tm-hppa.h (EXTRACT_RETURN_VALUE): Fix thinko in
+ last change.
+
+Thu Aug 8 10:12:36 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * symfile.c (symfile_bfd_open): Change ifdef from __WIN32__ to
+ _WIN32.
+
+ * somread.c: Rearrange order of includes to fix warnings under
+ hpux-10.10. Also don't include sys/file.h.
+
+Wed Aug 7 21:45:52 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dbxread.c: Don't include param.h or sys/file.h.
+ * (dbx_symfile_read): Determine symfile_relocatable from bfd
+ flags instead of file extension. Also clean up a little bit.
+
+Wed Aug 7 17:18:37 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dwarf2read.c dwarfread.c exec.c infcmd.c infrun.c main.c
+ mdebugread.c os9kread.c source.c top.c utils.c: Don't
+ include param.h or sys/file.h (or unistd.h in some cases).
+ * defs.h exec.c inflow.c remote-array.c remote-e7000.c
+ sparcl-tdep.c terminal.h utils.c: Replace all occurances of
+ __WIN32__, WINGDB, WIN32, etc... with _WIN32.
+ * main.c: Remove #ifndef WINGDB around option processing. Fix
+ bug with passing argc==0 and argv==NULL to getopt.
+ * (main) Remove calls to access() before source_command. Let
+ soure_command handle access errors.
+ * maint.c (maintenance_dump_me): #ifdef out for _WIN32.
+ * symtab.c (operator_chars): Make this global for wingdb.
+ * top.c (disconnect): #ifdef out for _WIN32.
+ * (source_command): If got an error and from_tty, then call print
+ error, else just return quietly.
+ * utils.c (fatal_dump_core): Can't kill ourselves under windows.
+ Just exit.
+ * (pollquit notice_quit): #ifdef out stuff that doesn't exist
+ under windows.
+
+Wed Aug 7 09:59:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Tweak for
+ structures > 4 bytes in size.
+
+ * valops.c (call_function_by_hand): Handle aligning stacks that
+ grow up correctly.
+ * config/pa/tm-hppa.h (USE_STRUCT_CONVENTION): Define.
+ (STACK_ALIGN): Define.
+ * hppa-tdep.c (hppa_alignof): Don't demand a minumim two byte
+ alignment on structs/unions.
+
+Sun Aug 4 16:22:42 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/powerpc/nm-aix.h (PTRACE_ARG3_TYPE): Define to "int *",
+ which is the documented type under at least AIX 3 and AIX 4.
+
+Sat Aug 3 04:02:46 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/alpha/alpha-osf3.mh (XM_FILE): Change from xm-alpha.h to
+ xm-alphaosf.h.
+ (MMALLOC_CFLAGS): Define NO_MMCHECK to not install consistency
+ checks.
+
+Thu Aug 1 10:11:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-mips.h (TM_MIPS_H): Enclose file contents in
+ this, define when contents are included.
+ (mips_read_processor_type): Add prototype.
+ * config/mips/xm-mips.h: Remove strdup decl, now in gdb_string.h
+ * mdebugread.c (ecoff_relocate_efi): Add prototype.
+ (fixup_sigtramp): Only needed when TM_MIPS_H is defined.
+
+Wed Jul 31 20:21:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * rs6000-nat.c (add_vmap): Return 0 to caller rather than random value.
+ (vmap_ldinfo): Ensure got_exec_file is not used uninitialized.
+ (fetch_core_registers): Add prototype.
+ (vmap_symtab): Ditto.
+ (objfile_symbol_add): Ditto.
+ (add_vmap): Ditto.
+ (vmap_ldinfo): Ditto.
+ (vmap_exec): Ditto.
+
+Tue Jul 30 17:57:46 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * stabsread.c (get_substring): Declare second arg as int.
+
+ * remote-es.c: Include gdb_string.h after defs.h.
+
+Mon Jul 29 21:13:20 1996 Fred Fish <fnf@cygnus.com>
+
+ * rs6000-tdep.c (push_arguments): Remove unused variable "pc".
+ (branch_dest): Remove unused variable "offset".
+ (pop_dummy_frame): Add prototype and make static.
+ (push_arguments): Guard against using len uninitialized.
+ (push_arguments): Guard against using arg uninitialized.
+ (frame_saved_pc): Remove unused variable "frameless".
+ (free_loadinfo): Ifdef out unused function.
+
+ * xcoffread.c (compare_lte): Change prototype and function to
+ be correct type for passing to qsort.
+ (add_stab_to_list): Ifdef out unused function and prototype.
+ (compare_lte): Add prototype
+ (arrange_linetable): Ditto.
+ (record_include_begin): Ditto.
+ (record_include_end): Ditto.
+ (process_linenos): Ditto.
+ (xcoff_next_symbol_text): Ditto.
+ (scan_xcoff_symtab): Ditto.
+ (xcoff_initial_scan): Ditto.
+
+ * mips-tdep.c (mips_read_processor_type): Add parens around
+ bitwise-and operands in comparison; previous expression always
+ evaluated to 0 because of equality comparison of two constants.
+
+ * rs6000-tdep.c (skip_prologue): Add missing parens around
+ operands of logical-or so that first operand does not bind
+ to previous logical-and.
+
+ * configure.in: Expand "long long" test to include code that triggers
+ known problem on HPUX with native compiler.
+ (configure): Regenerated.
+
+Mon Jul 29 18:12:27 1996 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c (som_solib_create_inferior_hook): Don't
+ warn if __d_pid can't be found.
+
+Sun Jul 28 10:46:39 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-mips.h (struct frame_info): Forward decl.
+ (struct type): Ditto.
+ (struct value): Ditto.
+
+ * config/mips/tm-mips.h (sigtramp_address): Move extern decl
+ from mips-tdep.c to here.
+ (sigtramp_end): Ditto.
+ (fixup_sigtramp): Ditto.
+
+ * config/mips/tm-mips.h (init_extra_frame_info): Add prototype.
+ (mips_frame_chain): Ditto.
+ (mips_step_skips_delay): Ditto.
+ (mips_frame_saved_pc): Ditto.
+ (mips_find_saved_regs): Ditto.
+ (mips_frame_num_args): Ditto.
+ (mips_pop_frame): Ditto.
+ (mips_extract_return_value): Ditto.
+ (mips_store_return_value): Ditto.
+ (mips_push_dummy_frame): Ditto.
+ (mips_push_arguments): Ditto.
+ (mips_do_registers_info): Ditto.
+ (ecoff_relocate_efi): Ditto.
+ (ecoff_relocate_efi): Ditto.
+ * irix4-nat.c (fetch_core_registers): Add prototype.
+ * mips-tdep.c (read_next_frame_reg): Add prototype
+ (heuristic_proc_start): Ditto.
+ (heuristic_proc_desc): Ditto.
+ (mips_print_register): Ditto.
+ * config/mips/nm-irix5.h (procfs_set_watchpoint): Add prototype.
+ (procfs_stopped_by_watchpoint): Ditto.
+ * config/mips/nm-irix4.h (procfs_set_watchpoint): Add prototype.
+ (procfs_stopped_by_watchpoint): Ditto.
+ * config/alpha/tm-alpha.h (ecoff_relocate_efi): Add prototype.
+ (struct symbol): Add forward decl for prototype.
+
+ * breakpoint.c (internal_breakpoint_number): Only needed if
+ GET_LONGJMP_TARGET or SOLIB_ADD is defined.
+
+ * objfiles.c (ecoff_relocate_efi): Remove prototype.
+
+Sat Jul 27 17:47:35 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add test for "long long" support.
+ * configure: Regenerate with autoconf.
+ * acconfig.h: Add CC_HAS_LONG_LONG
+ * config.in: Regenerate with autoheader.
+ * config/mips/tm-mips64.h (FORCE_LONG_LONG): Remove
+ * config/sparc/tm-sp64.h (CC_HAS_LONG_LONG): Remove.
+ * config/mips/tm-vr4300el.h (CC_HAS_LONG_LONG): Remove.
+ * config/mips/tm-vr4300.h (CC_HAS_LONG_LONG): Remove.
+ * config/mips/xm-irix5.h (CC_HAS_LONG_LONG): Remove
+ (PRINTF_HAS_LONG_LONG): Remove.
+ (FORCE_LONG_LONG): Remove.
+ * config/powerpc/xm-aix.h (UINT_MAX): Undef and use gdb's version.
+ * config/convex/xm-convex.h (CC_HAS_LONG_LONG): Remove
+ (PRINTF_HAS_LONG_LONG): Remove.
+ * config/xm-nbsd.h (CC_HAS_LONG_LONG): Remove.
+ (PRINTF_HAS_LONG_LONG): Remove.
+ * config/pa/tm-hppa.h (GET_FIELD): Put parens around
+ subtraction inside shift. Put parens around subtraction
+ in operand of bitwise and.
+ (struct frame_info): Forward declare
+ if __STDC__ defined.
+ (frame_saved_regs): Ditto.
+ (struct value): Ditto.
+ (struct type): Ditto.
+ (struct inferior_status): Ditto.
+ (init_extra_frame_info): Add prototype.
+ (skip_prologue): Ditto.
+ (frameless_function_invocation): Ditto.
+ (frame_chain): Ditto.
+ (frame_chain_valid): Ditto.
+ (saved_pc_after_call): Ditto.
+ (hppa_fix_call_dummy): Ditto.
+ (hppa_push_arguments): Ditto.
+ (pa_do_registers_info): Ditto.
+ (in_solib_call_trampoline): Ditto.
+ (in_solib_return_trampoline): Ditto.
+ (push_dummy_frame): Ditto.
+ * convex-tdep.c (decout): Use print_longest rather than
+ fprintf_filtered.
+ * defs.h: Remove use of FORCE_LONG_LONG and __GNUC__ to set
+ CC_HAS_LONG_LONG.
+ (INT_MIN): Fix so it works correctly when assigned to a long long.
+ * valprint.c (longest_to_int): Rewrite to remove dependence
+ on INT_MIN and INT_MAX.
+ (print_longest): Rewrite the code that falls back to synthesized
+ hex output when LONGEST value is not representable as in a long and
+ printf doesn't support printing long longs.
+ * ch-valprint.c (chill_val_print): Cast 2nd arg of
+ chill_print_type_scalar to LONGEST.
+ chill_print_type_scalar): Make static and add prototype.
+ * hppa-tdep.c (get_field): Ifdef out unused function.
+ (set_field): Ditto.
+ (extract_3): Ditto.
+ (extract_5_store): Ditto.
+ (extract_11): Ditto.
+ (extract_12): Ditto.
+ (deposit_17): Ditto.
+ (extract_14): Convert to static and add prototype.
+ (deposit_14): Ditto.
+ (extract_21): Ditto.
+ (deposit_21): Ditto.
+ (extract_17): Ditto.
+ (extract_5r_store): Ditto.
+ (extract_5R_store): Ditto.
+ (extract_5_load): Ditto.
+ (find_proc_framesize): Ditto.
+ (find_dummy_frame_regs): Ditto.
+ (sign_extend): Ditto.
+ (find_unwind_entry): Add prototype.
+ (find_return_regnum): Ditto.
+ (unwind_command): Ditto.
+ (find_dummy_frame_regs): Add parens around subtraction in operand
+ of bitwise-and.
+ (skip_prologue): Add parens around operands of logical-and inside
+ operand of logical-or.
+ (sign_extend): Add parens around operands of subtraction inside
+ operand of shift.
+ (low_sign_extend): Ditto.
+ * top.c (filename_completer): Convert old style decl of
+ filename_completion_function into prototype.
+ * f-lang.c (patch_common_entries): Ifdef out unused function.
+ * stabsread.c (read_cfront_baseclasses): Remove unused local
+ variable "msg_noterm".
+ (resolve_cfront_continuation): Remove unused local variable "fip".
+ (read_type): Remove unused variable xtypenums.
+ (read_cfront_static_fields): Remove unused variable "i".
+ (read_cfront_static_fields): Remove unused variable "nfields".
+ (read_cfront_member_functions): Add missing comment terminator.
+ (read_cfront_static_fields): Return 1 rather than random value.
+ (read_cfront_baseclasses): Ditto.
+ (read_cfront_baseclasses): Ditto.
+ (read_cfront_baseclasses): Ditto.
+ * somsolib.c (som_solib_create_inferior_hook): Remove unused
+ variable "u".
+ (som_solib_create_inferior_hook): Remove unused variable
+ shadow_contents.
+ (language.h): Add for needed prototypes.
+ (som_solib_sharedlibrary_command): Add prototype.
+ * hpread.c: (hpread_read_array_type): Add prototype.
+ * somread.c (hpread_build_pysmtabs): Add prototype.
+ (hpread_symfile_finish): Ditto.
+ (hpread_symfile_init): Ditto.
+ * hppah-nat.c (fetch_register): Convert old style decl
+ to prototype.
+ (gdbcore.h): Include for needed prototypes.
+ (fetch_register): Remove unused variable "mess".
+ * remote-pa.c (get_offsets): Ifdef out unused function.
+ (remote_start_remote): Remove unused variable "timeout".
+ (boot_board): Add prototype.
+ (reaad_frame): Add prototype.
+ (getpkt): Remove unused variable "bp".
+ (remote_kill): Add prototype.
+ (remote_mourn): Add prototype.
+ (remote_insert_breakpoint): Add prototype.
+ (remote_remove_breakpoint): Add prototype.
+ * valops.c (value_push): Only use if PUSH_ARGUMENTS is not defined.
+ * infcmd.c (do_registers_info): Only need prototype if
+ DO_REGISTERS_INFO is not defined.
+ (breakpoint_auto_delete_contents): Only need if
+ CALL_DUMMY_BREAKPOINT_OFFSET is defined.
+
+Sat Jul 27 08:49:49 1996 Fred Fish <fnf@cygnus.com>
+
+ * xcoffread.c (xcoff_end_psymtab): Add textlow_not_set parameter.
+ (END_PSYMTAB): Ditto.
+ (scan_xcoff_symtab): Call xcoff_end_psymtab with textlow_not_set.
+
+Fri Jul 26 14:07:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * printcmd.c (_initialize_printcmd): Initialize
+ tm_print_insn_info.flavour.
+
+Thu Jul 25 19:41:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (scm-valprint.o): Depends upon gdbcore_h.
+ (arm-tdep.o): Ditto.
+ (dcache.o): Ditto.
+ (i386ly-tdep.o): Ditto.
+ (i960-tdep.o): Ditto.
+ (m68k-tdep.o): Ditto.
+ (nindy-tdep.o): Ditto.
+ (scm-lang.o): Ditto.
+ (w65-tdep.o): Ditto.
+ (z8k-tdep.o): Ditto.
+ (m68k-tdep.o): Depends upon value_h and gdb_string.h
+ (m2-valprint.o): Depends upon m2-lang.h.
+ (sparc-tdep.o): Depends upon gdb_string.h
+ (valprint.o): Depends upon valprint.h
+
+ * remote-e7000.c (notice_quit): Remove prototype.
+ * top.c (initialize_targets): Remove prototype, now in target.h.
+ * stabsread.c (resolve_cfront_continuation): Remove prototype.
+ * dbxread.c (resolve_cfront_continuation): Remove prototype.
+ * symfile.h (set_demangling_style): Remove prototype.
+ * config/tm-sysv4.h (in_plt_section): Remove prototype, in objfiles.h.
+ * config/sparc/tm-sparc.h (single_step): Remove extern decl, now in
+ target.h.
+ * config/arc/tm-arc.h (one_stepped, single_step): Remove extern decls,
+ now in target.h.
+ * ser-unix.c (hardwire_restore): Remove obsolete prototype.
+ * sparc-tdep.c (single_step): Remove forward decl of isbranch.
+ * scm-lang.c (find_function_in_inferior): Remove prototype.
+ (value_allocate_space_in_inferior): Ditto.
+ * infrun.c (write_pc_pid): Remove prototype, now in inferior.h.
+ * defs.h (strchr): Remove declarations, they are declared in
+ gdb_string.h also.
+ (strrchr): Ditto.
+ (strstr): Ditto.
+ (strtok): Ditto.
+ (strerror): Ditto.
+ * f-valprint.c (f77_print_array_1): Remove extra arg that was being
+ passed to f77_print_array_1.
+ * gdbtypes.c (add_name): Remove unused variables lenstrlen and lenstr.
+ * scm-exp.c (scm_istr2int): Remove unused variable "j".
+ (scm_parse): Remove unused variable "str".
+ * hp300ux-nat.c (store_inferior_register): Remove unused variable
+ "buf".
+ (store_inferior_registers): Remove unnecessary decl "registers".
+ * m68k-tdep.c (m68k_pop_frame): Remove unused variable "fi".
+ * scm-lang.c (scm_get_field): Remove unused variable "val".
+ (scm_lookup_name): Remove unused variable "symval".
+ * objfiles.c (map_to_file): Remove unused local variable "tempfd".
+ * procfs.c (do_attach, do_detach): Remove unused variable "result".
+ (last_resume_pid): Remove unused static variable.
+ * alpha-tdep.c (alpha_linux_sigtramp_offset): Remove unused variable
+ "res".
+ * objfiles.c (map_to_address): Remove unused function.
+ * f-valprint.c (print_max): Remove extraneous extern decl,
+ in valprint.h.
+ (calc_f77_array_dims): Remove extraneous prototype, in f-lang.h.
+ * ch-exp.c (write_lower_upper_value): Remove prototype for
+ type_lower_upper.
+
+ * gdbtypes.c (cfront_mangle_name): #ifdef out unused function.
+ * ch-exp.c (parse_mode_call): Ditto.
+ * f-valprint.c (there_is_a_visible_common_named): Ditto.
+ * f-lang.c (clear_function_list): Ditto.
+ (get_bf_for_fcn): Ditto.
+ (clear_bf_list): Ditto.
+ (add_common_block): Ditto.
+ (patch_all_commons_by_name): Ditto.
+ (find_first_common_named): Ditto.
+ (add_common_entry): Ditto.
+ (allocate_saved_function_node): Ditto.
+ (allocate_saved_bf_node): Ditto.
+ (allocate_common_entry_node): Ditto.
+ (allocate_saved_f77_common_node): Ditto.
+
+ * arm-tdep.c (gdbcore.h): Include for necessary prototypes.
+ * dcache.c (gdbcore.h): Ditto.
+ * i386ly-tdep.c (gdbcore.h): Ditto.
+ * i960-tdep.c (gdbcore.h): Ditto.
+ * m2-valprint.c (m2-lang.h): Ditto.
+ * m68k-tdep.c (gdbcore.h): Ditto.
+ (value.h): Ditto.
+ (gdb_string.h): Ditto.
+ * nindy-tdep.c (gdbcore.h): Ditto.
+ * scm-lang.c (gdbcore.h): Ditto.
+ * scm-valprint.c (gdbcore.h): Ditto.
+ * w65-tdep.c (gdbcore.h): Ditto.
+ * z8k-tdep.c (gdbcore.h): Ditto.
+ * sparc-tdep.c (gdb_string.h): Include.
+ * valprint.c (valprint.h): Include.
+
+ * config/xm-lynx.h: Remove part of comment about INT_MIN
+ redefined warnings from defs.h, since INT_MIN define in
+ defs.h is now protected by #ifndef INT_MIN.
+ * config/i386/xm-i386bsd.h: Ditto.
+ * config/m68k/xm-hp300bsd.h: Ditto.
+ * config/m68k/xm-news.h: Ditto.
+
+ * config/pa/xm-hppah.h (INT_MIN): Remove bogus INT_MIN
+ definition as 0x80000000. The macro in defs.h is better.
+ * config/i386/xm-i386m3.h (INT_MIN): Ditto.
+ * config/i386/xm-i386mach.h (INT_MIN): Ditto.
+ * config/ns32k/xm-ns32km3.h (INT_MIN): Ditto.
+ * config/pa/xm-hppab.h: Ditto.
+
+ * core-aout.c (fetch_core_registers): Add prototype.
+ * hp300ux-nat.c (fetch_inferior_register): Ditto.
+ (store_inferior_register_1): Ditto.
+ (store_inferior_register): Ditto.
+ * config/m68k/tm-m68k.h (find_saved_regs): Ditto.
+ *scm-valprint.c (c_val_print): Ditto.
+ * procfs.c (add_fd): Ditto.
+ (remove_fd): Ditto.
+ (wait_fd): Ditto.
+ (sigcodename): Ditto.
+ (sigcodedesc): Ditto.
+ (procfs_kill_inferior): Ditto.
+ (procfs_xfer_memory): Ditto.
+ (procfs_store_registers): Ditto.
+ (create_procinfo): Ditto.
+ (procfs_init_inferior): Ditto.
+ (proc_set_exec_trap): Ditto.
+ (procfs_attach): Ditto.
+ (procfs_detach): Ditto.
+ (procfs_prepare_to_store): Ditto.
+ (procfs_files_info): Ditto.
+ (procfs_open): Ditto.
+ (procfs_wait): Ditto.
+ (procfs_fetch_registers): Ditto.
+ (procfs_mourn_inferior): Ditto.
+ (procfs_can_run): Ditto.
+ (procfs_thread_alive): Ditto.
+ (procfs_stop): Ditto.
+ * alpha-nat.c (fetch_core_registers): Ditto.
+ * config/alpha/tm-alpha.h (alpha_osf_skip_sigtramp_frame): Ditto.
+ * objfiles.c (ecoff_relocate_efi): Ditto.
+ * inflow.c (pass_signal): Ditto.
+ (handle_sigio): Ditto.
+ * annotate.c (breakpoint_changed): Ditto.
+ * callback.c (wrap): Ditto.
+ (fdbad): Ditto.
+ (fdmap): Ditto.
+ * utils.c (malloc_botch): Ditto.
+ (fputs_maybe_filtered): Ditto.
+ (vfprintf_maybe_filtered): Ditto.
+ * defs.h (notice_quit): Ditto.
+ * defs.h (xmalloc, xrealloc): Ditto.
+ * top.c (stop_sig): Ditto.
+ (init_signals): Ditto.
+ (user_defined_command): Ditto.
+ (source_cleanup_lines): Ditto.
+ (dont_repeat_command): Ditto.
+ (serial_log_command): Ditto.
+ (disconnect): Ditto.
+ * target.h (initialize_targets): Ditto.
+ * os9kread.c (read_minimal_symbols): Ditto.
+ * mdebugread.c (mdebug_psymtab_to_symtab): Ditto.
+ (fdr_name): Ditto.
+ (push_parse_stack): Ditto.
+ (pop_parse_stack): Ditto.
+ (is_pending_symbol): Ditto.
+ (add_pending): Ditto.
+ * serial.c (serial_logchar): Ditto.
+ (serial_interface_lookup): Ditto.
+ * serial.h (serial_log_command): Ditto.
+ * f-valprint.c (info_common_command): Ditto.
+ * gdbtypes.h (print_type_scalar): Ditto.
+ * scm-valprint.c (scm_scmlist_print): Ditto.
+ (scm_ipruk): Ditto.
+ * scm-lang.c (scm_printstr): Ditto.
+ (in_eval_c): Ditto.
+ (evaluate_subexp_scm): Ditto.
+ * scm-exp.c (scm_read_token): Ditto.
+ (scm_skip_ws): Ditto.
+ (scm_lreadparen): Ditto.
+ * m2-lang.c (emit_char): Ditto.
+ (m2_printchar): Ditto.
+ (m2_printstr): Ditto.
+ (m2_create_fundamental_type): Ditto.
+ * f-lang.c (emit_char): Ditto.
+ (f_printchar): Ditto.
+ (f_printstr): Ditto.
+ (f_create_fundamental_type): Ditto.
+ * ch-lang.c (chill_printchar): Ditto.
+ (chill_printstr): Ditto.
+ (chill_create_fundamental_type): Ditto.
+ (value_chill_length): Ditto.
+ (value_chill_card): Ditto.
+ (value_chill_max_min): Ditto.
+ (evaluate_subexp_chill): Ditto.
+ * ch-exp.c (PEEK_TOKEN): Ditto.
+ (peek_token_): Ditto.
+ (forward_token_): Ditto.
+ (parse_case_label): Ditto.
+ (parse_opt_untyped_expr): Ditto.
+ (parse_unary_call): Ditto.
+ (parse_call): Ditto.
+ (parse_named_record_element): Ditto.
+ (parse_tuple_element): Ditto.
+ (parse_opt_element_list): Ditto.
+ (parse_tuple): Ditto.
+ (parse_primval): Ditto.
+ (parse_operand6): Ditto.
+ (parse_operand5): Ditto.
+ (parse_operand4): Ditto.
+ (parse_operand3): Ditto.
+ (parse_operand2): Ditto.
+ (parse_operand1): Ditto.
+ (parse_operand0): Ditto.
+ (parse_expr): Ditto.
+ (parse_then_alternative): Ditto.
+ (parse_else_alternative): Ditto.
+ (parse_if_expression): Ditto.
+ (parse_untyped_expr): Ditto.
+ (growbuf_by_size): Ditto.
+ (match_simple_name_string): Ditto.
+ (decode_integer_value): Ditto.
+ (decode_integer_literal): Ditto.
+ (match_float_literal): Ditto.
+ (match_float_literal): Ditto.
+ (match_string_literal): Ditto.
+ (match_character_literal): Ditto.
+ (match_integer_literal): Ditto.
+ (match_bitstring_literal): Ditto.
+ (write_lower_upper_value): Ditto.
+ * ch-lang.h (type_lower_upper): Ditto.
+ * c-lang.c (emit_char): Ditto.
+ * dwarfread.c (free_utypes): Ditto.
+ * stabsread.h (resolve_cfront_continuation): Ditto.
+ * stabsread.c (get_substring): Ditto.
+ (read_one_struct_field): Ditto.
+ * stabsread.h (process_later): Ditto.
+ * demangle.c (set_demangling_command): Ditto.
+ * defs.h (set_demangling_style): Ditto.
+ * maint.c (maintenance_info_command): Ditto.
+ (print_section_table): Ditto.
+ (maintenance_info_sections): Ditto.
+ (maintenance_print_command): Ditto.
+ * symtab.h (maintenance_print_statistics): Ditto.
+ * objfiles.h (in_plt_section): Ditto.
+ * objfiles.c (add_to_objfile_sections): Ditto.
+ * bcache.c (hash): Ditto.
+ (lookup_cache): Ditto.
+ * exec.c (bfdsec_to_vmap): Ditto.
+ (ignore): Ditto.
+ * f-exp.y (growbuf_by_size, match_string_literal): Ditto.
+ * language.c (unk_lang_printchar): Ditto.
+ (unk_lang_printstr): Ditto.
+ (unk_lang_create_fundamental_type): Ditto.
+ (unk_lang_print_type): Ditto.
+ (unk_lang_val_print): Ditto.
+ (unk_lang_value_print): Ditto.
+ * target.c (update_current_target): Ditto.
+ (debug_to_open): Ditto.
+ (debug_to_close): Ditto.
+ (debug_to_attach): Ditto.
+ (debug_to_detach): Ditto.
+ (debug_to_resume): Ditto.
+ (debug_to_wait): Ditto.
+ (debug_to_fetch_registers): Ditto.
+ (debug_to_store_registers): Ditto.
+ (debug_to_prepare_to_store): Ditto.
+ (debug_to_xfer_memory): Ditto.
+ (debug_to_files_info): Ditto.
+ (debug_to_insert_breakpoint): Ditto.
+ (debug_to_remove_breakpoint): Ditto.
+ (debug_to_terminal_init): Ditto.
+ (debug_to_terminal_inferior): Ditto.
+ (debug_to_terminal_ours_for_output): Ditto.
+ (debug_to_terminal_ours): Ditto.
+ (debug_to_terminal_info): Ditto.
+ (debug_to_kill): Ditto.
+ (debug_to_load): Ditto.
+ (debug_to_lookup_symbol): Ditto.
+ (debug_to_create_inferior): Ditto.
+ (debug_to_mourn_inferior): Ditto.
+ (debug_to_can_run): Ditto.
+ (debug_to_notice_signals): Ditto.
+ (debug_to_thread_alive): Ditto.
+ (debug_to_stop): Ditto.
+ * breakpoint.h (set_breakpoint_sal): Ditto.
+ * remote-utils.c (usage): Ditto.
+ * remote.c (set_thread): Ditto.
+ (remote_thread_alive): Ditto.
+ (get_offsets): Ditto.
+ (read_frame): Ditto.
+ (remote_insert_breakpoint): Ditto.
+ (remote_remove_breakpoint): Ditto.
+ * sparc-nat.c (fetch_core_registers): Ditto.
+ * corelow.c (add_to_thread_list): Ditto.
+ (ignore): Ditto.
+ * inftarg.c (proc_wait): Ditto.
+ * infptrace.c (udot_info): Ditto.
+ (fetch_register): Ditto.
+ * ser-unix.c (hardwire_noflush_set_tty_state): Ditto.
+ (hardwire_print_tty_state): Ditto.
+ (hardwire_flush_output): Ditto.
+ (hardwire_flush_input): Ditto.
+ (hardwire_send_break): Ditto.
+ (hardwire_setstopbits): Ditto.
+ * ser-tcp.c (tcp_return_0): Ditto.
+ (tcp_noflush_set_tty_state): Ditto.
+ (tcp_print_tty_state): Ditto.
+ * solib.c (match_main): Ditto.
+ * gdbtypes.c (print_bit_vector): Ditto.
+ (print_arg_types): Ditto.
+ (dump_fn_fieldlists): Ditto.
+ (print_cplus_stuff): Ditto.
+ * symfile.h (entry_point_address): Ditto.
+ * symfile.c (decrement_reading_symtab): Ditto.
+ * valops.c (value_arg_coerce): Ditto.
+ * value.h (find_function_in_inferior): Ditto.
+ (value_allocate_space_in_inferior): Ditto.
+ * values.c (vb_match): Ditto.
+ * thread.c (info_thread_command): Ditto.
+ (restore_current_thread): Ditto.
+ (thread_apply_all_command): Ditto.
+ (thread_apply_command): Ditto.
+ * inferior.h (write_pc_pid): Ditto.
+ * infrun.c (delete_breakpoint_current_contents): Ditto.
+ * breakpoint.c (print_it_normal): Ditto.
+ (watchpoint_check): Ditto.
+ (print_it_done): Ditto.
+ (print_it_noop): Ditto.
+ (maintenance_info_breakpoints): Ditto.
+ (create_longjmp_breakpoint): Ditto.
+ (hbreak_command): Ditto.
+ (thbreak_command): Ditto.
+ (watch_commnd_1): Ditto.
+ (rwatch_command): Ditto.
+ (awatch_command): Ditto.
+ (do_enable_breakpoint): Ditto.
+ * ch-valprint.c (chill_val_print_array_elements): Ditto.
+ * eval.c (evaluate_subexp): Ditto.
+ (get_label): Ditto.
+ (evaluate_struct_tuple): Ditto.
+ * eval.c (init_array_element): Ditto.
+
+ * alpha-tdep.c (push_sigtramp_desc): Add prototype and make static.
+ * breakpoint.c (hw_breakpoint_used_count): Ditto.
+ (hw_watchpoint_used_count): Ditto.
+ * findvar.c (write_register_gen): Ditto.
+ (read_register_pid): Ditto.
+ * symtab.c (cplusplus_hint): Ditto.
+ * infcmd.c (breakpoint_auto_delete_contents): Ditto.
+ * ch-valprint.c (chill_print_type_scalar): Ditto.
+ * gdbtypes.c (add_name): Ditto.
+ (add_mangled_type): Ditto.
+ (cfront_mangle_name): Ditto.
+ * sparc-tdep.c (isbranch): Ditto.
+ * inftarg.c (child_stop): Ditto.
+ * win32-nat.c (child_stop): Ditto.
+ * mac-nat.c (child_stop): Ditto.
+ * remote-utils.c (sr_com): Ditto.
+ * dbxread.c (process_now): Ditto.
+ * ch-exp.c (require): Ditto.
+ (check_token): Ditto.
+ (expect): Ditto.
+ (parse_mode_call): Ditto.
+ (parse_mode_or_normal_call): Ditto.
+ * scm-lang.c (scm_lookup_name): Ditto
+ * f-lang.c (allocate_saved_bf_node): Ditto.
+ (allocate_saved_function_node): Ditto.
+ (allocate_saved_f77_common_node): Ditto.
+ (allocate_common_entry_node): Ditto.
+ (add_common_block): Ditto.
+ (add_common_entry): Ditto.
+ (find_first_common_named): Ditto.
+ (patch_common_entries): Ditto.
+ (patch_all_commons_by_name): Ditto.
+ (clear_bf_list): Ditto.
+ (get_bf_for_fcn): Ditto.
+ (clear_function_list): Ditto.
+ * scm-exp.c (scm_istr2int): Ditto.
+ (scm_istring2number): Ditto.
+ * scm-valprint.c (scm_inferior_print): Ditto.
+ * f-typeprint.c (print_equivalent_f77_float_type): Ditto.
+ * f-valprint.c (f77_get_dynamic_length_of_aggregate): Ditto.
+ (f77_create_arrayprint_offset_tbl): Ditto.
+ (f77_print_array_1): Ditto.
+ (f77_print_array): Ditto.
+ (list_all_visible_commons): Ditto.
+ (there_is_a_visible_common_named): Ditto.
+ * mdebugread.c (ecoff_relocate_efi): Ditto.
+ * callback.c (os_close): Ditto.
+ (os_get_errno): Ditto.
+ (os_isatty): Ditto.
+ (os_lseek): Ditto.
+ (os_open): Ditto.
+ (os_read): Ditto.
+ (os_read_stdin): Ditto.
+ (os_write): Ditto.
+ (os_write_stdout): Ditto.
+ (os_rename): Ditto.
+ (os_system): Ditto.
+ (os_time): Ditto.
+ (os_unlink): Ditto.
+ (os_shutdown): Ditto.
+ (os_init): Ditto.
+ (os_printf_filtered): Ditto.
+
+ * scm-lang.h (scm_parse): Change old style decl to prototype.
+ * config/alpha/tm-alphalinux.h (alpha_linux_sigtramp_offset): Ditto.
+ * top.c (init_proc): Ditto.
+ (query_hook): Ditto.
+ (error_hook): Ditto.
+ * f-lang.c (c_value_print): Ditto.
+ * ch-exp.c (parse_expression): Ditto.
+ (parse_primval): Ditto.
+ (parse_untyped_expr): Ditto.
+ (parse_opt_untyped_expr): Ditto.
+ (ch_lex): Ditto.
+ * config/sparc/tm-sparc.h (sparc_init_extra_frame_info): Ditto.
+ (sparc_frame_saved_pc): Ditto.
+ (sparc_push_dummy_frame): Ditto.
+ (sparc_pop_frame): Ditto.
+ * defs.h (fclose): Ditto.
+ (atof): Ditto.
+ (error_hook): Ditto.
+
+ * arc-tdep.c (single_step): Change arg to type "enum target_signal".
+ * rs6000-tdep.c (single_step): Ditto.
+ * sparc-tdep.c (single_step): Ditto.
+
+ * breakpoint.c (cleanup_executing_breakpoints): Change unused arg type
+ to PTR which is what make_cleanup expects.
+ * utils.c (null_cleanup): Change arg type to PTR.
+ * defs.h (null_cleanup): Change prototype to match actual function.
+ * config/sparc/tm-sparc.h (struct frame_info): Move forward decl.
+ * ch-valprint.c (chill_val_print): Cast 2nd arg of
+ chill_print_type_scalar to LONGEST.
+ * infrun.c (wait_for_inferior): Have empty switch case for
+ BPSTAT_WHAT_CHECK_SHLIBS when SOLIB_ADD is not defined.
+ (stop_on_solib_events): Only needed if SOLIB_ADD is defined.
+ * infcmd.c (attach_command): Only need auto_solib_add if SOLIB_ADD
+ is defined.
+ * symfile.c (generic_load): Scan long int using a long int spec,
+ not an int spec.
+ * infptrace.c (udot_info): Only need local variables if KERNEL_U_SIZE
+ is defined.
+ (fetch_register): Only need function if FETCH_INFERIOR_REGISTERS is
+ not defined.
+ * inflow.c (handle_sigio): Only need prototype when the actual
+ function is compiled in.
+ * valprint.c (longest_to_int): Expand error message to be
+ separate messages for args larger than largest signed int
+ and args smaller than smallest signed int.
+ * valprint.c (print_longest): Fix problems with support for case
+ where compiler supports type "long long" but the runtime doesn't
+ support printing them with "%ll".
+ * scm-valprint.c (scm_scmlist_print, scm_scmval_print): Change
+ return types to void since we don't actually return anything
+ meaningful and callees ignore the values anyway.
+ * procfs.c (modify_inherit_on_fork_flag): Enclose pr_flags in PIOCSET
+ ifdef.
+ (modify_run_on_last_close_flag): Ditto.
+ (wait_fd): Enclose local variables "num_fds" and "i" LOSING_POLL
+ ifdef
+ * alpha-tdep.c (push_sigtramp_desc): Return proc_desc rather than
+ random value.
+ * infrun.c (wait_for_inferior): Ensure random_signal is not used
+ uninitialized.
+ * valops.c (call_function_by_hand): Ensure struct_addr is not used
+ uninitialized.
+ * breakpoint.c (watch_command_1): Ensure prev_frame is not used
+ uninitialized.
+ * utils.c (vfprintf_maybe_filtered): Change second arg from "char *"
+ to "const char *".
+ * infptrace.c (udot_info): Add two dummy args so that the type is
+ correct for passing to add_info.
+ * f-lang.c (saved_fcn): Move decl to head of file so it can be used
+ in prototypes.
+ (saved_bf_symnum): Ditto.
+ (SAVED_FUNCTION): Ditto.
+ (SAVED_FUNCTION_PTR): Ditto.
+ (SAVED_BF): Ditto.
+ (SAVED_BF_PTR): Ditto.
+ * ch-exp.c (parse_named_record_element): Build error message in
+ temporary buffer before passing it to expect, rather than passing
+ wrong number of args to expect.
+ * demangle.c (set_demangling_style): Call set_demangling_command with
+ correct number of arguments.
+ * inferior.h (terminal_init_inferior_with_pgrp): Change arg type to
+ int to match actual function.
+ (os_isatty): Call fdmap with right number of arguments, was missing
+ the host_callback* arg.
+ * target.c (cleanup_target): Prototype all functions casts.
+ * target.h (one_stepped, single_step): Declare here and convert
+ single_step to prototype.
+ * infrun.c (one_stepped, single_step): Don't declare externs
+ here, they have moved to target.h.
+ * eval.c (init_array_element): Declare previously undeclared
+ last two args as LONGEST.
+ * dcache.c (dcache_xfer_memory): Change xfunc decls to prototype form.
+
+Thu Jul 25 16:11:54 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * dsrec.c (load_srec): Protect ANSI style function parms with PARAMS.
+
+Mon Jul 22 18:13:27 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (os9kread.o): Remove dependency on partial-stab.h.
+ * dbxread.c (read_dbx_symtab end_psymtab), partial-stab.h: Don't
+ use partial_symtab->textlow==0 as a flag, as 0 is a legitimate
+ text address. Use a seperate flag (textlow_not_set) instead.
+ This makes stabs in ELF .o files work a lot better.
+ * mdebugread.c xcoffread.c: Define textlow_not_set for
+ partial-stab.h.
+ * stabsread.h (end_psymtab): Add textlow_not_set arg to prototype.
+
+Sat Jul 20 10:41:06 1996 Fred Fish <fnf@cygnus.com>
+
+ * dwarf2read.c (struct filenames): Change internal "struct file"
+ to "struct fileinfo" to avoid conflict with "struct file" in
+ <sys/file.h> on HPUX and Solaris.
+
+Fri Jul 19 14:05:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dwarf2read.c: New file, DWARF 2 reader originally contributed by
+ Brent Benson, with additions by Gary Funck and Jerry Kreuscher.
+ * Makefile.in (COMMON_OBS): Add dwarf2read.o.
+ (SFILES): Add dwarf2read.c.
+ (dwarf2read.o): Add build rule.
+ * symfile.h (dwarf2_has_info, dwarf2_build_psymtabs): Declare
+ exported functions.
+ * elfread.c (elf_symfile_read): Call them.
+ (elf_symtab_read) [HARRIS_TARGET]: Skip some special symbols.
+
+Thu Jul 18 01:22:01 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * symfile.c (symfile_bfd_open):
+ * exec.c (exec_file_command): for __GO32__ and __WIN32__ systems,
+ free the user from having to type the .exe extension.
+
+Wed Jul 17 06:54:50 1996 Mark Alexander <marka@cygnus.com>
+
+ * mon960-rom.c: Shorten the mon960_inits string to a single
+ carriage return; this prevents a hang on connecting immediately
+ after powerup, when MON960 is attempting autobaud detection.
+
+Tue Jul 16 23:47:04 1996 Mark Alexander <marka@cygnus.com>
+
+ * a29k-tdep.c (get_saved_register): Allow PC to be modified
+ when innermost frame is selected, but not in outer frames.
+
+Tue Jul 16 23:37:25 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * command.c (do_setshow_command): Don't segfault when showing
+ var_string and var_string_noescape vars that are NULL.
+
+Mon Jul 15 16:55:48 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * win32-nat.c (handle_load_dll): dos_path_to_unix_path renamed to
+ cygwin32_conv_to_posix_path.
+ (child_create_inferior): unix_path_to_dos_path renamed to
+ cygwin32_conv_to_win32_path. Rewrite code to translate PATH.
+
+Mon Jul 15 16:44:05 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h printcmd.c: Create global disassemble_info structure
+ tm_print_insn_info.
+ * i386-tdep.c (set_assembly_language_command): set
+ tm_print_insn_info.mach to the appropriate value for 386 or 8086
+ disassembly.
+ * printcmd.c (print_insn): Move init of disassembler_info to
+ _initialize_printcmd. Set endian for disassembler here.
+ * sparc-tdep.c: Set tm_print_insn_info.mach as appropriate to
+ select sparc/sparclite.
+ * config/sparc/{tm-sparc.h tm-sparclite.h}: Get rid of
+ TM_PRINT_INSN. Set TM_PRINT_INSN_MACH to
+ bfd_mach_sparc/bfd_mach_sparc_sparclite.
+
+Fri Jul 12 19:04:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * hpread.c (hpread_lookup_type): Use xmmalloc/xmrealloc rather
+ than xmalloc/xrealloc.
+
+Fri Jul 12 17:59:47 1996 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.c (map_to_file): Error return from mmalloc_findbase is
+ a NULL pointer, not a -1.
+
+Fri Jul 12 10:16:24 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * i386-tdep.c (set_assembly_language_command): New routine to
+ select between i386 and i8086 instruction sets for disassembly.
+ New command `set assembly-language {i386 i8086}'.
+
+Thu Jul 11 21:13:21 1996 Mark Alexander <marka@cygnus.com>
+
+ * monitor.c (monitor_write_memory, monitor_read_memory_single):
+ Disable use of "long long" memory read/write commands; can't
+ use them because we hold the values to read/write in an int
+ variable, and because strtoul fails on values that exceed the
+ size of a long. This fixes breakpoint problems on MON960.
+
+Thu Jul 11 11:39:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/m68k/xm-hp300hpux.h (HAVE_MMAP): Remove definition.
+ * config/pa/xm-hppah.h (HAVE_MMAP): Ditto.
+
+Wed Jul 10 16:54:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (MMALLOC_CFLAGS): Eliminate intermediate MMALLOC_DISABLE
+ and MMALLOC_CHECK macros, and add comment indicating how host dependent
+ makefile fragment should modify MMALLOC_CFLAGS to not use mmalloc, or
+ to use it but to not do heap corruption checking.
+ * gdbserver/Makefile.in: Ditto.
+ * utils.c (init_malloc): Replace warning() use with direct call of
+ fprintf_unfiltered, since current_target has not yet been set and thus
+ we cannot use warning(). If we try to use mmcheck and it fails,
+ suggest that this configuration needs NO_MMCHECK or MMCHECK_FORCE
+ defined. Other small mmalloc related cleanups.
+ * config/sparc/sun4os4.mh (MMALLOC_CFLAGS): Define MMCHECK_FORCE to 1.
+ * config/alpha/alpha-osf2.mh (MMALLOC_CFLAGS): Set to -DNO_MMCHECK.
+
+ * config/sparc/xm-sun4os4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/i386/xm-i386v4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/m68k/xm-hp300hpux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/m68k/xm-m68kv4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT);
+ * config/m68k/xm-sun3os4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/pa/xm-hppah.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/sparc/xm-sun4sol2.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ Remove obsolete defines.
+
+ * config/alpha/alpha-linux.mh (MMALLOC_DISABLE):
+ * config/alpha/alpha-osf1.mh (MMALLOC_DISABLE):
+ * config/rs6000/rs6000.mh (MMALLOC_DISABLE):
+ * config/rs6000/aix4.mh (MMALLOC_DISABLE):
+ * config/powerpc/aix4.mh (MMALLOC_DISABLE):
+ * config/powerpc/aix.mh (MMALLOC_DISABLE):
+ * config/ns32k/ns32km3.mh (MMALLOC_DISABLE):
+ * config/mips/mipsm3.mh (MMALLOC_DISABLE):
+ * config/mips/decstation.mh (MMALLOC_DISABLE):
+ * config/m88k/cxux.mh (MMALLOC_DISABLE):
+ * config/i386/i386mk.mh (MMALLOC_DISABLE):
+ * config/i386/i386m3.mh (MMALLOC_DISABLE):
+ * config/i386/i386gnu.mh (MMALLOC_DISABLE):
+ Use MMALLOC_CFLAGS instead.
+
+Tue Jul 9 22:41:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300-tdep.c: Remove some outdated comments.
+ (h8300_skip_prologue): Rework to be more correct for the H8/300H.
+ Handle stm.l insns for the H8/S.
+ (examine_prologue): Likewise.
+
+Tue Jul 9 16:48:55 1996 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * ser-mac.c (mac_close): Change a typo SetSetBuf to SerSetBuf.
+
+Mon Jul 08 08:50:39 1996 Mark Alexander <marka@cygnus.com>
+
+ * mon960-rom.c (mon960_open): Add floating point detection to
+ prevent hang on non-FPU processors (PR 9775).
+ (mon960_cmds): Swap setmem.cmdw and setmem.cmdl to fix problem
+ setting breakpoints and improve loading speed.
+
+Sun Jul 7 14:57:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * coffread.c (record_minimal_symbol): Don't presave name string
+ on symbol_obstack before passing to prim_record_minimal_symbol.
+ It now handles saving the string itself.
+ * dbxread.c (read_dbx_dynamic_symtab): Ditto.
+ * mipsread.c (read_alphacoff_dynamic_symtab): Ditto.
+ * os9kread.c (record_minimal_symbol): Ditto.
+ * solib.c (solib_add_common_symbols): Ditto.
+
+ * coffread.c (coff_symtab_read): Don't presave name string on
+ symbol_obstack before passing to prim_record_minimal_symbol_and_info.
+ It now handles saving the string itself.
+ * dbxread.c (record_minimal_symbol): Ditto.
+ * elfread.c (record_minimal_symbol_and_info): Ditto.
+
+ * dstread.c (record_minimal_symbol): Remove static function that just
+ called prim_record_minimal_symbol with the same args (after change to
+ prim_record_minimal_symbol to do it's own name string saves).
+ * nlmread.c (record_minimal_symbol): Ditto.
+ * somread.c (record_minimal_symbol): Ditto.
+
+ * hpread.c (hpread_read_enum_type): Save symbol name on symbol obstack.
+ (hpread_read_function_type): Ditto.
+ (hpread_process_one_debug_symbol): Ditto.
+ * mdebugread.c (parse_symbol): Ditto.
+ (new_symbol): Ditto.
+ * minsyms.c (prim_record_minimal_symbol_and_info): Ditto.
+
+ * coffread.c (process_coff_symbol): Use obsavestring to save
+ SYMBOL_NAME, rather than obstack_copy0.
+ * dstread.c (create_new_symbol): Ditto
+ * symfile.c (obconcat): Ditto.
+ * stabsread.c (patch_block_stabs): Ditto.
+ * xcoffread.c (SYMNAME_ALLOC): Ditto.
+
+ * symfile.c (obsavestring): Update comments
+ * solib.c (solib_add_common_symbols): Remove local var origname.
+
+Wed Jul 3 15:56:08 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure: Re-build with autoconf-2.10.
+
+ * sparcl-tdep.c (_initialize_sparc_tdep) config/sparc/tm-sparc.h,
+ config/sparc/tm-sparclite.h: Initialize tm_print_insn from
+ TM_PRINT_INSN, which comes from the tm file.
+
+Tue Jul 02 21:41:20 1996 Mark Alexander <marka@cygnus.com>
+
+ * coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c,
+ os9kread.c: Replace identical sym_offsets functions with
+ default_symfile_offsets.
+ * somread.c (som_symfile_offsets): Use new SIZEOF_SECTION_OFFSETS
+ macro to allocate section_offsets.
+ * symfile.c (default_symfile_offsets): New function.
+ * symfile.h: Declare default_symfile_offsets.
+ * symtab.h: Define SIZEOF_SECTION_OFFSETS macro to
+ simplify allocation of section_offsets.
+
+Tue Jun 11 12:02:55 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (INTERNAL_LDFLAGS): Add in flags from configure.
+ * configure configure.in: Only make sol-thread.o for native.
+ Also, switch to dlopened libthread_db.so.1.
+ * sol-thread.c: Switch to using dlopen to get the thread_db
+ library.
+
+Thu Jun 13 16:53:25 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure, configure.in: Change test for libthread_db to only
+ work for configs where build/host/target are the same.
+
+Tue Jul 2 15:04:20 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/{linux.mh,xm-linux.h}: New files, for Linux on
+ PowerPC.
+
+ * configure.in (powerpc-*-linux): Add Linux, System V, and ELF
+ support.
+ * configure: Regenerate.
+
+Mon Jul 1 13:00:43 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Raymond Jou <rjou@mexican.cygnus.com>:
+ * mpw-make.sed: Add lines to whack out autoconf hook
+ @CONFIG_LDFLAGS@.
+
+Mon Jul 01 11:07:15 1996 Mark Alexander <marka@cygnus.com>
+
+ * remote-e7000.c (e7000_stop): New function.
+
+Fri Jun 28 06:34:19 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * configure, configure.in: Add target sparclet.
+ * monitor.h, monitor.c: Added monitor flags MO_NO_ECHO_ON_SETMEM
+ (don't expect echo on setmem command), MO_RUN_FIRST_TIME (if
+ command to start process running on target is different from one
+ to continue execution), MO_HEX_PREFIX (if addresses from monitor
+ have a "0x" prefix).
+ * monitor.c, parse.c, sparc-tdep.c: Don't require strings in the
+ registers array. This is to allow NULLs to be place holders in
+ the tm-*.h file so that only minor changes are needed when a new
+ processor is introduced (eg, one without floating point).
+ * sparc-tdep.c: Conditionally remove dependancies on floating
+ point.
+ * sparclet-rom.c, config/sparc/sparclet.mt,
+ config/sparc/tm-sparclet.h: New files for target sparclet.
+ * symfile.c (load_command): Add option for 2nd parameter; a load
+ offset added to the vma of each section.
+
+Fri Jun 28 05:39:19 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * main.c (main): Add option "l" for setting remote_timeout.
+
+Fri Jun 28 05:25:18 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-e7000.c, remote.c, target.h, top.c: Add set option
+ "remote_timeout" for setting remote_timeout. Add set option
+ "use_hard_breakpoints" for setting hardware .vs. memory
+ breakpoints.
+
+Fri Jun 28 04:32:18 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-e7000.c (e7000_parse_device): New function.
+ Add option "tcp_remote" to target command if using
+ tcp to connect to a remote host which is then connected
+ via serial port to the e7000 (for exampole, a port master).
+ (e7000_open): Change to call e7000_parse_device.
+
+Fri Jun 28 03:47:17 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * monitor.c (monitor_debug): Fix remotedebug buffering.
+
+Thu Jun 27 18:24:17 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/i386/cygwin32.mh, config/powerpc/cygwin32.mh
+ (NATDEPFILES): Add a space.
+
+Wed Jun 26 06:05:39 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * gdbtypes.c (create_array_type): If TYPE_LENGTH (result_type)
+ is zero, set TYPE_FLAG_TARGET_STUB to force reevaluation of the type.
+
+ * ch-exp.c (calculate_array_length): Function removed.
+
+Tue Jun 25 17:41:06 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * remote-e7000.c (e7000_read_inferior_memory_large): New function.
+ (e7000_xfer_inferior_memory): Call it.
+
+Tue Jun 25 23:14:07 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * gdb/gdbserver/Makefile.in (docdir): Removed.
+
+Tue Jun 25 22:05:38 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir):
+ Use autoconf set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * nlm/Makefile.in (bindir, libdir, datadir, mandir, infodir,
+ includedir): Use autoconf set values.
+ (docdir): Removed.
+ * nlm/configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * nlm/configure: Rebuilt.
+ * gdb/gdbserver/Makefile.in (datadir): Set to $(prefix)/share.
+
+Mon Jun 24 09:56:14 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * stabsread.c (read_cfront_member_functions): add type
+
+Sun Jun 23 23:40:48 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * win32-nat.c: #include <unistd.h>.
+ (unix_paths_to_dos_paths, dos_paths_to_unix_paths): Delete.
+ (child_create_inferior): Convert only env var PATH to win32 style.
+ (set_pathstyle_dos): Delete.
+ (_initialize_inftarg): Delete dos-path-style command.
+
+Thu Jun 20 13:42:23 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in: Revise sol-thread.o test.
+ * configure: Regenerated.
+
+ * source.c (find_source_lines): Reassign size to result of read.
+
+Tue Jun 18 16:25:54 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * h8300-dep.c (gdb_print_insn_h8300): Handle the H8/S.
+ (h8300_command): Likewise.
+ (set_machine): Likewise.
+ (set_machine_hook): Likewise.
+ (_initialize_h8300m): Likewise.
+
+ * config/h8300/tm-h8300.h (h8300smode): Declare.
+
+Sun Jun 16 15:21:51 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * somsolib.c (som_solib_create_inferior_hook): Handle tracking
+ of shl_load calls for hpux10.
+
+Thu Jun 13 11:16:10 1996 Tom Tromey <tromey@thepub.cygnus.com>
+
+ * config.in: Regenerated.
+ * acconfig.h (HAVE_THREAD_DB_LIB): Added entry.
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH, CY_AC_PATH_TKH): Use odd names to
+ avoid name clashes with SunOS headers.
+
+Tue Jun 11 19:52:50 1996 Fred Fish <fnf@cygnus.com>
+
+ From Michael Snyder <Michael_Snyder@next.com>:
+ * bcache.c (print_bcache_statistics): Avoid divide-by-zero
+ exception if one or more objfile has no symbols, such as when
+ a dynamic library has been stripped.
+
+Tue Jun 11 12:02:55 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (INTERNAL_LDFLAGS): Add in flags from configure.
+ * configure configure.in: Only make sol-thread.o for native.
+ Also, switch to dlopened libthread_db.so.1.
+ * sol-thread.c: Switch to using dlopen to get the thread_db
+ library.
+
+Mon Jun 10 14:17:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/sparc/{xm-sun4sol2.h,xm-sun4os4.h} (MMAP_BASE_ADDRESS):
+ Change from 0xE0000000 to 0xC0000000.
+
+Thu Jun 6 17:10:32 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/xm-solaris.h: Initial version of support for
+ Solaris on PowerPC.
+
+Wed Jun 5 01:52:57 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * configure.in (configdirs): Force 4100 builds to use 4300 GDB
+ target.
+ * configure: Rebuild.
+
+ * config/mips/vr4300el.mt (SIM_OBS): Include simulator in
+ little-endian builds.
+
+Mon Jun 3 11:48:29 1996 Jeffrey A Law (law@cygnus.com)
+
+ * inftarg.c (child_thread_alive): Protect declaration with
+ #ifndef CHILD_THREAD_ALIVE.
+
+ * source.c (find_source_lines): Check the time on the symtab's bfd if
+ it exists, else check the time on the exec_bfd.
+
+Thu May 30 09:43:17 1996 Mark Alexander <marka@cygnus.com>
+
+ * dsrec.c (make_srec): Fix calculation of address size
+ to allow addresses less than 0x100.
+
+Thu May 30 04:24:09 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (ch_lex): In case of LOC_TYPEDEF call calculate_array_length.
+
+Tue May 28 16:15:47 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * remote-mips.c: cannot use EINVAL for breakpoint test since
+ its value varies for different hosts (e.g. go32's is 19, while
+ sunos is 22). Changed to hardcoded 22 since that is what the
+ mips boards return.
+
+Tue May 28 11:14:58 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH): Don't use AC_TRY_RUN.
+ (CY_AC_PATH_TKH): Don't use AC_TRY_RUN.
+
+Sun May 26 16:56:35 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * solib.c (solib_absolute_prefix, solib_search_path): New variables.
+ (_initialize_solib): Add set/show commands for those variables.
+ (solib_map_sections): Implement searching using them.
+
+Sun May 26 14:14:49 1996 Fred Fish <fnf@cygnus.com>
+
+ Changes from: David Mosberger-Tang <davidm@azstarnet.com>
+
+ * NEWS: Add Alpha Linux as a new native configuration.
+
+ * mdebugread.c (parse_symbol): When we find a malloc() symbol with
+ return type VOID, assume no debugging info is available for that
+ object file and patch the return value into VOID *. Otherwise,
+ operations requiring an implicit call to malloc() will fail.
+
+ * infrun.c (wait_for_inferior): The criterion to detect entering a
+ sigtramp handler is now: (a) the current pc is inside a sigtramp
+ handler, (b) the previous pc is not in a sigtramp handler, and (c)
+ the current stack pointer is "inner" than the old one. Condition
+ (c) is new to avoid mistaking a return from a signal handler into
+ sigtramp as a new sigtramp invocation.
+
+ * dcache.c (struct dcache_block): Declare addr as CORE_ADDR. An
+ int may not be big enough to hold an address.
+ (dcache_hit): Ditto.
+ (dcache_peek_byte): Fix indentation.
+
+ * configure.in (alpha-*-linux*): Add target.
+ * configure: Rebuild
+
+ * config/alpha/tm-alpha.h (PROC_DESC_IS_DYN_SIGTRAMP): New macro.
+ (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+ (DYNAMIC_SIGTRAMP_OFFSET): Ditto.
+ (SIGCONTEXT_ADDR): Ditto.
+ (FRAME_PAST_SIGTRAMP_FRAME): Ditto.
+
+ * config/alpha/alpha-linux.mh: New file.
+ * config/alpha/alpha-linux.mt: Ditto.
+ * config/alpha/nm-linux.h: Ditto.
+ * config/alpha/tm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphaosf.h: Renamed from xm-alpha.h.
+ * config/alpha/alpha-osf1.mh (XM_FILE): Change from xm-alpha.h to
+ xm-alphaosf.h.
+ * config/alpha/alpha-osf2.mh: Ditto.
+
+ * blockframe.c (find_pc_partial_function): Pass PC to
+ SIGTRAMP_START and SIGTRAMP_END macros for the benefit of systems
+ that detect sigtramp code via designated code sequences (as is the
+ case for Linux/Alpha, for example).
+
+ * config/i386/tm-i386bsd.h: Change SIGTRAMP_START and SIGTRAMP_END
+ to ignore new PC argument.
+ * config/m68k/tm-hp300bsd.h: Ditto.
+ * config/vax/tm-vax.h: Ditto.
+
+ * alpha-tdep.c (alpha_linux_sigtramp_offset): New function.
+ (alpha_osf_skip_sigtramp_frame): Ditto.
+ (push_sigtramp_desc): Ditto.
+ (alpha_find_saved_regs): Use SIGCONTEXT_ADDR macro to extract
+ sigcontext address from frame.
+ (alpha_saved_pc_after_call): When in sigtramp, use
+ alpha_frame_saved_pc() instead of read-register().
+ (after_prologue): When inside a dynamically generated sigtramp
+ function, there is no prologue, so return address of first
+ instruction.
+ (alpha_in_prologue): Fix typo in comment.
+ (find_proc_desc): Use macro DYNAMIC_SIGTRAMP_OFFSET to determine
+ whether we're inside a dynamicaly generated sigtramp function. If
+ so, create and push and appropriate procedure descriptor.
+ (alpha_frame_chain): Use macro FRAME_PAST_SIGTRAMP_FRAME to obtain
+ the frame past a sigtramp frame (if the current frame is indeed a
+ sigtramp function).
+ (init_extra_frame_info): Don't read next frame register off of
+ stack-pointer when inside a dynamiccaly generated sigtramp.
+ (alpha_pop_frame): Also unlink and destroy procedure descriptors
+ created for dynamically generated sigtramp functions.
+
+ * alpha-nat.c: When compiling under Linux, include <asm/reg.h> and
+ <alpha/ptrace.h> instead of <machine/reg.h>
+
+Tue Jul 2 13:58:10 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_task_sc):
+ Give terminal to gdb while asking question.
+ (inf_resume): Don't validate the task suspend-count while execing.
+
+Thu Jun 13 11:04:52 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_task_sc): Query user before clearing any
+ additional suspend count.
+ (S_proc_wait_reply, gnu_attach): Don't call inf_validate_task_sc.
+ (inf_resume): Call inf_validate_task_sc here.
+ (gnu_resume): Call inf_update_procs to ensure noticing new threads.
+
+Fri Jun 7 17:00:43 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_create_inferior: attach_to_child): Return PID.
+
+Thu May 23 15:13:56 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300-tdep.c (IS_PUSH): Refine.
+ (IS_MOVE_FP, IS_MOV_SP_FP): Accept H8/300H varaints.
+ (IS_SUB4_SP, IS_SUBL_SP): New macros.
+ (h8300_skip_prologue): Handle H8/300H prologue code sequences.
+ (examine_prologue): Handle addresses from 0x010000 to 0xffffff
+ when in H8/300H mode. Get the return pointer's address correctly
+ for the H8/300H. Handle H8/300H prolouge code sequences.
+
+ * symfile.c (generic_load): Print the starting address
+ of the file just loaded.
+
+Thu May 23 12:09:52 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit @THREAD_DB_OBS@ out of makefile.
+
+Tue May 21 11:53:56 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (bpstat_do_actions): Avoid endless recursion
+ if a `source' command is contained in bs->commands.
+
+ * infrun.c (wait_for_inferior): Update step_frame_address when
+ stepping into a new line.
+
+ From schwab@issan.informatik.uni-dortmund.de (Andreas Schwab):
+ * breakpoint.c (breakpoint_1): Add shlib_disabled case to
+ bpenables array.
+
+Mon May 20 22:52:00 1996 Mark Alexander <marka@cygnus.com>
+
+ * dsrec.c (load_srec): Add WAITACK parameter, for machines
+ like EST visionICE that send back an ACK after each S-record.
+ * monitor.c (monitor_wait_srec_ack): New function.
+ (monitor_load): Pass monitor_wait_srec_ack to load_srec
+ if the monitor's MO_SREC_ACK flag is set.
+ * monitor.h: Define MO_SREC_ACK flag.
+ * remote-est.c (est_cmds): Add MO_SREC_ACK flag.
+ * sh3-rom.c (sh3_load): Accomodate change in load_srec prototype.
+ * srec.h: Add WAITACK parameter to load_srec prototype.
+
+Sun May 19 21:22:00 1996 Rob Savoye <rob@chinadoll>
+
+ * config/sparc/sparclite.mt: Add the sparc simulator.
+
+Sun May 19 16:49:37 1996 Fred Fish <fnf@cygnus.com>
+
+ * defs.h (read_command_lines, query_hook): Update prototypes.
+ (readline_begin_hook, readline_hook, readline_end_hook): Declare.
+ * breakpoint.c (commands_command): Build message in temporary buffer
+ and pass that, as well as tty control flag, to read_command_lines.
+ * top.c (readline_begin_hook, readline_hook, readline_end_hook):
+ Define here.
+ (command_loop): Check for non-NULL instream before looping.
+ (command_line_input): Use readline_hook when appropriate, to get
+ user input from a GUI window.
+ (read_next_line): Also build prompt if getting user input from a GUI.
+ (recurse_read_control_structure): Fix typo in comment.
+ (read_command_lines): Use passed in prompt and tty flag to decide how
+ to build message. Use readline_begin_hook when appropriate, to set
+ up a GUI interaction window. Just return head, whether NULL or not,
+ after using readline_end_hook to complete GUI interaction.
+ (define_command, document_command): Build message in a temporary
+ buffer and pass it to read_command_lines, along with tty flag.
+
+
+Sat May 18 02:43:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (frameless_look_for_prologue):
+ Add FUNCTION_START_OFFSET only if func_start is non-zero.
+ * minsyms.c (lookup_minimal_symbol_by_pc): Return NULL if
+ pc is not in a known section.
+ * stack.c (print_frame_info): Remove check for fi->pc in known
+ section, now handled by lookup_minimal_symbol_by_pc.
+
+
+Fri May 17 13:31:04 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * sh-stub.c: New file, was config/sh/stub.c.
+
+
+Wed May 15 08:25:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (read_next_line): Fix thinkos. From Donn Seeley.
+
+ * coffread.c (coff_symtab_read): Handle C_LABEL symbols like
+ C_STAT symbols.
+ * h8300-tdep.c (h8300_pop_frame): Reset $sp and $pc correctly.
+ Flush cached frames just before exiting.
+ * remote-sim.c (gdbsim_resume): Complain if the program isn't
+ being run.
+ * config/h8300/tm-h8300.h (BELIEVE_PCC_PROMOTION): Define.
+
+Tue May 14 18:05:16 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * procfs.c (procfs_thread_alive procfs_stop): Make static.
+ (procfs_pid_to_str): New routine to print out thread id's in an
+ intelligible manner.
+ * sol-thread.c (sol_thread_fetch_registers): Re-order manner in
+ which supply_register is called to fix bug with writing
+ individual regs.
+ * config/sparc/tm-sun4sol2.h: Define default for
+ target_pid_to_str in case host lacks libthread_db.
+
+Mon May 13 23:53:30 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in config.in configure configure.in
+ config/sparc/nm-sun4sol2.h config/sparc/sun4sol2.mh
+ config/sparc/tm-sun4sol2.h: Use autoconf to config Solaris thread
+ and pthread support, since pre-2.5 systems don't come with
+ libthread_db.so.1.
+
+ * procfs.c (info_proc): Use int instead of id_t. Old versions of
+ Irix don't seem to define this.
+
+Mon May 13 17:40:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (execute_control_command, case while_control): Allow
+ a while command to be interrupted.
+
+Mon May 13 16:17:36 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * sol-thread.c: More cleanup, add comments.
+ (sol_thread_resume): Prevent people from trying to step
+ inactive threads.
+ (sol_thread_wait sol_thread_fetch_registers
+ sol_thread_store_registers): Remove unnecessary check for
+ sol_thread_active. These routines won't get called unless threads
+ are active.
+
+Mon May 13 11:29:37 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ SH3-E support from Allan Tajii <atajii@hmsi.com>:
+ * sh-tdep.c (sh_reg_names, sh3_reg_names): Add empty names for
+ float registers.
+ (sh3e_reg_names): New register name array.
+ (sh_processor_type_table): Add sh3e processor type.
+ * config/sh/tm-sh.h (REGISTER_VIRTUAL_TYPE): Fix test.
+ (REGISTER_NAMES, NUM_REGS, NUM_REALREGS, etc): Adjust for
+ full set of registers.
+ * remote-e7000.c (want_sh3, want_sh3_nopc): New globals.
+ (e7000_fetch_registers, e7000_wait): Use them.
+ * sh3-rom.c (sh3_regnames): Add float registers.
+ (sh3e_cmds, sh3e_ops): New globals.
+ (sh3e_open): New function.
+ (_initialize_sh3_rom): Rename from _initialize_sh3, set up
+ sh3e target vector.
+
+Fri May 10 15:53:38 1996 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * sol-thread.c: Cleanup. gcc -Wall fixes. Add prototypes.
+ Print out messages instead of codes for thread_db errors. Make
+ access macros for thread and lwp manipulation. Make cleanups to
+ fixup inferior_pid in case of errors.
+
+Thu May 9 19:06:02 1996 Fred Fish <fnf@cygnus.com>
+
+ * aclocal.m4: Remove unused definition of AC_C_CROSS.
+ * configure.in: Add powerpcle-*-solaris* host and target config
+ so April 30th change does not get lost next time configure is
+ rebuilt.
+
+Thu May 9 14:13:08 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in, breakpoint.c, corelow.c, fork-child.c, inflow.c,
+ infrun.c, mac-nat.c, procfs.c, remote.c, sol-thread.c, thread.c,
+ win32-nat.c, config/nm-lynx.h: Rename thread.h to gdbthread.h to
+ avoid conflict with Solaris /usr/include/thread.h.
+
+Thu May 9 12:33:32 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * abug-rom.c: Config file for the older style ABug monitor that
+ runs on the mvme13x boards.
+ * config/m68k/monitor.mt: Add abug support for m68k cross
+ debugging.
+
+Wed May 8 20:33:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * infcmd.c (do_registers_info): Always print the raw floating
+ point value's bytes in big endian order, so the the leftmost bit
+ is the most significant.
+ * breakpoint.c (clear_momentary_breakpoints): Remove dead code
+ that is referenced nowhere else.
+ (set_breakpoint): Ditto.
+ (do_enable_breakpoint): Created from enable_once_breakpoint
+ with a couple of changes.
+ (enable_breakpoint): Call do_enable_breakpoint with an appropriate
+ bpdisp enum value to set disposition of breakpoint.
+ (enable_once_breakpoint): Ditto.
+ (enable_delete_breakpoint): Ditto.
+ * breakpoint.h (clear_momentary_breakpoints): Remove prototype.
+ * symtab.c (find_pc_line): Improve comments.
+ * xcoffread.c: Ditto.
+
+Tue May 7 18:37:06 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * target.c (debug_to_xfer_memory): Insert line breaks when
+ dumping the memory block.
+
+Mon May 6 13:52:52 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * fork-child.c (fork_inferior), inferior.h: init_trace_fun now
+ returns a possibly modified pid.
+ * inftarg.c (ptrace_him): Now returns pid;
+ * m3-nat.c (m3_trace_him): Now returns pid;
+ * infcmd.c (run_command): Minor cleanup.
+ * infrun.c (wait_for_inferior): Add another check for one_stepped
+ near where we read the pc to avoid erroneously setting
+ random_signal for multi-threaded support.
+ * procfs.c: Add support for Solaris LWPs. Remove def of
+ LOSING_POLL. Many cleanups... Several workarounds for Solaris
+ lossage. System call entry and exit are now handled by
+ dynamically registered handlers.
+ * (syscallname): Don't barf when handed an unknown syscall
+ number.
+ * (info_proc_syscalls): Ditto.
+ * sol-thread.c: New file. Implements Solaris thread support.
+ * symfile.c (symbol_file_add): Add call to target_new_objfile to
+ notify target-dependent code about new symbol tables.
+ * (clear_symtab_users): Call target_new_objfile to notify it of
+ the removal of all symbol tables.
+ * target.c (push_target): Make sure that to_close is non-zero
+ before calling it.
+ * target.h (target_new_objfile): Provide default.
+ * config/alpha/nm-osf2.h: Define LOSING_POLL because this version
+ of OSF can't hack using poll with /proc.
+ * config/sparc/nm-sun4sol2.h (target_new_objfile): Define to be
+ sol-thread-new-objfile.
+ * config/sparc/sun4sol2.mh: Add sol-thread.o to NATDEFFILES, and
+ add libthread_db.so.1 to NAT_CLIBS.
+ * config/sparc/tm-sun4sol2.h: Define PIDGET, TIDGET, and
+ target_pid_to_str.
+
+Sat May 4 02:13:34 1996 N Srin Kumar <nsrin@wipinfo.soft.net>
+
+ * procfs.c (remove_fd): Fix copy of fds to fill hole left after
+ removal of the requested fd.
+
+Mon May 6 07:52:48 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * rs6000-tdep.c (_initialize_rs6000_tdep): Don't do XCOFF specific
+ hooks under ELF.
+
+ * config/powerpc/tm-ppc-eabi.h: Define ELF_OBJECT_FORMAT.
+
+Thu May 2 12:46:14 1996 Jeffrey A Law (law@cygnus.com)
+
+ From Peter Schauer:
+ * breakpoint.h (enum bpdisp): Add del_at_next_stop.
+ * breakpoint.c (insert_breakpoints, watchpoint_check,
+ bpstat_stop_status): Avoid bad references to memory freed via
+ delete_breakpoint on watchpoints going out of scope.
+ Do not delete these watchpoints, disable them and change their
+ disposition to del_at_next_stop instead.
+ (breakpoint_auto_delete): Delete all breakpoints whose disposition
+ is del_at_next_stop.
+ (breakpoint_init_inferior): Use switch to avoid reference to
+ already deleted breakpoint.
+
+Wed May 1 17:29:18 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (rs6000-nat.o): Depend on xcoffsolib.h.
+ * config/rs6000/rs6000.mh (NATDEPFILES): Move xcoffread.o ...
+ * config/rs6000/rs6000.mt (TDEPFILES): ... to here.
+ * xcoffsolib.c (xcoff_relocate_symtab_hook): Define and initialize.
+ (solib_info): Call xcoff_relocate_symtab via the hook.
+ (sharedlibrary_command): Ditto.
+ * xcoffread.c: Remove all FAKING_RS6000 comments and defines.
+ (xcoff_add_toc_to_loadinfo_hook): Define and initialize here.
+ (xcoff_init_loadinfo_hook): Define and initialize here.
+ (scan_xcoff_symtab): Call xcoff_add_toc_to_loadinfo via the hook.
+ (xcoff_initial_scan): Call xcoff_init_loadinfo via the hook.
+ * xcoffsolib.h (xcoff_relocate_symtab_hook): Declare extern func.
+ * rs6000-tdep.c (_initialize_rs6000_tdep): Add initializations
+ of xcoff_add_toc_to_loadinfo_hook and xcoff_init_loadinfo_hook.
+ * rs6000-nat.c (_initialize_core_rs6000): Add initialization
+ of xcoff_relocate_symtab_hook.
+
+Tue Apr 30 13:22:02 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure (powerpcle-*-solaris*): Add Solaris support.
+
+ * config/powerpc/{solaris.m[ht],tm-solaris.h}: New files for
+ Solaris support.
+
+Mon Apr 29 16:17:31 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * c-valprint.c (c_val_print): Fix printing for arrays defined
+ with 0 length.
+
+Sun Apr 28 15:08:05 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ Support for bi-endian remote breakpoints.
+ * remote.c (big_break_insn, little_break_insn): New globals.
+ (break_insn): Remove.
+ (remote_insert_breakpoint, remote_remove_breakpoint): Use own
+ code if REMOTE_BREAKPOINT defined, otherwise call memory
+ breakpoint functions.
+ * config/sh/tm-sh.h (REMOTE_BREAKPOINT): Remove.
+ (BIG_REMOTE_BREAKPOINT, LITTLE_REMOTE_BREAKPOINT): Define.
+
+ * mon960-rom.c (mon960_cmds): Remove forward decl.
+ (mon960_load): Use current_monitor instead of mon960_cmds.
+ (mon960_regnames): Remove backslashes from line ends.
+ (_initialize_mon960): Fix documentation string.
+
+Sun Apr 28 12:10:35 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.h (psymbol_allocation_list): Expand comments which
+ describe the psymbol allocation list and how each field is
+ used.
+
+Sun Apr 28 03:44:30 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (delete_breakpoint): Fix bpt->val, bpt->exp
+ storage leaks.
+ (breakpoint_re_set_one): Fix b->exp, b->val, b->cond storage leaks.
+
+ * infcmd.c (run_command), solib.c (locate_base): Check for
+ target_has_execution in addition to inferior_pid, a core file
+ from a threaded program is yielding a non-zero inferior_pid.
+
+ * sparc-tdep.c (get_saved_register): Handle window registers
+ in a dummy frame correctly.
+
+Sat Apr 27 20:38:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (CLIBS): Move $(MMALLOC) past all other libs,
+ so that anything that wants an allocation function not yet pulled
+ in, will get it from mmalloc rather than a system library.
+ * Makefile.in (INSTALLED_LIBS): Reorder to match order of CLIBS,
+ to avoid surprising results when used.
+
+Sat Apr 27 00:12:05 1996 Dawn Perchik (dawn@cygnus.com)
+
+ * stabsread.c: Changes and bug fixes for cfront support.
+ Fix bug for class data members.
+ Fix parsing bug when no base classes exist.
+ Fix memory bug - allocate space for cplusplus specific info.
+ Add support for static data.
+ Add prototypes for static functions.
+ Enhance comments to show what each function expects to parse.
+ Cleanup code.
+ * stabsread.c(resolve_cont),dbxread.c(resolve_cont): Rename
+ function to resolve_cfront_continuation.
+
+Fri Apr 26 23:58:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Call registers_changed when
+ restarting the inferior to get over a nullified instruction.
+
+Tue Apr 24 12:12:55 1996 Dawn Perchik (dawn@cygnus.com)
+
+ * dbxread.c,stabsread.c,gdbtypes.c,partial-stab.h,valops.c:
+ Add new support for parsing cfront stabs.
+
+Wed Apr 24 00:32:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Move "have_waited" label
+ outside of #ifdef conditionals. Don't trash the wait status
+ if we get a signal and the current instruction is nullified.
+
+Mon Apr 22 20:17:01 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump version number to 4.16.1.
+ * NEWS: Update for 4.16 release.
+
+Mon Apr 22 16:32:29 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.h: Clean up comment formatting.
+ (current_monitor): Remove decl.
+ (LOADTYPES, LOADPROTOS, INIT_CMD, etc): Remove definitions.
+ (push_monitor, SREC_SIZE): Remove.
+ * monitor.c: Expand old macro into current_monitor derefs
+ everywhere.
+ * remote-os9k.c (current_monitor): Remove definition.
+
+Mon Apr 22 14:54:45 1996 Mark Alexander <marka@superball.cygnus.com>
+
+ * corefile.c (specify_exec_file_hook): Allow arbitrary number of
+ hooks.
+ (call_extra_exec_file_hooks): New function.
+ * h8300-tdep.c: Lint; add .h files to provide missing declarations,
+ remove unused variables.
+ (set_machine_hook): New function.
+ (_initialize_h8300m): Initialize it.
+
+Fri Apr 19 15:03:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * remote-mips.c (encoding): Don't specify size, to avoid bug in
+ SunOS native compiler.
+
+Thu Apr 18 18:46:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c: Use int rather than LONGEST for values, since
+ the formatting strings are not prepared to accept long longs.
+
+Wed Apr 17 20:17:27 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * arm-tdep.c (initialize_arm_tdep): Make apcs32 a `zinteger'.
+
+Tue Apr 16 17:38:23 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * corelow.c (add_to_thread_list): Make sure reg_sect is non-null
+ before de-referencing it. Prevents deref of NULL pointer if core
+ file lacks .reg section.
+ * defs.h: Rename floatformat_{to from}_long_double to
+ floatformat_{to from}_doublest. Get rid of FLOATFORMAT_{TO
+ FROM}... macros.
+ * findvar.c (extract_floating store_floating): Change all refs to
+ FLOATFORMAT_{FROM TO}... to floatformat_{from to}_doublest.
+ * utils.c: Change floatformat_{to from}_long_double to
+ floatformat_{to from}_doublest cuz the new routines will use
+ whatever size (double or long double) is appropriate.
+ * config/i960/tm-i960.h (REGISTER_CONVERT_TO_VIRTUAL
+ REGISTER_CONVERT_TO_RAW): Change FLOATFORMAT... macros to
+ floatformat... routine calls.
+
+Mon Apr 15 16:34:11 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_type): Move handling of '@' from type
+ number handling to handling of types proper (as emitted by gcc!).
+ For typedefs, allocate the typedef type before reading its
+ definition, to properly handling recursive types.
+
+Mon Apr 15 11:19:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * ch-exp.c (calculate_array_length): Fix prototype.
+
+Sat Apr 13 14:21:16 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-nindy.c (nindy_open): Acquire more target state so that
+ user can attach to a previously running program.
+ * (nindy_fetch_registers nindy_store_registers): Get rid of fp
+ conversion code. That's all handled in {extract store}_floating
+ now.
+ * utils.c (floatformat_to_double): Don't bias exponent when
+ handling zero's, denorms or NaNs.
+ * config/i960/tm-i960.h (REGISTER_CONVERT_TO_VIRTUAL
+ REGISTER_CONVERT_TO_RAW): Change to using DOUBLST and
+ FLOATFORMAT_TO/FROM_DOUBLEST macros.
+ * config/i960/tm-nindy960.h: Undefine
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW, and
+ REGISTER_CONVERTIBLE. These are no longer necessary now that all
+ the magic happens in extract/store_floating.
+
+Sat Apr 13 02:58:02 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * eval.c (evaluate_subexp_standard): Report error when attempting to
+ evaluate subscripts for types which cannot be subscripted.
+
+ * valarith.c (value_x_binop, value_x_unop): Add noside parameter.
+ Return a zero value with the return type of the member function
+ if noside is EVAL_AVOID_SIDE_EFFECTS instead of calling the member
+ function.
+ * values.h (value_x_binop, value_x_unop): Update prototypes
+ accordingly.
+ * eval.c (evaluate_subexp_standard): Update all callers of
+ value_x_binop, value_x_unop accordingly.
+
+ * valarith.c (value_neg, value_complement): Perform ANSI C/C++
+ integral promotion on operands.
+
+Fri Apr 12 13:19:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * README: Update for 4.16 release.
+ * configure.in (AC_CHECK_FUNCS): Also check for sbrk.
+ * configure: Regenerate with autoconf.
+ * config.in: Regenerate with autoheader.
+ * main.c (main): Only use sbrk() when HAVE_SBRK is defined.
+ * top.c (command_loop): Ditto.
+
+Fri Apr 12 09:45:29 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h: Define TARGET_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT
+ defaults for bi-endian targets. Replace function pointers for
+ floatformat routines with macros. No need for these to be runtime
+ selectable.
+ * findvar.c: Get rid of floatformat function pointers. Use
+ macros in extract_floating and store_floating.
+ * remote-nindy.c (nindy_fetch_registers nindy_store_registers):
+ Use floatformat macros.
+
+Thu Apr 11 21:28:02 1996 Fred Fish <fnf@cygnus.com>
+
+ From: Miles Bader <miles@gnu.ai.mit.edu>
+ * configure.in (AC_CHECK_HEADERS): check for endian.h.
+ Use AC_CHECK_TOOL to find AR & RANLIB. Add AC_PROG_AWK.
+ Add host & target cases for i[345]86-*-gnu*.
+ * config.in: Regenerate with autoheader.
+ * configure: Regenerate with autoconf.
+ * Makefile.in (AR, AWK): Set from corresponding autoconf substs.
+ (init.c): Don't scan mig-generated files.
+ * defs.h (endian.h): Include if HAVE_ENDIAN_H defined.
+ * config/nm-m3.h (ATTACH_NO_WAIT): Define.
+ * infcmd.c (attach_command): Use "#ifndef ATTACH_NO_WAIT"
+ rather than "#ifndef MACH".
+
+Thu Apr 11 18:49:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (remotewritesize): New GDB variable, controls size
+ of memory packets sent to the target.
+
+Thu Apr 11 13:47:52 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dcache.c: Add prototypes. Make many functions static.
+ * (dcache_peek dcache_fetch dcache_poke): Make dcache_fetch and
+ dcache_poke call dcache_xfer_memory directly in order to fix
+ problems with turning off dcache. dcache_peek is now unnecessary,
+ so it goes away.
+
+ * defs.h: Define new macros HOST_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT
+ and TARGET_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT to specify a pointer
+ to a struct floatformat. This allows for better handling of
+ targets whose floating point formats differ from the host by more
+ than just byte order.
+ * (floatformat_to_long_double floatformat_from_long_double):
+ Prototypes for new functions in utils.c.
+ * (floatformat_to_doublest floatformat_from_doublest): Prototypes
+ for pointers to floating point conversion functions. The actual
+ function uses either double or long double if the host supports it.
+ * findvar.c (floatformat_to_doublest floatformat_from_doublest):
+ Initialize to point at correct function depending on HAVE_LONG_DOUBLE.
+ * (extract_floating store_floating): Rewrite. Now, if host fp
+ format is the same as the target, we just do a copy. Otherwise,
+ we call floatformat_{to from}_doublest.
+ * remote-nindy.c (nindy_xfer_inferior_memory): Change param
+ `write' to `should_write'.
+ * utils.c (floatformat_to_long_double
+ floatformat_from_long_double): New routines that implement long
+ double versions of functions in libiberty/floatformat.c.
+ * config/i960/tm-i960.h (TARGET_LONG_DOUBLE_FORMAT): Define this for
+ i960 extended real (80 bit) numbers.
+ * nindy-share/nindy.c (ninMemGet ninMemPut): Return number of bytes
+ actually read or written.
+
+Wed Apr 10 02:56:06 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-valprint.c (chill_val_print): Remove call to calculate_array_length.
+ (calculate_array_length): Move function from here ...
+
+ * ch-exp.c (calculate_array_length): ... to here.
+ (parse_primval): If we have a symbol with an array type
+ and the length is 0, call calculate_array_length.
+
+Tue Apr 9 01:23:05 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard): In case of TYPE_CODE_SET:
+ Add some checks for powerset compatibility.
+
+ * valops.c (value_slice): Use lowbound instead of lowerbound for
+ call to slice_range_type to get correct bounds.
+
+Mon Apr 8 12:53:56 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (scm-exp.o, scm-lang.o, scm-valprint.o): Add targets and
+ dependencies.
+ * scm-lang.c (gdb_string.h): Include.
+ * objfiles.c (add_to_objfile_sections): Cast second arg of obstack_grow
+ call to correct type (char *).
+ * cp-valprint.c (cp_print_static_field): Ditto.
+ * somsolib.c (som_solib_create_inferior_hook): Add a declaration
+ for external find_unwind_entry function (from hppa-tdep.c).
+ * remote-pa.c (remote_write_bytes, remote_read_bytes): Change
+ type of second arg to "char *" to be type compatible with
+ dcache.
+ (remote_wait): Cast second arg to strtol to correct type.
+ * hppa-tdep.c (compare_unwind_entries): Change argument types to
+ "const void *" to be type compatible with qsort, and then
+ assign to local args prior to use.
+
+Mon Apr 8 15:35:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infptrace.c (kill_inferior): Remove call to "kill"; update
+ comments.
+
+Mon Apr 8 14:05:07 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * remote-e7000.c: don't append :23 to target port if __WIN32__
+ is defined (it's WinGDB).
+
+Sun Apr 7 22:34:29 1996 Fred Fish <fnf@cygnus.com>
+
+ From: Miles Bader <miles@gnu.ai.mit.edu>
+ * gnu-nat.c, gnu-nat.h, msg.defs, exc_request.defs, i386gnu-nat.c,
+ msg_reply.defs, notify.defs, process_reply.defs, reply_mig_hack.awk,
+ config/nm-gnu.h, config/i386/{i386gnu.mh, i386gnu.mt, nm-gnu.h,
+ m-i386gnu.h, xm-i386gnu.h}: New files for GNU hurd.
+
+Sun Apr 7 13:32:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (case host): Add i386sco5 host.
+ * configure: Regenerate.
+
+ From: Robert Lipe <robertl@dgii.com>
+ Add support for SCO OpenServer 5 (a.k.a. 3.2v5*) This
+ target is an SVR3.2 with COFF, ELF, and shared libes, but
+ no /proc.
+ * config/i386/i386sco5.mh: New file.
+ * config/i386/nm-i386sco5.h: New file.
+
+Sat Apr 6 08:55:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * bcache.c (bcache): When size of chunk to cache is exactly equal to
+ BCACHE_MAXLENGTH, stash chunk as unique copy.
+
+Sat Apr 6 00:46:26 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (INLINE_ADD_PSYMBOL): Remove ifdef.
+ (add_psymbol_to_list): Add an arg for passing CORE_ADDR values and
+ use it, rather than calling add_psymbol_addr_to_list.
+ (add_psymbol_addr_to_list): Delete.
+ (add_psymbol_to_list): Make psymbol static to avoid random data in
+ gaps due to alignment of structure members.
+ * symfile.h (INLINE_ADD_PSYMBOL, ADD_PSYMBOL_TO_LIST,
+ ADD_PSYMBOL_ADDR_TO_LIST): Remove. Real world tests show no
+ performance improvements by inlining via complicated macros and
+ they just make gdb larger and harder to maintain.
+ * dwarfread.c (add_enum_psymbol): Replace ADD_PSYMBOL_TO_LIST
+ and/or ADD_PSYMBOL_ADDR_TO_LIST macro(s) with call to
+ add_psymbol_to_list with appropriate long or CORE_ADDR args.
+ (add_partial_symbol): Ditto.
+ * partial-stab.h: Ditto.
+ * os9kread.c (read_os9k_psymtab): Ditto
+ * mdebugread.c (parse_partial_symbols): Ditto.
+ (handle_psymbol_enumerators): Ditto.
+ (demangle.h): Include.
+ * hpread.c (hpread_build_psymtabs): Ditto.
+ (hpread_build_psymtabs): Ditto.
+ (demangle.h): Include
+
+Thu Apr 4 20:16:55 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Check for setpgid function.
+ * config.in: Regenerate with autoheader.
+ * configure: Regenerate with autoconf.
+ * inflow.c (_initialize_inflow): Only try to use _SC_JOB_CONTROL
+ if it is actually defined.
+ (gdb_setpgid): Use HAVE_SETPGID.
+ * ch-exp.c: Change include of <string.h> to "gdb_string.h".
+ * c-exp.y, f-exp.y, m2-exp.y: Ditto.
+ * c-exp.y, serial.c: Include <ctype.h>.
+ * config/m68k/nm-news.h: Add typedef for pid_t which is
+ apparently missing from <sys/types.h>. Enclose entire
+ file in NM_NEWS_H ifndef and define when included.
+ * config/mips/nm-news-mips.h: Ditto.
+ * config/m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Change name of temporary variable.
+
+Thu Apr 4 19:04:18 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * arm-xdep.c: Move native-specific code to here from arm-tdep.c.
+ * arm-tdep.c (arm_apcs_32): New global.
+ (arm_addr_bits_remove, arm_saved_pc_after_call,
+ arm_push_dummy_frame, arm_pop_frame): New functions.
+ (arm_skip_prologue): Updated version from Richard Earnshaw.
+ (_initialize_arm_tdep): Add set/show "apcs32".
+ * config/arm/tm-arm.h (ADDR_BITS_REMOVE): Call
+ arm_addr_bits_remove.
+ (SAVED_PC_AFTER_CALL): Call arm_saved_pc_after_call.
+ (frame_find_saved_regs): Declare properly.
+ (PUSH_DUMMY_FRAME): Call arm_push_dummy_frame.
+ (POP_FRAME): Call arm_pop_frame, use ADDR_BITS_REMOVE instead of
+ explicit mask.
+ * config/arm/nm-arm.h: New file.
+ * config/arm/xm-arm.h (KERNEL_U_ADDR, FETCH_INFERIOR_REGISTERS):
+ Move definitions to nm-arm.h.
+ * config/arm/arm.mh (NAT_FILE): Define.
+
+ * symfile.c (generic_load): Initialize data_count properly.
+
+Thu Apr 4 17:17:53 1996 Fred Fish <fnf@cygnus.com>
+
+ * symmisc.c (print_objfile_statistics): Print memory used by
+ psymbol cache obstack.
+
+Thu Apr 4 15:43:07 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * symfile.c (report_transfer_performance): New function.
+ (generic_load): Call it to report transfer rate.
+ * remote-e7000.c (e7000_load): Ditto.
+
+Mon Apr 1 16:31:00 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Change references to config.h to be in objdir,
+ edit out rules to rebuild config.h.
+
+Mon Apr 1 08:32:23 1996 Fred Fish <fnf@cygnus.com>
+
+ * hppa-tdep.c (hppa_pop_frame): Call clear_proceed_status before
+ proceeding.
+
+Sun Mar 31 16:15:43 1996 Fred Fish <fnf@cygnus.com>
+
+ * hppah-nat.c (store_inferior_registers, store_inferior_registers,
+ fetch_register, child_xfer_memory): Use call_ptrace function supplied
+ by infptrace.c rather than calling ptrace directly.
+
+Sun Mar 31 15:39:00 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mon960-rom.c: Cleanups and elimination of unused code,
+ clarify documentation string.
+ (mon960_serial, mon960_ttyname): Remove.
+ * config/i960/tm-mon960.h (ADDITIONAL_OPTIONS,
+ ADDITIONAL_OPTION_CASES, ADDITIONAL_OPTION_HELP): Remove.
+
+Sat Mar 30 11:00:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Check whether printf family supports printing
+ long doubles or not and define PRINTF_HAS_LONG_DOUBLE if so.
+ * acconfig.h: Provide default undef for PRINTF_HAS_LONG_DOUBLE.
+ * configure: Regenerate.
+ * valprint.c (print_floating): Use PRINTF_HAS_LONG_DOUBLE.
+ * c-exp.y (parse_number): Use PRINTF_HAS_LONG_DOUBLE.
+ * configure.in: Fix have_gregset and have_fpregset autoconf
+ variable names so that they match the pattern required to
+ cache them.
+
+Fri Mar 29 21:39:56 1996 Fred Fish <fnf@cygnus.com>
+
+ * core-aout.c (fetch_core_registers): Cast core_reg_size to int
+ before testing against reg_ptr.
+ * eval.c (evaluate_subexp_standard): Cast type of
+ TYPE_FN_FIELD_VOFFSET to int.
+ * findvar.c (extract_signed_integer, extract_unsigned_integer,
+ extract_long_unsigned_integer): Cast type of sizeof to int.
+ * values.c (unpack_field_as_long, modify_field): Ditto.
+ * valops.c (value_assign, call_function_by_hand): Ditto.
+ * infcmd.c (do_registers_info): Ditto.
+ * ser-tcp.c (tcp_open): Ditto.
+ * remote.c (putpkt): Ditto.
+ * dcache.c (dcache_peek): Ditto.
+ * dcache.c (dcache_poke): Ditto.
+ * m2-exp.y (yylex): Ditto.
+ * gnu-regex.c (re_match_2): Ditto.
+ * f-lang.c (ADD_BF_SYMNUM, saved_bf_list_end, tmp_bf_ptr): Ifdef
+ out unused macro definition and variables.
+ * inftarg.c (proc_wait): Move from main.c to here, and make static.
+ * valprint.c (val_print_string): Change bufsize from int to unsigned.
+ * main.c (wait.h): Include.
+ * top.c (command_line_input): Remove unused variable "c".
+ * f-typeprint.c (f_type_print_varspec_prefix): Add missing enum
+ value TYPE_CODE_TYPEDEF to switch statement.
+ (f_type_print_varspec_suffix): Add missing enum value
+ TYPE_CODE_TYPEDEF to switch statement.
+ * ch-exp.c (parse_primval): Add remaining enumeration values to
+ switch statement, with no specific action.
+ (ch_lex): Add LOC_UNRESOLVED in switch statement.
+ (pushback_token): Ifdef out, since code using it is ifdef'd out.
+ * stabsread.c (cleanup_undefined_types): Remove unused label
+ "badtype".
+ * objfiles.h (print_symbol_bcache_statistics): Add prototype.
+ * maint.c (objfiles.h): Include.
+ (maintenance_print_statistics): Remove unused variable "temp".
+ * minsyms.c (lookup_minimal_symbol_solib_trampoline): Remove
+ unused variable "found_file_symbol".
+ * m2-exp.y (yylex): Add LOC_UNRESOLVED case to switch.
+ * language.c (lang_bool_type): Use existing function local type
+ variable rather than create block local variables.
+ * solib.c (disable_break): Enclose in ifndef SVR4_SHARED_LIBS.
+ * infptrace.c (wait.h, command.h): Include.
+ * ser-tcp.c (gdb_string.h): Include
+ * i386-tdep.c (codestream_seek): Change "place" to CORE_ADDR.
+ (i386_get_frame_setup): Change "pc" from int to CORE_ADDR.
+ * command.c (complete_on_enum): Make assignment used as truth value
+ explictly check against NULL.
+ (wait.h): Include.
+ * infrun.c (wait_for_inferior): Ifdef out prologue_pc since code
+ that uses it is ifdef'd out.
+ * parser-defs.h: Add prototype for write_dollar_variable.
+ * infrun.c: Add prototype for write_pc_pid.
+ * breakpoint.h: Add prototype for re_enable_breakpoints_in_shlibs.
+ * symmisc.c (bcache.h): Include.
+ * bcache.h: Add prototype for print_bcache_statistics.
+ * symfile.c: Include <time.h>.
+ * printcmd.c (print_scalar_formatted): Change len to unsigned int.
+ * valarith.c (value_equal): Cast result of TYPE_LENGTH to int.
+ * valarith.c (value_binop): Change result_len, promoted_len1,
+ and promoted_len2 to unsigned int.
+ * valarith.c (value_subscripted_rvalue): Change elt_offs and
+ elt_size to unsigned int.
+ * valops.c (value_array): Change typelength to unsigned int.
+ (destructor_name_p): Change len to unsigned int.
+ * scm-lang.h (scm_parse): Add prototype for scm_unpack.
+ * symfile.c (decrement_reading_symtab): Change return type to void.
+ * valarith.c (value_subscript): Remove unused variable "word".
+ (value_subscript): Remove unused variable "tint".
+ * valops.c (auto_abandon): Ifdef out, since code using it is also
+ ifdef'd out.
+ * eval.c (init_array_element): Remove unused variable "val".
+ * Makefile.in (values.o): Depends on scm-lang.h.
+ (command.o): Depends upon wait_h.
+ (ser-tcp.o): Depends upon gdb_string.h.
+ (infptrace.o): Depends upon wait_h and command_h.
+ (maint.o): Depends on objfiles.h and symfile.h.
+ * values.c (allocate_repeat_value): Remove unused variable
+ "element_type".
+ (scm-lang.h): Include.
+ * breakpoint.c (create_longjmp_breakpoint): Enclose in
+ GET_LONGJMP_TARGET define, unused otherwise.
+ * config/i386/nm-linux.h: Add prototypes for i386_insert_watchpoint,
+ i386_remove_watchpoint and i386_stopped_by_watchpoint.
+
+Thu Mar 28 12:53:19 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc64-*-solaris2*): Delete.
+ Stick with sparc-*-solaris2*.
+ * configure: Regenerated.
+
+Thu Mar 28 06:51:26 1996 Fred Fish <fnf@cygnus.com>
+
+ * valops.c (value_assign): Make copy of internal variable value
+ before returning it as a new value, since it is owned by the
+ internal variable and will be freed along with it.
+
+Wed Mar 27 08:36:17 1996 Jeffrey A Law (law@cygnus.com)
+
+ * From Peter Schauer.
+ * breakpoint.c (breakpoint_re_set_one): Keep temporary
+ breakpoints bp_until, bp_finish, bp_watchpoint_cope, bp_call_dummy
+ and bp_step_resume in case breakpoint_re_set_one is called due
+ to a step over a dlopen call.
+ * infrun.c (wait_for_inferior): Always remove breakpoints from
+ inferior in BPSTAT_WHAT_CHECK_SHLIBS case.
+
+Tue Mar 26 13:15:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-mips.h (COERCE_FLOAT_TO_DOUBLE): Only prefer
+ non-prototyped case over prototyped case for C.
+ * config/pa/tm-hppa.h (COERCE_FLOAT_TO_DOUBLE): Ditto.
+
+Sat Mar 23 17:24:28 1996 Fred Fish <fnf@cygnus.com>
+
+ * os9kread.c (os9k_process_one_symbol): Note nonportable
+ assumption that an int can hold a char *.
+
+ * bcache.h (struct hashlink): Wrap data[] inside union with
+ double to force longest alignment.
+ (BCACHE_DATA): New macro to access data[].
+ (BCACHE_ALIGNMENT): New macro to get offset to data[].
+ * bcache.c (lookup_cache, bcache): Use BCACHE_DATA to get
+ address of cached data. Use BCACHE_ALIGNMENT to compute
+ amount of space to allocate for each hashlink struct.
+
+Sat Mar 23 12:14:02 1996 Fred Fish <fnf@cygnus.com>
+
+ * ch-lang.c (evaluate_subexp_chill): Fix typo.
+
+Thu Mar 21 08:27:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump version to 4.15.3
+
+Thu Mar 21 10:56:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.in: Rename from config.h.in.
+ * configure.in: Call AC_CONFIG_HEADER with config.h:config.in.
+ Change CONFIG_HEADERS test in AC_OUTPUT accordingly.
+ * configure: Rebuild.
+ * Makefile.in (stamp-h): Depend upon config.in, not config.h.in.
+ Set CONFIG_HEADERS to config.h:config.in.
+
+Tue Mar 19 12:47:51 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * partial-stab.h (case N_ENDM): Finish current partial symbol
+ table for Solaris 2 cc.
+
+Tue Mar 19 10:39:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * rs6000-nat.c (exec_one_dummy_insn): Don't clobber the
+ PC in the registers array. From Peter Schauer.
+
+Mon Mar 18 13:47:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (reread_symbols): Reinitialize bcache struct
+ members to zero using memset. Also use memset to reinit
+ global_psymbols and static_psymbols, rather than explicitly
+ resetting each structure member.
+
+Sat Mar 16 19:47:36 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add fragment to create stamp-h.
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * configure.in (AC_CHECK_HEADERS): Check for link.h.
+ * configure: Regenerate with autoconf.
+ * config.h.in: Regenerate with autoheader.
+ * config/i386/nm-linux.h: Include solib.h only if HAVE_LINK_H
+ is defined.
+ * solib.c: Exclude most of the code if HAVE_LINK_H is not defined.
+ * config/i386/linux.mh: Reinstate XM_CLIBS, it is needed for
+ older a.out based systems.
+
+Sat Mar 16 16:45:43 1996 Fred Fish <fnf@cygnus.com>
+
+ * config.h.in: New file.
+ * acconfig.h: New file, for autoheader.
+ * configure.in (AC_CONFIG_HEADER): Add, generate config.h.
+ * configure: Regenerate.
+ * Makefile.in (defs_h): Add config.h
+ (distclean): Remove config.h and stamp-h during distclean.
+ (config.h, stamp-h): New targets to remake config.h when necessary.
+ * defs.h (config.h): Include before any other includes or defines.
+ * i386-tdep.c (gdb_string.h): Move include after include of defs.h.
+ * i386v4-nat.c (defs.h): Include before testing HAVE_SYS_PROCFS_H.
+
+Sat Mar 16 14:55:27 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * Makefile.in (INSTALLED_LIBS): Make sure that @LIBS@ will not
+ result in an empty line, to work around a bug in native Ultrix 4.4
+ and OSF/1-3.2C make.
+
+Sat Mar 16 13:33:17 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add gdbserver to configdirs under linux.
+ * configure: Regenerate.
+
+Fri Mar 15 12:06:58 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/i386/nm-nbsd.h (FLOAT_INFO): Comment out.
+ * config/i386/tm-nbsd.h (NUM_REGS): Define.
+
+Thu Mar 14 10:31:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * solib.c (solib_break_names): Add _r_debug_state for
+ vanilla SVR4 implementations. From Peter Schauer.
+
+Mon Mar 11 14:24:57 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * mon960-rom.c: New file; support mon960 rom monitor on i960.
+ * monitor.c (monitor_debug): Change remotedebug to buffer strings.
+ * monitor.c (monitor_open): Add test for flag MO_NO_ECHO_ON_OPEN before
+ epecting prompt and echo during open.
+ * monitor.c (monitor_stop): Add test for flag MO_SEND_BREAK_ON_OPEN to
+ determine if break should be sent as stop command.
+ * monitor.h: Add flags MO_NO_ECHO_ON_OPEN and MO_SEND_BREAK_ON_OPEN.
+ * i960-tdep.c (mon960_frame_chain_valid): New function for getting
+ stack frame on mon960.
+ * Makefile.in: Add mon960 files.
+ * configure.in: Changed i960-*-coff* and i960-*-elf* to target mon960;
+ added i960-nindy-coff* and i960-nindy-elf* for target nindy.
+ * configure: Regenerated.
+ * config/i960/mon960.mt, config/i960/tm-mon960.h: New files;
+ support mon960 rom monitor on i960.
+
+Mon Mar 11 11:02:47 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ With Michael Snyder:
+ * i386-tdep.c (skip_trampoline_code): Fix strncmp length.
+ * win32-nat.c (CHECK, DEBUG*, debug_*): New.
+ (handle_load_dll): Don't reload symbols.
+ (handle_exception): Use the DEBUG_* names.
+ (child_wait): Add DEBUG_* code.
+ (_initialize_inftarg): Add new commands to set debug_ names.
+
+Mon Mar 11 09:19:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * From Peter Schauer:
+ * breakpoint.c (insert_breakpoints): Use ALL_BREAKPOINTS_SAFE.
+ (bpstat_stop_status): Likewise.
+ (remove_solib_event_breakpoints): Likewise.
+ (clear_momentary_breakpoints): Likewise.
+ (re_enable_breakpoints_in_shlibs): Don't reenable a breakpoint
+ if we still can't read the memory for that breakpoint.
+ (mention): Add bp_shlib_event case to keep gcc quiet.
+
+Fri Mar 8 12:08:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * breakpoint.h (enum enable): New enum shlib_disabled for
+ shared library breakpoints that have been temporarily disabled.
+ * breakpoint.c: Handle temporarily disabled shared library
+ breakpoints like disabled breakpoints in most places.
+ (insert_breakpoints): Use shlib_disabled to indicate
+ that an unsettable breakpoint is only temporarily disabled.
+ (re_enable_breakpoints_in_shlibs): New function.
+ * corelow.c (solib_add_stub): After adding shared libraries,
+ try to reenable any temporarily disabled breakpoints.
+ * infcmd.c (attach_command): Likewise.
+ * infrun.c (wait_for_inferior): Likewise.
+
+Fri Mar 8 11:41:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * defs.h (extract_long_unsigned_integer): Declare.
+ * findvar.c (extract_long_unsigned_integer): New function.
+ * printcmd.c (print_scalar_formatted): Use it.
+ * valprint.c (val_print_type_code_int): Likewise.
+
+Thu Mar 7 17:40:50 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infcmd.c (do_registers_info): Ignore anonymous registers.
+ * sh-tdep.c (set processor): New command to set specific
+ processor type.
+ (sh_reg_names, sh3_reg_names): Arrays of register names for
+ SH and SH3 processors.
+ (sh_set_processor_type): New function.
+ * sh3-rom.c (sh3_open): Call it.
+ (sh3_regname): Add names of all the bank registers.
+ (sh3_supply_register): Clean up formatting.
+ * config/sh/tm-sh.h (NUM_REGS, NUM_REALREGS): Increase to include
+ bank registers.
+ (REGISTER_NAMES): Add names of bank registers.
+ (FP15_REGNUM): Define.
+ (REGISTER_VIRTUAL_TYPE): Use it.
+ * monitor.c: Clean up some comments.
+
+Thu Mar 7 12:09:51 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386b-nat.c: Revert part of Mar 5 change. FreeBSD collapsed the
+ s* and t* symbols too.
+
+Thu Mar 7 15:18:51 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * symfile.c (generic_load): Avoid division by zero.
+
+Wed Mar 6 17:57:59 1996 Jeffrey A Law (law@cygnus.com)
+
+ * breakpoint.c (bfd_lookup_symbol): Provide for all SVR4 systems,
+ not just those with HANDLE_SVR4_EXEC_EMULATORS.
+
+ From Peter Schauer:
+ * breakpoint.c (internal_breakpoint_number): Move to file scope.
+ (create_solib_event_breakpoint): Use an internal breakpoint number.
+
+Wed Mar 6 00:32:44 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * valarith.c (value_in): Change builtin_type_chill_bool to
+ LA_BOOL_TYPE.
+
+Tue Mar 5 23:48:36 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (parse_primval): Handle CARD, MAX, MIN.
+ (match_string_literal): Handle control sequence.
+ (match_character_literal): Deto.
+
+ * ch-lang.c (chill_printchar): Change formating of nonprintable
+ characters from C'xx' to ^(num).
+ (chill_printstr): Deto.
+ (value_chill_card, value_chill_max_min): New functions to process
+ Chill's CARD, MAX, MIN.
+ (evaluate_subexp_chill): Process UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN.
+
+ * expression.h (exp_opcode): Add UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN
+ for Chill's CARD, MAX, MIN.
+
+ * valarith.c (value_in): Add processing of TYPE_CODE_RANGE
+ and change return type from builtin_type_int to
+ builtin_type_chill_bool.
+
+Tue Mar 5 18:54:04 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/nm-nbsd.h (link_object, lo_name, etc): Move to here
+ from config/nm-nbsd.h.
+ * config/sparc/nm-nbsd.h (regs, fp_status, etc): Move to here
+ from config/sparc/tm-nbsd.h.
+
+ * config/m68k/nm-hp300hpux.h (FIVE_ARG_PTRACE): Define here
+ instead of in config/m68k/xm-hp300hpux.h.
+
+Tue Mar 5 12:05:35 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386b-nat.c, m68knbsd-nat.c (fetch_core_registers): Provide
+ implementation for NetBSD systems.
+
+Mon Mar 4 23:44:16 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valarith.c (binop_user_defined_p): Return 0 for BINOP_CONCAT.
+ (value_concat): Handle varying strings (add COERCE_VARYING_ARRAY).
+
+ * ch-lang.c (evaluate_subexp_chill case MULTI_SUBSCRIPT): Error
+ if "function" is pointer to non-function.
+
+Mon Mar 4 17:47:03 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (print_gdb_version): Update copyright year.
+
+Mon Mar 4 14:44:54 1996 Jeffrey A Law (law@cygnus.com)
+
+ From Peter Schauer:
+ * infrun.c (wait_for_inferior): Remove breakpoints and
+ switch terminal settings before calling SOLIB_ADD.
+ * solib.c (enable_break, SVR4 variant): Don't map in symbols
+ for the dynamic linker, the namespace pollution causes real
+ problems.
+
+Sun Mar 3 17:18:57 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (common_breakpoint): Explicitly terminate the
+ returned buffer.
+
+Wed Feb 28 22:32:18 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
+ * remote.c (remote_detach): Send a command 'D' to the target
+ when detaching, update the function's comments.
+
+Thu Jun 6 16:11:38 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (thread_cmd_list): New declaration.
+ (parse_int_arg): New function.
+
+Wed Jun 5 17:28:04 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.h (struct proc): Add DETACH_SC field.
+ * gnu-nat.c (make_proc): Set DETACH_SC.
+ (struct inf): Add DETACH_SC & DEFAULT_THREAD_DETACH_SC fields.
+ (make_inf): Set DETACH_SC & DEFAULT_THREAD_DETACH_SC fields.
+ (add_thread_commands): Add set/show for detach-suspend-count.
+ Add takeover-suspend-count cmd.
+ (inf_detach): Set suspend counts to the detach SC, not 0.
+ (set_thread_detach_sc_cmd, show_thread_detach_sc_cmd,
+ set_task_detach_sc_cmd, show_task_detach_sc_cmd,
+ set_thread_default_thread_detach_sc_cmd,
+ show_thread_default_thread_detach_sc_cmd): New functions.
+ (show_task_cmd): Also show detach-suspend-count values.
+ (thread_takeover_sc_cmd): New function.
+
+Fri May 31 16:49:24 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (show_thread_run_cmd): Actually print state.
+
+Thu May 30 10:47:56 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_signal): Make unforwardable exceptions an error.
+
+Tue May 28 17:06:36 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_stopped): proc_getprocinfo takes a
+ pointer to the flags now, not the flags themselves.
+
+Mon May 27 13:31:17 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_wait): Print debugging msgs for pending execs.
+ (gnu_create_inferior): Check return from ptrace.
+
+Sun May 26 16:56:35 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.h (struct proc): Add DEAD field.
+ * gnu-nat.c (make_proc): Initialize DEAD.
+ (inf_set_traced, inf_validate_task_sc, inf_validate_procs: Frob it.
+ (gnu_wait): Only abort for 0 threads if the task isn't dead.
+
+Sat May 25 17:06:05 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_signal): Pass SIGCODE when posting a signal.
+
+Wed May 22 18:44:28 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (S_proc_wait_reply): Add SIGCODE argument.
+ (inf_set_traced): Only give no-signal-thread error message if
+ turning *on* tracing.
+
+Wed May 15 13:03:16 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_procs): If INF has no threads, always
+ set inf->threads_up_to_date to 0.
+ (inf_signal): Pass in new SIGCODE argument to msg_sig_post_untraced.
+ (gnu_wait): Pass in new TIMEOUT arg to interrupt_operation.
+ (proc_update_sc): Cast thread state arg to thread_set_state.
+ (proc_get_state): Cast thread state arg to thread_get_state.
+ (inf_validate_task_sc): Cast task_basic_info arg to task_info.
+ * i386gnu-nat.c (gnu_fetch_registers, gnu_store_registers): Call
+ inf_update_procs before we lookup the thread.
+ * config/i386/i386gnu.mh (MH_CFLAGS): New variable.
+
+Tue May 7 17:52:33 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_kill_inferior): Use inf_set_task to clear the task.
+
+Mon May 6 19:06:49 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_set_traced): Use msg_set_init_int with
+ INIT_TRACEMASK instead of setting the exec flags.
+
+Fri May 3 19:10:57 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_procs): Don't clear INF->task if we find
+ the task's died, so others have a chance at it.
+ (gnu_resume): When single-stepping a single thread, given an error
+ if there is no such thread. When single-stepping one but running
+ the others, just given a warning and still run all the threads.
+ (gnu_wait): If there seem to be no threads, look harder, and
+ signal an error if there really aren't any.
+ (gnu_attach): Reset thread numbering to 0.
+
+ * i386gnu-nat.c (gnu_fetch_registers, gnu_store_registers): Give
+ thread name in warning messages.
+
+ * gnu-nat.c (active_inf): New function.
+ (show_sig_thread_cmd, show_stopped_cmd): Use it.
+ (info_port_rights, info_send_rights_cmd, info_port_sets_cmd,
+ info_recv_rights_cmd, info_port_rights_cmd, info_port_rights_cmd):
+ New functions.
+ (add_task_commands): Add new port-right info commands.
+
+Fri Apr 26 20:42:16 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_wait): Instead of _hurd_intr_rpc_mach_msg, just
+ use mach_msg with MACH_RCV_INTERRUPT.
+ (set_noninvasive_cmd): New function.
+ (add_task_commands): Add command entry for `set noninvasive'.
+
+Mon Mar 4 14:12:02 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_read_inferior): Use hurd_safe_memmove, not safe_bcopy.
+ (safe_bcopy): Function removed.
+
+Mon Dec 4 14:18:26 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (proc_update_sc): Assert only threads can have state.
+ (make_proc): Initialize state_valid & state_changed fields.
+
+Tue Nov 28 17:51:21 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * reply_mig_hack.awk: New file.
+
+Tue Nov 14 14:31:03 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * breakpoint.c (breakpoint_1): Print breakpoint thread field.
+
+ * lynx-nat.c (child_wait): Return TARGET_WAITKIND_SPURIOUS for new
+ threads.
+
+Mon Nov 13 18:30:53 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * target.c (debug_to_check_threads): New function.
+
+ * inflow.c (terminal_init_inferior_with_pgrp): New function.
+ (terminal_init_inferior): Call terminal_init_inferior_with_pgrp.
+ * inferior.h (terminal_init_inferior_with_pgrp): New declaration,
+ but only if PROCESS_GROUP_TYPE is defined.
+
+Mon Nov 6 16:42:09 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * target.c (debug_to_thread_alive): Pass through the return value.
+
+Thu Nov 2 18:05:00 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * target.c (signals, target_signal_from_host, target_signal_to_host):
+ Add mach exceptions.
+ * target.h (enum target_signal): Add mach exceptions.
+
+Mon Oct 30 16:41:04 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c: New file: gnu native backend.
+ * i386gnu-nat.c: New file: i386-specific part of gnu native backend.
+ * gnu-nat.h: New file.
+ * config/nm-gnu.h: New file.
+ * config/tm-i386gnu.h: New file.
+ * config/xm-i386gnu.h: New file.
+ * config/i386/i386gnu.mh: New file.
+ * config/i386/i386gnu.mt: New file.
+
+Wed Feb 28 15:50:12 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump version to 4.15.2 to establish
+ baseline for gdb 4.16 rerelease testing.
+
+Wed Feb 28 13:32:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c (som_solib_create_inferior_hook): Before returning
+ call clear_symtab_users.
+
+Tue Feb 27 00:04:46 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-e7000.c (e7000_open): Delete all breakpoints when
+ connecting to e7000. Change connect message to allow use of
+ monitor.exp in test suite.
+ * (e7000_load): Print transfer rate of download.
+ * symfile.c (generic_load): Print transfer rate of download.
+
+Sun Feb 25 13:58:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (mips*-*-vxworks*): New config.
+ * configure: Regenerated.
+
+ * config/mips/vxmips.mt, config/mips/tm-vxmips.h: New files.
+ * remote-vxmips.c (vx_convert_to_virtual, vx_convert_from_virtual):
+ Remove, never used.
+
+Sat Feb 24 12:30:28 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * partial-stab.h (case N_FUN): Function symbols generated
+ by SPARCworks cc have a meaningless zero value, do not update
+ pst->textlow if the function symbol value is zero.
+
+ * stabsread.c (define_symbol): Initialize SYMBOL_TYPE field
+ for function prototype declaration symbols.
+
+Fri Feb 23 22:33:04 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-e7000.c (e7000_load): New routine to download via the
+ network.
+ * (e7000_wait): Don't backup PC when we hit a breakpoint.
+ Apparantly new sh2 pods get this right...
+ * (e7000_ops): Add call to e7000_load.
+
+Thu Feb 22 00:52:42 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/m68k/{nbsd.mh,nbsd.mt,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h},
+ m68knbsd-nat.c: New files, support for NetBSD/m68k.
+
+ * configure.in (m68k-*-netbsd*): New config.
+ * configure: Regenerated.
+
+Wed Feb 21 19:00:21 1996 Fred Fish <fnf@cygnus.com>
+
+ * standalone.c (open, _initialize_standalone): Fix obvious typos
+ reported by Martin Pool <martin@citr.uq.oz.au>.
+
+Wed Feb 21 14:24:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * solib.c (solib_create_inferior_hook): Fix thinko.
+
+Tue Feb 20 23:59:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * solib.c (solib_break_names): Define for Solaris and Linux.
+ (enable_break): For SVR4 systems, first try to use the debugger
+ interfaces in the dynamic linker to track shared library events
+ as they happen, then fall back to BKPT_AT_SYMBOL code. Convert
+ BKPT_AT_SYMBOL code to use shared library event breakpoints.
+ (solib_create_inferior_hook): Simplify BKPT_AT_SYMBOL code,
+ it no longer needs to restart/wait on the inferior.
+ * symfile.c (find_lowest_section): No longer static.
+ * symfile.h (find_lowest_section): Corresponding changes.
+
+Tue Feb 20 18:54:08 1996 Fred Fish <fnf@cygnus.com>
+
+ * valops.c (COERCE_FLOAT_TO_DOUBLE): Define default value.
+ (value_arg_coerce): Use COERCE_FLOAT_TO_DOUBLE.
+ * config/alpha/tm-alpha.h (COERCE_FLOAT_TO_DOUBLE): Define to 1.
+ * config/mips/tm-mips.h: Ditto.
+ * config/pa/tm-hppa.h: Ditto.
+ * config/rs6000/tm-rs6000.h: Ditto.
+ * config/sparc/tm-sparc.h: Ditto.
+
+Tue Feb 20 17:32:05 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/{i386,ns32k}/nbsd.mh (NATDEPFILES): Remove core-aout.o.
+
+ * config/nm-nbsd.h (FETCH_INFERIOR_REGISTERS): Defined.
+ * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG):
+ #ifdef'd out definitions --- Causes serious gdb failures on
+ the i386. Need to investigate further before enabling.
+
+ * i386b-nat.c (fetch_inferior_registers, store_inferior_registers,
+ fetch_core_registers): New functions. These functions are defined
+ if FETCH_INFERIOR_REGISTERS is set. Registers are fetched/stored
+ with ptrace PT_GETREGS/PT_SETREGS.
+
+Tue Feb 20 16:55:06 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * findvar.c (extract_floating store_floating): Replace `long
+ double' with `DOUBLEST'.
+
+Mon Feb 19 15:25:51 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG):
+ Define.
+
+Mon Feb 19 10:32:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symtab.h (looup_minimal_symbol_solib_trampoline): Declare.
+
+ * breakpoint.h (remove_solib_event_breakpoints): Declare.
+ * breakpoint.c (remove_solib_event_breakpoints): New function.
+ * somsolib.c (solib_create_inferior_hook): Remove all solib event
+ breakpoints before inserting any new ones. Use a solib event
+ breakpoint for the breakpoint at "_start".
+ Remove extraneous "\n" from calls to warning.
+
+ * breakpoint.c (breakpoint_1): Add missing "sigtramp" to bptypes
+ name array.
+
+Mon Feb 19 01:09:32 1996 Doug Evans <dje@cygnus.com>
+
+ * dwarfread.c (add_partial_symbol): Use ADD_PSYMBOL_ADDR_TO_LIST
+ for CORE_ADDR values.
+ (new_symbol): Use SYMBOL_VALUE_ADDRESS for CORE_ADDR values.
+ * symfile.h (add_psymbol_{,addr}to_list): Add prototypes.
+
+Sun Feb 18 14:37:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (mipscoff_symfile_read): Unconditionally add
+ alpha coff dynamic symbols for all symbol files. Makes skipping
+ over the trampoline code work when stepping from a function in a
+ shared library into a function in a different shared library.
+
+Sun Feb 18 09:27:10 1996 Stu Grossman (grossman@cygnus.com)
+
+ * config/sparc/tm-sparc.h: Define PS_FLAG_CARRY. Define
+ RETURN_VALUE_ON_STACK to return long doubles on the stack.
+
+Sat Feb 17 16:33:11 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (ch-exp.o): Add dependencies.
+ (various): Add gdb_string.h to dependencies that need it.
+
+Sat Feb 17 08:57:50 1996 Fred Fish <fnf@cygnus.com>
+
+ * symmisc.c (print_symbol_bcache_statistics): Update description for
+ printing byte cache statistics.
+
+Thu Feb 16 16:02:03 1996 Stu Grossman (grossman@cygnus.com)
+
+ * Add native support for long double data type.
+ * c-exp.y (%union): Change dval to typed_val_float. Use DOUBLEST
+ to store actual data. Change types of INT and FLOAT tokens to
+ typed_val_int and typed_val_float respectively. Create new token
+ DOUBLE_KEYWORD to specify the string `double'. Make production
+ for FLOAT use type determined by parse_number. Add production for
+ "long double" data type.
+ * (parse_number): Use sscanf to parse numbers as float, double or
+ long double depending upon the type of typed_val_float.dval. Also
+ allow user to specify `f' or `l' suffix to explicitly specify
+ float or long double constants. Change typed_val to
+ typed_val_int.
+ * (yylex): Change typed_val to typed_val_int. Also, scan for
+ "double" keyword.
+ * coffread.c (decode_base_type): Add support for T_LNGDBL basic
+ type.
+ * configure, configure.in: Add check for long double support in
+ the host compiler.
+ * defs.h: Define DOUBLEST appropriatly depending on whether
+ HAVE_LONG_DOUBLE (from autoconf) is defined. Also, fix prototypes
+ for functions that handle this type.
+ * expression.h (union exp_element): doubleconst is now type
+ DOUBLEST.
+ * m2-exp.y f-exp.y (%union): dval becomes type DOUBLEST.
+ * findvar.c (extract_floating): Make return value be DOUBLEST.
+ Also, add support for numbers with size of long double.
+ * (store_floating): Arg `val' is now type DOUBLEST. Handle all
+ floating types.
+ * parser-defs.h parse.c (write_exp_elt_dblcst): Arg expelt is now
+ DOUBLEST.
+ * valarith.c (value_binop): Change temp variables v1, v2 and v to
+ type DOUBLEST. Coerce type of result to long double if either op
+ was of that type.
+ * valops.c (value_arg_coerce): If argument type is bigger than
+ double, coerce to long double.
+ * (call_function_by_hand): If REG_STRUCT_HAS_ADDR is defined, and
+ arg type is float and > 8 bytes, then use pointer-to-object
+ calling conventions.
+ * valprint.c (print_floating): Arg doub is now type DOUBLEST.
+ Use appropriate format and precision to print out floating point
+ values.
+ * value.h: Fixup prototypes for value_as_double,
+ value_from_double, and unpack_double to use DOUBLEST.
+ * values.c (record_latest_value): Remove check for invalid
+ floats. Allow history to store them so that people may examine
+ them in hex if they want.
+ * (value_as_double unpack_double): Change return value to DOUBLEST.
+ * (value_from_double): Arg `num' is now DOUBLEST.
+ * (using_struct_return): Use RETURN_VALUE_ON_STACK macro (target
+ specific) to expect certain types to always be returned on the stack.
+
+Fri Feb 16 14:00:54 1996 Fred Fish <fnf@cygnus.com>
+
+ * bcache.c, bcache.h: New files to implement a byte cache.
+ * Makefile.in (SFILES): Add bcache.c.
+ (symtab_h): Add bcache.h.
+ (HFILES_NO_SRCDIR): add bcache.h
+ (COMMON_OBJS): Add bcache.o
+ (bcache.o): New target.
+ * dbxread.c (start_psymtab): Make global_syms & static_syms
+ type "partial_symbol **".
+ * hpread.c (hpread_start_symtab): Ditto.
+ * os9kread.c (os9k_start_psymtab): Ditto.
+ * stabsread.h (start_psymtab): Ditto.
+ * {symfile.c, symfile.h} (start_psymtab_common): Ditto.
+ * maint.c (maintenance_print_statistics): Call
+ print_symbol_bcache_statistics.
+ * objfiles.c (allocate_objfile): Initialize psymbol bcache malloc
+ and free pointers.
+ * solib.c (allocate_rt_common_objfile): Ditto.
+ * symfile.c (reread_symbols): Ditto.
+ (free_objfile): Free psymbol bcache when objfile is freed.
+ (objfile_relocate): Use new indirect psymbol pointers.
+ * objfiles.h (struct objfile): Add psymbol cache.
+ * symfile.c (compare_psymbols): Now passed pointers to pointers to
+ psymbols.
+ (reread_symbols): Free psymbol bcache when freeing other objfile
+ resources.
+ (add_psymbol_to_list, add_psymbol_addr_to_list): Initialize new
+ psymbol using the psymbol bcache.
+ (init_psymbol_list): Psymbol lists now contain pointers rather than
+ the actual psymbols.
+ * symfile.h (psymbol_allocation_list): Psymbol lists now dynamically
+ grown arrays of pointers.
+ (ADD_PSYMBOL_VT_TO_LIST): Initialize new symbol using the psymbol
+ bcache.
+ * symmisc.c (print_partial_symbols): Now takes pointer to pointer
+ to partial symbol.
+ (print_symbol_bcache_statistics): New function to print per objfile
+ bcache statistics.
+ (print_partial_symbol, print_partial_symbols,
+ maintenance_check_symtabs, extend_psymbol_list):
+ Account for change to pointer to pointer to partial symbol.
+ * symtab.c (find_pc_psymbol, lookup_partial_symbol, decode_line_2,
+ make_symbol_completion_list):
+ Account for change to pointer to pointer to partial symbol.
+ * symtab.h (bcache.h): Include.
+ * xcoffread.c (xcoff_start_psymtab): Make global_syms & static_syms
+ type "partial_symbol **".
+
+Fri Feb 16 10:02:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * dwarfread.c (free_utypes): New function.
+ (read_file_scope): Call free_utypes as cleanup, rather than just
+ freeing the utypes pointer.
+
+Thu Feb 15 21:40:52 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * demangle.c (is_cplus_marker): New function, checks if a
+ character is one of the commonly used C++ marker characters.
+ * defs.h (is_cplus_marker): Add prototype.
+ * c-typeprint.c (c_type_print_base), ch-lang.c (chill_demangle),
+ cp-valprint.c (cp_print_class_method), mdebugread.c (parse_symbol),
+ stabsread.c (define_symbol, read_member_functions, read_struct_fields),
+ symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P),
+ values.c (vb_match): Use is_cplus_marker instead of comparison
+ with CPLUS_MARKER.
+
+Thu Feb 15 18:08:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.h (INLINE_ADD_PSYMBOL): Default this to 0 and possibly
+ delete entirely someday.
+
+Thu Feb 15 15:25:34 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit out makefile rebuild rule.
+ (host_alias, target_alias): Comment out instead of deleting.
+ (@LIBS@): Edit out references.
+
+Tue Feb 13 22:56:46 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+ Use n_psyms in OBJSTAT, not psyms.
+
+Mon Feb 12 15:59:31 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in (sparclet-*-aout*): New config.
+ * configure: Regenerated.
+
+Mon Feb 12 14:17:52 1996 Fred Fish <fnf@cygnus.com>
+
+ * somsolib.c (som_solib_add): Use xmalloc rather than bare
+ unchecked call to malloc.
+ * remote-mips.c (pmon_load_fast): ditto.
+ * remote-mm.c (mm_open): ditto.
+ * hpread.c (hpread_lookup_type): ditto.
+ * remote-adapt.c (adapt_open): ditto.
+
+Mon Feb 12 13:11:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * f-lang.c (allocate_saved_bf_node, allocate_saved_function_node,
+ allocate_saved_f77_common_node, allocate_common_entry_node,
+ add_common_block): Use xmalloc rather than malloc, some of which
+ were unchecked.
+ * gnu-regex.c: At same point as other gdb specific changes
+ #undef malloc and then #define it to xmalloc.
+ * ch-exp.c (growbuf_by_size): Use xmalloc/xrealloc rather than
+ bare unchecked calls to malloc/realloc.
+ * stabsread.c (dbx_lookup_type): Use xmalloc rather than bare
+ unchecked call to malloc.
+
+Wed Feb 7 11:31:26 1996 Stu Grossman (grossman@cygnus.com)
+
+ * symtab.c (gdb_mangle_name): Change opname var to be const to
+ match return val of cplus_mangle_name.
+ * i960-tdep.c: Change arg types of next_insn to match callers.
+
+Wed Feb 7 07:34:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/linux.mh (XM_CLIBS, GDBSERVER_LIBS): Remove. These
+ apparently aren't needed in any reasonably recent version of
+ linux.
+
+Tue Feb 6 21:37:03 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_range_type): If !self-subrange and language
+ is Chill, assume a true range. If a true_range is a sub_subrange,
+ use builtin_type_int for index_type.
+
+Tue Feb 6 18:38:51 1996 J.T. Conklin <jtc@slave.cygnus.com>
+
+ * nindy-share/nindy.c (say): Use stdarg.h macros when compiling
+ with an ANSI compiler.
+
+Mon Feb 5 18:24:28 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ From Michael_Snyder@NeXT.COM (Michael Snyder):
+ * valops.c (value_arg_coerce): Coerce float to double, unless the
+ function prototype specifies float.
+
+Mon Feb 5 09:51:55 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * language.c (set_language_command): Use languages table when
+ printing available languages.
+
+Sat Feb 3 12:22:05 1996 Fred Fish <fnf@cygnus.com>
+
+ Fix problems reported by Hans Verkuil (hans@wyst.hobby.nl):
+ * command.c (add_cmd): Add missing initialization for enums member.
+ Reorder members to match structure declaration to make it easier to
+ tell when one is missing.
+ * exec.c (exec_file_command): Fix problem where filename in malloc'd
+ memory is referenced after being freed.
+
+Sat Feb 3 03:26:21 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarfread.c (read_func_scope): Avoid GDB core dumps if
+ AT_name tag is missing.
+
+ * procfs.c (procfs_stopped_by_watchpoint): Fix logic when
+ FLTWATCH and FLTKWATCH are defined.
+
+ * remote.c (remote_read_bytes): Advance memaddr for transfers,
+ return number of bytes transferred for partial reads.
+
+ * top.c (init_signals): Reset SIGTRAP to SIG_DFL.
+
+Fri Feb 2 13:40:50 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * win32-nat.c (mappings): Add ppc registers.
+ (child_resume): Turn off step for ppc.
+
+Thu Feb 1 10:29:31 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/powerpc/(cygwin32.mh, cygwin32.mt, tm-cygwin32.h,
+ xm-cygwin32.h): New.
+ * config/i386/(*win32*): Becomes *cygwin32*.
+ * configure.in (i[3456]86-*-win32*): Becomes i[3456]86-*-cygwin32.
+ (powerpcle-*-cygwin32): New.
+ * configure: Regenerate.
+ * win32-nat.c (child_create_inferior): Call CreateProcess
+ with the right program arg.
+
+Thu Feb 1 11:01:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (SOFT_FLOAT): Provide a default definition.
+
+Wed Jan 31 19:01:28 1996 Fred Fish <fnf@cygnus.com>
+
+ * serial.c: Change fputc/fputs/fprintf to _unfiltered forms.
+
+Wed Jan 31 18:36:27 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sparc/xm-sun4os4.h (HAVE_TERMIOS): Remove.
+
+ * config/sparc/xm-sparc.h (HAVE_WAIT_STRUCT): Remove, never used.
+
+ * config/i386/nm-i386mach.h (CHILD_PREPARE_TO_STORE): Move to
+ here from config/i386/xm-i386mach.h, fix name.
+ * config/i386/nm-sun386.h: Ditto, from config/i386/xm-sun386.h.
+ * config/i386/nm-ptx4.h (CHILD_PREPARE_TO_STORE): Move to
+ here from config/i386/xm-ptx4.h.
+ * config/i386/nm-ptx4.h: Ditto, from config/i386/xm-ptx.h.
+ * config/i386/nm-symmetry.h: Ditto, from config/i386/xm-symmetry.h.
+ * config/m68k/nm-sun3.h: Ditto, from config/m68k/xm-sun3.h.
+ * config/sparc/nm-nbsd.h: Ditto, from config/sparc/xm-nbsd.h.
+ * config/sparc/nm-sun4os4: Ditto, from config/sparc/xm-sparc.h.
+
+ * config/sparc/nm-sun4sol2.h: New file, renamed from nm-sysv4.h.
+ (PRSVADDR_BROKEN): Move here from xm-sun4sol2.h.
+ * config/sparc/sun4sol2.mh (NAT_FILE): Update.
+
+Wed Jan 31 17:20:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Handle software
+ floating point correctly.
+ (STORE_RETURN_VALUE): Likewise.
+ * config/pa/tm-pro.h (SOFT_FLOAT): define.
+
+Wed Jan 31 13:34:52 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ Define to what should be reasonable values. However, apparently
+ a bug in linux mmap prevents mapped symbol tables from working.
+
+Tue Jan 30 18:26:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * defs.h (errno.h>: Move #include closer to head of file to solve
+ obscure problem with systems that declare perror with const arg, in
+ both errno.h and stdio.h, and const is defined away by intervening
+ local include.
+
+Tue Jan 30 15:41:10 1996 Fred Fish <fnf@cygnus.com>
+
+ From Jon Reeves <reeves@zk3.dec.com>:
+ * i386-stub.c (getpacket): Change fprintf stream from "gdb" to stderr.
+ (mem_fault_routine): Fix misplaced volatile type qualifier in decl.
+
+Mon Jan 29 19:05:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (diststuff): Make all-doc; diststuff target does not
+ exist in doc/Makefile.in.
+
+Mon Jan 29 18:44:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/m88k/xm-cxux.h (BP_HIT_COUNT): Remove, never used.
+
+Mon Jan 29 00:10:35 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-valprint.c (calculate_array_length): New function to
+ determine the length of an array type.
+ (chill_val_print (case TYPE_CODE_ARRAY)): If the length of an
+ array type is zero, call calculate_array_length.
+
+ * gdbtypes.c (get_discrete_bounds (case TYPE_CODE_ENUM)): The
+ values may not be sorted. Scan all entries and set the real lower
+ and upper bound.
+
+Sun Jan 28 15:50:42 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/xm-linux.h: Move include of solib.h and #define of
+ SVR4_SHARED_LIBS from here ...
+ * config/nm-linux.h: ...to here.
+
+Sat Jan 27 10:34:05 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for sys/procfs.h.
+ Also check for gregset_t and fpregset_t types.
+ * configure: Regenerate.
+ * core-regset.c (sys/procfs.h): Only include if HAVE_SYS_PROCFS_H
+ is defined.
+ (fetch_core_registers): Turn into stub unless both HAVE_GREGSET_T
+ and HAVE_FPREGSET_T are defined. These changes allow systems
+ like linux that are migrating to /proc support to use a single
+ configuration for both new and old versions.
+
+ * config/i386/linux.mt: Note that this is now for both a.out and
+ ELF systems.
+ * config/i386/linux.mh (NATDEPFILES): Add solib.o, core-regset.o,
+ i386v4-nat.o
+ * config/i386/tm-linux.h (tm-sysv4.h): Include.
+ * config/i386/xm-linux.h (solib.h): Include
+ (SVR4_SHARED_LIBS): Define.
+ * i386v4-nat.c: Only compile if HAVE_SYS_PROCFS_H is defined.
+ (supply_gregset, fill_gregset): Compile if HAVE_GREGSET_T defined.
+ (supply_fpregset, fill_fpregset): Compile if HAVE_FPREGSET_T
+ defined.
+
+Fri Jan 26 13:48:14 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sparc/xm-sparc.h (NEW_SUN_CORE): Remove, never used.
+ * config/i386/xm-sun386.h: Ditto.
+ * config/m68k/xm-sun2.h, config/m68k/xm-sun3.h: Ditto.
+
+Thu Jan 25 16:05:53 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (INSTALLED_LIBS, CLIBS): Include @LIBS@.
+
+Thu Jan 25 09:22:15 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ From Greg McGary <gkm@gnu.ai.mit.edu>:
+ * dcache.c (dcache_peek, dcache_poke): Advance addr for
+ multi-byte I/O.
+
+Thu Jan 25 13:08:51 1996 Doug Evans (dje@cygnus.com)
+
+ * infrun.c (normal_stop): Fix test for shared library event.
+
+Thu Jan 25 03:26:38 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in (sparc64-*-*): Add default host configuration.
+ (sparc64-*-solaris2*): Add target configuration.
+ (sparc64-*-solaris2* host): Link statically if GCC used.
+ * configure: Regenerated.
+ * sparc/sp64sol2.mt: New file.
+
+Wed Jan 24 22:31:37 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * Makefile.in (RUNTEST): srcdir renamed to rootsrc.
+
+Wed Jan 24 15:42:24 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (lint): Close backquotes.
+
+Wed Jan 24 13:19:10 1996 Fred Fish <fnf@cygnus.com>
+
+ * NEWS: Make note of new record and replay feature for
+ remote debug sessions.
+ * serial.c (gdbcmd.h): Include.
+ (serial_logfile, serial_logfp, serial_reading, serial_writing):
+ Define here, for remote debug session logging.
+ (serial_log_command, serial_logchar, serial_write, serial_readchar):
+ New functions for remote debug session logging.
+ (serial_open): Open remote debug session log file when needed.
+ (serial_close): Close remote debug session log file when needed.
+ (_initialize_serial): Add set/show commands for name of remote
+ debug session log file.
+ * serial.h (serial_readchar): Declare
+ (SERIAL_READCHAR): Call serial_readchar().
+ (SERIAL_WRITE): Call serial_write().
+ (serial_close): Declare as extern.
+ (serial_logfile, serial_logfp): Declare.
+ * top.c (execute_command): Declare serial_logfp. Log user command
+ in remote debug session log if log file is open.
+ * remote-array.c (array_wait): #ifdef out echo to gdb_stdout.
+ (array_read_inferior_memory): Rewrite to fix memory overwrite bug.
+ * remote-array.c (SREC_SIZE): Remove, duplicates define in
+ monitor.h.
+ * remote-array.c (hexchars, hex2mem): Remove, unused.
+ * gdbserver/low-linux.c (store_inferior_registers): Remove
+ unnecessary extern declaration of registers[].
+ * gdbserver/Makefile.in (all): Add gdbreplay.
+ * gdbserver/gdbreplay.c: New file.
+ * gdbserver/README: Give example of recording a remote
+ debug session with gdb and then replaying it with gdbreplay.
+
+Tue Jan 23 18:02:35 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (rs6000_builtin_type): Make bool type unsigned.
+ (read_one_struct_field): Support boolean bitfields.
+ * c-valprint.c (c_val_print): Print booleans properly.
+
+Tue Jan 23 18:54:09 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-vxsparc.c (vx_convert_to_virtual, vx_convert_from_virtual):
+ Remove, never used.
+ * config/sparc/vxsparc.mt (TDEPFILES): Add remote-vxsparc.o.
+
+Tue Jan 23 14:36:05 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.c (parse_tuple): Error if invalid mode.
+
+ * value.h (COERCE_ARRAY): Don't coerce enums.
+ (COERCE_ENUM): Don't COERCE_REF.
+ (COERCE_NUMBER): New macro (same as COERCE_ARRAY then COERCE_ENUM).
+ * valops.c (value_assign): Only do COERCE_ARRAY if internalvar (let
+ value_cast handle it otherwise); do *not* COERCE_ENUM either way.
+ * valarith.c: Use COERCE_NUMBER instead od COEREC_ARRAY.
+ Add COERCE_REF before COERCE_ENUM.
+ * values.c (value_as_long): Simplify.
+
+ * valops.c (value_array): Create internalvar if !c_style_arrays.
+
+ * language.c (lang_bool_type): Add Fortran support.
+ * eval.c (OP_BOOL): Use LA_BOOL_TYPE.
+
+Tue Jan 23 13:08:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
+ All references changed.
+ * breakpoint.c (bpstat_what): Add shlib_event to the class types.
+ Update state table. Reformat so that it's still readable.
+ When we hit the shlib_event breakpoint, set the calss of shlib_event.
+ (breakpoint_1): Add "shlib events" as a breakpoint type.
+ Print the shlib_event breakpoint like other breakpoints.
+ (create_solib_event_breakpoint): New function.
+ (breakpoint_re_set_one): Handle solib_event breakpoints.
+ * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
+ (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
+ action.
+ (create_solib_event_breakpoint): Declare.
+ * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
+ (normal_stop): Inform the user when the inferior stoped due
+ to a shared library event.
+ (_initialize_infrun): Add new set/show variable "stop-on-solib-events"
+ to control whether or not gdb continues the inferior or stops it when
+ a shared library event occurs.
+ * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
+ * somsolib.c (TODO list): Update.
+ (som_solib_create_inferior_hook): Arrange for gdb to be notified
+ when significant shared library events occur.
+ * hppa-tdep.c (find_unwind_entry): No longer static.
+
+Tue Jan 23 09:00:48 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * printcmd.c (print_insn): Pass fprintf_unfiltered to
+ INIT_DISASSEMBLE_INFO.
+
+Mon Jan 22 16:59:40 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (remotebreak): New GDB variable.
+ (remote_break): New global.
+ (remote_interrupt): Send a break instead of ^C if remote_break.
+ * NEWS: Describe the new variable.
+
+Mon Jan 22 16:24:11 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-tdep.c (_initialize_sparc_tdep): Always use print_insn_sparc.
+
+Fri Jan 19 07:19:38 1996 Fred Fish <fnf@cygnus.com>
+
+ * hp300ux-nat.c (getpagesize): Remove unused function
+ fetch_core_registers.
+ (hp300ux_core_fns): Remove, is unused.
+ (_initialize_core_hp300ux): Remove, is unused.
+ (gdbcore.h): Remove #include, no longer needed.
+
+Fri Jan 19 00:59:53 1996 Jeffrey A Law (law@cygnus.com)
+
+ * rs6000-nat.c (exec_one_dummy_insn): Rework to avoid
+ ptrace bug in aix4.1.3 on the rs6000.
+
+Wed Jan 17 13:22:27 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-hms.c (hms_ops): Add value for to_thread_alive.
+ * remote-nindy.c (nindy_ops): Ditto.
+ * remote-udi.c (udi_ops): Ditto.
+
+Tue Jan 16 18:00:35 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (pmon_opn, pmon_wait, pmon_makeb64, pmon_zeroset,
+ pmon_checkset, pmon_make_fastrec, pmon_check_ack,
+ pmon_load_fast): New functions. Support for the PMON monitor world.
+ (common_open): New function to merge support for different monitors.
+ (mips_open): Use common_open().
+ (mips_send_command): New function.
+ (mips_send_packet): Scan out-of-sequence packets.
+ (mips_enter_debug, mips_exit_debug): New functions.
+ (pmon_ops): New target definition structure.
+
+Tue Jan 16 11:22:58 1996 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (CLIBS): Add LIBS to allow libraries to be
+ specified on the make command line (via make LIBS=xxx).
+
+
+Fri Jan 12 21:41:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symtab.c (find_pc_symtab): Don't lose if OBJF_REORDERED
+ is set but there are no psymtabs.
+
+Fri Jan 12 15:56:12 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * dsrec.c (load_srec): Remove unused variable.
+ * monitor.c (monitor_expect): Don't expect a ^C to echo.
+ * serial.c (serial_open): Add parallel interface.
+ * sh3-rom.c (parallel, parallel_in_use): New.
+ (sh3_load): If parallel_in_use, download though the
+ parallel port.
+ (sh3_open): Open parallel port if specified.
+ (sh3_close): New function.
+ (_inititalize_sh3): Add sh3_close hook and documentation.
+ * monitor.c (monitor_close): Export.
+ * monitor.h (monitor_close): Add prototype.
+
+Fri Jan 12 13:11:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
+ * remote.c (remotetimeout): New GDB variable, use to set the
+ remote timeout for reading.
+
+Fri Jan 12 07:14:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * lynx-nat.c, irix4-nat.c, sparc-nat.c: Include gdbcore.h
+ to get "struct core_fns" defined.
+ * Makefile.in (lynx-nat.o, irix4-nat.o, sparc-nat.o):
+ Are dependent upon gdbcore_h.
+
+Thu Jan 11 23:13:24 1996 Per Bothner <bothner@cygnus.com>
+
+ * symfile.c (decrement_reading_symtab): New function.
+ * symfile.c, symtab.h (currently_reading_symtab): New variable.
+ * symfile.c (psymtab_to_symtab): Adjust currently_reading_symtab.
+ * gdbtypes.c (check_typedef): Don't call lookup_symbol if
+ currently_reading_symtab (since that could infinitely recurse).
+
+Thu Jan 11 17:21:25 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_struct_type): Trivial simplification.
+
+ * stabsread.c (define-symbol): Use invisible references
+ for TYPE_CODE_SET and TYPE_CODE_BITSTRING too.
+ * valops.c (call_function_by_hand): Likewise.
+ * eval.c (evaluate_subexp_standard): When known, use the formal
+ parameter type as the expected type when evaluating arg expressions.
+ * ch-lang.c (evaluate_subexp_chill): Likewise (for MULTI_SUBSCRIPT).
+
+Thu Jan 11 10:08:14 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * main.c (main): Disable window interface if --help or --version
+ specified.
+
+Wed Jan 10 16:08:49 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in, configure: Recognize rs6000-*-aix4*.
+ * config/powerpc/xm-aix.h: Reduce to include "xm-aix4.h".
+ * config/rs6000/aix4.mh (XM_FILE): Point to xm-aix4.h.
+ * config/rs6000/xm-aix4.h: New file.
+ * config/xm-aix4.h: New file.
+
+Wed Jan 10 11:25:37 1996 Fred Fish <fnf@cygnus.com>
+
+ From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
+ * gdbserver/low-linux.c: New file.
+ * remote.c (remote_read_bytes): Fix aborts on larger packets.
+
+ * config/i386/linux.mh (GDBSERVER_DEPFILES, GDBSERVER_LIBS):
+ Define.
+ * stabsread.c (define_symbol): If register value is too large,
+ tell what it is and what max is.
+
+Tue Jan 9 09:33:53 1996 Jeffrey A Law (law@cygnus.com)
+
+ * hpread.c (hpread_build_psymtabs): Finish Jan 4th
+ enum namespace -> enum_namespace change.
+
+Tue Jan 9 04:44:47 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (parse_primval): In case ARRAY, add missing
+ FORWARD_TOKEN ().
+
+Mon Jan 8 13:29:34 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-mips.c (mips_receive_header): Recognize \012 instead
+ of \n, but write \n when program sends a \012.
+ * ser-mac.c (mac_input_buffer): Increase size of buffer.
+
+Mon Jan 8 12:00:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infptrace.c (initialize_infptrace): Move function out of
+ #ifdef conditional; put code within the function inside an
+ #ifdef conditional.
+
+ * buildsym.c (end_symtab): Remove sort_pending and sort_linevec
+ arguments. Sorting is now dependent on OBJF_REORDERED. All
+ callers/references changed.
+ * dbxread.c (read_ofile_symtab): Correctly determine value for
+ last_source_start_addr for reordered executables.
+ (process_one_symbol): Handle N_FUN with no name as an end of
+ function marker.
+ * partial-stab.h (case N_FN, N_TEXT): Don't assume CUR_SYMBOL_VALUE
+ is the high text address for a psymtab.
+ (case N_SO): Likewise.
+ (case N_FUN): Handle N_FUN with no name as an end of function
+ marker.
+ * minsyms.c (lookup_minimal_symbol_by_pc): Examine all symbols
+ at the same address rather than a random subset of them.
+ * coffread.c (coff_symfile_init): Set OBJF_REORDERED.
+ * elfread.c (elf_symfile_init): Similarly.
+ * somread.c (som_symfile_init): Similarly.
+ * xcoffread.c (xcoff_symfile_init): Similarly.
+
+Fri Jan 5 17:46:01 1996 Stu Grossman (grossman@cygnus.com)
+
+ * stack.c (print_stack_frame print_frame_info) symmisc.c
+ (dump_symtab): Change RETURN_MASK_ERROR to RETURN_MASK_ALL so
+ that catch_errors doesn't get blindsided by QUIT and lose the
+ cleanup chain. This fixes a problem where ^C while in a
+ user-defined command sometimes leaves instream NULL and causes a
+ segfault in command_loop.
+
+Fri Jan 5 13:59:16 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in, configure: Add `-ldl -lw' for Solaris linking.
+
+Fri Jan 5 12:02:00 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/sh/sh.mt, config/powerpc/*.mt, config/pa/hppapro.mt,
+ config/m68k/monitor.mt, config/h8500/h8500.mt, config/h8300/h8300.mt:
+ srec.o renamed to dsrec.o.
+
+Thu Jan 4 16:04:54 1996 Stu Grossman (grossman@cygnus.com)
+
+ * breakpoint.c (remove_breakpoint): Change error to warning so
+ that hardware watchpoint removal problems won't leave breakpoint
+ traps in the target.
+ * remote-e7000.c (e7000_insert_breakpoint,
+ e7000_remove_breakpoint): Use e7000 based breakpoints, not memory
+ breakpoints.
+ * (e7000_wait): Adjust PC back by two when we see a breakpoint to
+ compensate for e7000 maladjustment.
+ * sparcl-tdep.c (sparclite_check_watch_resources): Fix logic bug
+ which prevented hardware watchpoints from working.
+
+Thu Jan 4 10:44:17 1996 Fred Fish <fnf@cygnus.com>
+
+ * infptrace.c (udot_info): New function.
+ (PT_*): Define each individually if that one is not defined.
+ * rs6000-nat.c (kernel_u_size): New function
+ Include <sys/user.h> for "struct user"
+ * alpha-nat.c (kernel_u_size): New function.
+ Include <sys/user.h> for "struct user"
+ * sparc-nat.c (kernel_u_size): New function.
+ Include <sys/user.h> for "struct user"
+ * i386b-nat.c (kernel_u_size): New function.
+ * i386v-nat.c (kernel_u_size): New function.
+ * config/i386/nm-fbsd.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/i386/nm-linux.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/sparc/nm-sun4os4.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/alpha/nm-osf2.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/rs6000/nm-rs6000.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+
+Thu Jan 4 11:00:01 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * mdebugread.c (mylookup_symbol): enum namespace becomes
+ enum_namespace type.
+ * symfile.c (add_psymbol_to_list)
+ (add_psymbol_addr_to_list): Ditto.
+ * symtab.c (lookup_partial_symbol): Ditto.
+ (lookup_symbol): Ditto.
+ (lookup_block_symbol): Ditto.
+ * win32-nat.c (handle_load_dll): Use incoming dll base.
+ (child_wait): Catch DLL load errors.
+ (create_child_inferior): Translated between paths correctly.
+
+Wed Jan 3 23:13:53 1996 Fred Fish <fnf@cygnus.com>
+
+ * i386v4-nat.c (supply_gregset, fill_gregset): Subtract NUM_FREGS
+ from NUM_REGS to get number of general registers that we care about.
+ * config/i386/tm-i386.h (REGISTER_BYTES): Define in terms
+ of number of general regs and number of floating point regs.
+
+Wed Jan 3 19:49:54 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * config/i386/tm-win32.h (IN_SOLIB_CALL_TRAMPOLINE): New.
+ (SKIP_TRAMPOLINE_CODE): New.
+ * config/i386/xm-win32.h (CANT_FORK): Deleted.
+ (SLASH*) Changed to use unix style slash.
+ * symtab.h (namespace enum): becomes typedef to avoid namespace
+ collision in C++.
+ * infcmd.c (path_command): Use empty string if PATH name not set.
+ * i386-tdep.c (skip_trampoline_code): New function.
+ * srec.c: Renamed dsrec.c to avoid filename collision.
+ * Makefile.in: Cope with renaming.
+
+Wed Jan 3 13:09:04 1996 Fred Fish <fnf@cygnus.com>
+
+ * symmisc.c (print_objfile_statistics): Print memory use statistics
+ for objfile psymbol, symbol, and type obstacks.
+
+Tue Jan 2 13:41:14 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/mips/nm-irix5.h: Restore.
+ (TARGET_HAS_HARDWARE_WATCHPOINTS, etc): Define as for Irix 4;
+ from Lee Iverson <leei@ai.sri.com>.
+ * config/mips/irix5.mh (NAT_FILE): Use nm-irix5.h.
+ * config/mips/irix[345].mh (MUNCH_DEFINE): Remove.
+
+For older changes see ChangeLog-95
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/contrib/gdb/gdb/ChangeLog-97 b/contrib/gdb/gdb/ChangeLog-97
new file mode 100644
index 0000000..4f9a949
--- /dev/null
+++ b/contrib/gdb/gdb/ChangeLog-97
@@ -0,0 +1,2855 @@
+Wed Dec 31 11:43:53 1997 Mark Alexander <marka@cygnus.com>
+
+ * dsrec.c (load_srec): Check remotedebug flag when printing
+ debug info.
+
+Wed Dec 31 10:33:15 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * breakpoint.c (breakpoint_re_set): add _siglongjmp to list of
+ longjmp breakpoints.
+
+Mon Dec 29 21:25:34 1997 Mark Alexander <marka@cygnus.com>
+
+ * dve3900-rom.c: New file to support Densan DVE-R3900/20 board.
+ * monitor.c (monitor_debug): Move to utils.c, rename to puts_debug.
+ (monitor_write_memory, monitor_read_memory, monitor_insert_breakpoint,
+ monitor_remove_breakpoint): Remove useless address bits if current
+ monitor has MO_ADDR_BITS_REMOVE flag.
+ * monitor.h (MO_ADDR_BITS_REMOVE): Define.
+ * utils.c (puts_debug): Formerly monitor_debug from monitor.c;
+ move here and make public. Add better support for carriage returns.
+ * defs.h (puts_debug): Declare.
+ * dsrec.c (load_srec): Use puts_debug to print remotedebug information.
+ Output header record correctly.
+ (make_srec): Output a header record instead of a termination record
+ if sect is non-NULL (value is ignored), but abfd is NULL.
+ * config/mips/tm-tx39.h (DEFAULT_MIPS_TYPE): Remove definition.
+ (REGISTER_NAMES): Define to add R3900-specific registers.
+ * config/mips/tm-tx39l.h: Ditto.
+ * config/mips/tx39.mt (TDEPFILES): Add dve3900-rom.o and support files.
+ * config/mips/tx39l.mt: Ditto.
+
+Wed Dec 24 12:48:48 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dsrec.c: Cosmetic improvements.
+ (make-srec): Change indexing of format and code tables to
+ remove confusing empty entries.
+
+Mon Dec 22 21:51:53 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (_initialize_remote_mips): Fix DDB doc string.
+
+Sun Dec 21 17:00:06 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c (d30v_frame_find_saved_regs): split most of
+ function off into d30v_frame_find_saved_regs_offsets;
+ (d30v_frame_find_saved_regs_offsets): new function. Got
+ backtrace working when calling from framefull (unoptimized)
+ routines (.e.g, main) into frameless (optimized) routines
+ (e.g., printf).
+
+Fri Dec 19 09:49:49 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c (d30v_frame_chain): test end_of_stack
+ (d30v_frame_find_saved_regs): set it.
+ * config/d30v/tm-d30v.h: improved FRAME_CHAIN_VALID
+
+Thu Dec 18 12:34:28 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Gavin Koch <gavin@cygnus.com>: mips-tdep.c
+ * (mips_push_arguments): For big-endian shorts and char's store at
+ * the correct location.
+
+Thu Dec 18 00:26:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): Delete check that symbols
+ for file not already loaded. Did not work when an include file
+ was involved.
+
+Wed Dec 17 10:43:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * elfread.c (elf_symfile_read): Since the partial symbol table is
+ searched last in first, insert mdebug or XCOFF info into the
+ partial symbol table before any DWARF2 info.
+
+Thu Dec 18 00:00:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symfile.c (init_psymbol_list): Handle init with zero elements.
+
+ * elfread.c (elf_symfile_read): If `mainline', clear psymbol table
+ using init_psymbol_list 0. For build_psymtabs functions, pass
+ mainline==0 so that psymbol_list isn't re-initialized.
+
+ * symfile.c (discard_psymtab): New function, correctly unlink an
+ empty psymtab from an object file.
+ * dbxread.c (end_psymtab): Call discard_psymtab.
+ * xcoffread.c (xcoff_end_psymtab): Ditto.
+ * hpread.c (hpread_end_psymtab): Ditto.
+ * os9kread.c (os9k_end_psymtab): Ditto.
+
+Wed Dec 17 10:47:05 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (set_raw_tracepoint): initialize addr_string
+ to NULL; (trace_actions_command): call readline_begin_hook only
+ if from_tty is true.
+
+Tue Dec 16 20:05:48 1997 Mark Alexander <marka@cygnus.com>
+
+ * configure.tgt: Change little-endian tx39 target name to tx39l.
+
+Tue Dec 16 11:24:30 1997 Jeffrey A Law (law@cygnus.com)
+
+ * remote-sim.c (gdbsim_open): Use "--architecture" instead of
+ ambigious short form.
+
+Tue Dec 16 10:29:16 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c (d30v_frame_chain): don't or in DMEM_START to
+ FP_REGNUM value before return; (prologue_find_regs): two sets
+ of offsets -- frame pointer and stack pointer, not just one that
+ tries to do double duty; (d30v_frame_find_saved_regs): stop once
+ we hit pc (in case we're stopped in the middle of the prologue)
+ and improve handling of frameless prologues; (d30v_push_arguments):
+ *ALL* arguments go on the stack until we run out of args registers,
+ force sp to be 8 byte aligned.
+
+ * config/tm-d30v.h (EXTRACT_STRUCT_VALUE_ADDRESS): fix, it's r2,
+ not r0; (FRAME_CHAIN_VALID): handle use of external memory;
+ (STACK_ALIGN): define.
+
+Mon Dec 15 15:13:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_wait): When HAVE_SIGACTION and SA_RESTART
+ intall cntrl-c handler with SA_RESTART clear. On BSD systems this
+ stops read syscalls's being restarted.
+
+ * configure.in (configdirs): Check for sigaction.
+ * configure: Re-generate.
+
+Mon Dec 15 11:38:52 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c: From change proposed by Gavin Koch.
+ (address_significant_size): New static variable.
+ (dwarf2_build_psymtabs_hard): Check consistency between
+ `address_size' and `address_significant_size'.
+ (read_address): MASK out all but the significant bits, as
+ determined by `address_significant_size', of any addresses.
+ (elf-bfd.h): Include.
+ (dwarf2_build_psymtabs_hard): Set `address_significant_size'
+ according to the arch_size of the elf object file.
+
+Thu Dec 11 13:40:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (dwarf_decode_lines): Change type of address to
+ CORE_ADDR.
+
+Thu Dec 11 14:28:01 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (trace_find_command): don't error if going
+ backwards thru the trace buffer in a loop.
+ * (struct tracepoint): delete unused field.
+
+Wed Dec 10 17:57:00 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c : don't bury lots of magic numbers in the code
+ instead use defines for the opcodes and opcode masks; update
+ to use actual d30v patterns; fix register sizes to be 4 bytes
+ not 2 bytes; improve prologue testing now that we have a C
+ compiler; fix stack frame handling enough to get backtraces
+ working; initial changes to push and pop frames (so that gdb
+ can call functions in the inferior).
+
+ * config/d30v/tm-d30v.h: update DMEM_START, IMEM_START, and
+ STACK_START; change FR_REGNUM to 61 (was 11). Reformat comment
+ about DUMMY FRAMES so that it is readable. Fix SAVED_PC_AFTER_FRAME
+ macro.
+
+Wed Dec 10 17:41:07 1997 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ch-valprint.c (chill_val_print): To avoid segfaults, don't print
+ a string whose dynamic length is longer than its static length.
+
+Wed Dec 10 15:54:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Check
+ cu_header.length is within dwarf_info_buffer not
+ dwarf_abbrev_buffer.
+
+Mon Dec 8 14:28:49 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (memrange_sortmerge): allow for memranges
+ that overlap. (collect_pseudocommand etc.) cleanup decls.
+
+Fri Dec 5 09:22:35 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Reverted back to old value...
+
+Thu Dec 4 09:30:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Changed to match new value.
+
+Wed Dec 3 12:44:15 1997 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c: Add declaration for x_command.
+
+ * printcmd.c (x_command): Remove static declaration.
+
+Wed Dec 3 12:00:42 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (finish_tfind_command): call do_display so that
+ auto-displays are updated by tfind. Also, keep track of frame
+ and current-function so that tfind behaves like stepping (only
+ show the stack frame if we step into a new function or return).
+
+Wed Dec 3 14:14:58 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * sol-thread.c: additional support for debugging threaded core
+ files on solaris; previously only kernel threads were found --
+ user threads generated errors.
+ * corelow.c: don't register core_ops as a target if
+ coreops_suppress_target is true (set by sol-thread.c).
+
+Tue Dec 2 14:53:09 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c: make "tdump" command handle literal memranges.
+
+Tue Dec 2 11:34:48 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c: use "lookup_cmd" to parse actions commands
+ (thus allowing unambiguous prefixes and aliases).
+
+Tue Dec 2 10:15:57 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt: Add support for Thumb target.
+
+Tue Dec 2 10:14:15 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c: move prototype of validate_actionline(), and
+ make it consistent with the function declaration.
+
+Thu Nov 27 09:07:18 1997 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (tracepoint_h): New macro for tracepoint.h
+ includes.
+ (tracepoint.o): Add rule to build.
+
+Wed Nov 26 22:59:04 1997 Jeffrey A Law (law@cygnus.com)
+
+ * remote-sim.c (gdbsim_cntrl_c): Lose ANSI prototype.
+
+ * tracepoint.c (set_raw_tracepoint): fix typo
+
+Wed Nov 26 11:33:09 1997 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c (set_raw_tracepoint): Make sure there's a trailing
+ slash on the directory name.
+
+ * top.c (get_prompt): New function.
+ * top.h: Declare it.
+
+Wed Nov 26 09:59:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (struct comp_unit_head): Change length and
+ abbrev_offset fields to unsigned int.
+ (dwarf2_build_psymtabs_hard): Verify length and offset read from
+ .debug_info section.
+
+Mon Nov 24 19:36:34 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c, tracepoint.h: new module, implements tracing,
+ which is a new functionality somewhat like breakpoints except
+ that a tracepoint stops the inferior only long enough to collect
+ and cache selected buffers and memory locations, then allows
+ the inferior to continue; the cached trace data can then be
+ examined later.
+
+Mon Nov 24 14:17:02 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * infcmd.c: export registers_info, for use by other modules.
+ * printcmd.c: export output_command, for use by other modules.
+ * stack.c: export locals_info and args_info, for use by other modules.
+ * remote.c: export getpkt, putpkt, and fromhex for external use.
+ Make fromhex case-insensative. New function "remote_console_output"
+ abstracts the acceptance of "O" packets from target.
+ Make all "remotedebug" output go to stdout, not stderr.
+
+Mon Nov 24 08:59:28 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valprint.c (print_longest): When CC has long long but printf
+ doesn't, print decimal value as three parts.
+
+ * config/i386/tm-fbsd.h: New file.
+ * config/i386/fbsd.mt (TM_FILE): Change to tm-fbsd.h.
+
+ * config/i386/nm-fbsd.h (FLOAT_INFO): Move definition from here.
+ * config/i386/tm-fbsd.h (FLOAT_INFO): To here.
+
+ * configure.in (PRINTF_HAS_LONG_LONG): Check full functionality of
+ %ll format specifier.
+ (SCANF_HAS_LONG_DOUBLE): Check the scanf family for support of
+ long double using %Lg.
+ * acconfig.h: Provide default undef for SCANF_HAS_LONG_DOUBLE.
+ * configure: Re-generate.
+
+ * c-exp.y (parse_number): Use sscanf %Lg when host has
+ SCANF_HAS_LONG_DOUBLE not PRINTF_HAS_LONG_DOUBLE
+
+Sun Nov 23 17:12:58 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (print_insn): Set the machine type if known.
+
+ * i386-tdep.c (_initialize_i386_tdep): Delete "set
+ assembly-language" command. Replaced by generic "set
+ architecture". Set initial machine using bfd_lookup_arch.
+
+Fri Nov 21 19:43:23 1997 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * valops.c (call_function_by_hand): If the function has a
+ prototype, convert its arguments as if by assignment. Otherwise,
+ do the usual promotions.
+ * stabsread.c (define_symbol): Set the TYPE_FLAG_PROTOTYPED flag
+ on functions' types when we can; all C++ functions should get it,
+ and if the Sun-style prototype notation is in the stabs, we can
+ notice that.
+
+Fri Nov 21 12:20:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4 (AM_CYGWIN32, AM_EXEEXT): Remove. They are already
+ defined by the inclusion of ../bfd/aclocal.m4.
+ * configure: Rebuild.
+
+Fri Nov 21 10:52:39 1997 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (SHELL): Really do the change.
+
+Fri Nov 21 02:19:57 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: also revert SHELL change until configury
+ changes work
+
+Thu Nov 20 16:35:13 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * sparc-tdep.c (sparc_pc_adjust): Don't assume sizeof (long) == 4.
+
+Thu Nov 20 04:11:27 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * aclocal.m4: add EXEEXT setting rule
+ * configure.in: call it
+ * configure: regenerate
+ * Makefile.in: pepper with EXEEXTs in appropriate places,
+ set SHELL = @SHELL@ for those lame hosts that don't have a /bin/sh
+ For some reason, EXEEXT isn't getting substututed in correctly
+ so for now, set EXEEXT to empty string
+
+Mon Nov 17 15:35:06 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.in (remote-sim.o): Depend on $(INCLUDE_DIR)/callback.h.
+
+Fri Nov 14 13:04:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * jv-exp.y (copy_exp, insert_exp): Avoid ANSI prototypes.
+
+Thu Nov 13 09:47:35 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-tdep.c (d30v_print_flags): Function to print the d30v flags
+ in a human readable format.
+ (print_flags_command): Command wrapper to call d30v_print_flags.
+ (d30v_do_registers_info): When printing out all of the registers,
+ print out the flag values in a human readable fashion.
+ (_initialize_d30v_tdep): Add info flags command to print the
+ flags.
+
+ * config/d30v/tm-d30v.h (PSW_*): Add macros for each of the PSW
+ bits that are defined.
+
+Wed Nov 12 14:58:39 1997 Jeff Holcomb <jeffh@cygnus.com>
+
+ * symfile.c (generic_load): Handle cancel from the
+ ui_load_progress_hook routine.
+ * dsrec.c (load_srec): Handle cancel from the
+ ui_load_progress_hook routine.
+
+Mon Nov 10 15:13:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * valprint.c (print_longest): The b, h, w, and g format specifiers
+ print unsigned values.
+
+Mon Nov 10 02:02:49 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * top.c (quit_confirm): Change exit message.
+
+Tue Nov 4 16:52:50 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/cygwin32.mh: because cygwin.dll calls malloc/realloc
+ to allocate memory for environ space, gdb cannot use memory
+ checks -- set -DNO_MMCHECK
+
+Tue Nov 4 13:50:59 1997 Jim Blandy <jimb@sendai.cygnus.com>
+
+ * jv-exp.y (ArrayAccess): Implement Name [ Expression ]; check the
+ code to see why this is not trivial.
+ (copy_exp, insert_exp): New functions.
+
+Fri Oct 24 17:24:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Handle the case
+ where a compilation unit die has no children (DW_TAG_compile_unit
+ has DW_children_no).
+ (scan_partial_symbols): Add comment for nesting_level.
+
+Wed Oct 29 15:53:24 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * solib.c (solib_break_names): add entry for Solaris 2.6 run
+ time linker. From Casper Dik via Peter Schauer.
+
+Tue Oct 28 17:31:47 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * configure.in (configdir): Add -lcomdlg32 and -ladvapi32
+ to WIN32LIBS.
+
+ * configure: Rebuild
+
+Fri Oct 24 16:48:21 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * sol-thread.c (sol_find_new_threads_callback,
+ sol_find_new_threads): New functions.
+ * config/sparc/nm-sun4sol2.h (FIND_NEW_THREADS): New macro, invoke
+ sol_find_new_threads.
+ * thread.c (info_threads_command): invoke FIND_NEW_THREADS if it
+ is defined.
+
+Thu Oct 23 16:16:04 1997 Jeff Law (law@fast.cs.utah.edu)
+
+ * dbxread.c (process_one_symbol): Put back initialization
+ of a variable lost during last change. Don't perform
+ assignment inside conditionals.
+ * stabsread.c (symbol_reference_defined): Return -1 for error/not
+ found. All callers changed appropriately.
+ (define_symbol): Don't perform assignment inside conditionals.
+
+Wed Oct 22 13:04:52 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mdebugread.c (psymtab_to_symtab_1): Handle new live range stabs
+ entries.
+
+ * dbxread.c: More comment cleanups.
+ * stabsread.c: Fix various violations of the GNU coding and
+ formatting standards. Update/add comments to make code clearer.
+ (resolve_reference): Delete unused function.
+ (ref_search_val): Remove function. It didn't belong in stabsread.c
+ (resolve_live_range): No longer returns a value. Do not add it
+ to the live range list until the entire range stab has been parsed.
+ (get_substring): Remove duplicate declaration.
+ (resolve_symbol_reference): Now static. Remove unnecessary code
+ to deal with cleanups.
+ (ref_add): Use xrealloc instea of realloc.
+ (process_reference): Reorganize slightly to make clearer.
+ * stabsread.h (resolve_symbol_reference): Remove declaration.
+ (resolve_reference): Likewise.
+ * symtab.c (find_active_alias): New function.
+ (lookup_block_symbol): Use find_active_alias.
+ * symtab.h (struct range_list): Fix dangling struct live_range
+ reference.
+ (ref_search_val): Remove decl.
+
+ * symtab.h (struct range_list): Renamed from struct live_range.
+ (struct symbol): Remove struct live_range_info substruct.
+ Bring the alias list and range list fields up to the toplevel
+ as "aliases" and "ranges".
+ (SYMBOL_ALIASES, SYMBOL_RANGES): Corresponding changes.
+ (SYMBOL_RANGE_START, SYMBOL_RANGE_END, SYMBOL_RANGE_NEXT): Delete.
+ * stabsread.c: Corresponding changes.
+
+ * dbxread.c: Fix various violations of the GNU coding and
+ formatting standards. Update/add comments to make code
+ clearer.
+ (process_later): Use xrealloc instead of realloc.
+
+ * symtab.c: Include inferior.h.
+
+Tue Oct 21 14:15:26 1997 Per Bothner <bothner@cygnus.com>
+
+ * ch-exp.c: Rename FIELD_NAME to DOT_FIELD_NAME (to avoid conflict).
+
+Fri Oct 17 13:22:02 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infcmd.c: Improve grammar of "set args" help.
+
+Thu Oct 16 15:03:58 1997 Michael Meissner <meissner@cygnus.com>
+
+ * remote-sds.c (sds_load): Properly declare as static.
+
+Wed Oct 15 10:27:14 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/sparc/tm-sparc.h (FIX_CALL_DUMMY): Mask off displacement
+ to 30 bits in call insn to handle --enable-64-bit-bfd.
+ (STORE_STRUCT_RETURN): Change to handle --enable-64-bit-bfd.
+
+Tue Oct 14 22:13:27 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * stabsread.c: Make ref_map entries dynamically allocated.
+
+Thu Oct 9 12:37:57 1997 Frank Ch. Eigler <fche@cygnus.com>
+
+ * printcmd.c (print_address_symbolic, address_info): Mask
+ target-specific flag bits from PC, for more aesthetic disassembly.
+ * config/mips/tm-mips.h: Added PC masking for MIPS family
+ (especially the MIPS16).
+
+Sat Oct 4 18:45:44 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (mips-initialize): Work around flakiness in
+ some versions of PMON after loading a program.
+
+Fri Oct 3 15:49:18 1997 Per Bothner <bothner@cygnus.com>
+
+ * c-lang.h, cp-valprint.c (static_field_print): Make non-static.
+ * parse.c, parser-defs.h (length_of_subexp): Make non-static.
+ * jv-exp.y (FieldAccess): Handle dollar-VARIABLE as primary.
+ (ArrayAccess): Likewise. Also remove warnings.
+ (CastExpression): Implement (typename) UnaryExpression.
+ (push_qualified_expression_name): Fix small bug.
+ * jv-lang.c: Use TYPE_TAG_NAME, not TYPE_NAME for class names.
+ (_initialize_jave_language): Fix typo (jave -> java).
+ (java_language): Java does *not* have C-style arrays.
+ (java_class_from_object): Make more general (and complicated).
+ (java_link_class_type): Fix typo "super" -> "class". Handle arrays.
+ (java_emit_char, java_printchar): New function.
+ (evaluate_subexp_java case BINOP_SUBSCRIPT): Handle Java arrays.
+ * jv-valprint.c (java_value_print): Implement printing of Java arrays.
+ (java_print_value_fields): New function.
+ (java_val_print): Better printing of TYPE_CODE_CHAR, TYPE_CODE_STRUCT.
+
+Fri Oct 3 09:52:26 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16
+ addresses to be odd.
+ (MIPS_FPU_SINGLE_REGSIZE, MIPS_FPU_DOUBLE_REGSIZE): Define.
+ * mips-tdep.c (mips_extract_return_value): Doubles aren't
+ returned in FP0 if FP registers are single-precision only.
+
+Mon Sep 29 23:03:03 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (set_reg_offset): New function.
+ (mips16_heuristic_proc_desc): Calculate offsets of registers
+ saved by entry pseudo-op after rest of prologue has been read.
+ Use set_reg_offset to ignore all but the first save of a given
+ register.
+ (mips32_heuristic_proc_desc): Initialize frame adjustment value.
+ * remote-sim.c (gdbsim_store_register): Don't update registers
+ that have a null or empty name.
+ * findvar.c (read_register_bytes): Don't fetch registers
+ that have a null or empty name.
+
+Tue Sep 30 13:35:54 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (NUM_REGS): Define conditionally.
+ (REGISTER_NAMES): Ditto.
+
+Fri Sep 26 21:08:22 1997 Keith Seitz <keiths@pizza.cygnus.com>
+
+ * dsrec.c (load_srec): add ui_load_progress_hook to
+ display some feedback to user
+
+ * symfile.c (generic_load): add ui_load_progress_hook to
+ display some feedback to user
+
+Fri Sep 26 17:32:22 1997 Jason Molenda (crash@pern.cygnus.com)
+
+ * command.c (add_cmd, add_show_from_set): Insert new commands in
+ alphabetical order.
+
+Fri Sep 26 12:22:00 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/mips-tm-mips.h (mips_extra_func_info): New frame_adjust
+ member for storing offset of MIPS16 frame pointer from SP.
+ * mips-tdep.c: Use RA_REGNUM instead of hardcoded 31 throughout.
+ (PROC_FRAME_ADJUST): Define.
+ (mips16_heuristic_proc_desc): Store frame pointer adjustment value.
+ (get_frame_pointer): Use frame pointer adjustment value when
+ calculating frame address.
+ * remote-sim.c (gdbsim_fetch_register): Don't fetch registers
+ that have a null or empty name.
+
+Fri Sep 26 12:40:51 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mips-tdep.c (_initialize_mips_tdep): Allow target files to
+ override default FPU type.
+
+Fri Sep 26 10:33:54 1997 Felix Lee <flee@cygnus.com>
+
+ * configure.tgt (v850-*-*): necmsg.lib instead of v850.lib.
+
+Wed Sep 24 14:02:09 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Use 1 word DIVH insn with
+ RRRRR=0 for simulator breakpoint. Previous breakpoint insn was two
+ words.
+
+Thu Sep 18 15:07:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-e7kpc.c (get_ds_base): Only use under Windows.
+ (windows.h): Include when any _WIN32 host.
+
+Wed Sep 24 18:12:47 1997 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * The following block of changes add support for debugging assembly
+ source files.
+ * breakpoint.c (resolve_sal_pc): Prevent crash when pc isn't
+ associated with a function.
+ * buildsym.c (record_line start_symtab end_symtab): Don't delete
+ symtabs which only have line numbers (but no other debug symbols).
+ * dbxread.c (read_dbx_symtab end_psymtab): Ditto.
+
+ * remote-sim.c: New functions gdbsim_insert/remove_breakpoint. Use
+ intrinsic simulator breakpoints if available, otherwise do it the
+ hard way.
+
+ * configure.tgt: Add d30v.
+ * d30v-tdep.c: New file.
+ * config/d30v/d30v.mt, config/d30v/tm-d30v.h: New files.
+
+Tue Sep 23 11:24:13 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (ALLCONFIG): Remove, inaccurate and never used.
+
+Tue Sep 23 00:08:18 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (mips_push_arguments): Tweak alignment of register
+ value if the remaining length of a non-integral argument is smaller
+ than the register size for big-endian non-EABI mode.
+
+ * rs6000-tdep.c (branch_dest): Handle return from signal
+ handler function via sigreturn kernel call.
+
+Mon Sep 22 15:32:06 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * stabsread.h, symtab.h, dbxread.c, symtab.c, stabsread.c:
+ Fix prototypes. Remove function scoped function declarations.
+
+Fri Sep 19 18:51:26 1997 Felix Lee <flee@cygnus.com>
+
+ * config/i386/windows.mh (XDEPFILES): need to list some files
+ explicitly, for odd reasons.
+
+Tue Sep 16 20:00:05 1997 Per Bothner <bothner@cygnus.com>
+
+ * jv-exp.y (push_fieldnames): New, to handle EXP.FIELD1....FIELDN.
+ (push_expression_name): New, to handle expression names.
+ (push_qualified_expression_name): New, for qualified expression names.
+ (parse_number): Fix bugs in parsing of non-decimal integers.
+ * jv-lang.h, jv-lang.c (java_demangle_type_signature): New.
+ * jv-lang.c (type_from_class): Just use name with java_lookup_class.
+ (java_link_class_type): Add dummy "class" field.
+ (java_lookup_type): New.
+ (evaluate_subexp_java case STRUCTOP_STRUCT): Force to address.
+ * jv-typeprint.c (java_type_print_base): Don't print "class" field.
+ Use java_demangle_type_signature to print array class types.
+ * jv-valprint.c (java_value_print): Preliminary array support.
+ Print pointer as TYPE@HEXADDR, instead of (TYPE)0xHEXADDR.
+ (java_val_print): Move check for object type to java_value_print.
+ Check for null. Print pointer as @HEXADDR, not 0xHEXADDR.
+
+ * valops.c (search_struct_field): Search basesclasses in
+ ascending, not descending order. Hack to avoid virtual baseclass
+ botch for Java interfaces.
+
+Tue Sep 16 19:56:23 1997 Per Bothner <bothner@cygnus.com>
+
+ * util.c (run_cleanup_chain, make_run_cleanup, do_run_cleanups):
+ New cleanup clean for cleanups to be run when at each 'run' command.
+ * infcmd.c (run_command): Call do_run_cleanups.
+
+ * solib.c (find_solib): Register cleanup to call clear_solib
+ on a new 'run' command.
+ (symbol_add_stub): First look for existing objfile with same name.
+
+Tue Sep 16 16:00:01 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c (sds_load): New function.
+ (sds_ops): Use it.
+ (sds_open): Don't set inferior_pid yet.
+ (sds_kill): Remove contents.
+ (sds_create_inferior): Rewrite to work more like monitor
+ interfaces.
+ (sds_restart): Remove, no longer used.
+
+ * monitor.h (MO_SREC_ACK_PLUS, MO_SREC_ACK_ROTATE): New flags.
+ * monitor.c (monitor_wait_srec_ack): Add DINK32-specific ack code.
+ * dsrec.c (load_srec): Always write a header S-record.
+ * dink32-rom.c (dink32_regnames): Fix the names of float registers.
+ (dink32_cmds): Set to use S-record downloading with acks.
+ * remote-est.c (est_cmds): Add MO_SREC_ACK_PLUS flag.
+
+Tue Sep 16 10:08:27 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Set to a truely illegal
+ instruction.
+
+ * exec.c (exec_file_command): Call set_architecture_from_file.
+
+Mon Sep 15 13:01:22 1997 Mark Alexander <marka@cygnus.com>
+
+ * dbxread.c (MSYMBOL_SIZE): New macro.
+ (end_psymtab): Use MSYMBOL_SIZE to extract size from minimal symbol.
+ * elfread.c (elf_symtab_read): If ELF symbol is "special",
+ such as a MIPS16 function, mark minimal symbol as special too.
+ * mips-tdep.c (pc_is_mips16): New function to check whether
+ a function is MIPS16 by looking at the minimal symbol. Use
+ pc_is_mips16 throughout instead of IS_MIPS16_ADDR macro.
+ * config/mips/tm-mips.h (SYMBOL_IS_SPECIAL, MAKE_MSYMBOL_SPECIAL,
+ MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): New functions for setting/testing
+ "special" MIPS16 bit in ELF and minimal symbols.
+ * mdebugread.c (parse_partial_symbols): Don't construct a partial
+ symbol table for a file that already has one.
+
+Sat Sep 13 08:32:13 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol, handle_psymbol_enumerators): Handle
+ yet another variant of enumerator debugging info, used by DU 4.0
+ native cc.
+
+Tue Sep 9 20:47:23 1997 Felix Lee <flee@cygnus.com>
+
+ * config/i386/windows.mh (XDEPFILES): reduce to libwingdb.a.
+ otherwise link command line is too long.
+
+Tue Sep 9 17:41:41 1997 Jeffrey A Law (law@cygnus.com)
+
+ * symtab.c, dbxread.c, stabsread.c: Fix up ANSI-C isms. Fix
+ some formatting problems.
+
+Mon Sep 8 16:45:51 1997 Stu Grossman <grossman@cygnus.com>
+
+ * ser-e7kpc.c: Don't include w32sut.h. We no longer use the UT
+ mechanism. Remove prototypes for dos_async_* functions. They don't
+ exist anymore.
+
+Mon Sep 8 12:48:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * top.c (quit_confirm, quit_force): New functions, broken out of
+ quit_command.
+ (quit_command): Just call quit_confirm and quit_force.
+ * top.h (quit_confirm, quit_force): Declare.
+
+Sun Sep 7 17:26:30 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * dbxread.c, buildsym.c, symtab.c, stabsread.c: Add support for
+ reading stabs extensions for live range information.
+ * stabsread.h, partial-stab.h: Add prototypes for new functions.
+ * symtab.h: Add structure for storing live range information.
+
+Wed Sep 3 16:39:39 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (set_arch): New function, update target_architecture.
+
+ * defs.h, top.c (set_architecture_from_arch_mach): Replace
+ set_architecture, takes the arch and machine as arguments.
+
+ * sh3-rom.c (sh3e_open): Update.
+ (sh3_open): Ditto.
+
+Tue Sep 2 12:00:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-e7000.c (e7000_fetch_registers): Fix typo, stray paren.
+ (e7000_wait): Ditto.
+
+Mon Sep 1 11:21:03 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (init_main): Add ``set processor'' as an alias for ``set
+ architecture''.
+
+Sat Aug 30 13:44:48 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sparc/sparclite.mt: Removed simulator references (erc32
+ has been disabled).
+
+Thu Aug 28 10:20:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-e7000.c (e7000_fetch_registers): Check
+ target_architecture instead of sh_processor_type.
+ (e7000_wait): Ditto.
+
+ * config/sh/tm-sh.h (sh_set_processor_type): Delete prototype.
+
+ * sh3-rom.c (sh3_open): Call set_architecture not
+ sh_set_processor_type.
+ (sh3e_open): Ditto.
+
+ * sh-tdep.c (sh_show_processor_type_command): Delete.
+ (sh_set_processor_type_command): Delete.
+ (sh_target_architecture_hook): Rename from sh_set_processor_type,
+ use AP to determine architecture.
+ (sh_show_regs): Use bfd_mach_sh* types.
+
+ * remote-sim.c (gdbsim_open): Pass --arch=XXX to simulator when
+ architecture was specified explicitly.
+
+ * defs.h (target_architecture, target_architecture_auto,
+ set_architecture, set_architecture_from_file): Declare.
+ (target_architecture_hook): Allow targets to be notified of set
+ arch commands.
+
+ * top.c (init_main): Add set/show/info architecture commands.
+ (set_architecture, show_architecture, info_architecture): New
+ functions, parse same.
+ (set_architecture_from_file): New function, determine arch from
+ BFD.
+
+Tue Aug 26 17:13:43 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Only pass endianness to sim_open
+ when set explicitly. Prepend endianness arg so that it can be
+ overridden.
+
+ * defs.h, top.c (target_byte_order_auto): Make global when
+ byteorder is selectable.
+
+Tue Aug 26 15:19:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_create_inferior): Pass exec_bfd into
+ sim_create_inferior.
+ (gdbsim_create_inferior): Pass -1 to proceed, sim_create_inferior
+ has already set the PC.
+ (gdbsim_create_inferior): Allow exec_file to be NULL, make "No
+ exec file" a warning. Ditto for "No program loaded".
+
+Mon Aug 25 17:08:01 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c: revert Sun change -- enable log file handling
+
+Mon Aug 25 12:21:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Pass exec_bfd to sim_open call.
+
+Sun Aug 24 21:16:59 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c: comment out sections that create and flush wigglers.log
+ log file when using the wiggler.
+
+Thu Aug 21 16:18:08 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/powerpc/ppc-eabi.mt:
+ * config/powerpc/ppc-sim.mt:
+ * config/powerpc/ppcle-eabi.mt:
+ * config/powerpc/ppcle-sim.mt: ser-ocd.c needs to be before
+ other ocd-related files in TDEPFILES
+
+Thu Aug 21 14:56:04 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ppc-bdm.c (bdm_ppc_wait): stop printfing ecr, der
+ * ocd.c: initialize remote_timeout
+ (ocd_wait): while looping, call ocd_do_command with OCD_AYT
+ (ocd_get_packet): remove find_packet goto. If there isn't
+ an 0x55 at the start, something is quite wrong so error out
+ instead of advancing in the packet and trying again. If checksum
+ is invalid, print error message instead of trying again.
+ * ser-ocd.c (ocd_readchar): error if we attempt to read past
+ the end of the from_wiggler_buffer.
+
+
+Wed Aug 20 14:08:39 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dink32-rom.c: Don't use "mf" command to fill, is too picky
+ about alignment.
+
+
+Tue Aug 19 08:41:36 1997 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.c (objfile_relocate): Add call to breakpoint_re_set
+ after relocations are complete.
+ * remote-vx.c (vx_add_symbols): Remove call to breakpoint_re_set,
+ this is now done in objfile_relocate.
+
+Mon Aug 18 17:29:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * win32-nat.c (handle_exception): Return a value indicating
+ whether the exception was handled. Don't handle random exceptions
+ the first time around, so that structured exception handling
+ works.
+ (child_wait): Check the return value of handle_exception. Set the
+ continue_status argument to ContinueDebugEvent accordingly.
+
+Mon Aug 18 11:14:15 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt: Add support for v850ea target.
+
+Sun Aug 17 20:31:57 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * m32r-stub.c: fix typo
+
+Sun Aug 17 17:33:34 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c: Remove unused remnants of remote.c.
+ (tob64): Return the result length.
+ (sds_interrupt): Send a stop message.
+ (sds_wait): Add debug output for signal interpretation, flag
+ that signal was due to a trap.
+ (sds_fetch_registers): Fill the registers array correctly for
+ PowerPC.
+ (sds_store_registers): Get the right values from registers array.
+ (putmessage): Tweak length handling so checksum comes out right.
+ (sds_insert_breakpoint, sds_remove_breakpoint): Do correctly.
+
+Fri Aug 15 20:53:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (init.c): Don't use xargs.
+
+Fri Aug 15 13:59:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Add the symbols for any
+ newly loaded objects upon a TARGET_WAITKIND_LOADED event.
+
+ Rewrite code which determines the TOC address for calling functions
+ in the inferior under AIX.
+ * rs6000-nat.c (find_toc_address): New function to determine
+ the required TOC address from a function address.
+ (_initialize_core_rs6000): Set up find_toc_address_hook to point
+ to find_toc_address.
+ (xcoff_relocate_symtab, xcoff_relocate_core): Remove
+ add_text_to_loadinfo calls.
+ (exec_one_dummy_insn): Change pid and status to int to get rid of
+ compiler warnings.
+ (xcoff_relocate_symtab): Cast ldi to `int *' when passing it to
+ ptrace to get rid of compiler warnings.
+ * rs6000-tdep.c: Add definition for find_toc_address_hook.
+ (rs6000_fix_call_dummy): If find_toc_address_hook is non zero,
+ patch TOC address load code in the call dummy with the value
+ returned from find_toc_address_hook.
+ (struct loadinfo, loadinfo, loadinfolen,
+ loadinfotextindex, xcoff_init_loadinfo, free_loadinfo,
+ xcoff_add_toc_to_loadinfo, add_text_to_loadinfo, find_toc_address):
+ Remove.
+ (_initialize_rs6000_tdep): Remove initialization of
+ coff_add_toc_to_loadinfo_hook and xcoff_init_loadinfo_hook.
+ * xcoffread.c (coff_add_toc_to_loadinfo_hook,
+ xcoff_init_loadinfo_hook): Remove.
+ (struct coff_symfile_info): Add toc_offset field.
+ (scan_xcoff_symtab): Record toc_offset value in toc_offset field
+ instead of calling xcoff_add_toc_to_loadinfo_hook.
+ (get_toc_offset): New function to return the value of the
+ toc_offset field for an object file.
+ (xcoff_initial_scan): Remove call of xcoff_init_loadinfo_hook.
+ * xcoffsolib.h (add_text_to_loadinfo): Remove declaration.
+ * config/rs6000/tm-rs6000.h: Add declarations for
+ find_toc_address_hook and get_toc_offset.
+
+Wed Aug 13 19:31:28 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c: New file, interface to SDS-compatible monitors.
+ * Makefile.in (remote-sds.o): Add build rule.
+ * config/powerpc/ppc-eabi.mt, config/powerpc/ppc-sim.mt
+ (TDEPFILES): Add remote-sds.o.
+
+Tue Aug 12 14:37:18 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c (ocd_wait): loop until we're in BDM mode instead of
+ assuming control has returned to GDB.
+
+Mon Aug 11 19:16:04 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dink32-rom.c: New file, support for DINK32 monitor.
+ * Makefile.in (dink32-rom.o): Add build rule.
+ * config/powerpc/ppc-eabi.mt, config/powerpc/ppc-sim.mt
+ (TDEPFILES): Add dink32-rom.o.
+ * monitor.h (MO_32_REGS_PAIRED, MO_SETREG_INTERACTIVE,
+ MO_SETMEM_INTERACTIVE, MO_GETMEM_16_BOUNDARY,
+ MO_CLR_BREAK_1_BASED): New monitor interface flags.
+ * monitor.c: Use them.
+ (monitor_store_register): Use setreg.term if defined.
+ (monitor_insert_breakpoint, monitor_remove_breakpoint): Notice
+ if set_break and clr_break fields are empty.
+
+Mon Aug 11 16:22:36 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c (ocd_insert_breakpoint, ocd_remove_breakpoint): Macro
+ BDM_BREAKPOINT already has braces around it, remove erroneous ones.
+ * ser-ocd.c (ocd_write): Conditionalize on _WIN32 instead of
+ __CYGWIN32__.
+ * config/powerpc/tm-ppc-eabi.h: Remove BDM_NUM_REGS, BDM_REGMAP
+ * ppc-bdm.c: move BDM_NUM_REGS, BDM_REGMAP here from tm.h file,
+ fill in doc fields of bdm_ppc_ops.
+ (bdm_ppc_fetch_registers): Don't ask for invalid registers such
+ as the MQ or floating point regs not present on ppc 8xx boards.
+ (bdm_ppc_store_registers): Don't write those same invalid registers.
+ * config/i386/cygwin32.mh: Stop including ocd.o ser-ocd.o.
+ * config/powerpc/ppc-eabi.mt:
+ * config/powerpc/ppcle-eabi.mt:
+ * config/powerpc/ppc-sim.mt:
+ * config/powerpc/ppcle-sim.mt: Include ser-ocd.o.
+
+Mon Aug 11 16:08:52 1997 Fred Fish <fnf@cygnus.com>
+
+ * frame.h (enum lval_type): Conditionalize on __GNUC__
+ instead of __STDC__.
+
+Sun Aug 10 19:08:26 1997 Jeffrey A Law (law@cygnus.com)
+
+ * utils.c (error): Fix return type for !ANSI_PROTOTYPES.
+
+Sun Aug 10 16:49:09 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c: move ocd_write_bytes proto to ocd.h since it is used
+ by ppc-bdm.c, use OCD_LOG_FILE to help debugging, define
+ BDM_BREAKPOINT if not defined in tm.h
+ (ocd_error): add new error cases
+ (ocd_start_remote): send the OCD_INIT command before
+ OCD_AYT and OCD_GET_VERSION calls, 80 was correct speed after all
+ (ocd_write_bytes): no longer static
+ (ocd_insert_breakpoint): no longer static
+ (ocd_remove_breakpoint): new
+ * ocd.h: add protos for ocd_write_bytes, ocd_insert_breakpoint,
+ and ocd_remove_breakpoint
+ * ppc-bdm.c: change bdm_ppc_ops so we call ocd_insert_breakpoint
+ and ocd_remove_breakpoint instead of memory_insert_breakpoint
+ and memory_remove_breakpoint.
+ (bdm_ppc_open): after calling ocd_open, modify DER
+ register so interrupts will drop us into debugging mode, finally
+ disable the watchdog timer on the board so we don't leave BDM
+ mode unexpectedly.
+
+Sat Aug 9 01:50:14 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * values.c (value_primitive_field): Account for offset when
+ extracting the value of a bitfield.
+ From Paul Hilfinger <hilfingr@CS.Berkeley.EDU>.
+
+Fri Aug 8 21:35:44 1997 Mark Alexander <marka@cygnus.com>
+
+ * gdbserver/utils.c (error): Change prototype to match defs.h.
+ * gdbserver/low-sim.c: Change simulator calls to use new interface.
+ * remote.c (remote_write_bytes): Include '$' at start of packet
+ and checksum at end of packet in overhead calculation.
+
+Fri Aug 8 15:59:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ser-ocd.c: If _WIN32, include <windows.h>.
+ (dll_do_command): New static variable if _WIN32.
+ (ocd_open): Set dll_do_command if _WIN32.
+ (ocd_write): Use dll_do_command rather than do_command.
+ * config/i386/cygwin32.mh (XDEPFILES): Remove libwigglers.a.
+ (BDM_DLLNAME, BDM_LIBNAME, BDM_DEFFILE): Don't define.
+ ($(BDM_LIBNAME)): Remove target.
+ * wigglers.def: Remove.
+
+ * config/i386/cygwin32.mh ($(BDM_LIBNAME)): Rename target from
+ libwigglers.def.
+ (libwigglers.a): Remove target.
+
+Fri Aug 8 13:11:01 1997 Mike Meissner <meissner@cygnus.com>
+
+ * config/powerpc/ppc{,le}-{eabi,sim}.mt (TDEPFILES): Make sure
+ ppc-bdm.o and ocd.o are used for all powerpc-eabi targets.
+
+Thu Aug 7 19:40:52 1997 Geoffrey Noer <noer@cygnus.com>
+
+ Changes to OCD support to support wiggler box as well as
+ target boxes:
+ * ocd.c: change speed in init command to 0 from 80,
+ add (temporary) logging commands to help debugging,
+ (ocd_open): if "target ocd wiggler lpt" then use special
+ ser-ocd.c serial interface which communicates with Wigglers.dll,
+ otherwise ("target ocd <foo>") do as we did before
+ (ocd_get_packet): add OCD_LOG_FILE and OCD_SET_CONNECTION to
+ switch of known commands of len 0
+ * ocd.h: add OCD_LOG_FILE
+ * serial.c (serial_open): do serial_interface_lookup on ocd
+ in the case of ocd
+ * ser-ocd.c: add buffer to contain responses from sending a
+ command to the Wigglers.dll.
+ (ocd_readchar): return curr char from buffer and increment ptr
+ (ocd_write): send buffer to Wigglers.dll, storing response in
+ return buffer and initializing curr location ptr to start of
+ buffer.
+
+Thu Aug 7 13:39:31 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.h: add OCD_SET_CONNECTION
+ * ocd.c: rename "do_command" to "ocd_do_command"
+
+Thu Aug 7 13:09:17 1997 Geoffrey Noer <noer@cygnus.com>
+
+ Nomenclature change. BDM is a specific type of OCD
+ (On Chip Debugging). Wiggler is the parallel port box controlled
+ by Wigglers.dll. The faster target box from Macraigor Systems
+ is not a wiggler.
+ * ocd.c:
+ * ocd.h:
+ * ppc-bdm.c:
+ * ser-ocd.c:
+ Replace all instances of "wiggler_" with "ocd_" and change most other
+ instances of "wiggler" to "ocd" or "ocd device" depending on context.
+ * config/m68k/monitor.mt: remove remote-wiggler.o from TDEPFILES
+ until OCD with that target is supported again.
+
+Wed Aug 6 16:15:31 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: add DLLTOOL = @DLLTOOL@, pass on DLLTOOL to
+ sub makes, change clean rule to also remove *.a to remove
+ libwigglers.a, in dependencies: add ppc-bdm.o ocd.o ser-ocd.o and
+ remove remote-wiggler.o
+ * configure.in: add DLLTOOL support
+ * configure: regenerate
+ * wigglers.def: new file for imports for wigglers.dll
+ * ser-ocd.c: new file which is layer between ocd.c and either the
+ wigglers.dll or the target box, only stub so far
+ * config/powerpc/ppc-eabi.mt: add ppc-bdm.o to TDEPFILES
+ * config/powerpc/ppc-sim.mt: add ppc-bdm.o to TDEPFILES
+ * config/i386/cygwin32.mh: add ocd.o ser-ocd.o libwigglers.a
+ to XDEPFILES, add rules to build libwigglers.a
+
+ checking in changes of Stu Grossman <grossman@cygnus.com>:
+ * remote-wiggler.c: delete
+ * ocd.c: new, was remote-wiggler.c
+ always include sys/types.h, include ocd.h, move WIGGLER
+ commands and many wiggler prototypes to ocd.h, make wiggler_desc
+ static, stop making local wiggler functions static,
+ define write_mem_command for wiggler_write_bytes
+ (wiggler_start_remote): stop hardcoding the target type,
+ instead set and use a target_type variable.
+ (wiggler_open): add new target_type and ops args
+ (wiggler_wait): now no longer takes pid and target_status as args,
+ stop trying to set target_status struct, remove BGND insn
+ checks
+ (read_bdm_registers): renamed to wiggler_read_bdm_registers
+ (wiggler_read_bdm_registers): numregs arg changed to reglen arg,
+ remove pktlen check, set reglen instead of numregs
+ (dump_all_bdm_regs): delete
+ (wiggler_fetch_registers): delete
+ (wiggler_prepare_to_store): now just an empty function
+ (wiggler_store_registers): delete
+ (wiggler_read_bdm_register): new
+ (wiggler_write_bdm_registers): new
+ (wiggler_write_bdm_register): new
+ (wiggler_write_bytes): use write_mem_command variable instead of
+ WIGGLER_WRITE_MEM
+ (get_packet): renamed to wiggler_get_packet, change refs throughout
+ (put_packet): renamed to wiggler_put_packet, change refs throughout
+ (wiggler_get_packet): add break to default case of switch,
+ change length of WIGGLER_GET_VERSION len to 10 from 4 to match
+ specs
+ (wiggler_mourn): unpush_target with current_ops, not &wiggler_ops
+ (flash_xfer_memory): delete
+ (noop_store_registers): new placeholder replacement for
+ target_store_registers() which prevents generic_load from trying to
+ set up the PC.
+ (bdm_update_flash_command): add store_registers_tmp variable,
+ make handling of wiggler_ops more generic -- define wiggler_ops
+ in a target-specific file instead (such as ppc-bdm.c in the case
+ of the ppc), use current_target to deal with registers again
+ making this file less target-specific.
+ (bdm_read_register_command): new
+ (_initialize_remote_wiggler): stop doing add_target (&wiggler_ops),
+ comment out add_cmd ("read-register", ...)
+ * ocd.h: new, contains common wiggler prototypes, command definitions
+ * ppc-bdm.c: file for ppc-specific OCD code, including target_ops
+ structure for ppc bdm
+ (bdm_ppc_open): new
+ (bdm_ppc_wait): new
+ (bdm_ppc_fetch_registers): new
+ (bdm_ppc_store_registers_: new
+ (_initialize_bdm_ppc): new
+ * config/powerpc/tm-ppc-eabi.h: add necessary CPU32 BDM defines
+
+Wed Aug 6 00:24:08 1997 Jeffrey A Law (law@cygnus.com)
+
+ * hpread.c (hpread_read_struct_type): Use accessor macros rather
+ than directly mucking around with data structures.
+
+Tue Aug 5 13:37:14 1997 Per Bothner <bothner@cygnus.com>
+
+ * gdbtypes.h: Re-interpret struct field. Suppport address of static.
+ Add a bunch of macros.
+ * coffread.c, dwarf2read.c, dwarfread.c, mdebugread.c, stabsread.c:
+ Update to use new macros.
+ * coffread.c, hpread.c, stabsread.c: Remove bugus TYPE_FIELD_VALUE.
+ * value.h, values.c (value_static_field): New function.
+ * cp-valprint.c, valops.c: Modify to use value_static_field.
+
+ * jv-lang.c (get_java_utf8_name): Re-write so it works with
+ implied (missing) data field, as defined by cc1java.
+ (java_link_class_type): Type length and field offset (in interior)
+ now includes object header. Get static fields working.
+ * jv-lang.h (JAVA_OBJECT_SIZE): Update for change in Kaffe.
+ * jv-typeprint.c (java_type_print_derivation_info,
+ java_type_print_base): New functions, for better Java output.
+ * jv-valprint.c: Start to support Java-specific output.
+
+Sun Aug 3 08:18:09 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-valprint.c (c_val_print): Use extract_address to retrieve
+ the address of the virtual function.
+ From Peter Bloecher (Peter.Bloecher@eedn.ericsson.se).
+
+ * eval.c (evaluate_subexp_standard), valarith.c (value_x_unop):
+ Handle C++ operator *.
+
+Fri Aug 1 15:21:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check for cygwin32 environment. Define and
+ substitute WIN32LIBS and WIN32LDAPP. Always set configdir to
+ unix; setting it to win was for an old Tcl/Tk configuration
+ scheme.
+ * Makefile.in (TK_CFLAGS): Add @TK_BUILD_INCLUDES@.
+ (WIN32LDAPP, WIN32LIBS): Define.
+ (CLIBS): Add $(WIN32LIBS).
+ (gdb): Use $(WIN32LDAPP).
+ * configure: Rebuild.
+
+Thu Jul 31 15:40:19 1997 Per Bothner <bothner@cygnus.com>
+
+ * symtab.h (SYMBOL_INIT_LANGUAGE_SPECIFIC, SYMBOL_INIT_DEMANGLED_NAME,
+ SYMBOL_DEMANGLED_NAME): Add demangling support for Java.
+ * utils.c (fprintf_symbol_filtered): Handle language_java.
+
+ * symtab.c (decode_line_1): Handle Java-style package.class.method.
+
+Wed Jul 30 14:04:18 1997 Per Bothner <bothner@cygnus.com>
+
+ * java-*: Renamed to jv-*, to make fit within 14 characters.
+ * jv-lang.h (java_type_print): Added declaration.
+ * jv-typeprint.c: New file. Provides java_print_type.
+ * jv-lang.c (java_link_class_type): New function.
+ (java_language_defn): Replace c_print_type by java_print_type.
+ * Makefile.in: Update accordingly.
+
+Tue Jul 29 10:12:44 1997 Felix Lee <flee@cygnus.com>
+
+ * Makefile.in (init.c): except some mswin files do need to be
+ scanned. oh well.
+
+Mon Jul 28 14:04:39 1997 Felix Lee <flee@cygnus.com>
+
+ * Makefile.in (init.c): don't try to scan mswin for _initialize
+ funcs. (generates misleading error message because files have
+ .cpp suffix, not .c suffix)
+
+Mon Jul 28 13:27:21 1997 Felix Lee <flee@cygnus.com>
+
+ * ser-e7kpc.c: <w32sut.h> -> "mswin/w32sut.h"
+
+Mon Jul 28 02:54:31 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * xcoffread.c (coff_getfilename): Do not strip directory component
+ of filename.
+
+Fri Jul 25 15:16:15 1997 Felix Lee <flee@cygnus.com>
+
+ * mon960-rom.c: removed unused #includes; no ioctl.h in Windows.
+ * nindy-share/ttyflush.c: find sleep() for _MSC_VER.
+ * remote-array.c: #include <ctype.h> for isascii().
+ * utils.c (notice_quit,pollquit): cleanup. _WIN32 -> _MSC_VER.
+
+Fri Jul 25 16:48:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (execute_command): Force cleanup of alloca areas.
+ * findvar.c (registers_changed): Likewise.
+
+Fri Jul 25 15:37:15 1997 Stu Grossman <grossman@cygnus.com>
+
+ * v850ice.c: Include <windows.h>. Support new v850 DLL interface.
+ * Add defs for target status.
+
+Tue Jul 22 12:11:48 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/mips/tm-mips64.h: longs, long longs, and pointers
+ are all 64 bits on EABI mips targets.
+
+Thu Jul 17 11:38:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * partial-stab.h (case N_BINCL): detect missing partial symtab.
+ * dbxread.c: Add a complaint for N_BINCL without a corresponding
+ partial symtab. Remove earlier change of 5/27/97.
+
+Wed Jul 16 10:38:03 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * sol-thread.c (sol_thread_[store, fetch]_registers): if
+ inferior_pid is an LWP rather than a Solaris thread, let
+ procfs handle the request.
+ (rw_common, sol_thread_xfer_memory): procfs_xfer_memory will
+ only work if inferior_pid points to an LWP (rather than a
+ Solaris thread). Use procfs_first_available to find a good LWP.
+ (info_solthreads): added a maintenance command to list all
+ known Solaris threads and their attributes.
+ * mips-tdep.c (mips_do_registers_info): Completely changed the
+ output format to be neat and columnar. Added the helper funcs
+ do_fp_register_row and do_gp_register_row. Also small mods to
+ mips_print_register, which is still used to print a single reg.
+
+Mon Jul 14 18:02:53 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * procfs.c (wait_fd): Handle an fd that has "hung up" or
+ otherwise terminated (Solaris threads).
+
+Thu Jul 10 00:02:41 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * defs.h (init_ui_hook): Change prototype to accept one arg.
+ * main.c (gdb_init): Change prototype to accept one arg.
+ * top.c (gdb_init): Accepts one argument which it uses to
+ call (*init_ui_hook).
+
+Fri Jul 4 14:49:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * source.c (OPEN_MODE, FDOPEN_MODE): Define; value depends upon
+ whether CRLF_SOURCE_FILES is defined.
+ (open_source_file): Use OPEN_MODE with open and openp.
+ (print_source_lines): Use FDOPEN_MODE with fdopen. If
+ CRLF_SOURCE_FILES is defined, ignore \r characters.
+ (forward_search_command): Use FDOPEN_MODE with fdopen.
+ (reverse_search_command): Likewise.
+ * config/i386/xm-cygwin32.h (CRLF_SOURCE_FILES): Define.
+ (LSEEK_NOT_LINEAR): Don't define.
+
+Thu Jul 3 17:41:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_extract_return_value): align 4-byte float
+ return values within the 8-byte FP register.
+
+Thu Jul 3 13:48:11 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): don't left-adjust 32-bit
+ integers in 64-bit register parameters before function calls.
+
+Mon Jun 30 17:54:51 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): special-case handling for
+ odd-sized struct parameters passed in registers / on stack.
+
+Mon Jun 30 15:30:38 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): tweak alignment of small
+ structs passed in registers for little-endian non-EABI mode.
+
+Mon Jun 30 13:05:39 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * breakpoint.c (frame_in_dummy): use generic dummy if available.
+ (check_duplicates, clear_command): compare sections only if
+ doing overlay debugging.
+
+Fri Jun 27 23:03:53 1997 Fred Fish <fnf@ninemoons.com>
+
+ * buildsym.h (struct subfile): Add debugformat member.
+ (record_debugformat): Declare global function.
+ * buildsym.c (start_subfile): Initialize debugformat member
+ to NULL.
+ (record_debugformat): New function to record the format.
+ (end_symtab): Copy format into symtab debugformat member.
+ (end_symtab): Free subfile debugformat member.
+ * symmisc.c (free_symtab): Free debugformat when freeing
+ symtab.
+ * symfile.c (allocate_symtab): Initialize the new debugformat
+ member for new symtabs.
+ * symtab.h (struct symtab): Add debugformat member.
+ * source.c (source_info): Print the debug format.
+
+ * os9kread.c (os9k_process_one_symbol): Call record_debugformat
+ with "OS9".
+ * hpread.c (hpread_expand_symtab): Call record_debugformat
+ with "HP".
+ (hpread_process_one_debug_symbol): Ditto.
+ * dbxread.c (process_one_symbol): Call record_debugformat
+ with "stabs".
+ * coffread.c (coff_start_symtab): Call record_debugformat
+ with "COFF".
+ * xcoffread.c (read_xcoff_symtab): Call record_debugformat
+ with "XCOFF".
+ * dwarfread.c (read_file_scope): Call record_debugformat
+ with "DWARF 1".
+ * dwarf2read.c (read_file_scope): Call record_debugformat
+ with "DWARF 2".
+ * dstread.c (dst_end_symtab): Set debugformat to be
+ "Apollo DST".
+ * mdebugread.c (new_symtab): Set debugformat to be "ECOFF".
+
+Fri Jun 27 21:05:45 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): handle alignment of
+ integer and struct args on stack for mips64 big-endian.
+
+Fri Jun 27 19:19:12 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/mips/tm-mips.h (USE_STRUCT_CONVENTION): MIPS_EABI returns
+ structs in a register wherever possible.
+ * mips-tdep.c (mips_extract_return_value): handle structs.
+ (mips_store_return_value): handle values smaller than MIPS_REGSIZE
+ (including structs, if gdb ever allows it).
+
+Fri Jun 20 17:58:34 1997 Fred Fish <fnf@cygnus.com>
+
+ * sh-tdep.c (sh_skip_prologue): Also recognize fmov insns.
+ (sh_frame_find_saved_regs): Recognize fmov insns and adjust
+ stack push count accordingly.
+ * sh-tdep.c (IS_FMOV, FPSCR_SZ): New defines
+
+Thu Jun 19 08:18:48 1997 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (floatformat_from_doublest): Improve test for infinity.
+
+Wed Jun 18 13:47:52 1997 Fred Fish <fnf@cygnus.com>
+
+ * dwarfread.c (isreg, optimized_out, offreg, basereg): Move
+ global variables into the struct dieinfo structure.
+ (locval): Pass pointer to a dieinfo struct rather than a
+ pointer to the raw location information. Change prototype.
+ Set isreg, optimized_out, offreg and basereg as appropriate.
+ (struct_type): Call locval with dieinfo struct pointer.
+ (new_symbol): Ditto.
+ (new_symbol): Call locval and save location before testing
+ the values of the new dieinfo struct flags, set by locval.
+
+Tue Jun 17 13:30:12 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * procfs.c (proc_set_exec_trap, procfs_init_inferior, procfs_wait,
+ unconditionally_kill_inferior): Undo Oct 26 1996 and Apr 26 1997
+ changes to trace PRFS_STOPTERM and handle PR_DEAD.
+ These changes tried to work around a problem with an early DU 4.0
+ release, but they trigger subtle timing dependent kernel bugs
+ in older OSF/1 releases.
+
+Tue Jun 17 06:52:47 1997 Fred Fish <fnf@cygnus.com>
+
+ * dwarfread.c (new_symbol): Use SYMBOL_VALUE_ADDRESS, instead of
+ SYMBOL_VALUE, to set the value of LOC_STATIC symbols.
+
+Mon Jun 16 18:38:28 1997 Mark Alexander <marka@cygnus.com>
+
+ * infrun.c (wait_for_inferior): Mark registers as invalid when
+ stepping over an instruction that triggered a watchpoint.
+ * remote-mips.c: Numerous changes to support hardware breakpoints
+ and watchpoints on LSI MiniRISC and TinyRISC boards.
+ * mips-tdep.c: Move MIPS16-related macros to config/mips/tm-mips.h.
+ (mips_breakpoint_from_pc): Account for different breakpoint
+ instructions used by PMON and IDT monitor.
+ * config/mips/tm-embed.h: Enable hardware breakpoints on embedded
+ MIPS targets.
+ * config/mips/tm-mips.h: Define breakpoint instructions for
+ PMON and IDT monitor. Move MIPS16-related macros here from
+ mips-tdep.c.
+
+Fri Jun 13 13:44:47 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/mips/tm-tx39[l].h, tx39[l].mt: change r3900 target to tx39.
+
+Fri Jun 13 14:14:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Fix some comments.
+ Add missing return statements after finding an "add imm{16,32},sp"
+ instruction.
+ (mn10300_frame_chain): Add in size of our register save area to find
+ our caller's frame if our caller does not have a frame pointer.
+
+Fri Jun 13 12:55:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * symfile.c (generic_load): Check return code of target_write_memory.
+
+Fri Jun 13 10:28:09 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/nm-linux.h: Enable prototypes that were #ifdef out.
+ * config/tm-sysv4.h (in_plt_section): Add prototype.
+
+ * maint.c (maintenance_translate_address): Avoid assignment
+ inside if, per GNU coding standards.
+ * symfile.c (simple_read_overlay_table): Avoid assignments inside if,
+ per GNU coding standards.
+
+ * monitor.c (parse_register_dump): Is really a void function.
+ Add prototype.
+ (monitor_read_memory): Remove unused variable "name".
+ (monitor_read_memory): Remove unused variable "regbuf".
+ (monitor_open): Remove unused variable "i".
+ (get_hex_word): Apparently unused, #if away for now.
+ (from_hex): Ditto.
+
+ * i386v4-nat.c (supply_fpregset): Remove unused variable "regi".
+ (fill_fpregset): Remove unused variables "regi", "to", "from" and
+ "registers".
+
+ * remote-e7000.c (ctype.h): Include.
+ (e7000_insert_breakpoint): #if away unused arg used by unused expr.
+ * frame.h (generic_get_saved_register): Add prototype.
+ (enum lval_type): Add partial forward decl.
+ * dsrec.c (make_srec): Remove unused variable "type_code".
+ * remote-sim.c (gdbsim_wait): Handle sim_running and sim_polling
+ cases by just ignoring them.
+ (command.h): Include.
+
+ * java-exp.y (parse_number): Remove unused variable "unsigned_p".
+ * java-lang.c (gdbcore.h): Include for prototypes.
+ (type_from_class): Remove unused variable "ftype".
+ (type_from_class): Remove unused variable "name_length".
+ (evaluate_subexp_java): Add default case to handle remaining
+ enumerations.
+ * java-valprint.c (c-lang.h): Include for prototypes.
+
+ * symfile.c (simple_read_overlay_region_table): #if away
+ unused function.
+ (simple_free_overlay_region_table): Ditto.
+ (overlay_is_mapped): Add default case to switch.
+ (simple_read_overlay_region_table): Ditto.
+ (simple_read_overlay_region_table): Add prototype.
+
+ * symtab.c (fixup_symbol_section): Remove unused msym variable.
+ (fixup_psymbol_section): Ditto.
+ (find_pc_sect_symtab): Make distance a CORE_ADDR.
+
+ * utils.c: Add comment about t_addr being either unsigned long or
+ unsigned long long.
+ (paddr): Change formats to match actual types args are cast to.
+ (preg): Ditto.
+ (paddr_nz): Ditto.
+ (preg_nz): Ditto.
+
+ * defs.h (perror_with_name): Is a NORETURN function.
+ * utils.c (perror_with_name): Is a NORETURN function.
+ (error): Is NORETURN independently of ANSI_PROTOTYPES.
+
+ * symtab.c (fixup_symbol_section): Remove prototype.
+ * symtab.h: (fixup_symbol_section): Add prototype.
+ * m32r-rom.c (report_transfer_performance): Add prototype.
+ * sparclet-rom.c: Ditto.
+ * dsrec.c: Ditto.
+
+ * c-exp.y (parse_number): Cast args to float* or double* as
+ appropriate for conversion format.
+ * java-exp.y (parse_number): Ditto.
+
+ * Makefile.in (c-exp.tab.c): Remove #line lines that refer
+ to nonexistant y.tab.c file.
+ (java-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
+
+ * sh-tdep.c (symfile.h): Include.
+ (gdb_string.h): Include.
+ (sh_fix_call_dummy): Ifdef away, currently unused.
+ * config/sh/tm-sh.h (pop_frame): Add prototype.
+ * config/sh/tm-sh.h (sh_set_processor_type): Add prototype.
+
+Sat Jun 7 02:34:19 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * eval.c (evaluate_subexp_for_sizeof): Handle dereferencing
+ of non-pointer values.
+
+ * symtab.c (gdb_mangle_name): Improve mangling of nested types,
+ their physical names already include the class name.
+
+ * valops.c (value_cast): Handle upcast of a class pointer.
+
+ From Andreas Schwab (schwab@issan.informatik.uni-dortmund.de):
+ * corelow.c (get_core_registers): Make secname big enough.
+
+Fri Jun 6 14:43:23 1997 Keith Seitz <keiths@pizza.cygnus.com>
+
+ * config/sh/tm-sh.h: add define for FPSCR_REGNUM
+ * sh-tdep.c (sh_show_regs): print out all registers for
+ the current processor
+
+Fri Jun 6 13:01:55 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_kill): Remove call to depreciated function
+ sim_kill.
+
+Thu Jun 5 11:39:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Fixes for recent correction to PE format:
+ * coffread.c (pe_file): New static variable.
+ (struct find_targ_sec_arg): Change resultp from pointer to int to
+ pointer to pointer to asection.
+ (find_targ_sec): Just store the section in args->resultp, not the
+ section offset value.
+ (cs_to_section): Compute the section offset value from the
+ section.
+ (cs_section_address): New static function.
+ (coff_symfile_read): Set pe_file.
+ (read_one_sym): When reading a PE file, adjust the symbol value to
+ include the section address if the symbol has an appropriate
+ storage class.
+
+Tue Jun 3 16:24:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * configure.tgt: add mipsr3900-elf target
+ * config/mips/r3900.mt r3900l.mt tm-r3900.h tm-r3900l.h: ditto
+
+Tue May 27 10:34:11 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * dbxread.c: Check malloc's return for null, prevent segv.
+
+Fri May 23 14:45:02 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * infcmd.c (jump_command): Don't try to dereference sfn if it's
+ NULL.
+
+Fri May 23 13:51:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (init_cmd_lists): Always initialize endianlist.
+ (init_main): Always define endian commands.
+ (set_endian_big): Issue warning if endian not selectable.
+ (set_endian_little): Ditto.
+ (set_endian_auto): Ditto.
+
+Thu May 22 11:53:21 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (simulator_command): Restrict access to the
+ simulator to periods when the simulator is open.
+
+Wed May 21 16:03:25 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c (init_procinfo): new function, abstracts some code
+ shared by create_procinfo and do_attach;
+ (procfs_set_inferior_syscall_traps): new function, abstracts
+ some code needed by procfs_init_inferior, do_attach, and
+ procfs_lwp_creation_handler; (procfs_first_available): new
+ function, find any LWP that's runnable; (procfs_thread_alive):
+ replace stub function with real implementation;
+ (procfs_lwp_creation_handler): fix bug starting new child
+ threads; (info_proc): bug fixes and enhancements for the
+ "INFO PROCESSES" command; (close_procinfo_file): call new
+ function "delete_thread" to cleanup GDB's thread database;
+ (proc_init_failed): add new argument "kill", to control whether
+ process is killed (so this function can be shared by
+ create_procinfo and do_attach); (procfs_exit_handler): handle
+ exit from an attached process, and cleanup procinfo handles
+ when the process exits; (procfs_resume, procfs_wait): cleanup
+ after a thread when it exits; (do_attach, do_detach): handle
+ attached processes with multiple threads; plus some general
+ improvements in the diagnostic output.
+ * sol-thread.c (sol_thread_alive): replace stub with real
+ implementation; (thread_to_lwp, lwp_to_thread): enhance to
+ handle threads that may have exited; (sol_thread_attach): add
+ startup setup stuff; (sol_thread_detach): add unpush_target
+ call; (sol_thread_mourn_inferior): add unpush_target call;
+ (sol_thread_wait, sol_thread_resume): enhance to deal with
+ thread exit cleanly; (sol_thread_new_objfile,
+ sol_thread_pid_to_str): detect unsuccessful startup and
+ don't crash; plus some general cleanup.
+ * thread.c (delete_thread): new function, allows targets to
+ notify gdb when a thread is no longer valid.
+ * infrun.c (wait_for_inferior): don't try to detect a new
+ thread on receiving a TARGET_EXITED event.
+
+Tue May 20 09:32:02 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Pass callback struct.
+ (init_callbacks): Remove call to sim_set_callbacks.
+
+Thu May 15 07:56:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/rs6000/tm-rs6000.h (SIG_FRAME_LR_OFFSET): Define.
+ * rs6000-tdep.c (frameless_function_invocation): Mark frames
+ with a zero PC as frameless to improve backtraces from core dumps
+ caused by dereferencing a NULL function pointer.
+ (frameless_function_invocation, frame_saved_pc, rs6000_frame_chain):
+ Handle frameless functions interrupted by a signal.
+
+ * sparc-tdep.c (sparc_init_extra_frame_info, sparc_frame_saved_pc):
+ Handle frameless functions interrupted by a signal.
+
+Wed May 14 08:58:55 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Update prologue comments
+ to reflect current reality. Gross attempt at handling out of
+ line prologues.
+
+ * mn10200-tdep.c (mn10200_skip_prologue): Don't look at the debug
+ symbols to find the end of the prologue.
+ * mn10300-tdep.c (mn10300_skip_prologue): Likewise.
+
+Thu May 8 08:42:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_TYPE_SIGNAL): Add
+ * configure: Re-generate.
+ * remote-sim.c: Signal returns RETSIGTYPE.
+
+Wed May 7 20:05:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.h (target_stop): Drop argument so it can be tested for
+ NULL.
+
+Sat May 3 20:51:48 1997 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (floatformat_from_doublest): Handle infinity properly.
+
+Thu May 1 11:44:46 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * Finalize merge from Hurd folk.
+ Mon Oct 30 16:41:04 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * thread.c (thread_apply_command, thread_apply_all_command,
+ thread_command): Make sure TP is alive.
+ (thread_alive): New function.
+ Tue Nov 14 14:31:03 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * infrun.c (sig_print_info): Deal better with long signal names.
+ Wed Nov 22 15:23:35 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * thread.c (thread_id_to_pid): New function.
+ Fri Dec 1 13:25:25 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * gnu-nat.c: (set_thread_cmd_list, show_thread_cmd_list,
+ set_thread_default_cmd_list, show_thread_default_cmd_list):
+ New variables. (set_thread_cmd, show_thread_cmd,
+ set_thread_default_cmd, show_thread_default_cmd): New functions.
+ Fri Apr 18 15:20:16 1997 Miles Bader <miles@gnu.ai.mit.edu>
+ * gnu-nat.c (inf_startup): remove TASK parameter.
+ (inf_set_task): replace with new function (inf_set_pid).
+ * gdbthread.h: Add extern decl for thread_cmd_list.
+
+Thu May 1 02:28:21 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * printcmd.c (disassemble_command): Adjust low function bound
+ by FUNCTION_START_OFFSET.
+
+Mon Apr 28 21:25:32 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * Makefile.in: Add rule for gnu-nat.o and i386gnu-nat.o (Gnu Hurd)
+ * config/i386/i386gnu.mh: remove rules for [i386]gnu-nat.o, now
+ in Makefile.in (as for other targets); add NATDEPFILE corelow.o to
+ satisfy symbol dependancy in solib.c (core_ops).
+ * target.[ch] conditionalize Mach-specific signals so that they
+ won't show up in non-Mach gdb's!
+ * thread.c: change name of static function "thread_switch" to
+ "switch_to_thread", to avoid conflict with Mach global symbol;
+ move thread_cmd_list to global scope so targets can add their
+ own thread commands.
+ * infrun.c: sig_print_info: allow for long signal names.
+ * gnu-nat.[ch]: tidying up comments.
+ * gnu-nat.c: remove calls to prune_threads and renumber_threads;
+ gnu_wait must not return -1 when inferior exits;
+ attach_to_child will modify inferior_pid in a way that allows
+ fork_inferior to remain unchanged; remove extra arg from
+ startup_inferior; move Mach thread commands here from thread.c.
+
+Mon Apr 28 18:21:20 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * symtab.c: decode_line_1, replace the assignment to
+ values.sals[0].pc which I accidentally left out on 4/3/97.
+
+Mon Apr 28 17:27:40 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * c-exp.y: make parse_number reject "123DEADBEEF".
+ (fix by Bob Manson).
+ * java-exp.y: Ditto.
+ * top.c: change "to enable to enable" to "to enable" in a couple
+ of help strings.
+
+Mon Apr 28 09:01:59 1997 Mark Alexander <marka@cygnus.com>
+
+ * breakpoint.c (remove_breakpoint): Pass correct type to
+ target_remove_watchpoint.
+ * target.h: Improve comment for target_{remove,insert}_breakpoint.
+
+Sat Apr 26 03:38:02 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-tdep.c (heuristic_proc_desc): Increase search limit
+ for return address register, handle `ret' instruction.
+
+ * corelow.c (get_core_registers): Initialize cf.
+
+ * procfs.c: Minor changes to make pre-ANSI compilers happy.
+ (procfs_notice_signals): Copy traced signal set back to
+ pi->prrun.pr_trace.
+ (unconditionally_kill_inferior): If PR_DEAD is defined,
+ rerun inferior after killing it.
+
+Fri Apr 25 00:10:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10300/tm-mn10300.h (EXTRACT_STRUCT_VALUE_ADDRESS): The
+ structure value address is found in $a0 now.
+ * config/mn10200/tm-mn10200.h (EXTRACT_STRUCT_VALUE_ADDRESS): Likewise.
+
+Thu Apr 24 13:31:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10300/tm-mn10300.h (STORE_RETURN_VALUE): Pointers are
+ returned in $a0.
+ (EXTRACT_RETURN_VALUE): Likewise.
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Check for a return
+ insn at "pc", not "fi->pc".
+
+Wed Apr 23 11:18:45 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10200/tm-mn10200.h (STORE_RETURN_VALUE): Pointers are
+ returned in $a0.
+ (EXTRACT_RETURN_VALUE): Likewise.
+
+Tue Apr 22 11:58:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/arm/tm-arm.h (TARGET_DOUBLE_FORMAT): Define to use
+ floatformat_ieee_double_littlebyte_bigword for little endian
+ target byte order.
+ * utils.c (floatformat_to_doublest): Create local preswapped
+ copy of input for floatformat_littlebyte_bigword formats.
+ (get_field, put_field): Treat floatformat_littlebyte_bigword
+ the same as floatformat_little.
+ (floatformat_from_doublest): Postswap output words for
+ the floatformat_littlebyte_bigwords format.
+
+Tue Apr 22 09:02:10 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/alpha/alpha-osf3.mh config/i386/{i386gnu linux}.mh
+ config/mips/{embed embed64 embedl embedl64 vr4300 vr4300el vr5000
+ vr5000el}.mt config/powerpc/{aix aix4}.mh config/rs6000/{aix
+ aix4}.mh config/sh/sh.mt config/sparc/sp64sim.mt:
+ config/v850/v850.mt:
+ Remove -lm. That's now handled by configure.
+
+ * Makefile.in (maintainer-clean): Add distclean to dependencies.
+ Remove duplicate rm's of files.
+
+Mon Apr 21 09:49:25 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-pa.c: Remove. It's broken and no longer necessary.
+
+ Sat Apr 19 11:56:10 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * java-exp.y: Combine TRUE and FALSE into BOOLEAN_LITERAL.
+ (Avoids name clash with broken AIX header files.)
+
+Sat Apr 19 01:49:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * serial.c (serial_log_command): Fix fputs_unfiltered calls.
+
+ * config/powerpc/tm-ppc-aix4.h, config/rs6000/tm-rs6000-aix4.h
+ (DONT_RELOCATE_SYMFILE_OBJFILE): Removed.
+ * xcoffsolib.h (struct vmap): Add new members tvma, toffs and dvma,
+ remove tadj.
+ * exec.c (bfdsec_to_vmap): Initialize new vmap members, initialize
+ tstart and dstart with section VMA.
+ * rs6000-nat.c (vmap_symtab): Relocate relative to the VMA in the
+ object file.
+ (vmap_ldinfo, xcoff_relocate_core): Adjust tstart by section offset
+ of the text section, remove DONT_RELOCATE_SYMFILE_OBJFILE hack.
+ (vmap_exec): Relocate relative to the VMA in the object file,
+ relocate .bss section as well.
+ (xcoff_relocate_core): No longer adjust section addresses by VMA.
+ * rs6000-tdep.c (find_toc_address): Change type of tocbase
+ to CORE_ADDR.
+ * xcoffread.c (secnum_to_bfd_section): New routine to get
+ BFD section from CS section number.
+ (scan_xcoff_symtab): Make toc_offset section relative.
+
+ * symtab.c (total_number_of_methods): Avoid core dump if
+ baseclass type is still undefined.
+
+Fri Apr 18 17:25:10 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (SUBDIRS): Add mswin so that make cleanup cleans up
+ that directory.
+ * defs.h utils.c (error warning): Make message be const.
+ * main.c (fputs_unfiltered): Only send gdb_stdout and gdb_stderr
+ to hook. Otherwise send it to fputs.
+ * monitor.c monitor.h (monitor_get_dev_name): New function. Does
+ the obvious.
+ * remote-e7000.c: Remove debugify stuff. Change printf, fprintf
+ to _filtered forms to make output appear in GUIs. Replace all
+ uses of SERIAL_READCHAR with readchar, which has better error
+ checking.
+ * (e7000_parse_device): Add prototype.
+ (readchar): Improve doc. Handle random serial errors.
+ (expect): Disable notice_quit code. It's busted. Remove
+ serial error handling (it's now handled in readchar). Remove
+ remote_debug echoing. That's handled in readchar as well.
+ (e7000_parse_device): Remove serial_flag arg. It's not
+ necessary.
+ (e7000_open): Split into two pieces. Second part is
+ e7000_start_remote, and is error protected. Now, when we connect
+ to the target, we setup the initial frame and registers so that
+ the user gets an immediate indication of where the target is.
+ (gch): Remove debug output. That's handled by readchar.
+ (e7000_read_inferior_memory): Handle errors better.
+ (_initialize_remote_e7000): Get rid of `<xxx>' things from
+ command names. They show up when doing completion and confuse
+ things horribly.
+ * ser-e7kpc.c: Get rid of the DLL's since we can access the device
+ directly from Win32s and Win95. Get rid of debugify crud.
+ * serial.c: Remove debugify cruft.
+ * (serial_logchar serial_log_command serial_write serial_readchar
+ serial_send_break serial_close): Merge common functionality into
+ serial_logchar. Clean up rest of routines.
+ * sparclet-rom.c: Disembowel. Leave only download routine.
+ Download routine now switches to remote target automatically.
+ * top.c (disconnect): Only define if SIGHUP is defined. Cleans
+ up MSVC/Win32 problem.
+ * utils.c (gdb_flush): Don't call hook unless it's for gdb_stdout
+ or gdb_stderr.
+ * config/sh/tm-sh.h: Define TARGET_SH for WinGDB.
+ * config/sparc/tm-sparclet.h: Remove override for prompt.
+
+Fri Apr 18 13:38:19 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Only pass -E to sim_open if
+ TARGET_BYTE ORDER_SELECTABLE.
+
+Fri Apr 18 16:52:41 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (init_callbacks): Initialize poll_quit and magic
+ fields of gdb_callback.
+ (gdbsim_stop): Add gdbsim_stop to list of supported client
+ operations.
+ (gdbsim_wait, gdbsim_resume): Move call to sim_resume into
+ sim_wait where gdb is in a position to handle a long running
+ function.
+ (gdbsim_cntrl_c): New function. Wrap the sim_resume call in a
+ SIGINT handler.
+ (gdb_os_poll_quit): New function. Check for a quit pending on the
+ console.
+
+Thu Apr 17 14:30:04 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * objfiles.c (allocate_objfile): Allow NULL bfd argument.
+ * defs.h (enum language): Add language_java.
+ * java-exp.y, java-lang.c, java-lang.h, java-valprint.c: New files.
+ * Makefile.in: Update for new files.
+ * symfile.c (deduce_language_from_filename): Recognize .java.
+
+Thu Apr 17 02:20:23 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-stub.c (stash_registers): Rewrite.
+ (restore_registers): Renamed to restore_and_return.
+ (cleanup_stash): New function.
+ (process_exception): New function.
+ (_catchException*): Rewrite.
+
+ * remote-sim.c (gdbsim_load): Update call to sim_load.
+ (gdbsim_create_inferior): No longer pass start_address to
+ sim_create_inferior.
+ (gdbsim_open): Pass endian indicator as arg.
+
+Tue Apr 15 15:31:09 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (get_offsets): Don't use scanf for interpreting
+ response to qOffsets.
+
+Tue Apr 15 14:51:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbserver/Makefile.in (INSTALL_XFORM): Remove.
+ (INSTALL_XFORM1): Remove.
+ (install-only): Use $(program_transform_name) directly, rather
+ than using $(INSTALL_XFORM) and $(INSTALL_XFORM1).
+ (uninstall): Transform name.
+
+Mon Apr 14 17:06:27 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (mips_load): Ensure that PC gets updated
+ after a load on LSI target.
+
+Mon Apr 14 15:54:51 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ * procfs.c (notice_signals): fix typo
+
+Mon Apr 14 16:25:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbserver/Makefile.in (INSTALL): Change install.sh to
+ install-sh.
+
+Mon Apr 14 11:55:27 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ * config/i386/cygwin32.mh: remove -lkernel32 from XM_CLIBS
+ since gcc automatically includes it
+
+Thu Apr 10 13:20:53 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * procfs.c: Substantial (but incomplete) changes to support
+ sysv4.2mp procfs as implemented in UnixWare 2.1. The procinfo
+ struct now has substructs like struct flt_ctl instead of
+ just a fltset_t and has a ctl_fd, status_fd, as_fd, and
+ map_fd instead of a single fd. Non-sysv4.2mp procfs models
+ still have the structs and multiple fds, but don't use the
+ entire struct and the four fds all point to the same thing.
+ We use PROCFS_USE_READ_WRITE to decide whether to talk to
+ procfs with reads/writes or use ioctl instead. We use
+ HAVE_MULTIPLE_PROC_FDS to determine whether procfs really has
+ multiple fds or not. PROC_NAME_FMT is split out into
+ CTL_PROC_NAME_FMT, AS_PROC_NAME_FMT, MAP_PROC_NAME_FMT,
+ STATUS_PROC_NAME_FMT.
+
+ (procfs_notice_signals): now a necessary wrapper around
+ (notice_signals): which are the new guts for noticing signals
+ (open_proc_file): gets a new flag arg used in sysv4.2mp to
+ determine whether or not to attempt to open the ctl_fd.
+ (procfs_read_status): new local function, reads procfs status
+ (procfs_write_pcwstop): new local function, writes a PCWSTOP
+ (procfs_write_pckill): new local function, writes a PCKILL
+ (unconditionally_kill_inferior): remove signo since we now
+ just call procfs_write_pckill().
+ (procfs_xfer_memory): call lseek with SEEK_SET rather than 0
+ (proc_iterate_over_mappings): the whole function is ifdefed
+ on UNIXWARE to keep things readable.
+
+ Expanded the syscall_table to include new potential sysv4.2mp
+ members. Note that all ifdefs of UNIXWARE should be eliminated
+ if possible or renamed to describe what's being selected for a
+ bit better. Sysv4.2mp and IRIX both have SYS_sproc so the
+ IRIX specific code now also checks it's not UNIXWARE.
+
+ * config/i386/tm-i386v42mp.h: also define HAVE_PSTATUS_T,
+ HAVE_NO_PRRUN_T, PROCFS_USE_READ_WRITE, and UNIXWARE
+ * config/mips/nm-irix4.h: set CTL_PROC_NAME_FMT et al to
+ "/debug/%d" as PROC_NAME_FMT used to be
+
+Wed Apr 9 11:36:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c: Almost completely rewritten based on mn10200
+ port.
+ * config/mn10300/tm-mn10300.h: Likewise.
+
+Tue Apr 8 10:45:24 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/pa/{hppabsd.mt hppahpux.mt hppaosf.mt}: Remove
+ remote-pa.o from TDEPFILES. Nobody uses it, and besides, it's a
+ lousy out-of-date clone of remote.c.
+
+Fri Apr 4 08:21:21 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote.c: Fix problems realized while showering.
+ * (hexnumlen): Add prototype. Use max, not min.
+ * (remote_write_bytes remote_read_bytes): Fix max packet size
+ calculations to properly account for packet overhead. Also handle
+ (probably rare) case where remote_register_buf_size isn't set.
+
+ * remote.c: Fix doc for `C' and `S' commands to indicate full
+ address.
+ * (remote_ops extended_remote_ops remote_desc remote_write_size):
+ Make static.
+ * (remote_fetch_registers remote_write_bytes remote_read_bytes):
+ Record size of response to fetch registers command, use this to
+ limit size of memory read and write commands.
+ * (push_remote_target): New function to make it possible to have
+ another target switch to the remote target.
+ * target.h: Add prototype for push_remote_target.
+ * sh-tdep.c (sh_frame_find_saved_regs): Fix sign extension bugs
+ for hosts which default to unsigned chars (such as SGI's).
+ * (_initialize_sh_tdep): Don't set remote_write_size. It's now
+ handled automatically in remote.c.
+
+Thu Apr 3 15:10:30 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(),
+ find_pc_sect_function(), find_pc_sect_partial_function(): new
+ functions for debugging overlays; pc without section is ambiguous.
+ * breakpoint.[ch]: add section pointer to breakpoint struct;
+ add section argument to check_duplicates(); check section as well
+ as pc in [breakpoint_here_p(), breakpoint_inserted_here_p(),
+ breakpoint_thread_match(), bpstat_stop_status()];
+ add section argument to describe_other_breakpoints();
+ use INIT_SAL() macro to zero-out new sal structures;
+ make resolve_sal_pc() fix up the sal's section as well as its pc;
+ match on section + pc in clear_command() and delete_breakpoint();
+ account for overlay sections in insert_breakpoints(),
+ remove_breakpoint() and breakpoint_re_set_one();
+ all this to support overlays where a PC is not unique.
+ * exec.c: change xfer_memory() to handle overlay sections.
+ * findvar.c: change read_var_value() to handle overlay sections.
+ * frame.h: declaration for block_for_pc_sect() [blockframe.c].
+ * infcmd.c: jump_command() warns against jumping into an overlay
+ that's not in memory. Also use INIT_SAL() to initialize sals.
+ * infrun.c: wait_for_inferior() sets a flag to invalidate cached
+ overlay state information; Also use INIT_SAL() to init sals.
+ * m32r-rom.c: modify load routines to use LMA instead of VMA.
+ * m32r-stub.c: mask exit value down to 8 bits; screen out any
+ memory read/writes in the range 600000 to a00000, and ff680000
+ to ff800000 (hangs because nothing is mapped there); fix strcpy().
+ * maint.c: maintenance command "translate-address" supports overlays.
+ * minsyms.c: lookup_minimal_symbol_by_pc_sect() supports overlays.
+ * objfiles.[ch]: add ovly_mapped field to the obj_section struct;
+ this constitutes gdb's internal overlay mapping table. Add macro
+ ALL_OBJSECTIONS() to loop thru the obj_structs and look at overlays.
+ Add function find_pc_sect_section().
+ * printcmd.c: modify print_address_symbolic() with overlay smarts;
+ modify address_info() with overlay smarts; add function sym_info()
+ to support the INFO SYMBOL command (translate address to symbol(s));
+ modify disassemble_command() to work on unmapped overlays.
+ * source.c: use INIT_SAL() to initialize sals.
+ * symfile.[ch]: change generic_load() to use section's LMA address
+ instead of VMA address, for overlay sections.
+ Add numerous functions for finding a PC's section / overlay,
+ translating between VMA and LMA address ranges, determining if an
+ overlay section is mapped, etc. Add several user commands for
+ overlay debugging. Add support for a "generic" form of automatically
+ reading overlay mapping info from the inferior (based on the default
+ (simple) overlay manager which Cygnus provides as an example).
+ * symtab.[ch]: add functions find_pc_sect_symtab(),
+ find_pc_sect_psymtab(), find_pc_sect_psymbol(), find_pc_sect_line()
+ for lookup; modify lookup_symbol and decode_line_1() to use them;
+ modify find_function_start_sal() to account for overlay sections;
+ add macro INIT_SAL() for initializing struct symtab_and_line.
+ * target.c: fix a comment in the declaration of target_ops.
+
+Thu Apr 3 10:31:12 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_in_call_stub, mips_in_return_stub,
+ mips_skip_stub, mips_ignore_helper): New functions for dealing
+ with MIPS16 call/return thunks.
+ (mips_init_frame_pc_first): New function to implement
+ INIT_FRAME_PC_FIRST macro; includes code from old macro plus
+ new code to skip over MIPS16 thunks.
+ (mips_frame_chain): Skip over MIPS16 thunks.
+ * config/mips/tm-mips.h (mips_in_call_stub, mips_in_return_stub,
+ mips_skip_stub, mips_ignore_helper): Declare.
+ (IN_SOLIB_CALL_TRAMPOLINE, IN_SOLIB_RETURN_TRAMPOLINE,
+ SKIP_TRAMPOLINE_CODE, IGNORE_HELPER_CALL): New macros that invoke
+ the above functions.
+ (INIT_FRAME_PC_FIRST): Change to invoke mips_init_frame_pc.
+ (mips_init_frame_pc): Declare.
+ * infrun.c (wait_for_inferior): Use new IGNORE_HELPER_CALL macro
+ to decide if certain library function calls should be ignored.
+
+Wed Apr 2 14:16:51 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Check return code from sim_open.
+ Update call to sim_open (new arg SIM_OPEN_DEBUG).
+
+Mon Mar 31 14:55:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbinit.in: New file.
+ * .gdbinit: Remove.
+ * configure.in: Generate .gdbinit from gdbinit.in.
+ * configure: Rebuild.
+
+Sat Mar 29 13:57:20 1997 Fred Fish <fnf@cygnus.com>
+
+ * COPYING: Install new version of file from FSF.
+ * copying.c (show_copying_command): Update FSF address.
+
+Fri Mar 28 18:33:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Remove .gdbinit.
+
+Fri Mar 28 15:38:04 1997 Mike Meissner <meissner@cygnus.com>
+
+ * remote-sim.c (gdb_os_{,e}vprintf_filtered): Change stdarg type
+ to va_list from void *, since va_list might not be a pointer
+ type.
+
+Thu Mar 27 14:21:46 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Clean up comment and extraneous semicolon
+ for mips_monitor_prompt variable.
+
+Thu Mar 27 12:46:58 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Add `set monitor-prompt' command.
+
+Wed Mar 26 06:47:44 1997 Mark Alexander <marka@cygnus.com>
+
+ Fix from Peter Schauer:
+ * mdebugread.c (parse_procedure): Set address of procedure to
+ block start; this fixes problems with shared libraries introduced
+ by change of Mar 21.
+
+Mon Mar 24 19:43:16 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * symtab.c (find_pc_symtab): change to support the case
+ where the objfile is reordered and contains both coff and
+ stabs debugging info (continue on if a psymtab isn't found).
+
+Sun Mar 23 16:19:20 1997 Mark Alexander <marka@cygnus.com>
+
+ Fixes from Peter Schauer:
+ * config/mips/tm-mips.h (REGISTER_CONVERT_TO_TYPE,
+ REGISTER_CONVERT_FROM_TYPE): Swap words if target, not host,
+ is big-endian and if registers are 32 bits.
+ * mips-tdep.c (mips_print_register, mips_extract_return_value,
+ mips_store_return_value): Fix floating-point word-order problems on
+ little-endian targets introduced by changes of Mar 21.
+
+Sun Mar 23 15:43:27 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (target_resume_hook, target_wait_loop_hook): New
+ globals.
+ (remote_resume, remote_wait): Use them.
+ * d10v-tdep.c: Set the above hooks.
+ (tracesource): New GDB variable, controls source display in
+ traces.
+ (display_trace): Find and display source line if requested.
+ (trace_info): Mention empty trace buffer if appropriate.
+ (tdisassemble_command): Robustify argument handling.
+
+ * configure.host: Remove extra bogus Linux case.
+
+Sat Mar 22 16:41:35 1997 Fred Fish <fnf@cygnus.com>
+
+ * remote-sim.c (simulator_command): Add comment about dealing with
+ NULL or empty args.
+
+Sat Mar 22 02:48:11 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-exp.y (yylex): Handle nested template parameter lists.
+ * symtab.c (decode_line_2): Fix test for valid choice number.
+
+Fri Mar 21 19:10:05 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): On non-EABI architectures,
+ copy first two floating point arguments to general registers, so that
+ MIPS16 functions will receive the arguments correctly.
+ (mips_print_register): Print double registers correctly on
+ little-endian hosts.
+ (mips_extract_return_value): Return double values correctly
+ on little-endian hosts.
+
+ * mdebugread.c (parse_procedure): Adjust address of procedure relative
+ to address in file descriptor record; this accounts for constant
+ strings that may precede functions in the text section. Remove
+ now-useless lowest_pdr_addr from argument list and all calls.
+
+Fri Mar 21 15:36:25 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.tgt (powerpc*-{eabi,linux,sysv,elf}*): Determine
+ whether the simulator will be built by whether the Makefile in the
+ simulator directory was built.
+
+ * configure.in (--enable-sim-powerpc): Delete switch.
+ * configure: Regenerate.
+
+Thu Mar 20 20:52:04 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Look for save of "a1"
+ in the prologue too.
+
+ * remote-sim.c (gdb_os_vprintf_filtered): Fix to work with non-ANSI
+ compilers.
+ (gdb_os_evprintf_filtered): Similarly.
+
+Wed Mar 19 16:13:22 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ New UnixWare 2.1 configuration
+ * config/i386/i386v42mp.mt: new
+ * config/i386/i386v42mp.mh: new
+ * config/i386/tm-i386v42mp.h: new
+ * config/i386/nm-i386v42mp.h: new
+ * configure.tgt: added new entries
+ * configure.host: added new entries
+
+Mon Mar 17 17:52:00 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * dsrec.c (load_srec): Print leading zeroes when printing section
+ addresses.
+
+Mon Mar 17 15:00:16 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * remote-sim.h: Delete - moved to ../include/remote-sim.h.
+
+ * Makefile.in (remote_utils_h): Update path to remote-sim.h.
+
+Fri Mar 7 20:55:28 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * remote-sim.c (flush_stdout, write_stderr, flush_stderr,
+ vprintf_filtered, evprintf_filtered): Callbacks that accept
+ varargs.
+
+Sat Mar 15 00:50:46 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (insert_breakpoints, watchpoint_check,
+ bpstat_stop_status): Do not disable watchpoints going out of scope.
+ (insert_breakpoints): Make sure that the current frame is valid
+ before calling find_frame_addr_in_frame_chain.
+
+ * top.c (setup_user_args): Handle quotes and backslashes.
+ (print_gdb_version): Update copyright year.
+
+Fri Mar 14 15:44:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (elfread.o): Depend upon elf-bfd.h and elf/mips.h.
+
+Thu Mar 13 22:51:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * utils.c (pollquit, notice_quit): If _WIN32, limit test for
+ cntl-C to wingdb.
+ (initialize_utils): If _WIN32, don't call ScreenRows and ScreenCols
+ except under wingdb. (Contributed by Martin Hunt).
+
+Thu Mar 13 12:40:49 1997 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in: Run AC_CONFIG_AUX_DIR before AC_CANONICAL_SYSTEM.
+
+Thu Mar 13 11:00:22 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.h (sim_state, SIM_DESC): New types.
+ (sim_open): Return a `descriptor' as result.
+ (*): New argument of descriptor result from sim_open.
+ * remote-sim.c (gdbsim_desc): Renamed from gdbsim_open_p.
+ (gdbsim_open): Record result of sim_open in gdbsim_desc.
+ Pass argv list to sim_open, argv[0] = pseudo program name.
+ (*): Pass gdbsim_desc to sim_foo fns.
+
+Wed Mar 12 14:40:06 1997 Tom Tromey <tromey@cygnus.com>
+
+ * config.in: Regenerated.
+
+ * acconfig.h (START_INFERIOR_TRAPS_EXPECTED, sys_quotactl,
+ HAVE_HPUX_THREAD_SUPPORT): Define.
+
+Tue Mar 11 07:25:27 1997 Mark Alexander <marka@cygnus.com>
+
+ First cut at supporting simulators in gdbserver:
+
+ * configure, configure.in: Allow gdbserver to be configured
+ for cross-target environments.
+ * gdbserver/Makefile.in: Add simulator support.
+ * gdbserver/configure.in: Eliminate assumption that host == target.
+ Simplify using gdb/configure.tgt and gdb/configure.host.
+ Fix other minor configuration errors.
+ * gdbserver/low-sparc.c: Fix compile error.
+ * gdbserver/remote-utils.c: Eliminate assumption that registers
+ and addresses are four bytes. Fix minor compile errors and warnings.
+ * gdbserver/server.c: Rewrite numerous instances of identical code
+ for starting inferior processes to call new function start_inferior.
+ Eliminate assumption that registers and addresses are four bytes.
+ * gdbserver/server.h: Add missing prototypes to eliminate compiler
+ warnings.
+ * gdbserver/low-sim.c: New file to mate gdbserver with simulators.
+ * config/mips/vr5000.mt: Add Vr5000 simulator support to gdbserver.
+ * config/i386/linux.mh: Eliminate gdbserver support as a first step
+ in moving such support from host to target makefile fragments.
+ * config/i386/linux.mt: Move gdbserver support here from linux.mh.
+
+Mon Mar 10 12:27:47 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * symtab.h (INIT_SAL): New macro to initialize symtab_and_line,
+ to insure consistant initialization of unused fields to zero.
+ * symtab.c: replace initializations of sals with new macro INIT_SAL.
+ * breakpoint.c: ditto.
+ * infrun.c: ditto.
+ * infcmd.c: ditto.
+ * source.c: add call to INIT_SAL macro.
+
+Sat Mar 8 00:16:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-tdep.c (isbranch): Always handle v9 branch instructions,
+ they might get used on 32 bit targets as well.
+
+Wed Mar 5 19:34:09 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * remote-mips.c (mips_exit_debug): Some IDT boards don't
+ send the full exit string.
+
+Wed Mar 5 12:59:27 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_push_arguments): Handle new calling
+ conventions.
+ (mn10200_store_struct_return): Likewise.
+
+Tue Mar 4 10:31:02 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_fetch_instruction): New function; replace
+ common code throughout with calls to it.
+ (mips_find_saved_regs): Examine MIPS16 entry instruction to determine
+ correct saved addresses of $s0 and $s1.
+ (mips_find_saved_regs, mips16_heuristic_proc_desc): Use MIPS_REGSIZE
+ instead of hardcoded 4.
+ (mips16_skip_prologue): Handle extended instructions correctly.
+
+Mon Mar 3 12:29:20 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * defs.h (LONGEST): Move #ifndef LONGEST to outside.
+ Try BFD_HOST_64_BIT if ! CC_HAS_LONG_LONG.
+
+Thu Feb 27 18:54:11 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (IS_MIPS16_ADDR, MAKE_MIPS16_ADDR, UNMAKE_MIPS16_ADDR):
+ New macros for testing, setting, and clearing bit 0 of addresses.
+ Change numerous bits of code where bit 0 was being manipulated
+ to use these macros.
+
+Thu Feb 27 14:12:41 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Put back the form feeds.
+
+Thu Feb 27 12:04:24 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Remove form feeds (^L) from source.
+ (mips_initialize): LSI PMON doesn't support 'set regsize' command.
+ (pmon_wait): Don't need to exit and re-enter debug mode on LSI
+ PMON after a continue; it causes target program misbehavior.
+ (mips_fetch_register): Don't fetch unsupported registers; this
+ cuts down on wasted serial traffic.
+
+Thu Feb 27 09:38:16 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in configure (HPUX/OSF thread support): Enable this
+ only when running GCC, since HP's thread header files use ANSI C
+ which is not supported by their default compiler.
+
+ * configure.host (i[3456]86-*-windows): Disable long long
+ support for WinGDB. Add mswin to configdirs.
+ * configure.in configure: Move calls to configure.host and
+ configure.tgt to the top of configure.in to allow them to set
+ config variables before they are referenced.
+
+Tue Feb 25 20:21:52 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (mips*-*-lnews*): New target.
+
+Mon Feb 24 16:35:00 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Don't fix fi->frame
+ if we're not the innermost frame. Fix minor typos.
+
+Sat Feb 22 03:39:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.c (read_type): Fix handling of template names
+ with template parameters containing `::'.
+
+ * valops.c (search_struct_field, search_struct_method):
+ Pass correct valaddr parameter to baseclass_offset.
+ Prevent gdb crashes by making sure that the virtual base pointer
+ from an user object still points to accessible memory.
+
+Tue Feb 18 13:36:34 1997 Mark Alexander <marka@cygnus.com>
+
+ * maint.c: Eliminate -Wall warnings by including some header files.
+
+Tue Feb 18 13:06:30 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-sim.c (init_callbacks): Undo previous change.
+
+Tue Feb 18 11:13:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * maint.c: Fix dereference of pointer.
+ * remote-sim.c: Fix reference of structure member "last_error".
+ * debugify.c: Include config.h to get ANSI definitions.
+
+Sat Feb 15 17:43:46 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-vx.c (vx_attach): Remove code added by kung. It made no
+ sense.
+
+Fri Feb 14 13:00:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * main.c (print_gdb_help): Make static to match declaration.
+
+Thu Feb 13 18:18:18 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-e7000.c, ser-e7kpc.c, serial.c: Remove // comments.
+
+Wed Feb 12 15:58:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * debugify.c, debugify.h: Make safe for non-ansi compilers.
+
+Wed Feb 12 15:30:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * defs.h: Fix prototypes for new cleanup functions.
+
+Wed Feb 12 15:08:47 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * debugify.c, debugify.h: Fix for general gnu use. Remove C++
+ comment, add PARAMS, add license info and fix indentation.
+
+Wed Feb 12 14:42:47 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * debugify.c, debugify.h: New files. Provide common macros
+ for writing debug info to a log file or stdio.
+
+Wed Feb 12 02:44:39 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * c-valprint.c (c_val_print): Fix printing for arrays defined
+ with 0 length.
+
+Tue Feb 11 22:24:39 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * defs.h: Fix cntl-C to read from the Windows message queue.
+ Add prototypes for make_final_cleanup (and the other cleanup
+ routines.
+ * remote-e7000.c: Fix sync code to timeout if unable to sync.
+ Change sync code to report status while trying to sync-up
+ with hardware. Add debugging output and document.
+ * ser-e7kpc.c: Swap order of len & offset to match implementation.
+ Add debugging output and document.
+ * serial.c: Add debugging output.
+ * top.c: Add call to do_final_cleanups.
+ Remove conditionals preventing Win32 from getting SIGQUIT.
+ * utils.c: (*_cleanup): Modify cleanup routines to accept a cleanup
+ chain as a parameter. Extract this generic code from the cleanup
+ routines into separate funtions (*_my_cleanup). Keep old
+ functionality by passing "cleanup_chain" to the new funtions.
+ Define the cleanup chain "final_cleanup_chain" to be a cleanup
+ chain which will be executed only when gdb exits. Add functions
+ (*_final_cleanup) to match the original (*_cleanup) functions.
+ (pollquit, quit, notice_quit): Fix to read cntl-C from the
+ Windows message queue.
+
+Tue Feb 11 15:36:31 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-rom.c: #include <sys/types.h>.
+ #ifdef out new load support if wingdb.
+ * m32r/tm-m32r.h (TARGET_M32R): Define, for wingdb.
+
+Tue Feb 11 12:28:09 1997 Jeffrey A Law (law@cygnus.com)
+
+
+ * config/mn10200/tm-mn10200.h (STORE_STRUCT_RETURN): Fix.
+ * mn10200-tdep.c (mn10200_store_struct_return): New function.
+
+ * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE): Fix case when
+ extracting a return value from a register pair.
+
+ * mn10200-tdep.c (mn10200_push_arguments): Stack only needs to
+ be two byte aligned. Round argument sizes up to two byte boundary.
+ Write out args in two byte hunks.
+ (mn10200_push_return_address): Implement.
+ * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE): Abort for
+ structures > 8 bytes (temporary).
+ (STORE_RETURN_VALUE): Likewise.
+ (CALL_DUMMY): No longer undefine.
+ (USE_STRUCT_CONVENTION): Use for args > 8 bytes.
+ (REG_STRUCT_HAS_ADDR): Define.
+
+Mon Feb 10 18:35:55 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (non_heuristic_proc_desc): New function.
+ (find_proc_desc): Move non-heuristic proc search code into separate
+ function.
+ (gdb_print_insn_mips): Use non-heuristic method to find procedure
+ descriptor, to avoid prologue examination when disassembling.
+ * remote-mips.c: Add support for new "lsi" target (LSI MiniRISC
+ aka MicroMeteor board).
+ (mips_exit_debug): Prevent protocol reinitialization if an error
+ occurs while exiting debug mode.
+
+Mon Feb 10 16:11:57 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c: Remove lots of debugging printfs, update/improve
+ comments, formatting, etc. Plus other minor fixes for problems
+ I found during my first pass over the mn10200 port.
+ (mn10200_analyze_prologue): New function.
+ (mn10200_frame_chain, mn10200_init_extra_frame_info): Use it.
+ * config/mn10200/tm-mn10200.h: Lots of updates/improvements to
+ comments, formatting, etc. Minor fixes for problems I found during
+ my first pass over the mn10200 port.
+ (TARGET_*_BIT): Define appropriately for ints, long longs, doubles and
+ pointers.
+ (REGISTER_VIRTUAL_TYPE): Define as a long.
+ (EXTRACT_RETURN_VALUE): Rework to deal with long ints living
+ in register pairs.
+ (STORE_RETURN_VALUE): Similarly.
+
+ * blockframe.c (generic_get_saved_regs): Remove unused variable
+ "addr".
+ * breakpoint.c (frame_in_dummy): Move struct breakpoint *b decl
+ inside #ifdef CALL_DUMMY.
+ (watch_command_1): Initialize target_resources_ok.
+ * command.c (do_setshow_command): Provide dummy initialization
+ for "match".
+ * valops.c (find_function_addr): Move function & prototype inside
+ #ifdef CALL_DUMMY.
+ (value_arg_coerce): Similarly.
+ (value_of_variable): Provide dummy initialization of "frame".
+
+Mon Feb 10 07:54:26 1997 Fred Fish <fnf@cygnus.com>
+
+ * xcoffread.c (RECORD_MINIMAL_SYMBOL): Add NULL asection* parameter
+ to prim_record_minimal_symbol_and_info call that was missed in Jan 3
+ change.
+ (scan_xcoff_symtab): Ditto.
+
+Sun Feb 09 09:23:26 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (common_breakpoint): Prevent 64-bit addresses
+ from being sent to 32-bit targets by masking off upper bits.
+ * mips-tdep.c (heuristic_proc_start): Mask off upper 32 bits
+ of PC on 32-bit targets.
+ (mips16_heuristic_proc_desc): Recognize 'addiu s1,sp,n' as a
+ frame setup instruction.
+ (mips32_heuristic_proc_desc): Fix warning found by gcc -Wall.
+ (mips16_skip_prologue): Recognize 'addiu s1,sp,n' as a valid
+ prologue instruction. Fix warnings and bugs found by gcc -Wall.
+ * buildsym.c (finish_block): Improve handling of overlapping blocks;
+ fixes problem on MIPS16 printing function arguments.
+
+Sat Feb 8 01:14:43 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarf2read.c (dwarf2_linkage_name): New function to get
+ the linkage name of a die from DW_AT_MIPS_linkage_name or
+ DW_AT_name.
+ (read_func_scope, dwarf2_add_field, dwarf2_add_member_fn,
+ new_symbol): Use it instead of accessing DW_AT_name.
+ (read_partial_die): Use DW_AT_MIPS_linkage name as name of the
+ partial die if present.
+ (dwarf2_add_member_fn): Make a copy of physname on the type obstack.
+
+Fri Feb 7 10:06:22 1997 Jeffrey A Law (law@cygnus.com)
+
+ * blockframe.c (generic_frame_chain_valid): If the new frame
+ is not INNER_THAN the old frame, then it's not valid.
+
+Tue Feb 04 09:04:37 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips16_get_imm): Fix calculation of extended immediate.
+ (mips16_heuristic_proc_desc): Recognize jal(x) instruction.
+
+Mon Feb 03 17:57:58 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips16_decode_reg_save): Distinguish between
+ sd and sw instructions correctly.
+ (heuristic_proc_start): Add support for MIPS16.
+ (mips16_get_imm, mips16_heuristic_proc_desc,
+ mips32_heuristic_proc_desc): New helper functions for
+ heuristic_proc_desc.
+ (heuristic_proc_desc): Rewrite and reorganize to support MIPS16.
+ (mips_push_arguments): Don't align small arguments in EABI.
+ (mips32_skip_prologue): Attempt to shrink code size a little.
+
+Mon Feb 3 11:06:05 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-stub.c: New -- remote protocol support for M32R cpu.
+ * m32r-rom.c: Several experiments with improved download time.
+
+Fri Jan 31 08:26:39 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (MIPS16_INSTLEN): Define.
+ (mips_find_saved_regs): Replace hardcoded 2's with MIPS16_INSTLEN.
+ (heuristic_proc_start): Recognize 'entry' pseudo-op as a start
+ of function on MIPS16.
+ (mips32_skip_prologue, mips16_skip_prologue): New helper functions
+ for mips_skip_prologue.
+ (mips_skip_prologue): Recognize both 16- and 32-bit prologues.
+
+Wed Jan 29 12:45:54 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/ppc{,le}-sim.mt (SIM): Remove the library
+ ../sim/common/libcommon.a.
+
+Tue Jan 28 15:54:13 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: fix a null pointer ref in generic_get_saved_register
+
+Tue Jan 28 15:39:50 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10200-tdep.c (mn10200_frame_chain): Get basic backtracing
+ working.
+
+Mon Jan 27 14:31:52 1997 Mark Alexander <marka@cygnus.com>
+
+First set of changes for mips16:
+ * config/mips/tm-mips.h (MIPS16_BIG_BREAKPOINT,
+ MIPS16_LITTLE_BREAKPOINT, BREAKPOINT_FROM_PC): Define.
+ (ABOUT_TO_RETURN): Call new function mips_about_to_return.
+ (mips_breakpoint_from_pc, mips_about_to_return): Declare.
+ * mem-break.c (memory_breakpoint_from_pc): New function.
+ (memory_insert_breakpoint, memory_remove_breakpoint): Use
+ memory_breakpoint_from_pc to determine breakpoint contents and size.
+ * target.h (memory_breakpoint_from_pc): Declare.
+ * monitor.c (monitor_insert_breakpoint): Use memory_breakpoint_from_pc
+ to determine size of breakpoint instruction.
+ * mips-tdep.c (mips32_decode_reg_save, mips16_decode_reg_save):
+ New helper functions for mips_find_saved_regs.
+ (mips_find_saved_regs): Recognize mips16 prologues.
+ (mips_addr_bits_remove): Strip off upper 32 bits of address
+ when target CPU is 32 bits but CORE_ADDR is 64 bits.
+ (mips_step_skips_delay): No branch delay slot on mips16.
+ (gdb_print_insn_mips): Disassemble mips16 code.
+ (mips_breakpoint_from_pc, mips_about_to_return): New functions.
+
+Mon Jan 27 10:34:03 1997 Jeffrey A Law (law@cygnus.com)
+
+ * tm-mn10200.h (NUM_REGS): Decrease to 12.
+ (REGISTER_NAMES): Elimination registers not found on the mn10200.
+ (PC_REGNUM, MDR_REGNUM, PSW_REGNUM): Corresponding changes.
+ (LIR_REGNUM, LAR_REGNUM): Delete. They don't exist on the mn10200.
+
+Sat Jan 25 00:07:59 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarf2read.c: Replace integral tag, name and form fields in
+ internal structure definitions with the corresponding enumeration
+ types from dwarf2.h. Add default cases to switches on enumerations
+ where appropriate.
+ Make quoting of string arguments in complaint messages consistent.
+ Check for NULL returns from DW_STRING.
+ (struct partial_die_info): Add sibling and has_type fields, remove
+ unused value field.
+ (DW_*): Move access macro definitions near the definition of the
+ attribute structure.
+ (struct field_info): New structure to pass information about fields
+ and member functions between die processing routines.
+ (dwarf2_build_psymtabs_hard): Set cu_header_offset.
+ (scan_partial_symbols): Do not enter DW_TAG_subprogram dies into
+ the partial symbol table if the DW_AT_*_pc attributes are missing.
+ Add file scope base type definitions to the partial symbol table.
+ Skip over child dies if the die has a sibling attribute.
+ (add_partial_symbol): Enter global variables with type attributes
+ and without location descriptors into the partial symbol table.
+ Store value of DW_TAG_variable dies in the partial symbol table.
+ Do not enter global variables into the minimal symbol table.
+ Add base type definitions to the partial symbol table.
+ (psymtab_to_symtab_1): Use dwarf2_get_pc_bounds to determine highpc.
+ (process_die): Move check for DW_AT_low_pc to read_func_scope.
+ Add a typedef symbol for base type definitions to the symbol table.
+ Ignore DW_TAG_inlined_subroutine tags for now.
+ (read_file_scope): Use dwarf2_get_pc_bounds to determine pc bounds.
+ (read_func_scope, read_lexical_block_scope): Use dwarf2_get_pc_bounds
+ to determine pc bounds, ignore dies with invalid bounds.
+ (dwarf2_get_pc_bounds): New routine to extract and validate the
+ DW_AT_*_pc attributes of a die.
+ (dwarf2_add_field, dwarf2_attach_fields_to_type, skip_member_fn_name,
+ dwarf2_add_member_fn, dwarf2_attach_fn_fields_to_type):
+ New functions to handle fields and member functions.
+ (read_structure_scope): Rewritten to use them.
+ (read_array_type): Renamed from dwarf_read_array_type.
+ Default upper array bound to describe an array with unspecified
+ length.
+ Create array types in backwards order, as dwarf2 puts out the array
+ dimensions from left to right.
+ (read_subroutine_type): Handle DW_TAG_unspecified_parameters,
+ DW_AT_artificial and DW_AT_prototyped.
+ (read_base_type): Make an unsigned type for DW_ATE_boolean.
+ Pass objfile to dwarf_base_type.
+ (read_partial_die): Use read_attribute to read in the attributes.
+ Handle DW_AT_sibling and DW_AT_type.
+ Follow references when determining DW_AT_name and DW_AT_external
+ attributes of the die.
+ Validate DW_AT_*_pc attributes.
+ (read_full_die): Use read_attribute to read in the attributes.
+ (read_attribute): New function to read an attribute described
+ by an abbreviated attribute.
+ (new_symbol): Relocate symbol value for DW_TAG_label with baseaddr.
+ Do not set SYMBOL_VALUE_ADDRESS for DW_TAG_subprogram,
+ SYMBOL_BLOCK_VALUE for the symbol will be set later by finish_block.
+ Change symbol class for global variables with a zero valued location
+ descriptor to LOC_UNRESOLVED.
+ Handle DW_AT_const_value attributes for DW_TAG_variable,
+ DW_TAG_formal_parameter and DW_TAG_enumerator.
+ Build a typedef symbol for DW_TAG_base_type.
+ (dwarf2_const_value): New routine to copy a constant value from an
+ attribute to a symbol.
+ (dwarf_base_type): Use passed in objfile, not current_objfile
+ when calling dwarf2_fundamental_type.
+ (dump_die): Use DW_* accessor macros to access values of attributes.
+ (decode_locdesc): Handle DW_OP_plus_uconst.
+
+Wed Jan 22 01:31:16 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10200-tdep.c: New file.
+ * config/mn10200/tm-mn10200.h: New, REGISTER_SIZE is 24 bits not 32,
+ SP_REGNUM and FP_REGNUM are different, also no lar or lir.
+ * config/mn10200/mn10200.mt: New file.
+ * configure.tgt: add mn10200 entry.
+
+Tue Jan 21 18:32:23 1997 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * configure.in configure: Check if host has libdl if doing
+ Solaris threads.
+
+Tue Jan 21 17:03:26 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10300-tdep.c: Wrote/fixed implementations of
+ mn10300_frame_chain, mn10300_init_extra_frame_info,
+ mn10300_frame_saved_pc
+ * config/mn10300/tm-mn10300.h: Redefine INIT_EXTRA_FRAME_INFO
+ and INIT_FRAME_PC macros.
+
+Tue Jan 21 17:01:20 1997 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * configure.in configure: Check if host has libm. Make sure we
+ are using gcc when using the -export-dynamic option. Fixes a
+ problem with building under Solaris/SunPro cc.
+
+Mon Jan 20 13:52:13 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/{embed,embed64,embedl,embedl64}.mt:
+ Link in simulator on MIPS embedded targets.
+
+Sat Jan 18 02:31:29 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (frameless_look_for_prologue): Mark frames
+ with a zero PC as frameless to improve backtraces from core dumps
+ caused by dereferencing a NULL function pointer.
+
+Thu Jan 16 14:10:41 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: fix BREAKPOINT definition.
+
+Tue Jan 14 16:01:06 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10300-tdep.c: made a lot more generic, ripping out code
+ from copied target (no more mn10300_scan_prologue,
+ init_extra_frame_info, and mn10300_fix_call_dummy calls)
+ * config/mn10300/tm-mn10300.h: undefine INIT_EXTRA_FRAME_INFO
+ and INIT_FRAME_PC macros
+
+Thu Jan 9 11:44:40 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sparc-tdep.c (sparc_frame_find_saved_regs): Don't use
+ FP_REGISTER_BYTES to compute offsets into the saved frame,
+ since it fails for SPARC targets configured without any
+ FP regs. Instead, use DUMMY_STACK_REG_BUF_SIZE.
+
+Mon Jan 6 11:15:14 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * symtab.c (fixup_symbol_section): Handle NULL symbols without
+ crashing.
+
+Fri Jan 3 12:08:16 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in configure configure.in: Remove ENABLE_CLIBS,
+ ENABLE_OBS, and THREAD_DB_OBS. These are consolidated into LIBS
+ and CONFIG_OBS.
+ * configure configure.in: Clean up test cases around thread support.
+ * configure.tgt (v850-*-*): Include v850ice.o and v850.lib if
+ host is Windows.
+ * c-valprint.c ch-valprint.c cp-valprint.c eval.c expprint.c
+ printcmd.c valops.c value.h values.c: Add bfd_section arg to
+ value_at and value_at_lazy.
+ * coffread.c dbxread.c elfread.c mdebugread.c minsyms.c symtab.h:
+ Add bfd_section arg to prim_record_minimal_symbol_and_info.
+ * corefile.c gdbcore.h printcmd.c valops.c: Use read_memory_section
+ instead of read_memory. It takes a bfd_section arg.
+ * coffread.c dbxread.c elfread.c gdb-stabs.h objfiles.h: Remove
+ unnecessary cast for assignment of struct dbx_symfile_info.
+ Struct objfile now uses a real pointer instead of PTR for this
+ element.
+ * dbxread.c (dbx_symfile_init): Stash bfd section pointers for
+ text, data and bss into dbx_symfile_info.
+ * exec.c (xfer_memory): Handle transfers for user-specified
+ sections.
+ * findvar.c (read_var_value locate_var_value): Copy bfd section
+ from the symbol to the value.
+ * gdb-stabs.h: Add section pointers for text, data and bss
+ sections.
+ * maint.c (translate address command): Add test code for overlay
+ address translation.
+ * printcmd.c (do_examine do_one_display): Now takes a bfd section
+ arg.
+ * (print_formatted x_command): Record current section along with
+ current address for repeated commands.
+ * sparc-nat.c (fetch_inferior_registers): Change
+ target_xfer_memory to target_{read write}_memory to allow changes
+ to target_xfer_memory interface for section info.
+ * symmisc.c (dump_msymbols print_symbol): Print section
+ assocaited with symbol.
+ * symtab.c (fixup_symbol_section): New routine to
+ add section info to symbols returned by lookup_symbol.
+ * symtab.h (struct general_symbol_info): Add bfd section to
+ symbols.
+ * target.c target.h (target_xfer_memory): Add bfd section to
+ args.
+ * (target_read_memory_section): New routine to read data from a
+ specific section.
+ * (target_memory_bfd_section): New global variable to pass bfd
+ section in to targets.
+ * valarith.c (value_add value_addr value_array): Preserve bfd
+ section when computing new value.
+ * value.h (struct value): Add bfd section to values.
+ * values.c (allocate_value value_copy): Initialize/preserve bfd
+ section.
+ * (unpack_double): Clean up _MSC_VER conditionals to remove
+ duplicate code.
+ * v850ice.c: New module to support communication with NEC's
+ PC-based ICE.
+ * config/v850/tm-v850.h (REGISTER_NAMES): Replace sp, gp, fp, and
+ ep names with rxx names. sp and fp are renamed via a different
+ mechanism.
+
+Fri Jan 3 14:20:05 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10300-tdep.c (mn10300_push_arguments): rewrote,
+ also removed code elsewhere that made use of RP_REGNUM.
+ * config/mn10300/tm-mn10300.h: ripped out RP_REGNUM, V0_REGNUM,
+ ARG0_REGNUM, ARGLAST_REGNUM (all not appropriate for mn10300
+ arch.), redefined SAVED_PC_AFTER_CALL, EXTRACT_RETURN_VALUE,
+ EXTRACT_STRUCT_VALUE_ADDRESS, STORE_RETURN_VALUE.
+
+For older changes see ChangeLog-96
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/contrib/gdb/gdb/ChangeLog-98 b/contrib/gdb/gdb/ChangeLog-98
new file mode 100644
index 0000000..bd19b49
--- /dev/null
+++ b/contrib/gdb/gdb/ChangeLog-98
@@ -0,0 +1,7122 @@
+Thu Dec 31 15:26:13 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * corelow.c (core_ops): Don't initialize statically.
+ (init_core_ops): New function, fills in core_ops.
+ (_initialize_corelow): Use it.
+
+Thu Dec 31 16:54:30 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by
+ Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+ Edith Epstein <eepstein@sophia.cygnus.com>
+ David Taylor <taylor@texas.cygnus.com>
+
+ * config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Change to read
+ nullify instruction bit from IPSW only when we are not in a system
+ call.
+ (STRCAT_REGISTER, pa_do_strcat_registers_info): Additional
+ parameter -- precision.
+
+ * Makefile.in (BUILD_TUI): To build the tui, only when configured
+ with --enable-tui.
+ (YLWRAP): Use ylwrap to avoid problems on systems w/o bison.
+ (gdb$(EXEEXT)): Make it dependent on BUILD_TUI.
+ (all-tui): Remove dependency from phony target.
+ (c-exp.tab.c): Use ylwrap instead of bison.
+ (jv-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
+
+ * configure.in (ENABLE_CFLAGS): Define and export BUILD_TUI.
+
+ * configure: Regenerated.
+
+ * c-typeprint.c (c_type_print_base): Get to the method name by
+ skipping over all the namespaces, classes and '::'.
+
+ * infcmd.c (run_command): Only call SOLIB_RESTART if it's
+ defined.
+ (detach_command): Ditto.
+
+ * infptrace.c (call_ptrace): Add some debugging code.
+
+ * infrun.c (follow_inferior_fork): Only define on HP.
+ (wait_for_inferior): Only call SOLIB_IN_DYNAMIC_LINKER if we have
+ shared libraries; restore test of IN_SOLIB_DYNSYM_RESOLVE_CODE
+ removed by HP.
+
+ * Makefile.in (ALLDEPFILES): Add somread.c, hp-psymtab-read.c,
+ hp-symtab-read.c.
+ (SFILES): Remove the above files
+ (COMMON_OBS): Remove somread.o
+ (SFILES): Add the tui files to this, so they get
+ included in etags tables.
+ (all-tui): New rule, which does a recursive make in the tui
+ subdir.
+ (gdb$(EXEEXT)): Add tui-all to the list of
+ dependencies, and add tui/libtui.a to the link list.
+ (tui/libtui.a): When recursing, pass down
+ ${FLAGS_TO_PASS}. And don't echo the make command. This is
+ closer to what the other recursions do.
+ (HFILES_NO_SRCDIR) add hpread.h.
+ (COMMON_OBS): Add hp-psymtab-read.o, hp-symtab-read.o
+ Allow the TUI code to be conditionally enabled.
+ (TUI_TARGET, TUI_LIBRARY): New variables, whose values are set by
+ the configuration script. They're set to the empty string when
+ the TUI isn't enabled.
+ (gdb$(GDBEXT)): Use those, instead of referring to tui-all and
+ tui/libtui.a directly.
+
+ * Makefile.in: Avoid spurious relinking.
+ (gdb$(EXEEXT)): Depend on the actual tui library, not on a
+ fictitious target. Since the fictitious target never existed, make
+ would always relink.
+ (tui/libtui.a): Renamed from all-tui. Always recurse to make sure
+ the library is up to date.
+ (TUI_TARGET): Variable removed; there's no need for it any more.
+
+ * Makefile.in: Look for tui include files in the tui source dir.
+
+ * Use automake's `aclocal' program to generate aclocal.m4, to allow
+ us to use automake macros in configure.in with impunity.
+
+ * acconfig.h: Add an entry for the `TUI' symbol.
+
+ * acinclude.m4: New file, containing the code from the old
+ aclocal.m4. Incorporate (by reference) ../bfd/acinclude.m4, not
+ ../bfd/aclocal.m4, since we only want bfd's local macros.
+
+ * aclocal.m4: Now automagically generated. Just run aclocal!
+
+ * annotate.c (annotate_catchpoint): New function.
+
+ * annotate.h: Taking the new includes (symtab.h and gdbtypes.h).
+ not taking the ansic C build fix.
+ (annotate_catchpoint): Declare.
+
+ * blockframe.c (blockvector_for_pc_sect): Check that the end of
+ the block is >= to the pc, not just >.
+
+ * breakpoint.c (create_temp_exception_breakpoint): #If it out --
+ nothing calls it.
+ (bpstat_stop_status): Don't call SOLIB_HAVE_LOAD_EVENT if it's not
+ defined; don't call SOLIB_HAVE_UNLOAD_EVENT if it's not defined.
+ (bpstat_get_triggered_catchpoints): If we don't have shared
+ library support, then don't call SOLIB_LOADED_LIBRARY_PATHNAME nor
+ SOLIB_UNLOADED_LIBRARY_PATHNAME.
+ (watch_command_1): Don't require a run before a watch command
+ unless we're on HP [it's an HP OS bug, not a generic limitation]
+ (catch_load_command_1): Don't define if no shared libraries.
+ (catch_command_1): Don't claim to support fork catchpoints unless
+ CHILD_INSERT_FORK_CATCHPOINT is defined, don't claim to support
+ vfork catchpoints unless CHILD_INSERT_VFORK_CATCHPOINT is defined,
+ don't clain to support shared library load catchpoints if shared
+ libraries aren't supported, and don't claim to support exec
+ catchpoints unless CHILD_INSERT_EXEC_CATCHPOINT is defined
+
+ (bpstat_do_actions): If we just set cmd to NULL, don't then try to
+ set it to cmd->next as we'll SEGV.
+ (bpstat_do_actions): Simplify significantly. It's
+ now almost as simple as before the merge and it no longer has the
+ HP bug that breakpoint commands are executed repeatedly.
+
+ (break_at_finish_command_1): Rewrite and make sure
+ selected_frame points to a frame before using it. Fix string
+ termination error.
+ (break_at_finish_at_depth_command_1): Ditto.
+
+ (can_use_hw_watchpoints): New static variable.
+ (read_memory_nobpt): Test for breakpoint type bp_none.
+ (insert_breakpoints): Test for breakpoint type bp_catch_exec;
+ insure have a current frame before getting the frame address.
+ (remove_breakpoints): Check for breakpoints of types bp_none,
+ bp_catch_fork, bp_catch_vfork, and bp_catch_exec.
+ (bpstat_stop_status): Fix updates of b->hit_count.
+ (bpstat_have_active_hw_watchpoints): New function.
+ (create_exec_event_watchpoint): New function.
+ (watch_command_1): Use can_use_hw_watchpoints.
+ (catch_fork_command_1): Change name of function to call from
+ target_create_catch_(v)fork_hook to create_(v)fork_even_catchpoint.
+ (delete_breakpoint): Test for already deleted breakpoints; add
+ support for bp_catch_fork, bp_catch_vfork, and bp_catch_exec
+ breakpoints.
+ (_initialize_breakpoint): Add can-use-hw-watchpoints to list of
+ user settable debugger variables.
+
+ (clear_command): When there is no argument
+ to the clear command, delete all breakpoints that are hit at
+ default line. This will include a breakpoint whose line number
+ does not correspond to the default line, but has been set at
+ the default address.
+
+ (delete_breakpoint): Don't call bpstat_clear_actions, instead
+ clear things explicitly; if clearing breakpoint_at, then also
+ clear any associated actions so that bpstat_do_actions won't try
+ to execute them.
+ (_initialize_breakpoint): Fix function name for bx command.
+
+ (tbreak_command): Remove static from declaration.
+ (maintenance_info_breakpoints): Ditto.
+
+ (reattach_breakpoints): New funct definition, used with with
+ hardware watchpoints
+ (breakpoint_1): Change format and add entries to bptypes[]
+ (maintenance_info_breakpoints): Function is no longer static
+
+ (_initialize_breakpoint): Removed a comment.
+ (exception_catchpoints_are_fragile,
+ exception_support_initialized): Define.
+ (breakpoint_here_p): Fixed syntax error in conditional
+ (disable_watchpoints_before_interactive_call_start): Fixed call to
+ check_duplicates. Need a section parameter.
+ (enable_watchpoints_after_interactive_call_stop): Fixed call to
+ check_duplicates. Need a section parameter.
+ (breakpoint_re_set_one): Fixed call to check_duplicates. Need a
+ section parameter.
+ (delete_command): Fixed syntax error in conditional
+ (breakpoint_re_set): Fixed some typos.
+
+ (args_for_catchpoint_enable): New type for handling exceptions.
+ (current_exception_event): New variable for handling exceptions.
+ (insert_breakpoints): Check for additional breakpoint types --
+ bp_catch_throw, bp_catch_catch, call_disabled. Also, do some
+ additional work to handle an exception catchpoint.
+ (remove_breakpoint): There are additional breakpoint types to
+ check for: Bp_catch_throw, bp_catch_catch, call_disabled. Also do
+ some additional work to remove the exception catchpoints
+ (breakpoint_init_inferior): New input parameter. If there are
+ exception catchpoints delete them.
+ (breakpoint_here_p): There are additional breakpoint enable
+ settings to check for: Shlib_disabled, call_disabled
+ (breakpoint_thread_match): There are additional breakpoint enable
+ settings to check for: Call_disabled
+ (ep_is_catchpoint): There are additional breakpoint types to check
+ for: Bp_catch_throw, bp_catch_catch
+ (ep_is_exception_catchpoint): New function
+ (bpstat_find_step_resume_breakpoint): New function
+ (bpstat_do_actions): Introduce a local copy of the bpstat
+ structure.
+ (print_it_normal): There are additional breakpoint types to check
+ for: Bp_catch_throw, bp_catch_catch Changeing the control
+ structure a bit (adding else ifs) Add code to print out info about
+ exceptions.
+ (bpstat_stop_status): There are additional breakpoint enable
+ settings to check for: Call_disabled. there are additional
+ breakpoint types to chack for: Bp_catch_catch and bp_catch_throw.
+ Check to see if stopped due to an exception. Minor fixes to the
+ catch_errors calls. Make sure to count all encountered
+ breakpoints. There was something funky going on previously with
+ the counting.
+ (bpstat_what): Add cases for new breakpoint types:
+ bp_catch_catch, bp_catch_throw.
+ (bpstat_get_triggered_catchpoints): Check for new breakpoint types
+ : Bp_catch_catch, bp _catch_throw.
+ (breakpoint_1): Account for new breakpoint types.
+ (describe_other_breakpoints): Account for new breakpoint enable
+ setting (call_disabled)
+ (check_duplicates): Account for new breakpoint enable setting
+ (call_disabled)
+ (disable_breakpoints_in_shlibs): New function
+ (disable_watchpoints_before_interactive_call_start): New function
+ (mention): Account for new breakpoint types.
+ (break_command_1): Some additional checking for a valid PC.
+ (watch_command_1): Some dditional checking to prevent a watch
+ before a run command.
+ (ep_parse_optional_filename): Simplified for loop.
+ (create_exception_catchpoint): New function
+ (cover_target_enable_exception_callback): New function
+ (handle_gnu_4_16_catch_command): This used to be thcatch_command_1
+ function.e
+ (create_temp_exception_breakpoint): New function
+ (catch_command_1): Differs from gdb 4.16 and gdb 4.17. Is now
+ calling catch_exception_command_1 using the EX_EVENT_CATCH and
+ EX_EVENT_THROW values as parameters.
+ (clear_command): Additional comments
+ (delete_breakpoint): Handle exceptions. Check for additional
+ breakpoint enable settings: Shlib_disabled, call_disabled.
+ (delete_command): Hp folks are claiming that we should not delete
+ shlib_event breakpoints
+ (breakpoint_re_set_one): Moved call to check_duplicates. Add new
+ breakpoint types to switch statement.
+ (breakpoint_re_set_thread): New function
+ (enable_command): Account for new breakpoint types.
+
+ (insertion_state_t): New enumerated type.
+ (remove_breakpoint): New param in funct prototype.
+ (insert_breakpoints): Check for bp_catch_fork and bp_catch_vfork.
+ (remove_breakpoints): Changed call to remove_breakpoint.
+ (detach_breakpoints): New function.
+ (remove_breakpoint): New parameter, is. Also changed the
+ way b->inserted is set.
+ (ep_is_catchpoint): New function.
+ (ep_is_shlib_catchpoint): New function.
+ (print_it_normal): Check for bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec. Also new code
+ to print out catchpoints properly.
+ (bpstat_stop_status): Check for bp_catch_fork, bp_catch_vfork,
+ and bp_catch_exec. Also, some code to check for catching a
+ shared library load/unload.
+ (bpstat_what): Added catch_shlib_event to class enumeration.
+ Defined new macro, shlr. Expanded the bpstat_what_main_action
+ table. Add cases for bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, and bp_catch_exec.
+ (bpstat_get_triggered_catchpoints): New function.
+ (breakpoint_1): Changes to bptypes definition. Also check for
+ bp_catch_load, bp_catch_unload, bp_catch_fork, bp_catch_vfork,
+ bp_catch_exec. Similar changes to the switch statement.
+ (set_raw_breakpoint): Initialize new breakpoint structure fields.
+ dll_pathname, triggered_dll_pathname, forked_inferior_pid,
+ exec_pathname.
+ (create_solib_load_unload_event_breakpoint): New function.
+ (create_solib_load_event_breakpoint): New function.
+ (create_solib_unload_event_breakpoint): New function.
+ (create_fork_vfork_event_catchpoint): New function.
+ (create_fork_event_catchpoint): New function.
+ (create_vfork_event_catchpoint): New function.
+ (mention): New cases for bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (ep_skip_leading_whitespace): New function.
+ (ep_find_event_name_end): New function.
+ (ep_parse_optional_if_clause): New function.
+ (ep_parse_optional_filename): New function.
+ (catch_fork_kind): New enumerated type.
+ (catch_fork_command_1): New function.
+ (catch_exec_command_1): New function.
+ (catch_load_command_1): New function.
+ (catch_unload_command_1): New function.
+ (catch_throw_command_1): New function.
+ (catch_command_1): Now calls catch_throw_command_1.
+ (tcatch_command): New function.
+ (delete_breakpoint): Changed call to remove_breakpoint.
+ Also free the new fields in the breakpoint structure.
+ (breakpoint_re_set_one): Handle bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (disable_command): Handle bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (enable_command): Handle bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (_initialize_breakpoint): Alter add_com call for catchpoints,
+ add add_com call for watchpoints.
+
+ * breakpoint.h (enum bptype): New entries bp_catch_catch,
+ bp_catch_throw, and bp_none, bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork,bp_catch_exec. Add declarations for
+ new functions bpstat_have_active_hw_watchpoints and
+ create_exec_event_catchpoint.
+ (tbreak_command): Add prototype.
+ (update_breakpoints_after_exec): Add prototype; update comments.
+ (reattach_breakpoints): New funct prototype declaration.
+ (enable): New enumerated value call_disabled.
+ (bpstat_find_step_resume_breakpoint): New funct decl.
+ (inf_context): New enumerated type.
+ (breakpoint_re_set_thread): New funct decl.
+ (breakpoint_init_inferior): New parameter.
+ (disable_watchpoints_before_interactive_call_start): New funct decl.
+ (enable_watchpoints_after_interactive_call_stop): New funct decl.
+ (disable_breakpoints_in_shlibs): New funct decl.
+ (struct breakpoint): New fields, dll_pathname,triggered_dll_pathname,
+ forked_inferior_pid,exec_pathname BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK.
+ (bpstat_get_triggered_catchpoints): New function.
+ (detach_breakpoints): New function.
+ (create_solib_load_event_breakpoint): New function.
+ (create_solib_unload_event_breakpoint) New function.
+ (create_fork_event_catchpoint): New function.
+ (create_vfork_event_catchpoint): New function.
+ (ep_is_catchpoint): New function.
+ (ep_is_shlib_catchpoint) New function.
+ (enum bpstat_what_main_action): New entry.
+
+ * buildsym.c (finish_block): Get rid of processing_hp_compilation;
+ handle LOC_INDIRECT case. Set the BLOCK_GCC_COMPILED to the right
+ compiler.
+ (push_context): Add symbols for parameters to the context_stack.
+ (merge_symbol_lists): New function. Merges two symbol lists.
+ (struct context_stack): Add new field param.
+
+ (processing_hp_compilation): New external var.
+
+ * c-exp.y: Use external flag hp_som_som_object_present to decide
+ whether code was compiled by HP's compilers. Add two new C++
+ tokens for true and false.
+ (yylex): Check for template name is done differently for the
+ HP/aCC compiler case; change some of the template processing code
+ for handling HP aCC templates.
+
+ * c-lang.c (c_create_fundamental_type): Added case to handle
+ template args. Handle FT_BOOLEAN type. Set no sign flag for
+ FT_CHAR.
+ (cplus_builtin_types): New structure for c++ builtin types.
+ (cplus_language_defn): Use cplus_builtin_types instead of
+ c_builtin_types.
+
+ * c-typeprint.c (c_type_print_base): Don't print 'privete' label
+ for a class if all members are private, similarly don't print
+ 'public' for a struct. Add support for sized enums (HP/aCC). get
+ rid of the 'static' keyword printed by the demangler for member
+ function, when printing the type of a class. 'static' will be
+ added by this function. If the demangled name is null, and the
+ method is not stubbed, get the signature by looking at the
+ information stored in the symbol structure. Remove printing of
+ 'const' and 'volatile' keywords for methods. This is now taken
+ care as part of the demangled member names.
+ (cp_type_print_method_args): New function. To print a C++ method
+ arguments and name to the output stream.
+
+ (c_type_print_cv_qualifier): New function. Print out "const" and
+ "volatile" attributes.
+ (c_type_print_varspec_prefix): Print const or volatile qualifiers.
+ (c_type_print_args): Print 'void' for c++.
+ (c_type_print_varspec_suffix): Print 'void' for a no argument
+ function.
+ (c_type_print_base): Print const or volatile qualifiers. Do not
+ print 'unnamed union' if HP aCC compiler used. Distinguish
+ between struct and class based on the DECLARED_TYPE. Handle
+ HP/aCC compiler case for not printing vtable. Add Template
+ support.
+
+ (cp_type_print_derivation_info): Print out 'protected' when
+ appropriate. This applies only to HP's compilers, not gcc.
+
+ (c_val_print): Added parameter embedded_offset. Add
+ embedded_offset to valaddr in function calls; fix calls to
+ val_print and cp_print_value_fields. process TYPE_CODE_METHOD as
+ well. moved call to check_typedef out of conditional. added
+ embedded offset param to val_print call.
+
+ (c_value_print): Add new parameter to call to val_print.
+ handle pointer to class case. Attempt to
+ determine the real type of the object to be printed.
+ ensure that const char *, const unsigned char *
+ come out without the type but the volatile variants
+ and the signed variants don't.
+
+ * coff-solib.c (coff_solib_add): Add parameters to call
+ to symbol_file_add.
+
+ * coff-solib.h: (Solib_REMOVE_INFERIOR_HOOK): New macro. defined
+ to 0. functionality not implemented for coff.
+ (SOLIB_CREATE_CATCH_LOAD_HOOK): New macro, generate error message
+ for coff.
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK): Ditto.
+ (SOLIB_HAVE_LOAD_EVENT): Ditto.
+ (SOLIB_LOADED_LIBRARY_PATHNAME): Ditto.
+ (SOLIB_HAVE_UNLOAD_EVENT): Ditto.
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME): Ditto.
+ (SOLIB_IN_DYNAMIC_LINKER): Ditto.
+ (SOLIB_RESTART): Ditto.
+
+ * command.c (find_cmd): New function. (lookup_cmd_1): Call it,
+ change parsing if tui_version or xdb_commands is set.
+ (_initialize_command): Install new alias if xdb_commands is set.
+
+ * complaints.h: Add ifdef...endif pair at beginning and end of file.
+
+ * config.in, configure: Regenerated.
+
+ * config/pa/hppabsd.mh (NATDEPFILES): Added new files
+ hp-psymtab-read.o and hp-symtab-read.o.
+ * config/pa/hppahpux.mh (NATDEPFILES): Ditto.
+
+ * config/pa/hppahpux.mh (TERMCAP): Use -lHcurses.
+ * config/pa/hppaosf.mh (NATDEPFILES): Ditto.
+
+ * config/pa/hpux1020.mh (TERMCAP): Use -lHcurses.
+ (MH_CFLAGS): New flag, -D__HP_CURSES, this define
+ is used by HP's linker to find the correct curses library.
+
+ * config/pa/hpux1020.mh: New file.
+
+ * config/pa/hpux1020.mt: New file.
+
+ * config/pa/hpux1100.mh (TERMCAP): Link against -lcurses, not
+ -lHcurses. The latter does not contain mvwaddstr, wscrl, or
+ wstbwlmkfzz.
+
+ * config/pa/hpux1100.mh (TERMCAP): Use -lHcurses.
+ (MH_CFLAGS): New flag, -D__HP_CURSES, this define
+ is used by HP's linker to find the correct curses library.
+
+ * config/pa/hpux1100.mh (TERMCAP): When hosting on hpux 11.00, use
+ -lHcurses rather than -lcurses.
+
+ * config/pa/hpux1100.mh: New file.
+
+ * config/pa/hpux1100.mt: New file.
+
+ * config/pa/nm-hppah.h (CHILD_HAS_SYSCALL_EVENT): New macro
+ (CHILD_THREAD_ALIVE): New macro
+ (STOPPED_BY_WATCHPOINT): Add a condition to the macro,
+ ! stepped_after_stopped_by_watchpoint
+ (TARGET_ENABLE_HW_WATCHPOINTS): New macro
+ (hppa_enable_hw_watchpoints): New funct decl
+ (TARGET_DISABLE_HW_WATCHPOINTS): New macro
+ ( hppa_disable_hw_watchpoints): New funct decl
+ these are for HP's implementation of fast
+ watchpoints (via page protection).
+ (target_pid_to_str): New macro, calls hppa_pid_to_str
+ (target_tid_to_str): New macro, calls hppa_tid_to_str
+
+ * config/pa/nm-hppah.h (CHILD_POST_WAIT): Delete;
+ (CHILD_CREATE_CATCH_FORK_HOOK): Replace with
+ CHILD_INSERT_FORK_CATCHPOINT and CHILD_REMOVE_FORK_CATCHPOINT.
+ (CHILD_CREATE_CATCH_VFORK_HOOK): Replace with
+ CHILD_INSERT_VFORK_CATCHPOINT and CHILD_REMOVE_VFORK_CATCHPOINT.
+ (CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC,
+ CHILD_INSERT_EXEC_CATCHPOINT, CHILD_REMOVE_EXEC_CATCHPOINT,
+ CHILD_HAS_EXECD, CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL,
+ CHILD_POST_ATTACH, TARGET_HAS_HARDWARE_WATCHPOINTS,
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT,
+ TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT,
+ TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT, STOPPED_BY_WATCHPOINT,
+ HAVE_NONSTEPPABLE_WATCHPOINT, target_insert_watchpoint,
+ target_remote_watchpoint): New macros.
+
+ * config/pa/nm-hppah.h (CHILD_XFER_MEMORY): Reinsert accidentally
+ deleted define.
+
+ * config/pa/nm-hppah.h:
+ (PREPARE_TO_PROCEED): Defined macro to use
+ hppa_prepare_to_proceed.
+ (hppa_pid_to_str): Extern decl.
+ (hppa_tid_to_str): Extern decl.
+ (target_pid_or_tid_to_str): New macro definition.
+ (hppa_pid_or_tid_to_str): Extern decl.
+ (ENSURE_VFORKING_PARENT_REMAINS_STOPPED): New macro - for
+ handling events caused by a call to vfork.
+ (hppa_ensure_vforking_parent_remains_stopped): Extern decl.
+ (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK): New macro -
+ for handling events caused by a call to vfork.
+ (hppa_resume_execd_vforking_child_to_get_parent_vfork): Extern decl.
+
+ * config/pa/nm-hppah.h: Fix PREPARE_TO_PROCEED macro.
+
+ * config/pa/nm-hppah.h: Fix for gcc compile on HPUX, change
+ PT_RDUAREA to PT_RUAREA.
+
+ * config/pa/nm-hppah.h: Introduced an HPUXHPPA define.
+ A bit of a hack so that I can ifdef some code that
+ only works for the HP wildebeest debugger.
+
+ * config/pa/nm-hppah.h: Lots of new CHILD_ defines;
+ process_event_kind enum.
+
+ * config/pa/tm-hppa.h (BREAKPOINT32): New define.
+ (CALL_DUMMY_HAS_COMPLETED): New define.
+
+ * config/pa/tm-hppa.h (STACK_ALIGN): New macro.
+ (NO_EXTRA_ALIGNMENT_NEEDED): New macro.
+ (PC_REQUIRES_RUN_BEFORE_USE): New macro.
+ (REGISTER_NAMES): Formatting in file changed.
+ (CR27_REGNUM): Base register for thread local storage.
+ (USE_STRUCT_CONVENTION): New macro used to decide whether
+ a function returning a value of type type will
+ put it on the stack or into registers (based on the
+ PA risc calling conventions).
+ (EXTRACT_RETURN_VALUE): Fixed calculation for extracting return value.
+ (VALUE_RETURNED_FROM_STACK): New macro.
+ (TARGET_READ_PC): Declared the function used in the definition.
+ (SKIP_TRAMPOLINE_CODE): Declared the function used in the definition.
+ (TARGET_WRITE_PC): Declared the function used in the definition.
+ (TARGET_READ_FP): Declared the function used in the definition.
+
+ * config/pa/tm-hppa.h (STRCAT_REGISTER): Define macro for
+ future use.
+ (pa_do_strcat_registers_info): Moved function decl from
+ defs.h to this HPUX specific .h file.
+
+ * config/pa/tm-hppa.h (USE_STRUCT_CONVENTION): Type_LENGTH returns
+ bytes, not bits; fix off by 8 error.
+
+ * config/pa/tm-hppa.h:
+ New comment for obj_unwind_info definition
+ New typedef, obj_private_struct
+
+ * config/pa/tm-hppa.h: Delete most target_ macros -- use default
+ versions instead; remove extraneous comma from proc_wait macro.
+
+ * config/pa/tm-hppa.h: Get rid of macro HP_COMPILED_TARGET.
+
+ * config/pa/tm-hppa.h: Removed redefinitions of
+ USE_STRUCT_CONVENTION and STACK_ALIGN macros.
+
+ * config/pa/tm-hppa.h: Some new definitions
+ New macros: Arg0_REGNUM, ARG1_REGNUM, ARG2_REGNUM, ARG3_REGNUM.
+ target_pid_to_exec_file, target_acknowledge_forked_child,
+ target_create_catch_fork_hook, target_create_catch_vfork_hook,
+ target_has_forked, target_has_vforked, require_attach,
+ require_detach, proc_wait
+ New funct decls: Hppa_pid_to_exec_file,
+ hppa_acknowledge_forked_child, hppa_create_catch_fork_hook,
+ hppa_create_catch_vfork_hook, hppa_target_has_forked,
+ hppa_target_has_vforked, hppa_require_attach,
+ hppa_require_detach, process_wait
+ (unwind_table_entry): Added comments to describe struct fields.
+
+ * config/pa/tm-hppah.h (somsolib.h): Include it.
+
+ * config/pa/tm-hppah.h:
+ (CHILD_ENABLE_EXCEPTION_CALLBACK): New define
+ (CHILD_GET_CURRENT_EXCEPTION_EVENT): New define
+
+ * configure.host (hppa-*-hpux10.20, hppa-*-hpux11.0*): New configs.
+
+ * configure.in (AC_CHECK_HEADERS): Add check for term.h.
+
+ * configure.in: Add an --enable-tui argument.
+
+ * configure.in: Construct tui/Makefile from tui/Makefile.in.
+
+ * configure.in: Use AM_PROG_CC_STDC. If we have the GUI, then we
+ need this to process libgui.h.
+
+ * convex-tdep.c (decout): Change FILE to GDB_FILE.
+
+ * corefile.c: Include objfiles.h, symfile.h.
+ (core_file_command): Attempt to determine the name of the symbol
+ file from the core file.
+ (read_memory_string): New function.
+
+ * corefile.c (core_file_command): Temporary hack to make non-hpux
+ work. For, non-hpux, t->to_core_file_to_sym_file does not have a
+ reasonable value. No target_ops vector on the stack gives it a
+ non-zero value. fix later.
+
+ * corelow.c (core_file_to_sym_file): Added new local variable,
+ failing command, and do some explicit type castings.
+ (core_ops): Add three new fields: to_has_syscall_event,
+ to_enable_exception_callback, to_get_current_exception_event.
+ Necessary since we still have oldstyle initialization in
+ this file
+
+ * corelow.c: Include unistd.h
+ (core_file_to_sym_file): New function
+ (core_file_thread_alive): New function
+ (core_ops): Added new target ops vector fields. see below. And
+ yes we definitiely need to initialize them here, as long as
+ we're using static initialization.
+
+ * cxux-nat.c (add_shared_symbol_files): Additonal params for calls
+ to symbol_file_add.
+
+ * defs.h (gdb_file_isatty): New function decl.
+
+ * defs.h (GDB_FILE): If TUI is defined, define a structure rather
+ than making this an alias for FILE.
+ (gdb_stdout, gdb_stderr): If TUI is defined, then define these
+ as pointers to variables of type GDB_FILE rather than making them
+ be aliases for stdout and stderr.
+
+ * defs.h (TUIDO): Add definition conditionalized on definition
+ (or lack thereof) of TUI.
+
+ * defs.h (command_class): Add two additional values.
+ (precision_type): New enum.
+
+ * defs.h (gdb_fclose): Add declaration.
+
+ * defs.h (store_address): Change prototype to match function.
+
+ * defs.h (tui_version, xdb_commands, dbx_commands): Add decl's.
+
+ * defs.h (gdb_file_deallocate): New function declaration
+
+ * defs.h:
+ (streamtype): New enumerated type to distinguish between
+ output to a FILE and output to a buffer.
+ (tui_stream): New struct type, named GDB_FILE. Contains,
+ streamtype, FILE, buffer, and bufferlength fields.
+ (gdb_stdout): Of type GDB_FILE, will pass this around gdb
+ rather than stdout.
+ (gdb_stderr): Of type GDB_FILE, will pass this around gdb
+ rather than stderr.
+ (fputs_unfiltered_hook): Change stream parameter from FILE to
+ GDB_FILE
+ (flush_hook): Change stream parameter from FILE to GDB_FILE
+ (gdb_fclose): Fix declaration for gdb_fclose; parameter is now of
+ type GDB_FILE **
+ (gdb_file_adjust_strbuf): New function declaration. function lives in
+ utils.c.
+ (gdb_file_init_astring): New function declaration. function lives
+ in utils.c
+ (gdb_file_get_strbuf): New function declaration. function lives
+ in utils.c
+
+ * defs.h: Additional include files included when TUI is defined.
+
+ * defs.h: Funct decl source_full_path_of.
+
+ * demangle.c: Add HP_DEMANGLING_STYLE_STRING.
+
+ * demangle.c: Added new demangling style, EDG_DEMANGLING_STYLE_STRING,
+ to the demanglers structure. This is for support of
+ Kuck & Assoc.'s changes for demangling.
+
+ * eval.c (evaluate_subexp_standard): C++ member function changes.
+
+ * eval.c (evaluate_subexp_standard): Verify TYPE_TARGET_TYPE is
+ non NULL before dereferencing it.
+
+ * eval.c (evaluate_subexp_standard): With HP/aCC compiler it is not possible
+ to perform inferior calls via function pointers.
+ Resolve calls to overloaded functions using find_overload_match.
+ We cannot handle HP/aCC pointers to member functions.
+ Deal with HP/aCC pointers to members in various kind of expressions.
+
+ * f-lang.c (f_printchar): Change FILE to GDB_FILE.
+ (f_printstr): Ditto.
+ (emit_char): Ditto.
+
+ * f-lang.c (f_printstr): Change stdout to gdb_stdout.
+
+ * f-typeprint.c (f_print_type): Change FILE to GDB_FILE.
+ (f_type_print_varspec_prefix): Ditto.
+ (f_type_print_args): Ditto.
+ (f_type_print_varspec_suffix): Ditto.
+ (print_equivalent_f77_float_type): Ditto.
+ (f_type_print_base): Ditto.
+
+ * findvar.c (): Hp snapshot 3 changes. (extract_address): Coerce
+ return value from extract_unsigned_integer to CORE_ADDR.
+ (store_address): Change val from CORE_ADDR to LONGEST; changes to
+ support machines where CORE_ADDR and LONGEST are different sizes.
+ (get_saved_register): Coerce arg to store_address to LONGEST.
+ (read_relative_register_raw_bytes): Cast last arg to
+ store_address to LONGEST. (read_register): Cast return from
+ extract_address to a CORE_ADDR. (write_register_pid): Change val
+ from LONGEST to CORE_ADDR. (read_pc_pid): Save and restore
+ inferior_pid if necessary. (write_pc_pid): Ditto.
+ (read_var_value): Cast arg to store_address.
+
+ * findvar.c (read_relative_register_raw_bytes_for_frame): New
+ function.
+ (read_relative_register_raw_bytes): Call it.
+
+ * findvar.c (symbol_read_needs_frame): Handle LOC_THREAD_LOCAL_STATIC and
+ LOC_INDIRECT.
+
+ * fork-child.c (fork_inferior): Chenge fifth parameter to be a
+ function returning void.
+
+ * fork-child.c (fork_inferior): Delete unused variable f.
+
+ * fork-child.c:
+ (Startup_WITH_SHELL): New macro -- interim fix for a bug
+ (breakup_args): New function -- breaks up an argument string into
+ an argument suitable for passing into execvp().
+ (fork_inferior): Handling problems with starting up gdb with a shell.
+ -- again, this appears to be an interim fix.
+
+ * fork-child.c:
+ (fork_inferior): Added a comment
+ (clone_and_follow_inferior): New function.
+ (startup_inferior): Minor formatting changes.
+
+ * fork-child.c:
+ (fork_inferior): Hp change is problematic. The -f option has
+ different meanings for different shells. It is particularly
+ inappropriate for bourne shells.
+
+ * fork-child.c:
+ (fork_inferior): Added new parameter, pre_trace_fun.
+ pre_trace_fun is a function pointer. For some targets,
+ like HPUX, this function gets called to prepare for forking
+ a child.
+
+ * fork-child.c:
+ (fork_inferior): Fixed call to init_trace_fun
+
+ * fork-child.c:
+ Moved definition of STARTUP_WITH_SHELL to inferior.h
+ Added a DEBUGGING macro. Currently set to 0. May remove
+ later.
+ breakup_args: Add DEBUGGING ifdefs. more sophisticated
+ parsing to break up args.
+ (fork_inferior): Rename kshell variable to shell. new local
+ variable, tryname. Make use of STARTUP_WITH_SHELL macro.
+ More error processing if starting up with a shell.
+ (startup_inferior): Distinguish between starting up with a shell
+ and not doing so.
+
+ * gdbthread.h:
+ Declarations for load_infrun_state and save_infrun_state take
+ an additional parameter.
+
+ * gdbthread.h: Note that sometime between gdb 4.16 and 4.17,
+ thread.h was renamed gdbthread.h
+ (load_infrun_state): Additional parameters
+ (store_infrun_state): Additional parameters
+
+ * gdbthread.h: Include breakpoint.h
+
+ * hp-psymtab-read.c (QUICK_LOOK_UP): Redefine to be 0.
+ (hpread_build_psymtabs): Deal with enums.
+ (hpread_start_psymtab): Include section offset.
+ (hpread_end_psymtab): Take care of offset.
+
+ * hp-psymtab-read.c (TRUE): Define.
+ (FALSE): Define.
+ (file_exists): New function. Checks for existance of file.
+ (hpread_pxdb_needed): Rewrite.
+ (hpread_quick_traverse): Use correct demangling style.
+ Handle F77 case.
+ (hpread_get_header): Rewrite.
+ (hpread_get_textlow): Add support for DOC_FUNCTION.
+ (hpread_build_psymtabs): Make sure we do the right thing
+ for pxdb and F77.
+
+ * hp-psymtab-read.c (hpread_pxdb_check): Change parenthesis positions.
+
+ * hp-psymtab-read.c (hpread_quick_traverse): Compare CORE_ADDR
+ variable end_addr to 0 instaed of NULL to get rif of gcc warning.
+
+ * hp-psymtab-read.c:
+ (Hpread_get_textlow): Added param to function
+ Defined convennience macros and some datatypes and variables for
+ processing the quick lookup-tables. Looks like the code existed
+ before, but has been munged.
+ (hpread_pxdb_needed): Major rearrangements of code. Additional local
+ variables. Also, more extensive checking for various scenarios:
+ debug info for optimized code vs. unoptimized code, pxdb has been
+ run vs. pxdb has not been run.
+ (VALID_FILE): New macro
+ (VALID_MODULE): New macro
+ (VALID_PROC): New macro
+ (VALID_CLASS): New macro
+ (FILE_START): New macro
+ (MODULE_START): New macro
+ (PROC_START): New macro
+ (FILE_END): New macro
+ (MODULE_END): New macro
+ (PROC_END): New macro
+ (FILE_ISYM): New macro
+ (MODULE_ISYM): New macro
+ (PROC_ISYM): New macro
+ (VALID_CURR_FILE): New macro
+ (VALID_CURR_MODULE): New macro
+ (VALID_CURR_PROC): New macro
+ (VALID_CURR_CLASS): New macro
+ (CURR_FILE_START): New macro
+ (CURR_MODULE_START): New macro
+ (CURR_PROC_END): New macro
+ (CURR_FILE_ISYM): New macro
+ (CURR_MODULE_ISYM): New macro
+ (CURR_PROC_ISYM): New macro
+ (TELL_OBJFILE): New macro
+ (pst_syms_struct): New typedef to keep track of the start/end symbol
+ table (LNTT) indices of psymtabs created so far.
+ (pst_syms_count): New variable
+ (pst_syms_size): New variable
+ (told_objfile): New variable
+ (init_pst_syms): New function. sets up psymtab symbol index stuff.
+ (clear_pst_syms): New function. clean up psymtab symbol index stuff.
+ (record_pst_syms): New function. add info about newest psymtab to symbol
+ index table.
+ (find_next_pst_start): New function. Find a suitable symbol table index.
+ (find_next_file_isym): New function
+ (find_next_proc_isym): New function
+ (find_next_module_isym): New function
+ (scan_procs): New function. Scan and record partial symbols for all
+ functions starting from specified index and in a specified code range.
+ (hpread_quick_traverse: Major rearrangement of code. The function
+ now uses all the nifty macros. There are some new local variables.
+ Check for EDG_DEMANGLING style. ifdef out some code for handling F77.
+ Previously, the function looped over all the modules in the table.
+ Now, the function loops over all the files, modules, and procedures.
+ With HP aCC and CTTI, it is possible for a compiled object to have a
+ file and no module.
+ (hpread_build_psymtabs): Added a section of code ifdefed by
+ QUICK_LOOK_UP. It check to see whether or not there are any globals
+ in the executable. Fix number of params to hpread_start_psymtab call.
+ Some changes to the way DNTT_TYPE_MODULE is handled.
+ (hpread_get_textlow): Change in signature, minor code changes. The
+ function finds the low address associated with a specified symbol.
+ In looking for the address for the symbol avoid going of the end of
+ the LNTT file.
+
+ * hp-psymtab-read.c: Change TRUE to 1 and FALSE to 0. Do some
+ reformatting.
+
+ * hp-psymtab-read.c: Include demangle.h
+ (trans_lang): New function to let gdb know the correct language.
+ (hpread_quick_traverse): Use ARM style demangling.
+ Demangle procedures names.
+ Use gdb language names instead of hp language names.
+ Add symbol to list using its demangled name.
+
+ * hp-psymtab-read.c: New file.
+ (hpread_call_pxdb): New function. Call PXDB to process our file.
+ (hpread_pxdb_check): New function. Return TRUE if the file needs
+ pre-processing by PXDB and we have thus called PXDB to do this
+ processing and the file needs to be re-loaded.
+ (hpread_quick_traverse): New function. Traverse the quick look-up
+ tables, building a set of psymtabs.
+ (hpread_get_header): New function. Get appropriate header from obj
+ file, based on pxdb type
+ (hpread_symfile_init): No change from hpread.c
+ (hpread_build_psymtabs): If there are quick lookup tables, read those,
+ then scan the global section LNTT. Otherwise, just scan the whole LNTT.
+ Changed: Add a global function entry to the global partial symbol list.
+ Handle end of symbols, for QLT case.
+ In case of TAGDEF, if it is a class or a template, add the name to the
+ var_namespace, so that it is known as a type by gdb.
+ In case of CONSTANT, and it is global, add it to the globals.
+ (hpread_symfile_finish): No change from hpread.c
+ (hpread_get_lntt): Make it not static
+ (hpread_get_gntt): No change from hpread.c
+ (hpread_get_slt): Make it not static
+ (hpread_get_textlow): No change from hpread.c
+ (hpread_start_psymtab): No change from hpread.c
+ (hpread_end_psymtab): No change from hpread.c
+
+ * hp-symtab-read.c (hpread_get_scope_start): Renamed. It was
+ hpread_get_depth.
+ (hpread_type_translate): Distinguish between signed and unsigned char
+ types.
+ (hpread_psymtab_to_symtab): Set flag for hp compilation.
+ (hpread_read_function_type): Append symbols for parameters to local
+ list as well as to the global list. Get the parameters types from the
+ local list instead of the global list.
+ (hpread_read_struct_type): Add new field num_fn_fields to next_fn_field
+ structure. Rewrite handling of templates
+ (hpread_type_lookup): Change handling of dntt_type_modifier.
+ (hpread_process_one_debug_symbol): Call hpread_get_scope_start instea
+ of hpread_get_depth. Handle enum as well.
+ (hpread_get_scope_depth): New function. Get nesting depth for a
+ DNTT entry.
+
+ * hp-symtab-read.c (hpread_psymtab_to_symtab): Set
+ processing_gcc_compilation to 0.
+
+ * hp-symtab-read.c (hpread_psymtab_to_symtab_1): Change stdout to
+ gdb_stdout; change fflush to gdb_flush.
+ (hpread_psymtab_to_symtab): Change fflush to gdb_flush.
+
+ * hp-symtab-read.c (hpread_read_enum_type): Declare variable.
+ (hpread_read_struct_type): Eliminate references
+ to 'args' member of fn_field.
+
+ * hp-symtab-read.c (hpread_read_struct_type): A static member
+ is now indicated by the bitsize field, not the bitpos.
+ Initialize physname to empty.
+ (fix_static_member_physnames): Use new macros to deal with
+ physnames.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Change references
+ to bitpos member of struct field to use the FIELD_BITPOS macro.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Comment out reference to
+ obsolete field fn_field.args.
+ Add struct complaint definitions for complaints.
+ (hpread_read_struct_type): Change call to complain.
+ (hpread_read_array_type): Change call to complain.
+ (hpread_type_lookup): Change call to complain.
+ (hpread_process_one_debug_symbol): Change calls to complain.
+ (hpread_type_translate): Change calls to complain.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Make sure bitvector
+ has been allocated before calling has_vtable.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Revert change,
+ just check for vtable without checking for bitvectors too.
+
+ * hp-symtab-read.c:
+ (Hpread_expand_symtab): Change name of local variable from
+ at_end_of_module to at_module_boundary.
+ Also, if demangling style is already EDG, do not reset it
+ to the HP demangling style.
+ Change at_end_of_module param to hpread_process_one_debug_symbol
+ call to at_module_boundary.
+ No longer break out of loop when reach end of module. With CTTI,
+ the compiler can generate function symbols which are not in
+ any module. Typically they show up after the end of one
+ module and before the start of the next module.
+ (hpread_read_struct_type): Check that the debug info for
+ a TEMPLATE_ARG is correct.
+ (hpread_process_one_debug_symbol): Change name of at_end_of_module_p
+ param to at_module_boundary_p.
+ Also set *at_module_boundary_p = -1 if missing a module end and set
+ it to 1 when finished expanding the debug info.
+ Handle TLS variable.
+
+ * hp-symtab-read.c: Include defs.h, symtab.h, gdbtypes.h, complaints.h.
+ (fixup_class): New static variable.
+ (fixup_method): New static variable.
+ (hpread_get_location): Rewrite.
+ (hpread_has_name): Add cases for DNTT_TYPE_DOC_FUNCTION and
+ DNTT_TYPE_DOC_MEMFUNC
+ (hpread_expand_symtab): Use HP demangling style.
+ Set hp_som_som_object_present to 1.
+ (hpread_type_translate): Error out if not immediate. Issue warning
+ if there is an unhandled type code.
+ (error_in_hpread_type_translate_complaint): Remove this structure.
+ (hpread_read_enum_type): Don't assume size of enum is always 4 bytes.
+ (hpread_read_function_type): Add new parameter to indicate a new block.
+ Do not add the parameters to the symbol list.
+ If the type was read in earlier, do not modify the type structure.
+ If we are creating a new block, set the local symbol list to be the
+ param list.
+ Need to mark this type as preprocessed.
+ (hpread_read_doc_function_type): New function. Read and internalize
+ a native DOC function debug symbol.
+ (hpread_read_struct_type): A method can be of type doc_function and
+ doc_memfunc too.
+ Handle case in which a method is read before its class. Deal with
+ incomplete method types.
+ Handle cases in which HP/aCC compiler creates operator names w/o
+ the 'operator' keyword. Rewrite the loop over the fileds.
+ (fix_static_member_physnames): New function. Adjust the physnames for
+ each static member.
+ (fixup_class_method_type): New function. Fix-up the type structure for a
+ class.
+ (hpread_read_array_type): Change complaint to warning.
+ (hpread_type_lookup): Add case for DNTT_TYPE_DOC_FUNCTION.
+ For structures/classes set static member to point to strings with full
+ names.
+ Change calls to hpread_read_function_type to pass extra parameter.
+ (hpread_record_lines): Handle case for SLT_NORMAL_OFFSET.
+ (class_of): New function. Given a function "f" which is a member of a class,
+ find the classname that it is a member of.
+ (hpread_process_one_debug_symbol): Deal with possible alias field from the
+ som record for the Function or Entry type.
+ Do the demangling ourselves if the gdb demangler failed.
+ Add support for DOC functions.
+ For function types, add parameters to local list.
+ (hpread_get_scope_depth): Make this function a no-op.
+ (hpread_adjust_bitoffsets): New function. Adjust the bitoffsets for all
+ fields of an anonymous union.
+ (hpread_get_next_skip_over_anon_unions): New function. Skip over anonymous
+ unions.
+
+ * hp-symtab-read.c: Include demangle.h
+ (hpread_expand_symtab): Ensure we are using ARM-style demangling.
+ (hpread_process_one_debug_symbol): Set the mangled and demangled
+ names for functions.
+ Record the class name to generate the demangled names of member
+ functions.
+
+ * hp-symtab-read.c: New file.
+ (hpread_get_depth): No change from hpread.c
+ (hpread_get_line): No change from hpread.c
+ (hpread_get_location): No change from hpread.c
+ (hpread_has_name): Make it not static. Return 1 for DNTT_TYPE_BLOCKDATA
+ and DNTT_TYPE_MEMFUNC. Return 0 for CLASS_SCOPE, REFERENCE,PTRMEM,
+ PTRMEMFUNC, CLASS, GENFIELD, VFUNC, MEMACCESS, INHERITANCE,
+ FRIEND_CLASS, FRIEND_FUNC, MODIFIER, OBJECT_ID, TEMPLATE, TEMPLATE_ARG,
+ FUNC_TEMPLATE, LINK.
+ (hpread_psymtab_to_symtab_1): No changes from hpread.c
+ (hpread_psymtab_to_symtab): Make it a static function
+ (hpread_expand_symtab): Modified
+ (hpread_type_translate): If not typep.dntti.immediate do not abort,
+ but complain and return. Same for default action. Handle more HP_TYPEs.
+ (hpread_lookup_type): Initially allocate a correct-size type-vector.
+ (hpread_alloc_type): Reset type_addr only if a type was allocated.
+ (hpread_read_enum_type): If this has already a type associated, return.
+ (hpread_read_function_type): Do different things depending on whether
+ function is a MEMFUNC, a TEMPLATE, a FUNCTION som record.
+ Do not use the LOC_REGPARM_ADDR symbol class.
+ (hpread_read_struct_type): Handle classes and templates too. Major
+ rewrite.
+ (hpread_get_nth_template_arg): New function.
+ (hpread_read_templ_arg_type): New function.
+ (hpread_read_set_type): No change from hpread.c
+ (hpread_read_array_type): Modified
+ (hpread_read_subrange_type): Add handling of more DNTT entries.
+ added support for templates, classes, references, virtual functions.
+ (hpread_type_lookup): Handle DNNT_TYPE_MODULE.
+ (hpread_record_lines): No changes from hpread.c
+ (hpread_process_one_debug_symbol): Handle WITH, COMMON,
+ CLASS_SCOPE. Expand TAGDEF case to handle classes and templates.
+
+ * hppa-tdep.c (pa_do_strcat_registers_info): Has a new parameter,
+ precision, which is passed into the call to pa_strcat_fp_reg to
+ indicate whether to display the floating point registers using
+ single or double preceision.
+ (pa_strcat_registers): Introduce local variable, precision, and
+ pass it into call to pa_strcat_fp_reg.
+ (pa_strcat_fp_reg): Modified function. New parameter, precision,
+ used by function to decide whether to use single or double
+ precision. Also added the code to put a double precision value
+ into a buffer.
+
+ * hppa-tdep.c: Add'l includes <machine/save_state.h>,
+ <unistd.h>, declare pa_register_look_aside, define is_pa_2.
+ (rp_saved): Check for where to read the return pointer from.
+ (pa_do_registers_info): Handle is_pa_2. (pa_register_look_aside):
+ new function. (pa_print_registers): Handle is_pa_2.
+ (in_solib_call_trampoline): Handle a compiler/linker error.
+ (skip_trampoline_code): Changes to some masks used in examining
+ instructions. (inst_saves_fr): Test for FSTWS instruction.
+ (skip_prologue): Renamed to skip_prologue_hard_way.
+ (after_prologue): New function. (skip_prologue): New function.
+
+ * hppa-tdep.c (after_prologue): If f is NULL, don't dereference
+ it.
+
+ * hppa-tdep.c (after_prologue): If no debug info, return zero
+ telling caller that we need to find the end of the prologue via
+ the hard way (instruction examination).
+
+ * hppa-tdep.c (find_unwind_entry): Avoid dereferencing a null
+ pointer.
+
+ * hppa-tdep.c (hppa_pid_to_exec_file): Deleted -- no longer used.
+
+ * hppa-tdep.c (hppa_prepare_to_proceeed): Add prototype.
+ (read_unwind_info): Purecov comments, bug fixes.
+ (find_unwind_entry): Purecov comments, bug fixes.
+ (find_stub_with_shl_get): Purecov comments.
+ (frame_chain): Additional parens.
+ (hppa_push_arguments): Changes to commented out version of routine.
+ (hppa_fix_call_dummy): Purecov comments, fix location of end.o.
+ (in_solib_call_trampoline): Purecov comments.
+ (in_solib_return_trampoline): Purecov comments.
+ (setup_d_pid_in_inferior): Fix location of end.o.
+ (initialize_hp_cxx_exception_support): Fix location of end.o.
+ (child_enable_exception_callback): Purecov comments.
+
+ * hppa-tdep.c:
+ (Pa_do_strcat_registers_info): New routine. called by
+ tui/tuiRegs.c:_tuiRegisterFormat to place a register name
+ and value into a string buffer. Interface may change in
+ future. Checking this in so that we have something
+ functional for HP.
+ (pa_strcat_registers): New routine, called by
+ pa_do_strcat_registers_info. Does same thing as
+ pa_print_registers except it takes a stream parameter.
+ This routine should disappear in future. Checking in
+ so that we have something functional to give HP
+ (pa_strcat_fp_reg): New routine, called by
+ pa_do_strcat_registers_info and pa_strvat_registers
+ to place a floating point register name and value into
+ a buffer. This interface may change in future.
+ Checking in so that we have something functional to give HP.
+
+ * hppa-tdep.c: (Pa_print_fp_reg): Change prototype to match def'n.
+ (pa_register_look_aside): Fix comment immediately before function.
+
+ * hppa-tdep.c: Changes to better support stack unwinding,
+ reading and writing registers for HPUX. The HP folks had
+ an advantage ... access to a runtime architecture spec ;-}.
+ New includes: Ptrace.h
+ (internalize_unwinds): Initialize new fields in table.
+ (read_unwind_info): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type
+ are now ...->table[index].stub_unwind.stub_type.
+ (find_proc_framesize): Added a check for pc == 0.
+ (rp_saved): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type
+ are now ...->table[index].stub_unwind.stub_type.
+ (frameless_function_invocation): Stub_type becomes
+ stub_unwind.stub_type
+ (saved_pc_after_call): Stub_type becomes stub_unwind.stub_type
+ (hppa_frame_saved_pc): Stub_type becomes stub_unwind.stub_type
+ (frame_chain_valid): Stub_type becomes stub_unwind.stub_type
+ (hppa_call_dummy): Stub_type becomes stub_unwind.stub_type
+ (pa_print_fp_reg): Additional params to call val_print
+ (in_solib_call_trampoline): Stub_type becomes stub_unwind.stub_type
+ (in_solib_return_trampoline): Stub_type becomes stub_unwind.stub_typ
+ (skip_trampoline_code): Additional code to handle external
+ dyncalls. Also stub_type becomes stub_unwind.stub_type
+ (hppa_pid_to_exec_file): New funct. FOr HPUX 10.0 and beyond there
+ is an explicit ptrace request for getting the pathname associated
+ with a process id (pid).
+
+ * hppa-tdep.c: Fix for gcc compile on HPUX
+ (hppa_pid_to_exec_file): Remove unwanted param from
+ call to call_ptrace. Note, hppa_pid_to_exec_file goes
+ away in subsequent hp snapshots.
+
+ * hppa-tdep.c: Include bfd.h.
+ include dl.h
+ (args_for_find_stub): New structure.
+ (find_unwind_entry): Deal with null input pc value.
+ (rp_saved): Ditto.
+ For the import stub, return -24 always.
+ (hppa_frame_saved_pc): Save old pc value, to detect we are in a loop.
+ (init_extra_frame_info): Use TARGET_READ_FP.
+ (frame_chain): Include thread support.
+ If the caller's pc is zero, we loose and return, just like stack bottom.
+ Disable warning about being unable to find unwind info.
+ (hppa_push_arguments): Rewrite.
+ (hppa_value_returned_from_stack): New function. Handles returning a value
+ larger that 64 bits, stored on the stack.
+ (find_stub_with_shl_get): New function. To look up symbols in shlibs.
+ (cover_find_stub_with_shl_get): New function. Cover routine for
+ find_stub_with_shl_get to pass to catch_errors.
+ (hppa_fix_call_dummy): Comment out old stub mechanism. Rewrite using dyncall.
+ (target_read_fp): New function.
+ (pa_do_registers_info): Floating point registers start at FP4.
+ (pa_print_registers): Use FP4_REGNUM instead of 72.
+ (skip_trampoline_code): Do machine instruction matching for PA2.0.
+ (setup_d_pid_in_inferior): New function. Exception handling support.
+ (initialize_hp_cxx_exception_support): Ditto.
+ (child_enable_exception_callback): Ditto.
+ (child_get_current_exception_event): Ditto.
+
+ * hppah-nat.c (child_post_wait, child_post_follow_vfork,
+ child_post_follow_inferior_by_clone): New functions.
+
+ * hppah-nat.c (child_xfer_memory): Make sure the call to ptrace really
+ fails before we give up.
+ (hppa_pid_to_str): New function. Format a process id.
+ (hppa_tid_to_str): New function. Format a thread id.
+
+ * hppah-nat.c (child_xfer_memory): Use xmalloc, not alloca.
+ (child_post_wait): Delete.
+ (child_post_follow_vfork): Delete decl of child_ops; delete
+ large chunks of function -- let it be handled by the normal
+ mechanism that notices and handles exec events, in resume().
+
+ * hppah-nat.c (require_notification_of_exec_events): New function;
+ just notify of exec events, not all events, and just the specified
+ pid, don't include it's children (10.20 version).
+ (child_acknowledge_created_inferior): Call new function
+ require_notification_of_exec_events instead of
+ require_notification_of_events.
+
+ * hppah-nat.c [!GDB_NATIVE_HPUX_11]: Move HPUX 10.x-specific
+ support code here from infptrace.c.
+
+ * hppah-nat.c: Removed #define ptrace call_ptrace
+ replaced all calls to ptrace with calls to call_ptrace
+ (parent_attach_all): Removed call to ptrace
+
+ * hpread.c (hpread_psymtab_to_symtab_1): Change fflush to
+ gdb_flush; change stdout to gdb_stdout.
+ (hpread_psymtab_to_symtab): Change fflush to gdb_flush.
+
+ * hpread.h: New file. Includes all includes, struct defs, defines
+ from hpread.c.
+
+ * infcmd.c
+ (attach_command): New local variable, exec_file, added code to
+ determine exec_file from pid if exec_file is not already known,
+ call new target operation, target_post_attach -- a no-op unless
+ on HPUXHPPA
+ (detach_command): After detaching, do a SOLIB_RESTART
+
+ * infcmd.c (objfiles.h): Fix typo on include line.
+
+ * infcmd.c (run_command): Only call SOLIB_RESTART if it's
+ defined.
+ (detach_command): Ditto.
+
+ * infcmd.c:
+ (run_stack_dummy): Add calls to
+ disable_watchpoints_before_interactive_call_start and
+ enable_watchpoints_after_interactive_call_stops
+ (finish_command): Alter code handling the evaluation and printing
+ of the target function's return value.
+ (attach_command): When given a pid, but no exec file, try to determine
+ the exec file from the process. If the process does not record a
+ full path name, try to qualify the filename against the source path.
+ (_initialize_infcmd): Add some verbiage about how to use the attach command
+
+ * infcmd.c:
+ Include objfiles.h
+ (run_command): If program has already been started, and decide
+ to restart it, then kill the target, flush the caches,
+ call init_wait_for_inferior. Also purge old solib objfiles.
+
+ * infcmd.c: Changed calls to val_print, using a new macro,
+ SOLIB_RESTART
+ (run_command): Calls SOLIB_RESTART
+ (do_registers_info): Changed calls to val_print
+
+ * infcmd.c: Made the symfile.h include preceed the
+ objfiles.h include. The other ordering caused a
+ compile problem (incompletely defined types).
+
+ * inferior.h (REQUIRE_DETACH): Fix default definition.
+ * inftarg.c (child_post_attach): Fix declaration, make static.
+ (proc_wait): Make globally visible.
+ (child_insert_fork_catchpoint, etc): Fix return type.
+
+ * inferior.h (STARTUP_WITH_SHELL): New define.
+ (START_INFERIOR_TRAPS_EXPECTED): New define
+
+ * inferior.h (fork_inferior): Change fifth parameter to be a function
+ returning void.
+
+ * inferior.h (proc_wait): Declare.
+
+ * inferior.h:
+ (Require_ATTACH): New macro
+ (REQUIRE_DETACH): New macro
+ (detach): Definition is now an extern
+ (clone_and_follow_inferior): New definition, it's also an extern
+
+ * inferior.h:
+ (Require_attach): Default definition for require_attach funct
+ (require_detach): Default definition for require_detach funct
+ (pre_fork_inferior): New funct decl for function defined in
+ infptrace.c
+ (fork_inferior): New parameter in funct decl.
+
+ * inferior.h:
+ New variable decls: Inferior_ignoring_startup_exec_events,
+ inferior_ignoring_leading_exec_events -- these variables
+ are used when processing an exec call.
+ (CALL_DUMMY_HAS_COMPLETED): New default macro -- for targets
+ where PC in call dummy implies that call dummy has
+ completed. Note, that on HPUX this inference does not hold.
+
+ * infptrace.c
+ (require_notification_of_events): New function
+ (child_acknowledge_created_inferior): Previously named
+ hppa_acknowledge_forked_child. Also calling
+ require_notification_of_events and clearing some semaphore
+ variables
+ (child_post_startup_inferior): New function
+ (child_create_catch_fork_hook): Previously named
+ hppa_create_catch_fork_hook
+ (child_create_catch_vfork_hook): Previously named
+ hppa_create_catch_vfork_hook
+ (child_has_forked): Previously named hppa_target_has_forked
+ (child_has_vforked): Previously named hppa_target_has_vforked
+ (process_wait): Changed to call target_post_wait
+ (attach): Add call to require_notification_of_events
+ (child_pid_to_exec_file): New function
+ (hppa_require_attach): New local variable, pt_status
+ (hppa_get_process_events): New function
+
+ * infptrace.c (call_ptrace): Simplify control flow.
+ (proc_wait): Move here from inftarg.c, add target_post_wait call.
+
+ * infptrace.c (call_ptrace): Add some debugging code.
+
+ * infptrace.c (child_pid_to_exec_file): Declare variable.
+
+ * infptrace.c (kill_inferior): Clean up call to proc_wait.
+
+ * infptrace.c:
+ (Call_ptrace): When the ptrace request is PT_SETTRC,
+ call ptrace and then call parent_attach_all.
+
+ * infptrace.c:
+ (Child_has_syscall_event): New function. only applicable
+ (for now) on HPUX 10.30 and beyond via the ttrace call.
+ In infptrace.c there is a default operation.
+ With ttrace, it is possible to tell the kernel to
+ notify the debugger that the target program is about to make
+ or return from a syscall.
+ (child_thread_alive): New function. a default function.
+ ptrace doesn't support kernel threads.
+ (hppa_enable_page_protection_events): Defualt function
+ (hppa_disable_page_protection_events): Default function
+
+ * infptrace.c (child_pid_to_exec_file): Fix number of params to
+ cal_ptrace call.
+
+ * infptrace.c (hppa_pid_or_tid_to_str): New function.
+ (hppa_switched_threads): New function.
+ (hppa_ensure_vforking_parent_remains_stopped): New function.
+ (hppa_resume_execd_vforking_child_to_get_parent_vfork): New function.
+
+ * infptrace.c: Most of the changes found in infptrace.c should
+ be moved to hppah-nat.c
+ (PT_VERSION): A new define
+ (startup_semaphore_t): A new struct type. it is used to
+ coordinate the parent and child processes after a fork and
+ before an exec on HPUX.
+ (call_ptrace): Changes to determine whether the ptrace
+ request is for starting the tracing of the target process.
+ (parent_attach_all): New funct. used on HPUX for coordinating
+ the parent and child processes after a fork and before and exec.
+ (hppa_acknowledge_forked_child): New funct. prabably belongs
+ in hppah-nat.c
+ (hppa_enable_catch_fork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_disable_catch_fork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_create_catch_fork_hook): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_enable_catch_vfork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_disable_catch_vfork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_create_catch_vfork_hook): New funct. probably belongs to
+ hppah-nat.c
+ (hppa_target_has_forked): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_target_has_vforked): New funct. probably belongs in
+ hppah-nat.c
+ (process_wait): New funct. also ifdefed for proc_wait.
+ (kill_inferior): Call proc_wait rather than wait. this is
+ pretty hacky.
+ (pre_fork_inferior): New function. used only by HPUX.
+ probably should be defined elsewhere.
+
+ * infrun.c (follow_inferior_fork): Only define on HP.
+ (wait_for_inferior): Only call SOLIB_IN_DYNAMIC_LINKER if we have
+ shared libraries; restore test of IN_SOLIB_DYNSYM_RESOLVE_CODE
+ removed by HP.
+
+ * infrun.c (normal_stop): Add a call to the TUIDO
+ macro just before the annotate_stopped label. This
+ updates the windows after each program stop.
+
+ * infrun.c (normal_stop): Verify stop_command is non-zero before
+ dereferencing it (it won't be set if dbx_commands is set).
+
+ * infrun.c (resume): Add #ifdef HPPAHPUX around HPUX-specific
+ code.
+
+ * infrun.c (resume): Add missing semicolon.
+
+ * infrun.c (wait_for_inferior): Fix syntax error.
+
+ * infrun.c (follow_fork_mode_kind_names): Removed "both" option.
+ (follow_fork): Added parameters. additional code for handling
+ following of parent, following of child
+ (resume): Added code for deciding how to resume in presence of
+ fork. Additional params to follow_fork call.
+
+ * infrun.c (follow_exec): Ifdef for HPUXHPPA for the moment, the
+ code in here assumes the existance of the child_ops target
+ vector. This is incorrect for Solaris.
+
+ * infrun.c (resume): Fixed ifdefs, HPPAHPUX -> HPUXHPPA.
+
+ * infrun.c (wait_for_inferior): Fixed a matching parens problem --
+ matching curly brace inside ifdefed code which is not being
+ compiled. Change local validFlag to be an 'int' rather than a
+ 'bool' and fixed the corresponding assignment statements.
+
+ * infrun.c:
+ Two new global variables: Inferior_ignoring_startup_exec_events and
+ inferior_ignoring_leading_exec_events.
+ New static variables: Parent_of_vfork_trap_expected_and_ignorable,
+ step_resume_breakpoint, through_sigtramp_breakpoint, pending_follow,
+ follow_vfork_when_exec
+ (follow_inferior_fork): Does what follow_fork did!
+ (follow_fork): Is now a wrapper function for follow_inferior_fork
+ (follow_vfork): Is now a wrapper function for follow_inferior_fork
+ (follow_exec): New function, handles an exec event.
+ (resume): Remove 3 local variables: Child_pid, has_forked, has_vforked.
+ move and expand code that tries to follow a fork (i.e. also check
+ for vfork and exec
+ (init_wait_for_inferior): Initialize the new structure, pending_follow
+ (delete_breakpoint_current_contents): When deleting all the breakpoints also
+ set the breakpoint struct pointer to NULL.
+ (wait_for_inferior): A number of changes.
+ The step_resume_breakpoint and through_sigtramp_breakpoint local
+ variables are now visible in entire module.
+ Changed name of variable from child_inferior_pid to saved_inferior_pid.
+ Added several cases to the event processing switch statement:
+ Target_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED, TARGET_WAITKIND_EXECD.
+ Also, for TARGET_WAITKIND_STOPPED, check to see if expecting a trap
+ from the parent of a vfork (ignorable) otherwise break as usual.
+ When determining the value of 'random_signal' (0 or 1), no longer check for
+ catchpoints.
+ When determining how to handle unexpected signals, must now take into
+ account fork, vfork, and exec.
+ Change call to PC_IN_CALL_DUMMY to a call to CALL_DUMMY_HAS_COMPLETED
+ At stop_stepping label, check to see if stopped for fork or
+ vfork event.
+
+ * infrun.c: New code is related to threads and fork/vfork/exec.
+ New static variable: Thread_step_needed
+ Deleted static variable: Parent_of_vfork_trap_expected_and_ignorable
+ Altered the pending_follow and fork_event structs
+ (follow_inferior_fork): Before detaching from child and removing
+ all breakpoints form it -- but only if forking or following
+ vforks as soon as they happen. Also reset the solib inferior hook.
+ The same kind of logic applies to hitting step_resume_breakpoints
+ (calling breakpoint_re_set_thread) and to resetting and inserting
+ breakpoints.
+ (follow_exec): Forward decl
+ (follow_vfork): Check to see if gdb followed the child. If
+ the child exec'd before gdb saw the parent's vfork event
+ then call follow_exec.
+ (follow_exec): If the exec occured after a vfork, then follow
+ the vfork as well. Do it before following the exec.
+ Make sure to update breakpoints after and exec
+ (resume): New local variable, should_resume.
+ Change parameters in calls to follow_fork, follow_vfork, and
+ follow_exec. Some changes to the way various pending_follow.kind
+ situations are handled (there's TARGET_WAITKIND_FORKED,
+ TARGET_WAITKIND_VFORKED, ARGET_WAITKIND_EXECD. Some additional
+ conditions to check before deciding to resume the target (i.e.
+ should_resume=1, stepping?, thread_step_needed?i, regular
+ resume?)
+ (proceed): When proceeded at location that does not have a breakpoint
+ set thread_step_needed=0 to indicate that it is not necessary to
+ single step thread over breakpoint. SOme additional checks to see
+ if it is necessary to step thread over breakpoint.
+ (start_remote): Remove call to clear_proceed_status.
+ (init_wait_for_inferior): Initialize new fields in fork_event
+ structure and add a call to clear_proceed_status.
+ (wait_for_inferior): New local variable: New_thread_event.
+ Initialize thread_step_needed = 0.
+ Minor massaging of conditions for adding a new thread to the thread list.
+ No longer resuming execution after adding a new thread. Let user play with thread first.
+ Some changes in the way TARGET_WAITKIND_FORKED, ARGET_WAITKIND_VFORKED,
+ TARGET_WAITKIND_EXECD are handled -- this is all HPUX related.
+ Simplified TARGET_WAITKIND_STOPPED -- HP previously had some
+ more complicated code in here.
+ Moved the code to resume threads to after the large case statement that processes the events.
+ Additional processing for stop_signal=TARGET_SIGNAL_TRAP.
+ Cleanup code at process_event_stop_test label.
+ Set thread_step_needed when processing a BPSTAT_WHAT_SINGLE.
+ Minor massaging of fork/vfork/exec part of stop_stepping code.
+ (normal_stop): Minor changes. calling show_and_print_stack_frame.
+ (xdb_handle_command): New function
+ (_initialize_infrun): Handle xdb_commands. also handle dbx commands
+
+ * infrun.c: Changes to support following forks, and handling
+ catchpoints.
+ (follow_fork_mode_kind_names): New array
+ (follow_fork): New function. implements the follow parent,
+ or child functionality.
+ (resume): Additions to check whether the target process
+ just forked and decide which process to follow.
+ (wait_for_inferior): Additional variables (child_inferior_pid,
+ stepping_through_solib_after_catch,
+ - stepping_through_solib_catchpoints.
+ - Altered CURRENTLY_STEPPING macro to check for stepping through
+ a shared library after hitting a catchpoint.
+ - Add parameters to save_infrun_state call
+ - Check for fork and vfork when deciding if event is a random
+ signal
+ - When considering stops due to breakpoints, check for
+ BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
+ - Check for stop due to an explicit catchpoint
+ - When checking for single stepping event, also check for
+ stepping to get out of dynamic linker's hook after catching
+ a shlib event
+ (is_internal_shlib_eventpoint): New funct. check to see if
+ event type is bp_shlib_event.
+ (stopped_for_internal_shlib_event): New funct. check for shlib
+ events
+ (stopped_for_shlib_catchpoint): New funct. check for catchpoints.
+ (normal_stop): Additions to check for shlib event
+ (set_follow_fork_mode_command): New funct. handles the new follow
+ fork command.
+ (_initialize_infrun): Additions for follow-fork-mode command.
+
+ * infrun.c: Ifdefing references to
+ switched_from_inferior_pid for HPUXHPPA. They don't seem
+ useful for Solaris (i.e. non-HPUX)
+
+ * infrun.c: Included tuiData.h and tuiDataWin.h, ifdefed for TUI.
+ Included top.h. New static variables: Switched_from_inferior_pid,
+ number_of_threads_in_syscalls.
+ (follow_inferior_fork): If there is a step_resume breakpoint
+ explicitly reset the thread number.
+ (resume): For TARGET_WAITKIND_VFORKED, removed a check for getting
+ the vfork event to soon.
+ (init_wait_for_inferior): Added parameter to call to
+ breakpoint_init_inferior. Initialize number_of_threads_in_syscalls.
+ (wait_for_inferior): New local variables: Prev_sal,
+ enable_hw_watchpoints_after_wait, stepping_through_sigtramp,
+ stepped_after_stopped_by_watchpoint. Enable watchpoints after a wait.
+ Added cases for TARGET_WAITKIND_SYSCALL_ENTRY and
+ TARGET_WAITKIND_SYSCALL_RETURN.
+ Do additional processing if stop due to breakpoint, but breakpoint is
+ only valid for a thread other than the one currently running. Additional
+ parameters to save_infrun_state and load_infrun_state. Some additional
+ processing for BPSTAT_WHAT_STEP_RESUME. Some additional processing to
+ handle stepping over a function.
+ (normal_stop): Added notification of switching threads. ifdefing some
+ TUI changes and leaving out non-essential TUI changes.
+ (restore_selected_frame): Ifdefing some TUI changes
+ (restore_inferior_status): Ifdefing some TUI changes
+
+ * infrun.c: Removed the TUI ifdefs and TUI code. Also removed
+ include for top.h. HP introduced this. I'm taking it out.
+
+ * inftarg.c (child_detach_from_process): Declare.
+ (child_attach_to_process): Declare.
+ (child_stop): Make static to match declaration.
+
+ * inftarg.c (ptrace_him): Change prototype back to return int.
+
+ * inftarg.c (ptrace_me): Remove debug output, pass NULL to
+ fork_inferior if not HPUX.
+
+ * inftarg.c:
+ (child_require_attach): New funct prototype and definition
+ (child_require_detach): New funct prototype and definition
+ (proc_wait): Funct prototype and definition are enclosed by
+ proc_wait ifndef
+ (child_attach_to_process): New function, does most of the
+ work that child_attach used to do and some additional
+ work to determine whether gdb is already attached to the
+ target how to react.
+ (child_attach): Altered. It's now a wrapper for
+ child_attach_to_process.
+ (child_require_attach): New function, called if should attach
+ even when gdb is already attached to target.
+ (child_detach_from_process): New function, does most of the
+ work that child_detach used to do and some additional work
+ to determine whether gdb is currently attached to the target.
+ (child_detach): Altered. It's now a wrapper for
+ child_detach_from_process.
+ (child_require_detach): New function, called if should try to
+ detach even when gdb is not attached to target.
+ (ptrace_him): Calls a new function, target_acknowledge_forked_child.
+ Currently, target_acknowledge_forked_child, is only defined to
+ do something for HPUX.
+ (child_create_inferior): Changed call to fork_inferior.
+ (child_ops): Added to_require_attach and to_require_detach fields
+ to the child_ops target ops vector.
+
+ * inftarg.c:
+ Some hacks for ttrace work
+ (child_wait): Additional local variables, additional code in
+ while loop to check for: Process exited, process forked,
+ process vforked, process execd
+ (child_thread_alive): John B. seems to think that the kill
+ call is inapproapriate for HPUX.
+ (child_attach_to_process): Using strtol rather than atoi.
+ no longer check for case where there is no known exec file.
+ (child_post_attach): New function, a default, a no-op
+ (child_insert_fork_catchpoint): New function, a default, a no-op
+ (child_remove_fork_catchpoint): New function, a default, a no-op
+ (child_create_catch_fork_hook): Deleted
+ (child_create_catch_vfork_hook): Deleted
+ (child_insert_vfork_catchpoint): New function, a default, a no-op
+ (child_remove_vfork_catchpoint): New function, a default, a no-op
+ (child_can_follow_vfork_prior_to_exec ):new function, a default,
+ a no-op
+ (child_insert_exec_catchpoint): New function, a default, a no-op
+ (child_remove_exec_catchpoint): New function, a default, a no-op
+ (child_has_execd): New function, a default, returns 0
+ (child_reported_exec_events_per_exec_call): New function, a
+ default, returns 1
+ (child_has_exited): New function, a default.
+ (child_core_file_to_sym_file): New function, a default, returns NULL.
+ (child_ops): Initialize new target_ops vector fields to the
+ child* functions.
+ * infptrace.c:
+ (Call_ptrace): For HPUX, handle additional requests: Pt_CONTIN1,
+ PT_STEP1.
+ (require_notification_of_events): Add several signals to the
+ set of events requiring notification: Ptrace_SIGNAL,
+ PTRACE_EXEC, PTRACE_FORK, PTRACE_VFORK
+ (child_acknowledge_created_inferior): This function is only
+ defined if CHILD_ACKNOWLEDGE_CREATED_INFERIOR is defined.
+ (child_post_startup_inferior): Function is only defined if
+ CHILD_POST_STARTUP_INFERIOR is defiend. Also, now call
+ require_notification_of_events.
+ (child_create_catch_fork_hook): Deleted
+ (child_create_catch_vfork_hook): Deleted
+ (child_insert_fork_catchpoint): New function
+ (child_remove_fork_catchpoint): New function
+ (child_insert_vfork_catchpoint): New function
+ (child_remove_vfork_catchpoint): New function
+ (child_has_forked): Now enclosed by a CHILD_HAS_FORKED ifdef
+ (child_has_vforked): Now enclosed by CHILD_HAS_VFORKED ifdef
+ (child_can_follow_vfork_prior_to_exec): New function
+ (child_insert_exec_catchpoint): New function
+ (attach): Removed call to require_notification_of_events
+ (child_post_attach): New function, call to
+ require_notification_of_events moved here.
+ (child_pid_to_exec_file): New enclosed by CHILD_PID_TO_EXEC_FILE ifdef
+ introduced the concept of a saved_inferior_pid
+ (hppa_require_attach): Add some code to decide if gdb is already
+ attached to process. Can not figure this out via a ptrace call.
+ (hppa_insert_hw_watchpoint): New function
+ (hppa_remove_hw_watchpoint): New function
+
+ * inftarg.c:
+ (child_attach_to_process): Change position in file
+ (child_detach_from_process): Change position in file
+
+ * inftarg.c:
+ (child_attach_to_process): Changed parameter to child_wait call
+
+ * inftarg.c:
+ (child_post_wait): New function declaration and definition
+ (ptrace_him):
+ - change return value to a void.
+ - change target_acknowledge_forked_child call to
+ target_acknowledge_created_inferior
+ - call target_post_startup_inferior rather than returning pid.
+ (child_attach_to_process): Change param name, fail_if_already_attached
+ -> after_fork.
+ Invert a couple of if-then-else statments.
+ Use REQUIRE_ATTACH macro
+ (child_attach): Change params in child_attach_to_process call
+ (child_require_attach): Change params in child_attach_to_process call
+ (child_detach_to_process): Change param name,
+ fail_if_already_attached -> after_fork.
+ Invert a couple of if-then-else statments.
+ Use REQUIRE_DETACH macro
+ (child_detach): Change params in child_detach_from_process call
+ (child_require_detach): Change params in child_detach_from_process
+ call
+ (child_post_startup_inferior): New function
+ (child_acknowledge_created_inferior): New function
+ (child_clone_and_follow_inferior): New function
+ (child_post_follow_inferior_by_clone): New function
+ (child_create_catch_fork_hook): New function
+ (child_create_catch_vfork_hook): New function
+ (child_has_forked): New function
+ (child_has_vforked): New function
+ (child_post_follow_vfork): New function
+ (child_stop): No longer a static function
+ (child_pid_to_exec_file): New function
+
+ * inftarg.c:
+ (child_wait): Child_pid becomes related pid. return pid
+ rather than inferior_pid. Changes are in code handling fork
+ and vfork
+
+ * inftarg.c:
+ Include gdb_stat.h and sys/unistd.h
+ (child_wait): New local variables. Check for live threads.
+ Check for syscall events
+ (child_thread_alive): No longer a static funct.
+ (ptrace_him): Remove some code inserted in snap3
+ (child_create_inferior): Added a bunch of code to handle a
+ bad interaction between start-up-with-shell and the HP
+ catch-fork/catch-exec logic. I am ifdefing this for
+ HPUXHPPA for now.
+ (child_has_syscall_event): New default target_ops function
+ (child_enable_exception_callback): New default target_ops function
+ (child_get_current_exception_event): New default target_ops function
+ (child_ops): 3 new fields
+
+ * inftarg.c: Remove HPUX_SNAP1 and HPUX_SNAP2 ifdefs
+
+ * inftarg.c: Reverted previous change.
+
+ * infttrace.c (hppa_remove_hw_watchpoint): Fix check for write
+ access hardware watchpoint.
+
+ * infttrace.c (proc_wait): Rename from proc_wait.
+
+ * infttrace.c (require_notification_of_exec_events): New function;
+ just notify of exec events, not all events, and just the specified
+ pid, don't include it's children.
+ (child_acknowledge_created_inferior): Call new function
+ require_notification_of_exec_events instead of
+ require_notification_of_events.
+ (child_post_startup_inferior): Call require_notification_of_events
+
+ * infttrace.c: Changed all references to boolean to int.
+ Changed all references to TRUE and FALSE to 1 and 0.
+
+ * irix5-nat.c (symbol_add_stub): Add params to call to
+ symbol_file_add.
+
+ * jv-lang.c (get_dynamics_objfile): Add 2 more parameters to call
+ to allocate_objfile.
+
+ * main.c (fputs_unfiltered): Changes to prevent cursor form
+ jumping around in the TUI. Altered where tuiTermUnsetup and
+ tuiTermSetup are called
+
+ * main.c (fputs_unfiltered): Changed function so that it
+ checks to see if output is to a string buffer or to a
+ FILE stream and does the correct action (i.e. strcat or
+ fputs). Fixed params for fputs call.
+
+ * main.c (fputs_unfiltered): Don't try to call the TUI's
+ CommandCharCount functions when the TUI isn't enabled.
+
+ * main.c (fputs_unfiltered): Change FILE to GDB_FILE.
+
+ * main.c (main): If the user gives the --version or --help flags,
+ disable the TUI.
+
+ * main.c (tui_version, xdb_commands, dbx_commands): New variables.
+ (main): New command line arguments --tui, --xdb, --dbx; add call
+ to tyiCleanUp via tuiDo to main loop.
+ (fputs_unfiltered): Tui related changes.
+
+ * main.c: Define 2 new global variables, gdb_stdout and gdb_stderr
+ of type GDB_FILE.
+ (main): Allocate space for and initialize gdb_stdout and gdb_stdin.
+
+ * objfiles.c (find_pc_sect_section): Make end condition be less
+ than s->endaddr, not less than or equal to s->endaddr.
+
+ * objfiles.c:
+ (allocate_objfile): 2 new parameters: User_loaded and is_solib.
+ When appropriate, record in the object file that it is user loaded.
+ The run command can use this information to purge object file
+ entries associated with the old inferior and keep user loaded
+ object files loaded via the add-symbol-file command.
+ (objfile_purge_solibs): New function. deletes all objectfile entries
+ that are not explicitly loaded by the user.
+
+ * objfiles.c:
+ (objfile_relocate): Check for LOC_INDIRECT
+ (find_pc_sect_section): Change condition from
+ pc < s->endaddr to pc <= s->endaddr
+
+ * objfiles.h:
+ New variables: User_loaded and is_solib
+ (OBJF_SHARED): New macro. used to distinguish objfile for
+ shared library from "vanilla" objfile.
+ (allocate_objfile): Add new parameters to function decl.
+ (objfile_purge_solibs): New function decl.
+
+ * objfiles.h: Add some typedefs: Importentry, ExportEntry.
+ Add some new variables: Import_list, import_list_size,
+ export_list, export_list_size
+
+ * osfsolib.c:
+ (symbol_add_stub): Added params to call to symbol_file_add
+
+ * pa/hpux1020.mh (NATDEPFILES): Add corelow.o, symbol table and
+ solib files.
+
+ * pa/hpux1100.mh (NAT_FILE): Use nm-hppah11.h.
+ (NATDEPFILES): Add symbol table and solib files.
+
+ * pa/nm-hppah11.h: New file, HPUX11-only definitions.
+
+ * pa/tm-hppa.h (proc_wait): Remove decl and macro.
+
+ * parse.c (write_dollar_variable): Handle cases in which variables
+ besides the debugger ones start with $ and $$.
+ (parse_nested_classes_for_hpacc): New function. Parse a string that
+ is possibly a namespace / nested class specification.
+ (find_template_name_end): New function.
+
+ * procfs.c:
+ (procfs_init_inferior): Return value is now a void.
+
+ * procfs.c (procfs_ops): Initializing new target ops vector fields. see list below.
+
+ * procfs.c:
+ (procfs_ops): Adding new target_ops vector fields and
+ removing a few. see list below
+
+ * procfs.c: Added new fields to procfs_ops.
+ Necessary since we still have oldstyle initialization in
+ this file
+
+ * pyr-tdep.c (pyr_do_registers_info): Change stdout to gdb_stdout.
+ (frame_locals_address): Change stderr to gdb_stderr.
+ (frame_args_addr): Ditto.
+
+ * pyr-xdep.c (fetch_inferior_registers): Change stderr to
+ gdb_stderr.
+
+ * serial.c (serial_close): Call gdb_fclose, not fclose on a
+ GDB_FILE.
+
+ * serial.c (serial_logchar): Change chtype to ch_type. sigh.
+
+ * solib.c (look_for_base): The parameter to file must be
+ of type FILE *. So cast exec_bfd -> iostream in the call
+ to fileno as a FILE *, not a GDB_FILE *. This will work because
+ exec_bfd -> iostream is declared and given a value in bdf and
+ bfd will continue to use FILE rather than GDB_FILE.
+
+ * solib.c:
+ (solib_add): Remove references to exec_ops.
+
+ * solib.c:
+ (solib_add): Update exec_ops.to_sections
+
+ * solib.c:
+ (symbol_add_stub): Added params to call to symbol_file_add
+
+ * solib.h:
+ (SOLIB_REMOVE_INFERIOR_HOOK): New macro. defined to 0.
+ functionality not implemented for this target.
+
+ * solib.h: Added macro definitions. These macros generate
+ error messages for solaris??
+ (SOLIB_CREATE_CATCH_LOAD_HOOK)
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK)
+ (SOLIB_HAVE_LOAD_EVENT)
+ (SOLIB_LOADED_LIBRARY_PATHNAME)
+ (SOLIB_HAVE_UNLOAD_EVENT)
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME)
+ (SOLIB_IN_DYNAMIC_LINKER)
+ (SOLIB_RESTART)
+
+ * somread.c (is_in_import_list): Ditto.
+
+ * somread.c (som_symfile_read): Added some comments
+
+ * somread.c (som_symfile_read): Read in import and export lists.
+ (som_symtab_read): Change test for dynamic executable.
+ (is_in_import_list): New function. Check if a given symbol name
+ is in the import list.
+ (init_import_symbols): New function. Read in and initialize the
+ som import list.
+ (init_export_symbols): New function. Read in and initialize the
+ som export list.
+
+ * somread.c:
+ (som_symfile_read): Fix missing comment delimiters
+
+ * somsolib.c (DLD_FLAGS_MAPPRIVATE): New macro.
+ Define bit of __dld_flags in HP-UX a.out files.
+ (DLD_FLAGS_HOOKVALID): Ditto.
+ (DLD_FLAGS_LISTVALID): Ditto.
+ (DLD_FLAGS_BOR_ENABLE): Ditto.
+ (som_solib_total_st_size): Cumulative size in bytes of the
+ symbol tables of all shared objects on the so_list_head list.
+ (som_solib_st_size_threshhold_exceeded): Threshold for adding symbols
+ for shlibs.
+ (som_solib_sizeof_symbol_table): New function. Computes size of
+ symbol table for a shlib.
+ (som_solib_load_symbols): New function. Load symbols from shlib.
+ (som_solib_add): Detect if __dld_list is not valid.
+ Record main program's symbol table size.
+ Load symbols if called from command line.
+ Keep threshold into account when loading shlib symbols.
+ (som_solib_create_inferior_hook): Use dld_flags macros.
+ (som_sharedlibrary_info_command): Let user know if symbols were
+ not loaded.
+ (som_solib_restart): Discard all the shlibs descriptors.
+ (_initialize_som_solib): Chenge help message for auto-solib-add
+ command.
+ Set threshold for symbol table to 50 megabytes.
+
+ * somsolib.c (_initialize_som_solib): Added call to som_solib_restart.
+ (som_solib_restart): New function
+ (som_solib_in_dynamic_linker): New function
+ (som_solib_desire_dynamic_linker_symbols): New function
+ (som_solib_unloaded_library_pathname): New function
+ (som_solib_loaded_library_pathname): New function
+ (som_solib_library_pathname): New function
+ (som_solib_have_unload_event): New function
+ (som_solib_have_load_event): New function
+ (som_solib_create_catch_unload_hook): New function
+ (som_solib_create_catch_load_hook): New function
+ (som_solib_create_inferior_hook): Rewritten
+ dld_cache: New struct
+ addr_and_unwind_t: New struct
+ (find_unwind_entry) added prototype
+
+ * somsolib.c (som_solib_create_inferior_hook): Introduce new local
+ msymbol2 and change some msymbol's to msymbol2's -- was clobbering
+ msymbol, passing a NULL to lookup_minimal_symbol_solib_trampoline,
+ and ultimately core dumping with a SEGV.
+
+ * somsolib.c:
+ Include assert.h
+ (som_solib_mapped_entry): Additional comments for text_addr,
+ text_link_addr, text_end, and tsd_start_addr fields. Commenting
+ out 2 tsd fields, __data_start and __data_end.
+ (som_solib_add_solib_objfile): Add params to calls to symbol_file_add.
+ Add some code for distinguishing between a shared library and other
+ objfiles. This appears to be a prelude to thread local storage.
+ (som_solib_load_symbols): Changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ (som_solib_add): Change comment to correctly specify path
+ to end.o -- /opt/langtools/lib/end.o. changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ Removed several SOLIB_DEBUG ifdefs and the associated printfs.
+ Add code to find the start address for the object file's thread
+ local storage
+ (som_solib_create_inferior_hook): Fix warning messages use correct
+ path to end.o -- /opt/langtools/lib/end.o. Change control flow.
+ No longer user early returns from function is cases of error.
+ (reset_inferior_pid): New function
+ (som_solib_remove_inferior_hook): New function
+ (so_lib_thread_start_addr): New function. used for tsd.
+
+ * somsolib.c: Removed references to ASSERT macro.
+
+ * somsolib.c: Add debugging macro.
+ (struct som_solib_mapped_entry): Add new field tsd_start_addr.
+ (struct so_list): Added new field solib_addr.
+ (som_solib_add_solib_objfile): New function.
+ (som_solib_load_symbols): Rewritten.
+ (som_solib_add): Make sure we don't load the symbols in if the
+ threshold was exceeded.
+ (som_solib_get_solib_by_pc): New function. Return the address of
+ handle of the shared library.
+ (som_solib_restart): Disable breakpoints at restart.
+ (_initialize_som_solib): Set threshold to 100 megabytes.
+
+ * somsolib.c: Add include of fcntl.h so that O_RDONLY is defined.
+
+ * somsolib.h (DISABLE_UNSETTABLE_BREAK): New macro.
+ (PC_SOLIB): New macro.
+
+ * somsolib.h:
+ (SOLIB_CREATE_CATCH_LOAD_HOOK): Define
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK): Define
+ (SOLIB_HAVE_LOAD_EVENT): Define
+ (SOLIB_LOADED_LIBRARY_PATHNAME): Define
+ (SOLIB_HAVE_UNLOAD_EVENT): Define
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME): Define
+ (SOLIB_IN_DYNAMIC_LINKER): Define
+ (SOLIB_RESTART): Define
+
+ * somsolib.h:
+ (SOLIB_REMOVE_INFERIOR_HOOK): New macro. defined to use
+ som_solib_remove_inferior_hook.
+
+ * somsolib.h:
+ (som_solib_create_catch_load_hook)
+ (som_solib_create_catch_unload_hook)
+ (som_solib_have_load_event)
+ (som_solib_loaded_library_pathname)
+ (som_solib_have_unload_event)
+ (som_solib_unloaded_library_pathname)
+ (som_solib_in_dynamic_linker)
+ Fix prototypes to use type names, not parameter names.
+
+ * source.c (find_source_lines): Make non static.
+ (open_source_file): Ditto.
+ (source_full_path_of): New function.
+ (print_source_lines): Rename to print_source_lines_base and make
+ static; formatting.
+ (print_source_lines): New function.
+ (forward_search_command): Tui changes.
+ (reverse_search_command): Tui changes.
+ (_initialize_source): Add xdb and dbx compatibility commands.
+
+ * source.c (list_command): Handle case of odd number of source
+ lines to display.
+
+ * source.c:
+ (source_full_path_of): New function. file was overlooked
+ in merge ;-/.
+
+ * stack.c (func_command): Make high bound be <, not <=.
+
+ * stack.c (_initialize_stack): For the backtrace command, delete
+ the help line about usage, since this has to be a valid help
+ message for the 'where' command too.
+
+ * stack.c (current_frame_command): Add a check for the
+ existance of a stack. If there is no stack produce an
+ error message and exit.
+
+ * stack.c (down_silently_base, up_silently_base,
+ args_plus_locals_info, print_frame_info_base,
+ print_stack_frame_base, print_stack_frame_base_stub): Declare.
+ (print_frame_local_vars): Add'l parameter.
+ (print_stack_frame_stub): New version created, old version renamed
+ to show_and_print_stack_frame_base_stub.
+ (print_stack_frame_base_stub, print_only_stack_frame_stub,
+ show_and_print_stack_frame, print_only_stack_frame,
+ stack_publish_stopped_with_no_frame, print_frame_info,
+ show_stack_frame, backtrace_full_command, args_plus_locals_info,
+ select_and_print_frame, select_and_maybe_print_frame,
+ current_frame_command, func_command): New functions.
+ (backtrace_command): New function, old renamed to
+ backtrace_command_1.
+ (print_block_frame_locals, print_frame_local_vars): Additional
+ parameter, number of tabs.
+ (up_silently_command): New function, old renamed to
+ up_silently_command_base.
+ (down_silently_command): New function, old renamed to
+ down_silently_base.
+ (_initialize_stack): Register new commands based on values of
+ xdb_commands and dbx_commands variables.
+
+ * stack.c (func_command): Make high bound be <, not <=.
+
+ * stack.c (parse_frame_specification): Fix prototype to match
+ function definition.
+ (show_and_print_stack_frame_stub): Fix name.
+ (select_and_print_frame): Change uncaught tuiDO call.
+
+ * stack.c (up_silent_base): Rename from up_silently_command_base.
+
+ * symfile.c (symbol_file_command): Only call SOLIB_RESTART if it's
+ defined.
+
+ * symfile.c (add_psymbol_with_dem_name_to_list): New function.
+ Adds a symbol with a long value to a psymtab. Differs from
+ add_psymbol_to_list in taking both a mangled and a demangled name.
+
+ * symfile.c (compare_psymbols): Call strcmp directly, instead of
+ using macro.
+
+ * symfile.c (symbol_file_add): Reindent portions.
+ (symbol_file_command): Add call to tuiDo.
+
+ * symfile.c (symbol_file_command): Only call SOLIB_RESTART if it's
+ defined.
+
+ * symfile.c (symfile_bfd_open): Add code to call PXDB on hpux, if
+ the file has not already been processed by pxdb.
+ Added define USE_PXDB.
+
+ * symfile.c (symfile_bfd_open): Change parenthesis positioning
+ around call to hpread_pxdb_check.
+
+ * symfile.c (symfile_bfd_open): Make not static.
+ (RESET_HP_UX_GLOBALS): New macro. Resets globals when new symbol
+ file loaded.
+ (USE_PXDB): Not needed. Removed.
+ (symbol_file_add): Add HP specific code to deal with pxdb.
+ (symbol_file_command): Reset HP specific globals if new symbol file
+ loaded.
+ (symfile_bfd_open): Comment out checking for pxdb.
+ (reread_symbols): Reset HP specific globals.
+
+ * symfile.c (symfile_bfd_open): Uncomment hpus specific code.
+
+ * symfile.c:
+ (symbol_file_add): Add user_loaded and is_solib parameters.
+ fixed number of parameters in call to allocate_objfile
+ (symbol_file_command): Added call to SOLIB_RESTART macro.
+ fixed number of parameters in calls to symbol_file_add.
+ (add_symbol_file_command): Fixed number of parameters in calls to
+ symbol_file_add.
+
+ * symfile.c: Added prototype for hpread_pxdb_check.
+
+ * symfile.c: Changed HPUX_SNAP1 ifdef to HPUXHPPA. enclosed calls to
+ RESET_HP_UX_GLOBALS with an HPUXHPPA ifdef
+
+ * symfile.h (symfile_bfd_open): Add protptype.
+
+ * symfile.h: Add prototype for add_psymbol_with_dem_name_to_list.
+
+ * symfile.h: Clarify purpose of auto_solib_add.
+
+ * symmisc.c (maintenance_print_symbols): Call gdb_fclose, not
+ fclose on a GDB_FILE* during cleanup.
+ (maintenance_print_psymbols): Call gdb_fclose, not fclose on a
+ GDB_FILE* during cleanup.
+ (maintenance_print_msymbols): Call gdb_fclose, not fclose on a
+ GDB_FILE* during cleanup.
+
+ * symmisc.c (maintenance_print_symbols): Gdb_fclose now takes a
+ GDB_FILE ** parameter. Fix the local GDB_FILE variables and the
+ call to make_cleanup.
+ (maintenance_print_psymbols): Ditto
+ (maintenance_print_msymbols): Ditto
+
+ * symmisc.c (print_objfile_statistics): Close quotes in
+ output strings.
+
+ * symmisc.c:
+ (Print_symbol): Add LOC_INDIRECT to switch statement
+ (print_partial_symbols): Add LOC_INDIRECT to switch statement
+
+ * symtab.c (find_pc_sect_psymtab): High bounds should be <, not <=.
+ (find_pc_sect_symtab): Ditto.
+
+ * symtab.c (hp_som_som_object_present): New flag to indicate HP
+ compiled code.
+ (find_pc_sect_psymtab): Change tests to make sure we are checking
+ the texthigh adress as well.
+ (lookup_transparent_type): New function. Look up a type name
+ in the struct_namespace. The type returned must not be opaque.
+ (find_pc_sect_symtab): Make sure we check the address 'pc' itself,
+ too.
+ (find_addr_symbol): Prepare to handle LOC_INDIRECT address class, but
+ leave it commented out.
+ (find_pc_sect_line): Return correct information if pc is in import
+ or export stub (trampoline).
+ (decode_line_1): Skip two chars, if they are '$$'. Like for HP's
+ $$dyncall. Handle cases in which varaible and function names can start
+ with $.
+ (overload_list_add_symbol): If cannot demangle name, use it as is.
+ Free string after use.
+ (make_symbol_overload_list): Initialize oload_name to NULL and
+ oload_name_len to 0. If demangle not successful, use name as it is.
+ Free string after use.
+
+ * symtab.c (lookup_symbol): Changed call to find_pc_sect_symtab,
+ to the original find_pc_symtab, in HP added fragment.
+
+ * symtab.c (lookup_symbol): Change HPUX_SNAP1 ifdef to a HPUXHPPA ifdef
+
+ * symtab.c (lookup_symbol): Ifdef the searching of symbol in the
+ minimal symbol tables, for hpux we move this check at the end
+ of the function.
+ Before we error out if symbol is not found in the symtab, look
+ in the statics.
+ Before erroring out if static symbol not found look in the globals.
+
+ * symtab.c (lookup_symbol): Return symbol as soon as found.
+ (decode_line_1): Check whether we have a conditional break. Temporarily
+ remove it from the line, to not confure perenthesis checking.
+ Handle namespaces.
+ (overload_list_add_symbol): New function. Overload
+ resolution support.
+ (make_symbol_overload_list): Ditto.
+
+ * symtab.c:
+ (find_template_name_end): New prototype decl.
+ (lookup_symbol): When a global or static symbol shows up in the
+ psymtab table, but not the symtab table, tell the user that
+ the symbol may be an inlined function or a template function and
+ provide some guidance to the user about how to more fully
+ specify the symbol.
+ (lookup_transparent_type): When a global or static symbol shows up
+ in the psymtab table, but not the symtab table, tell the user that
+ the symbol may be an inlined function or a template function and
+ provide some guidance to the user about how to more fully
+ specify the symbol.
+ (decode_line_1): Handle template function specification when decoding a
+ line. May need to be ifdefed for HP's aCC?
+ (_initialize_symtab): Handle dbx commands.
+
+ * symtab.h (address_class): Add new address calss for
+ LOC_THREAD_LOCAL_STATIC and LOC_INDIRECT.
+ (lookup_transparent_type): Add prototype.
+ (exception_event_kind): New enum for exception catchpoints.
+ (exception_event_record): New structure for exception catchpoints.
+ (CURRENT_EXCEPTION_KIND): New macro.
+ (CURRENT_EXCEPTION_CATCH_SAL): New macro.
+ (CURRENT_EXCEPTION_CATCH_LINE): New macro.
+ (CURRENT_EXCEPTION_CATCH_FILE): New macro.
+ (CURRENT_EXCEPTION_CATCH_PC): New macro.
+ (CURRENT_EXCEPTION_THROW_SAL): New macro.
+ (CURRENT_EXCEPTION_THROW_LINE): New macro.
+ (CURRENT_EXCEPTION_THROW_FILE) new macro.:
+ (Current_EXCEPTION_THROW_PC): New macro.
+
+ * symtab.h(make_symbol_overload_list): Add prototype.
+
+ * symtab.h:
+ (symbol_file_add): Add new params to function decl.
+
+ * target.c (cleanup_target): Changed casting of default functions for
+ to_has_forked, to_has_vforked, to_pid_to_exec_file to get rid of
+ warnings.
+
+ * target.c (cleanup_target): Changed the default functions for
+ to_pid_to_exec_file and to_core_file_to_sym_file
+
+ * target.c (cleanup_target): Fixed PARAMS for to_has_syscall_event
+
+ * target.c (cleanup_target): Syntax error, mismatched paranthesis.
+
+ * target.c:
+ (Default_clone_and_follow_inferior): New funct prototype declaration
+ and function definition
+ (dummy_target): More target_ops vector changes for HPUX
+ new fields. ifdefed for HPUX_SNAP2. New fields are
+ to_post_wait, to_post_startup_inferior
+ to_acknowledge_created_inferior, to_clone_and_follow_inferior,
+ to_post_follow_inferior_by_clone, to_create_catch_fork_hook,
+ to_create_catch_vfork_hook, to_has_forked, to_has_vforked,
+ to_post_follow_vfork, to_pid_to_exec_file
+ (de_fault): Add new HPUX specific target_ops operations to
+ the de_fault macro
+ (INHERIT): Add new HPUX specific target_ops operations to the
+ INHERIT macro
+ (find_default_clone_and_follow_inferior): New funct definition
+ (debug_to_post_wait): New funct
+ (debug_to_post_startup_inferior): New funct
+ (debug_to_acknowledge_created_inferior): New funct
+ (debug_to_clone_and_follow_inferior): New funct
+ (debug_to_post_follow_inferior_by_clone): New funct
+ (debug_to_create_catch_fork_hook): New funct
+ (debug_to_create_catch_vfork_hook): New funct
+ (debug_to_has_forked): New funct
+ (debug_to_has_vforked): New funct
+ (debug_to_post_follow_vfork): New funct
+ (setup_target_debug): Initialize new target_ops vector fields.
+
+ * target.c:
+ (Cleanup_target): Fixed the return type on a few of the
+ default function values.
+
+ * target.c:
+ (Dummy_target): Add 3 new fields
+ (nosupport_runtime): New function, used in cleanup_target
+ (cleanup_target): Changes in the de_fault macro, both to
+ accomodate the new target_ops vector fields and to use
+ more accurate default functions.
+ (update_current_target): Add new target_ops vector fields to the
+ INHERIT macro
+ (generic_mourn_inferior): The call to breakpoint_init_inferior now takes a
+ parameter
+ (normal_pid_to_str): Adding a \0 to the end of buf.
+ (debug_to_has_syscall_event): New func
+ (debug_to_enable_exception_callback): New func
+ (debug_to_get_current_exception_event): New func
+ (setup_target_debug): Initialize the 3 new target_ops vector fields
+
+ * target.c:
+ (Struct signals): Fix message associated with SIGRETRACT.
+
+ * target.c:
+ (Dummy_target): Fix syntax error
+ (cleanup_target): Changed the default values for the new
+ target_ops vector fields. HP folks inappropriately set
+ most of them to noprocess(). They should be a mixture
+ of ignore() and return_zero().
+
+ * target.c:
+ (Dummy_target): Add new target_ops vector fields and their initializations
+ (cleanup_target): Added new new target_ops vector fields to the de_fault
+ macro definition.
+ (update_current_target): Added new new target_ops vector fields to the INHERIT
+ macro definition
+ (return_one): New function, used by the de_fault macro
+ (debug_to_post_attach): New function
+ (debug_to_wait): Added new cases: Target_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED,
+ TARGET_WAITKIND_EXECD
+ (debug_to_insert_fork_catchpoint): New function
+ (debug_to_remove_fork_catchpoint): New function
+ (debug_to_insert_vfork_catchpoint): New function
+ (debug_to_remove_vfork_catchpoint): New function
+ (debug_to_can_follow_vfork_prior_to_exec): New function
+ (debug_to_insert_exec_catchpoint): New function
+ (debug_to_remove_exec_catchpoint): New function
+ (debug_to_core_file_to_sym_file): New function
+ (setup_target_debug): Give new fields in current_target target_ops vector values.
+
+ * target.c: Hp merge, 4/15/98 snapshot
+ There are new target_ops fields that pertain only
+ to HPUX. All the changes relate to this. First,
+ new fields are added to the dummy_target target_ops
+ vector: To_require_attach, to_require_detach.
+
+ * target.c: Remove HPUX_SNAP1 and HPUX_SNAP2 ifdefs
+
+ * thread.c (info_threads_command): Call print_only_stack_frame
+ instead of print_stack_frame.
+ (_initialize_thread): Make t an alias for thread only if
+ xdb_commands is not set.
+
+ * thread.c (thread_command): If no arguments, don't generate an
+ error, instead tell the user which thread is current.
+ (info_threads_commands): Don't lose the users position within the
+ current thread -- remember it and then restore it.
+
+ * thread.c:
+ (struct thread_info): Add stepping_through_sigtramp field
+ (add_thread): Initialize stepping_through_sigtramp field
+ (load_infrun_state): Add stepping_through_sigtramp param and
+ make sure it gets assigned a value.
+ (save_infrun_state): Add stepping_through_sigtramp param and
+ make sure that the value gets saved.
+ (info_threads_command): Ifdefing some local variables and
+ code for HPUXHPPA. HP folks want print the tid rather than pid?
+ Also, looks like the HP folks solved the same thread switching
+ problem that 4.17 solves. Taking 4.17.
+ (restore_current_thread): Print out the current frame after
+ switching threads.
+ (thread_apply_all_command): Ifdefing a print statement for
+ HPUXHPPA. The HP folks want to print out a tid rather than pid?
+ (thread_apply_command): Ifdefing a print statement for
+ HPUXHPPA. The HP folks want to print out a tid rather than pid?
+ (thread_command): Decided not to take HP change.
+
+ * thread.c: Fixing gdb core dump problem causing many testsuite
+ failures.
+ (add_thread): Remove call to bpstat_clear, initialize
+ tp->stepping_through_solib_catchpoints = NULL;
+
+ * thread.c: Changes for catchpoints, shared libaries,
+ (thread_info): Additional fields in the thread_info struct
+ for stepping_through_solib_after_catch and
+ stepping_through_solib_catchpoints.
+ (add_thread): Initialize the new thread_info fields.
+ (load_infrun_state): Additional parameters for handling
+ catchpoints and shared libraries.
+ (save_infrun_state): Additional parameters for handling
+ catchpoints and shared libraries.
+
+ * top.c (command_loop): Initialize space_at_cmd_start to 0.
+ (set_prompt): New function.
+ (togglelist, stoplist): New command lists.
+ (command_loop): Tui changes -- paranoia to make sure
+ insert mode is off when not editing.
+ (quit_force): Clean up tui on exit.
+ (init_main): Make definition of info status command dependent upon
+ dbx mode not being set.
+ (fputs_unfiltered_hook): Changed stream parameter from FILE
+ to GDB_FILE
+ (flush_hook): Changed stream parameter from FILE to GDB_FILE
+
+ * top.h (set_prompt): Declare.
+
+ * typeprint.c (whatis_exp): Decide real runtime type. For the vtable
+ case.
+
+ * utils.c (query): Changes to prevent cursor from jumping around in the
+ TUI. Call tuiBufferGetc explicitly, rather than passing it
+ into tuiDo. The tuiDo function does some additional work
+ that is inappropriate when handling queries.
+ (GDB_FILE_ISATTY): New macro that takes a GDB_FILE param and
+ determines whether or not it's using a tty.
+ (gdb_file_isatty); called by the GDB_FILE_ISATTY macro. Does
+ the actual work
+ (init_page_info): Call GDB_FILE_ISATTY rather than ISATTY
+ (print_spaces): Fix parameter to fputc. fix call to
+ gdb_file_adjust_strbuf.
+ (gdb_file_init_astring): Fix parameter to xmalloc
+ (gdb_file_deallocate): New function to deallocate
+ a GDB_FILE object and possibly a string buffer
+ (gdb_file_init_astring): Initialize buffer as the empty
+ string. Indent GNU style.
+ (gdb_fopen): Gdb_fopen is called if the GDB_FILE object is
+ actually afile rather than astring. The routine now allocates space
+ for a GDB_FILE object and initializes its fields in addition to
+ performing an fopen.
+ (gdb_flush): Fix the parameter passed into fflush. It's now
+ stream->ts_filestream.
+ (gdb_fclose): Pass in an object of type GDB_FILE **. Fix parameter
+ to fclose. It's now tmpstream->ts_filestream. Make sure to free
+ the GDB_FILE object and set the GDB_FILE * object to NULL.
+ (gdb_adjust_strbuf): New function. Determine if the current
+ ts_strbuf field contains sufficient space to concatenate a string
+ of length n on the end. If not, then reallocate the ts_strbuf.
+ (print_spaces): Check to see if the GDB_FILE is afile or
+ astring. If it is astring, then adjust the size of the ts_strbuf
+ field and concatenate the correct number of spaces onto the end of
+ the buffer. Otherwise continue to use fputc.
+ (gdb_file_get_strbuf): New function. return a ptr to the ts_strbuf
+ field in a GDB_FILE object.
+ (gdb_file_init_astring): New function to allocate space for and
+ initialize a GDB_FILE object when it is an astring.
+ (set_width): Declare it.
+ (pagination_enabled): Define it.
+ (query): Tui changes.
+ (init_page_info, set_width): New functions.
+ (set_width_command): Call set_width.
+ (_initialize_utils): Replace termcap stuff with call to
+ init_page_info; if xdb_commands set, define am and sm commands;
+ define pagination as a set/show command.
+ (vfprintf_maybe_filtered): Change FILE to GDB_FILE.
+ (fputs_maybe_filtered): Ditto.
+ (print_spaces): Ditto.
+ (gdb_printchar): Ditto.
+ (gdb_flush): Ditto.
+ (fputs_filtered): Ditto.
+ (vfprintf_filtered): Ditto.
+ (vfprintf_unfiltered): Ditto.
+ (fprintf_filtered): Ditto.
+ (fprintf_unfiltered): Ditto.
+ (fprintfi_filtered): Ditto.
+ (print_spaces_filtered): Ditto.
+ (fprintf_symbol_filtered): Ditto.
+ (gdb_fclose): New function.
+
+ * valops.c (call_function_by_hand): Assign to param_type only
+ if function has parameters.
+
+ * valops.c (call_function_by_hand): Ifdef the
+ HP_COMPILED_TARGET stuff.
+ (value_arg_coerce): Ditto.
+
+ * valops.c (call_function_by_hand): Make sure param_type is
+ initialized to NULL.
+
+ * valops.c (find_rt_vbase_offset): Add parameter to value_at.
+ (value_rtti_type): Ditto.
+ (value_full_object): Ditto.
+
+ * valops.c (search_struct_field_aux): Fixed mismatching parenths
+
+ * valops.c (search_struct_field_aux): Make sure TYPE_TAG_NAME
+ is not null before copying it.
+
+
+ * valops.c (search_struct_field_aux): Set found_class_name to null
+ if class has no name (anon unions case). Adjust base_addr
+ computation.
+
+ * valops.c (value_arg_coerce): Change final arg to int.
+
+ * valops.c (value_arg_coerce): Remove the conditional on HP
+ compiled target, for doing coercion of float to double. Removed
+ third parameter, using_gcc.
+ (call_function_by_hand): Do not use HP_COMPILED_TARGET, just
+ use the gcc_compiled variable.
+
+ * valops.c (value_cast): Take case of the enclosing_type and
+ pointer_to_offset fields.
+ (value_at): Use VALUE_CONTENTS_ALL_RAW
+ (value_fetch_lazy): Ditto
+ (value_assign): Handle enclosing_type, embedded_offset and
+ pointed_to_offset fields.
+ (value_repeat): Use VALUE_CONTENTS_ALL_RAW and VALUE_ENCLOSING_TYPE.
+ (value_ind): Set enclosing_type and embedded_offset correctly,
+ for a pointer value being dereferenced. Target memory bytes
+ corresponding to the size of the enclosing type are retreived.
+ (value_addr): Handle enclosing_type and pointed_to_offset.
+ (value_push): Use VALUE_CONTENTS_ALL and VALUE_ENCLOSING_TYPE.
+ (value_arg_coerce): Coerce floats to doubles only if gcc was not
+ used to compile the target.
+ (call_function_by_hand): Handle pointers to functions as paramters.
+ (value_array): Use VALUE_CONTENTS_ALL and VALUE_ENCLOSING_TYPE.
+ (search_struct_method): Produce more informative error message.
+ (find_rt_vbase_offset): Deal with negative offsets.
+ (value_find_oload_method_list): New function. Return the list of
+ overloaded methods of a specified name.
+ (find_method_list): New function. Search through the methods of an
+ object (and its bases) to find a specified method.
+ (value_full_object): New function. Given a value, check its real
+ run-time type.
+ (value_rtti_target_type): New function. Given a pointer value V, find
+ the real (RTTI) type of the object it points to.
+ (value_rtti_type): New function. Find the real run-time type of a
+ value using RTTI.
+
+ * valops.c: Include gdbcmd.h
+ Set global overload_resolution to 0.
+ (find_function_in_inferior): Modify error message.
+ (value_allocate_space_in_inferior): Modify error message.
+ (value_cast): Deal with HP/aCC peculiarities.
+ (value_of_variable): Use SYMBOL_SOURCE_NAME instead of SYMBOL_NAME.
+ (value_addr): Modify address value by adding the embedded offset.
+ (value_ind): Modify the address of the object by the pointed_to_offset.
+ (call_function_by_hand): Do not do any extra alignment if not needed.
+ Fetch the return value from the stack rather then from the register,
+ for the hppa architecture.
+ (search_struct_field): Rewritten. Now this function uses
+ search_struct_field_aux to do all the work.
+ (search_struct_field_aux): New function. This is the old
+ search_struct_field rewritten.
+ (find_rt_vbase_offset): Give error if virtual table pointer is not good.
+ (find_overload_match): New function. Find the best function that
+ matches on the argument types according to the overload resolution
+ rules.
+ (_initialize_valops): Add new set/show command for overload-resolution.
+
+ * value.h (VALUE_POINTED_TO_OFFSET): New macro.
+ Add field pointed_to_offset to value structure.
+ Add prototypes for new functions in valops.c.
+
+ * value.h (write_register_pid): Change prototype to match
+ function.
+
+ * value.h: Hp merge, 4/15/98 snapshot
+ Added parameter to val_print func decl.
+ Added new macro, VALUE_EMBEDDED_OFFSET, and
+ new func decl, find_rt_vbase_offset, for C++
+ support.
+
+ * values.c (allocate_value): Allocate also for value_embedded_offset
+ and value_enclosing_type.
+ (value_copy): Copy value_embedded_offset and value_enclosing_type too.
+ Use all_raw in copying the value itself.
+ (value_primitive_field): Add handling of base subobjects.
+
+ * values.c (value_copy): Copy the pointed_to_offset as well.
+ (allocate_value): Allocate the pointed_to_offset as well.
+ (value_virtual_fn_field): Rewrite.
+
+ * values.c (value_primitive_field): Adjust embedded offset and
+ offset calculation.
+
+ * values.c (value_static_field): Take into consideration that static
+ data members can be minimal symbols too.
+
+ * values.c (value_virtual_fn_field): Fix call to value_at.
+
+ * win32-nat.c (handle_load_dll): Added params to call to symbol_file_add.
+
+ Other changes have to do with XDB compatability. Leave oout
+ for now.
+
+ defs.h (vfprintf_filtered): Change FILE to GDB_FILE in decl.
+ (fprintf_filtered): Ditto.
+ (fprintfi_filtered): Ditto.
+ (vfprintf_unfiltered): Ditto.
+ (fprintf_unfiltered): Ditto.
+
+ infcmd.c (_initialize_infcmd): If xdb_commands is set, make S an
+ alias for next and define R, lr, g. Define go.
+
+ pyr-tdep.c (pyr_print_insn): Change FILE to GDB_FILE.
+
+
+ * breakpoint.c (create_temp_exception_breakpoint): #If it out --
+ nothing calls it.
+ (bpstat_stop_status): Don't call SOLIB_HAVE_LOAD_EVENT if it's not
+ defined; don't call SOLIB_HAVE_UNLOAD_EVENT if it's not defined.
+ (bpstat_get_triggered_catchpoints): If we don't have shared
+ library support, then don't call SOLIB_LOADED_LIBRARY_PATHNAME nor
+ SOLIB_UNLOADED_LIBRARY_PATHNAME.
+ (watch_command_1): Don't require a run before a watch command
+ unless we're on HP [it's an HP OS bug, not a generic limitation]
+ (catch_load_command_1): Don't define if no shared libraries.
+ (catch_command_1): Don't claim to support fork catchpoints unless
+ CHILD_INSERT_FORK_CATCHPOINT is defined, don't claim to support
+ vfork catchpoints unless CHILD_INSERT_VFORK_CATCHPOINT is defined,
+ don't clain to support shared library load catchpoints if shared
+ libraries aren't supported, and don't claim to support exec
+ catchpoints unless CHILD_INSERT_EXEC_CATCHPOINT is defined
+
+ There are new target_ops vector fields that pertain
+ only to HPUX. Added the to_require_attach and
+ to_require_detach fields to exec_ops. These new
+ fields are ifdef'ed for HPUX_SNAP1.
+
+ * breakpoint.h:
+ Fix compile error in enum bptype.
+
+ * coff-solib.h:
+ Fixed a number of macro definitions. SOLIB_LOADED_LIBRARY_PATHNAME,
+ SOLIB_HAVE_LOAD_EVENT, SOLIB_HAVE_UNLOAD_EVENT,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_IN_DYNAMIC_LINKER. These
+ macros are only meaningful (for now) for SOM. So, all
+ the macros were defined as error(...), but were used in
+ conditions. This caused the compile to crap out. I redefined
+ these (for now) to be 0.
+
+ * procfs.c:
+ (procfs_create_inferior): Fix call to fork_inferior -- need another
+ parameter.
+
+ * solib.h:
+ Fixed a number of macro definitions. SOLIB_LOADED_LIBRARY_PATHNAME,
+ SOLIB_HAVE_LOAD_EVENT, SOLIB_HAVE_UNLOAD_EVENT,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_IN_DYNAMIC_LINKER. These
+ macros are only meaningful (for now) for SOM. So, all
+ the macros were defined as error(...), but were used in
+ conditions. This caused the compile to crap out. I redefined
+ these (for now) to be 0.
+
+ * valops.c:
+ (search_struct_field): Undeclared local variable, "assigned".
+ (find_rt_vbase_offset): Fixed call to value_at
+
+ * value.h: Fix signature for find_rt_vbase_offset funct decl
+ (missing a param)
+
+Wed Dec 30 17:48:12 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * i386-stub.c: Fix error string in last change.
+
+1998-12-30 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * utils.c: <Readline/readline.h> instead of "readline/readline.h".
+
+ * configure.in (TERM_LIB): Search for the appropriate term library
+ on the host system.
+ * configure: Regenerated.
+ * Makefile.in (TERMCAP): Set based on autoconf check.
+ * config/*/*.mh: Don't override TERMCAP setting.
+
+Wed Dec 30 17:23:14 1998 Mark Alexander <marka@cygnus.com>
+
+ * value.c (value_virtual_fn_field): Handle the situation where
+ vtbl is a pointer to a structure instead of a pointer to an array.
+
+Mon Dec 28 17:43:36 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Jim Blandy <jimb@cygnus.com>,
+ Edith Epstein <eepstein@cygnus.com>, Elena Zannoni
+ <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David
+ Taylor <taylor@cygnus.com>, as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * c-lang.h (cp_print_value_fields): Update prototype; fixed
+ prototype decl for c_val_print function -- it needed an
+ embedded_offset param; fixed prototype of cp_print_value_fields.
+ Include value.h.
+ (C_LANG_H): Define.
+
+ * c-valprint.c (c_val_print): Add new parameter embedded_offset.
+ Add embedded_offset to valaddr in function calls. fix calls to
+ val_print, and cp_print_value_fields. Attempt to determine the
+ real type of the object to be printed. fixed call to
+ cp_print_value_fields. process TYPE_CODE_METHOD as well. moved
+ call to check_typedef out of conditional. add embedded offset
+ param to val_print call.
+
+ (c_value_print): Add new parameter to call to val_print. Handle
+ pointer to class case. Ensure that const char *, const unsigned
+ char * come out without the type but the volatile variants and the
+ signed variants don't.
+
+ * ch-lang.h (chill_val_print): Add parameter to decl.
+
+ * ch-valprint.c: The various print routines have an additional
+ parameter. Currently, the new parameter is only used when printing
+ C++ expressions. So, in ch-valprint.c, the new parameter is always
+ 0. Changes in calls to val_print, chill_val_print, c_val_print
+ Affected functions are chill_val_print_array_elements,
+ chill_val_print, chill_print_value_fields, chill_value_print.
+
+ * cp-valprint.c add vtable pointers names for aCC (HP) compiler.
+ (cp_print_class_method): Print message for HP/aCC case.
+ (cp_print_class_member): Add comments.
+ (cp_print_value): Adjust address computations for virtual base
+ classes. add new parameter 'offset'. Find correct offset for
+ base class in HP/aCC case. Change call to cp_print_value_fields
+ to have extra par.
+ (cp_print_value_fields): Do not print also if the only field is
+ the vtable pointer. Print out vtable ptr, for HP/aCC compiled
+ case. do not print leading '=' in case of anonymous union, or
+ struct. add new parameter 'offset'. Do not print the vtable
+ pointer as a member, in the HP aCC case. Changed calls to
+ val_print to have extra parameter.
+ (cp_print_hpacc_virtual_table_entries): New function. Print vtable
+ entries, in HP/aCC compiled case.
+ (cp_print_static_field): Change call to cp_print_value_fields, and
+ val_print.
+
+ * d30v-tdep.c (d30v_print_register): Add embedded_offset param
+ to val_print call.
+
+ * defs.h: Additional include files included when TUI is defined.
+ (gdb_file_isatty): New function decl.
+ (GDB_FILE): If TUI is defined, define a structure rather
+ than making this an alias for FILE.
+ (gdb_stdout, gdb_stderr): If TUI is defined, then define these
+ as pointers to variables of type GDB_FILE rather than making them
+ be aliases for stdout and stderr.
+ (TUIDO): Add definition conditionalized on definition
+ (or lack thereof) of TUI.
+ (command_class): Add two additional values.
+ (precision_type): New enum.
+ (gdb_fclose): Add decl.
+ (store_address): Change prototype to match function.
+ (tui_version, xdb_commands, dbx_commands): Add decls.
+ (gdb_file_deallocate): New function decl
+ (pa_do_strcat_registers_info): New function decl.
+ (streamtype): New enumerated type to distinguish between output to
+ a FILE and output to a buffer.
+ (tui_stream): New struct type, named GDB_FILE.
+ (gdb_stdout): Of type GDB_FILE, will pass this around gdb rather
+ than stdout.
+ (gdb_stderr): Of type GDB_FILE, will pass this around gdb rather
+ than stderr.
+ (fputs_unfiltered_hook): Change stream parameter from FILE to
+ GDB_FILE.
+ (flush_hook): Change stream parameter from FILE to GDB_FILE.
+ (gdb_fclose): Fix decl for gdb_fclose; parameter is now of
+ type GDB_FILE **.
+ (gdb_file_adjust_strbuf): New function decl. function lives
+ in utils.c.
+ (gdb_file_init_astring): New function decl. function lives
+ in utils.c.
+ (gdb_file_get_strbuf): New function decl. function lives in
+ utils.c.
+ (source_full_path_of): Declare.
+
+ * exec.c (_initialize_exec): Make definition of file command be
+ dependent upon dbx_commands not being set.
+ (exec_file_attach): New function.
+ (exec_file_command): Call it.
+ (exec_ops): Add new target vector fields.
+
+ * f-lang.h (f_print_type): Change FILE to GDB_FILE in decl.
+ (f_val_print): Ditto.
+ (f_val_print): Add parameter to the function decl.
+
+ * f-valprint.c (_initialize_f_valprint): If xdb_commands is set,
+ define lc command.
+ (f77_create_arrayprint_offset_tbl): Change FILE to GDB_FILE.
+ (f77_print_array): Ditto.
+ (f77_print_array_1): Ditto.
+ (f_val_print): Ditto.
+ (f_val_print): Add a parameter; this new parameter is currently
+ only non-zero when handling C++ expressions. In this file its
+ value is always 0. changed fflush to gdb_flush.
+
+ * gnu-nat.c: (init_gnu_ops): Add new target vector fields.
+ (gnu_create_inferior): Add param to fork_inferior call.
+
+ * hppa-tdep.c (after_prologue): If f is NULL, don't dereference
+ it. if no debug info, return zero telling caller that we need to
+ find the end of the prologue via the hard way (instruction
+ examination).
+ (find_unwind_entry): Avoid dereferencing a null
+ pointer.
+ (hppa_pid_to_exec_file): Deleted -- no longer used.
+ (hppa_prepare_to_proceeed): Add prototype.
+ (read_unwind_info): Purecov comments, bug fixes.
+ (find_unwind_entry): Purecov comments, bug fixes.
+ (find_stub_with_shl_get): Purecov comments.
+ (frame_chain): Additional parens.
+ (hppa_push_arguments): Changes to commented out version of routine.
+ (hppa_fix_call_dummy): Purecov comments, fix location of end.o.
+ (in_solib_call_trampoline): Purecov comments.
+ (in_solib_return_trampoline): Purecov comments.
+ (setup_d_pid_in_inferior): Fix location of end.o.
+ (initialize_hp_cxx_exception_support): Fix location of end.o.
+ (child_enable_exception_callback): Purecov comments.
+ (pa_do_strcat_registers_info): Has a new parameter, precision,
+ which is passed into the call to pa_strcat_fp_reg to indicate
+ whether to display the floating point registers using
+ single or double preceision.
+ (pa_strcat_registers): Introduce local variable, precision, and
+ pass it into call to pa_strcat_fp_reg.
+ (pa_strcat_fp_reg): Modified function. New parameter, precision,
+ used by function to decide whether to use single or double
+ precision. Also add the code to put a double precision value
+ into a buffer.
+ (pa_do_strcat_registers_info): New routine. called by
+ tui/tuiRegs.c:_tuiRegisterFormat to place a register name
+ and value into a string buffer. Interface may change in
+ future. Checking this in so that we have something
+ functional for HP.
+ (pa_strcat_registers): New routine, called by
+ pa_do_strcat_registers_info. Does same thing as
+ pa_print_registers except it takes a stream parameter.
+ This routine should disappear in future. Checking in
+ so that we have something functional to give HP
+ (pa_strcat_fp_reg): New routine, called by
+ pa_do_strcat_registers_info and pa_strvat_registers
+ to place a floating point register name and value into
+ a buffer. This interface may change in future.
+ Checking in so that we have something functional to give HP.
+ (pa_print_fp_reg): Change prototype to match def'n.
+ (pa_register_look_aside): Fix comment immediately before function.
+ Changes to better support stack unwinding, reading and writing
+ registers for HPUX. New includes ptrace.h, bfd.h, dl.h.
+ (internalize_unwinds): Initialize new fields in table.
+ (read_unwind_info): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type are
+ now ...->table[index].stub_unwind.stub_type.
+ (find_proc_framesize): Add a check for pc == 0.
+ (rp_saved): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type are
+ now ...->table[index].stub_unwind.stub_type.
+ (frameless_function_invocation): Stub_type becomes
+ stub_unwind.stub_type
+ (saved_pc_after_call): Stub_type becomes stub_unwind.stub_type
+ (hppa_frame_saved_pc): Stub_type becomes stub_unwind.stub_type
+ (frame_chain_valid): Stub_type becomes stub_unwind.stub_type
+ (hppa_call_dummy): Stub_type becomes stub_unwind.stub_type
+ (pa_print_fp_reg): Additional params to call val_print
+ (in_solib_call_trampoline): Stub_type becomes
+ stub_unwind.stub_type
+ (in_solib_return_trampoline): Stub_type becomes
+ stub_unwind.stub_typ
+ (skip_trampoline_code): Additional code to handle external
+ dyncalls. Also stub_type becomes stub_unwind.stub_type
+ (hppa_pid_to_exec_file): New funct. FOr HPUX 10.0 and beyond there
+ is an explicit ptrace request for getting the pathname associated
+ with a process id (pid).
+ (hppa_pid_to_exec_file): Remove unwanted param from call to
+ call_ptrace.
+ (args_for_find_stub): New structure.
+ (find_unwind_entry): Deal with null input pc value.
+ (rp_saved): Ditto.
+ For the import stub, return -24 always.
+ (hppa_frame_saved_pc): Save old pc value, to detect we are in a loop.
+ (init_extra_frame_info): Use TARGET_READ_FP.
+ (frame_chain): Include thread support.
+ If the caller's pc is zero, we lose and return, just like stack
+ bottom.
+ Disable warning about being unable to find unwind info.
+ (hppa_push_arguments): Rewrite.
+ (hppa_value_returned_from_stack): New function. Handles returning
+ a value larger than 64 bits, stored on the stack.
+ (find_stub_with_shl_get): New function. To look up symbols in shlibs.
+ (cover_find_stub_with_shl_get): New function. Cover routine for
+ find_stub_with_shl_get to pass to catch_errors.
+ (hppa_fix_call_dummy): Comment out old stub mechanism.
+ Rewrite using dyncall.
+ (target_read_fp): New function.
+ (pa_do_registers_info): Floating point registers start at FP4.
+ (pa_print_registers): Use FP4_REGNUM instead of 72.
+ (skip_trampoline_code): Do machine instruction matching for PA2.0.
+ (setup_d_pid_in_inferior): New function. Exception handling support.
+ (initialize_hp_cxx_exception_support): Ditto.
+ (child_enable_exception_callback): Ditto.
+ (child_get_current_exception_event): Ditto.
+
+ * hpux-thread.c (hpux_thread_ops): Add new target vector fields.
+
+ * infcmd.c: Include objfiles.h.
+ (attach_command): New local variable, exec_file, add code to
+ determine exec_file from pid if exec_file is not already known,
+ call new target operation, target_post_attach -- a no-op unless
+ on HPUXHPPA.
+ (detach_command): After detaching, do a SOLIB_RESTART.
+ (objfiles.h): Fix typo on include line.
+ (run_command): Only call SOLIB_RESTART if it's defined.
+ (detach_command): Ditto.
+ (run_command): If program has already been started, and decide
+ to restart it, the kill the target, flush the caches,
+ call init_wait_for_inferior. Also purge old solib objfiles.
+ (run_stack_dummy): Add calls to
+ disable_watchpoints_before_interactive_call_start and
+ enable_watchpoints_after_interactive_call_stops.
+ (finish_command): Alter code handling the evaluation and printing
+ of the target function's return value.
+ (attach_command): When given a pid, but no exec file, try to
+ determine the exec file from the process. If the process does not
+ record a full path name, try to qualify the filename against the
+ source path.
+ (_initialize_infcmd): Add some verbiage about how to use the
+ attach command.
+ (do_registers_info): Changed calls to val_print
+ made the symfile.h include preceed the
+ objfiles.h include. The other ordering caused a
+ compile problem (incompletely defined types).
+
+ * inftarg.c (child_post_attach): Fix decl, make static.
+ (proc_wait): Make globally visible.
+ (child_insert_fork_catchpoint, etc): Fix return type.
+ (child_detach_from_process): Declare.
+ (child_attach_to_process): Declare.
+ (child_stop): Make static to match decl.
+ (ptrace_him): Change prototype back to return int.
+ (ptrace_me): Remove debug output, pass NULL to fork_inferior if
+ not HPUX.
+ (proc_wait): function prototype and definition are enclosed by
+ proc_wait ifndef
+ (child_attach_to_process): New function, does most of the work
+ that child_attach used to do and some additional work to determine
+ whether gdb is already attached to the target how to react.
+ (child_attach): Altered. It's now a wrapper for
+ child_attach_to_process.
+ (child_require_attach): New function, called if should attach even
+ when gdb is already attached to target.
+ (child_detach_from_process): New function, does most of the work
+ that child_detach used to do and some additional work to determine
+ whether gdb is currently attached to the target.
+ (child_detach): Altered. It's now a wrapper for
+ child_detach_from_process.
+ (child_require_detach): New function, called if should try to
+ detach even when gdb is not attached to target.
+ (ptrace_him): Calls a new function,
+ target_acknowledge_forked_child. Currently,
+ target_acknowledge_forked_child, is only defined to do something
+ for HPUX.
+ (child_create_inferior): Changed call to fork_inferior.
+ (child_ops): Add to_require_attach and to_require_detach fields
+ to the child_ops target ops vector.
+ Some hacks for ttrace work:
+ (child_wait): Additional local variables, additional code in
+ while loop to check for process exited, process forked,
+ process vforked, process execd.
+ (child_thread_alive): John B. seems to think that the kill
+ call is inapproapriate for HPUX.
+ (child_attach_to_process): Using strtol rather than atoi.
+ no longer check for case where there is no known exec file.
+ (child_post_attach): New function, a default, a no-op.
+ (child_insert_fork_catchpoint): New function, a default, a no-op.
+ (child_remove_fork_catchpoint): New function, a default, a no-op.
+ (child_insert_vfork_catchpoint): New function, a default, a no-op.
+ (child_remove_vfork_catchpoint): New function, a default, a no-op.
+ (child_can_follow_vfork_prior_to_exec ):new function, a default,
+ a no-op.
+ (child_insert_exec_catchpoint): New function, a default, a no-op.
+ (child_remove_exec_catchpoint): New function, a default, a no-op.
+ (child_has_execd): New function, a default, returns 0.
+ (child_reported_exec_events_per_exec_call): New function, a
+ default, returns 1.
+ (child_has_exited): New function, a default.
+ (child_core_file_to_sym_file): New function, a default, returns NULL.
+ (child_ops): Initialize new target vector fields.
+
+ * jv-lang.h: (Java_val_print): Add embedded_offset param to func
+ decl.
+
+ * jv-valprint.c: Changing calls to val_print to accomodate new param.
+ (java_value_print): Add embedded_offset param to val_print call
+ (java_print_value_fields): Add embedded_offset param to val_print
+ call.
+ (java_val_print): Add embedded_offset param. alter call to
+ c_val_print to accomodate embedded_offset param.
+
+ * language.c (lang_bool_type): Return builtin_type_bool in c++
+ case.
+ (unk_lang_val_print): Add embedded_offset param to
+ prototype decl and definition.
+
+ * language.h (LA_VAL_PRINT macro, la_val_print function decl):
+ altered to accomodate the new parameter to the various print
+ functions.
+
+ * m2-lang.h (m2_val_print): Add a parameter to the function decl.
+
+ * m2-valprint.c (m2_val_print): Add a parameter.
+ This parameter is currently only used when evaluating C++
+ expressions. So, it is always 0 in this file.
+
+ * m3-nat.c (m3_create_inferior): Add param to fork_inferior call
+ (m3_pid_to_exec_file): New function
+ (m3_ops): Add new target vector fields.
+
+ * mac-nat.c (init_child_ops): Add new target vector fields.
+
+ * mips-tdep.c: Chnages to accomodate additional parameter
+ to val_print.
+ (mips_print_register): Alter calls to val_print
+
+ * monitor.c (monitor_write): Change stderr to gdb_stderr.
+ (monitor_remove_breakpoint): Ditto.
+ (init_base_monitor_ops): Add new target vector fields.
+
+ * ppc-bdm.c (init_bdm_ppc_ops): Add new target vector fields.
+
+ * printcmd.c (do_examine): When saving a value_ptr, remove it from
+ the list of value_ptr's to be freed automatically; when discarding
+ a previously saved value_ptr, free it.
+ (print_formatted): Update comments; add new comments.
+ (printf_command, print_insn): Purecov comments.
+ (_initialize_printcmd): Add assign as a command if dbx_commands is
+ set; create va as an alias for disassemble if xdb_commands is set.
+ (address_info): New cases LOC_INDIRECT and
+ LOC_THREAD_LOCAL_STATIC.
+ (display_command): If tui_version and exp starts with a '$', then
+ don't display it unless tui_vSetLayoutTo fails.
+ (disassemble_command): Add tuiDo calls.
+ (print_scalar_formatted): For integers that are long long, check
+ the print format and print out in binary octal, decimal, or
+ hex. Call the new print_*_chars functions in valprint.c
+ (print_frame_args): Altered calls to val_print, to reflect
+ additional parameter to val_print (case LOC_BASEREG_ARG).
+
+ * procfs.c: (Procfs_init_inferior): Return value is now a void.
+ (procfs_ops): Add new target vector fields.
+ (procfs_create_inferior): Fix call to fork_inferior -- need another
+ parameter.
+
+ * remote-adapt.c (adapt_open): Change stderr to gdb_stderr.
+ (adpat_insert_breakpoint): Ditto.
+ (init_adapt_ops): Add new target vector fields.
+
+ * remote-array.c (array_wait): Change fflush to gdb_flush and
+ stdout to gdb_stdout.
+ (init_array_ops): Add new target vector fields.
+
+ * remote-bug.c (bug_load): Change fflush to gdb_flush; stdout to
+ gdb_stdout.
+ (bug_wait): Change stderr to gdb_stderr.
+ (bug_insert_breakpoint): Ditto.
+ (init_bug_ops): Add new target vector fields.
+
+ * remote-e7000.c
+ (init_e7000_ops): Add new target vector fields.
+ * remote-eb.c (init_eb_ops): Ditto.
+ * remote-es.c (init_es1800_ops): Ditto.
+ (init_es1800_child_ops): Ditto.
+ * remote-es.c (init_es1800_ops): Ditto.
+ (init_es1800_child_ops): Ditto.
+ * remote-hms.c (init_hms_ops): Ditto.
+ * remote-hms.c (init_hms_ops): Ditto.
+ * remote-nindy.c (init_nindy_ops): Ditto.
+ * remote-nrom.c (init_nrom_ops): Ditto.
+ * remote-os9k.c (init_rombug_ops): Ditto.
+ * remote-rdp.c (init_remote_rdp_ops): Ditto.
+ * remote-sds.c (init_sds_ops): Ditto.
+ * remote-sim.c (init_gdbsim_ops): Ditto.
+ * remote-st.c (init_st2000_ops): Ditto.
+ * remote-udi.c (init_udi_ops): Ditto.
+ * remote-vx.c (init_vx_ops): Ditto.
+ (init_vx_run_ops): Ditto.
+ * remote-vx.c: (Init_vx_ops): Ditto.
+ (init_vx_run_ops): Ditto.
+
+ * remote-mips.c (mips_getstring): Change stderr to gdb_stderr.
+ (pmon_insert_breakpoint): Ditto.
+ (pmon_remove_breakpoint): Ditto.
+ (check_lsi_error): Ditto.
+ (common_breakpoint): Ditto.
+ (pmon_makeb64): Ditto.
+
+ * remote-mips.c (mips_xfer_memory): Change fflush to gdb_flush;
+ change stdout to gdb_stdout.
+
+ * remote-mm.c (mm_open): Change stderr to gdb_stderr.
+ (init_mm_ops): Add new target vector fields.
+ (mm_load): Fixed params in commented out call to symbol_file_add.
+
+ * remote-nindy.c (instream): Change decl to FILE.
+
+ * remote-udi.c (udi_load): Fixed params in call to symbol_file_add.
+
+ * remote-vx.c (vx_add_symbols): Fixed params in call to
+ symbol_file_add.
+
+ * remote.c (init_remote_ops): Cosmetic change to match expected
+ test output.
+
+ * rs6000-nat.c (add_vmap): Add params to call to allocate_objfile.
+
+ * scm-lang.h: Add parameter to scm_val_print function decl.
+
+ * scm-valprint.c (scm_scmval_print): Cast svalue to (int); new
+ parameter. This parameter is currently only used when evaluating
+ C++ expressions. So, it is always 0 in this file.
+ (c_val_print): Fixed prototype decl; it needed an embedded_offset
+ param.
+
+ * sol-thread.c (sol_core_ops): Add new target vector fields.
+ (sol_thread_ops): Ditto.
+
+ * somsolib.c (DLD_FLAGS_MAPPRIVATE): New macro.
+ Define bit of __dld_flags in HP-UX a.out files.
+ (DLD_FLAGS_HOOKVALID): Ditto.
+ (DLD_FLAGS_LISTVALID): Ditto.
+ (DLD_FLAGS_BOR_ENABLE): Ditto.
+ (som_solib_total_st_size): Cumulative size in bytes of the
+ symbol tables of all shared objects on the so_list_head list.
+ (som_solib_st_size_threshhold_exceeded): Threshold for adding symbols
+ for shlibs.
+ (som_solib_sizeof_symbol_table): New function. Computes size of
+ symbol table for a shlib.
+ (som_solib_load_symbols): New function. Load symbols from shlib.
+ (som_solib_add): Detect if __dld_list is not valid.
+ Record main program's symbol table size.
+ Load symbols if called from command line.
+ Keep threshold into account when loading shlib symbols.
+ (som_solib_create_inferior_hook): Use dld_flags macros.
+ (som_sharedlibrary_info_command): Let user know if symbols were
+ not loaded.
+ (som_solib_restart): Discard all the shlibs descriptors.
+ (_initialize_som_solib): Chenge help message for auto-solib-add
+ command.
+ Set threshold for symbol table to 50 megabytes.
+ (_initialize_som_solib): Add call to som_solib_restart.
+ (som_solib_restart): New function
+ (som_solib_in_dynamic_linker): New function
+ (som_solib_desire_dynamic_linker_symbols): New function
+ (som_solib_unloaded_library_pathname): New function
+ (som_solib_loaded_library_pathname): New function
+ (som_solib_library_pathname): New function
+ (som_solib_have_unload_event): New function
+ (som_solib_have_load_event): New function
+ (som_solib_create_catch_unload_hook): New function
+ (som_solib_create_catch_load_hook): New function
+ (som_solib_create_inferior_hook): Rewritten
+ dld_cache: New struct
+ addr_and_unwind_t: New struct
+ (find_unwind_entry) add prototype
+ Include assert.h, remove references to ASSERT macro,
+ add include of fcntl.h so that O_RDONLY is defined.
+ (som_solib_create_inferior_hook): Introduce new local
+ msymbol2 and change some msymbol's to msymbol2's -- was clobbering
+ msymbol, passing a NULL to lookup_minimal_symbol_solib_trampoline,
+ and ultimately core dumping with a SEGV.
+ (som_solib_mapped_entry): Additional comments for text_addr,
+ text_link_addr, text_end, and tsd_start_addr fields. Commenting
+ out 2 tsd fields, __data_start and __data_end.
+ (som_solib_add_solib_objfile): Add params to calls to symbol_file_add.
+ Add some code for distinguishing between a shared library and other
+ objfiles. This appears to be a prelude to thread local storage.
+ (som_solib_load_symbols): Changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ (som_solib_add): Change comment to correctly specify path
+ to end.o -- /opt/langtools/lib/end.o. changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ Removed several SOLIB_DEBUG ifdefs and the associated printfs.
+ Add code to find the start address for the object file's thread
+ local storage
+ (som_solib_create_inferior_hook): Fix warning messages use correct
+ path to end.o -- /opt/langtools/lib/end.o. Change control flow.
+ No longer user early returns from function is cases of error.
+ (reset_inferior_pid): New function
+ (som_solib_remove_inferior_hook): New function
+ (so_lib_thread_start_addr): New function. used for tsd.
+ (struct som_solib_mapped_entry): Add new field tsd_start_addr.
+ (struct so_list): Add new field solib_addr.
+ (som_solib_add_solib_objfile): New function.
+ (som_solib_load_symbols): Rewritten.
+ (som_solib_add): Make sure we don't load the symbols in if the
+ threshold was exceeded.
+ (som_solib_get_solib_by_pc): New function. Return the address of
+ handle of the shared library.
+ (som_solib_restart): Disable breakpoints at restart.
+
+ * sparcl-tdep.c (init_sparclite_ops): Add new target vector fields.
+
+ * target.c (cleanup_target): Changed casting of default functions
+ for to_has_forked, to_has_vforked, to_pid_to_exec_file to get rid
+ of warnings. Fixed PARAMS for to_has_syscall_event. Fixed the
+ return type on a few of the default function values.
+ (cleanup_target): Changes in the de_fault macro, both to
+ accomodate the new target_ops vector fields and to use
+ more accurate default functions.
+ (debug_to_open): Change stderr to gdb_stderr.
+ (debug_to_close): Ditto.
+ (debug_to_attach): Ditto.
+ (debug_to_post_attach): Ditto.
+ (debug_to_require_attach): Ditto.
+ (debug_to_detach): Ditto.
+ (debug_to_require_detach): Ditto.
+ (debug_to_resume): Ditto.
+ (debug_to_wait): Ditto.
+ (debug_to_post_wait): Ditto.
+ (debug_to_fetch_registers): Ditto.
+ (debug_to_store_registers): Ditto.
+ (debug_to_prepare_to_store): Ditto.
+ (debug_to_xfer_memory): Ditto.
+ (debug_to_files_info): Ditto.
+ (debug_to_insert_breakpoint): Ditto.
+ (debug_to_remove_breakpoint): Ditto.
+ (debug_to_terminal_init): Ditto.
+ (debug_to_terminal_inferior): Ditto.
+ (debug_to_terminal_ours_for_output): Ditto.
+ (debug_to_terminal_ours): Ditto.
+ (debug_to_terminal_info): Ditto.
+ (debug_to_kill): Ditto.
+ (debug_to_load): Ditto.
+ (debug_to_lookup_symbol): Ditto.
+ (debug_to_create_inferior): Ditto.
+ (debug_to_post_startup_inferior): Ditto.
+ (debug_to_acknowledge_created_inferior): Ditto.
+ (debug_to_clone_and_follow_inferior): Ditto.
+ (debug_to_post_follow_inferior_by_clone): Ditto.
+ (debug_to_insert_fork_catchpoint): Ditto.
+ (debug_to_remove_fork_catchpoint): Ditto.
+ (debug_to_insert_vfork_catchpoint): Ditto.
+ (debug_to_remove_vfork_catchpoint): Ditto.
+ (debug_to_has_forked): Ditto.
+ (debug_to_has_vforked): Ditto.
+ (debug_to_can_follow_vfork_prior_to_exec): Ditto.
+ (debug_to_post_follow_vfork): Ditto.
+ (debug_to_insert_exec_catchpoint): Ditto.
+ (debug_to_remove_exec_catchpoint): Ditto.
+ (debug_to_has_execd): Ditto.
+ (debug_to_reported_exec_events_per_exec_call): Ditto.
+ (debug_to_has_syscall_event): Ditto.
+ (debug_to_has_exited): Ditto.
+ (debug_to_mourn_inferior): Ditto.
+ (debug_to_can_run): Ditto.
+ (debug_to_notice_signals): Ditto.
+ (debug_to_thread_alive): Ditto.
+ (debug_to_stop): Ditto.
+ (debug_to_enable_exception_callback): Ditto.
+ (debug_to_get_current_exception_event): Ditto.
+ (debug_to_pid_to_exec_file): Ditto.
+ (debug_to_core_file_to_sym_file): Ditto.
+ (default_clone_and_follow_inferior): New function prototype
+ decl and function definition.
+ (dummy_target): Add new target_ops vector fields and their
+ initializations. More target_ops vector changes for HPUX new
+ fields.
+ (de_fault): Add new HPUX specific target_ops operations to the
+ de_fault macro
+ (INHERIT): Add new HPUX specific target_ops operations.
+ (debug_to_post_wait): New function.
+ (debug_to_post_startup_inferior): Ditto.
+ (debug_to_acknowledge_created_inferior): Ditto.
+ (debug_to_clone_and_follow_inferior): Ditto.
+ (debug_to_post_follow_inferior_by_clone): Ditto.
+ (debug_to_create_catch_fork_hook): Ditto.
+ (debug_to_create_catch_vfork_hook): Ditto.
+ (debug_to_has_forked): Ditto.
+ (debug_to_has_vforked): Ditto.
+ (debug_to_post_follow_vfork): Ditto.
+ (setup_target_debug): Initialize new target_ops vector fields.
+ (nosupport_runtime): New function, used in cleanup_target
+ (update_current_target): Add new new target_ops vector fields to
+ the INHERIT macro definition.
+ (generic_mourn_inferior): The call to breakpoint_init_inferior now
+ takes a parameter.
+ (normal_pid_to_str): Add a \0 to the end of buf.
+ (debug_to_has_syscall_event): New function.
+ (debug_to_enable_exception_callback): New function.
+ (debug_to_get_current_exception_event): New function.
+ (setup_target_debug): Initialize the 3 new target_ops vector fields
+ (struct signals): Fix message associated with SIGRETRACT.
+ (return_one): New function, used by the de_fault macro
+ (debug_to_post_attach): New function.
+ (debug_to_wait): Add new cases TARGET_WAITKIND_FORKED,
+ TARGET_WAITKIND_VFORKED, TARGET_WAITKIND_EXECD.
+ (debug_to_insert_fork_catchpoint): New function.
+ (debug_to_remove_fork_catchpoint): Ditto.
+ (debug_to_insert_vfork_catchpoint): Ditto.
+ (debug_to_remove_vfork_catchpoint): Ditto.
+ (debug_to_can_follow_vfork_prior_to_exec): Ditto.
+ (debug_to_insert_exec_catchpoint): Ditto.
+ (debug_to_remove_exec_catchpoint): Ditto.
+ (debug_to_core_file_to_sym_file): Ditto.
+ (setup_target_debug): Give new fields in current_target target_ops
+ vector values.
+
+ * target.h: Include symtab.h.
+ (target_waitkind): New enumerated values
+ TARGET_WAITKIND_SYSCALL_ENTRY, TARGET_WAITKIND_SYSCALL_RETURN,
+ TARGET_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED,
+ TARGET_WAITKIND_EXECD.
+ (target_waitstatus): Add a syscall_id field to structure.
+ (child_has_syscall_event): New decl.
+ (child_thread_alive): New decl.
+ (target_ops): Add 3 new fields: To_has_syscall_event,
+ to_enable_exception_callback, to_get_current_exception_event
+ (target_enable_exception_callback): New macro.
+ (target_has_syscall_event): New macro.
+ (target_get_current_exception_event): New macro.
+ (TARGET_DISABLE_HW_WATCHPOINTS): New macro.
+ (TARGET_ENABLE_HW_WATCHPOINTS): New macro.
+ (PC_REQUIRES_RUN_BEFORE_USE): New macro.
+ (target_tid_to_str): New macro.
+ (target_waitstatus): Additional fields in struct to keep track
+ of child pid and pathname to execd file.
+ (target_ops): Add in the new target_ops function pointer fields.
+ New macros to go along with new target_ops fields.
+ In target_waitstatus.value, change name of child_pid field to
+ related_pid.
+ (target_pid_or_tid_to_str): Define default macro.
+ Add missing #endif after PC_REQUIRES_RUN_BEFORE_USE definition
+ (ENSURE_VFORKING_PARENT_REMAINS_STOPPED): Define default macro.
+ (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK): Define default
+ macro.
+ There are new function decls for to_require_attach
+ and to_require_detach. There are also new macros,
+ target_require_attach and target_require_detach. There are
+ also new function decls for find_default_require_detach
+ and find_default_require_attach.
+ (target_ops): New fields to_post_wait, to_post_startup_inferior
+ to_acknowledge_created_inferior, to_clone_and_follow_inferior,
+ to_post_follow_inferior_by_clone, to_create_catch_fork_hook,
+ to_create_catch_vfork_hook, to_has_forked, to_has_vforked,
+ to_post_follow_vfork, to_pid_to_exec_file.
+ New function definitions child_pid_to_exec_file, child_post_wait,
+ child_post_startup_inferior, child_acknowledge_created_inferior,
+ child_clone_and_follow_inferior,
+ child_post_follow_inferior_by_clone, child_create_catch_fork_hook,
+ child_create_catch_vfork_hook, child_has_forked,
+ child_has_vforked, child_acknowledge_created_inferior,
+ child_post_follow_vfork.
+ New macros target_post_startup_inferior,
+ target_acknowledge_created_inferior,
+ target_clone_and_follow_inferior,
+ target_post_follow_inferior_by_clone,
+ target_create_catch_fork_hook, target_create_catch_vfork_hook,
+ target_pid_to_exec_file.
+ (find_default_clone_and_follow_inferior): New function prototype.
+
+
+ * v850ice.c (init_850ice_ops): Init new target vector fields.
+
+ * valprint.c (print_binary_chars): Print out long long as
+ a binary number.
+ (print_octal_chars): Print out long long as an octal number
+ (print_decimal_chars): Print out long long as a decimal number
+ (strcat_longest): Define it.
+ * valprint.c: Hp merge, 4/15/98 snapshot
+ Add parameter to val_print. This is used for
+ evaluating C++ expressions.
+
+ * value.h (VALUE_POINTED_TO_OFFSET): New macro.
+ Add field pointed_to_offset to value structure.
+ Add prototypes for new functions in valops.c.
+ (write_register_pid): Change prototype to match
+ function.
+ (val_print function decl): Additional parameter.
+ (VALUE_EMBEDDED_OFFSET): New macro.
+ (find_rt_vbase_offset): New function decl -- for C++ support.
+
+Wed Dec 23 15:03:42 1998 Per Bothner <bothner@cygnus.com>
+
+ * Makefile.in (READLINE_CFLAGS): Search $(READLINE_SRC)/.. rather
+ than $(READLINE_SRC) so #include <readline/readline.h> will work.
+ * top.c: #include <readline/history.h> instead of "history.h".
+ * tracepoint.c: Likewise.
+ * mac-xdep.c: Likewise.
+
+Wed Dec 23 12:32:00 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * defs.h (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT): Define using
+ TARGET_BYTE_ORDER and not target_byte_order.
+
+Tue Dec 22 10:51:33 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/i386/cygwin.mh (TERMCAP): define.
+ (from Chris Faylor, cgf@cygnus.com)
+
+ * top.c: specify directory name for including readline.h
+
+ * tracepoint.c: ditto.
+
+ * utils.c: ditto.
+
+Mon Dec 21 13:30:34 1998 Mark Alexander <marka@cygnus.com>
+
+ * value.c (value_virtual_fn_field): Handle the situation where
+ vtbl is a pointer to a structure instead of a pointer to an array.
+
+Mon Dec 21 10:38:11 1998 Andrew Cagney <cagney@chook>
+
+ * mips-tdep.c: (MIPS_DEFAULT_FPU_TYPE): Default to
+ MIPS_FPU_DOUBLE.
+
+1998-12-17 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * blockframe.c (get_frame_saved_regs): If the saved_regs_addr ptr
+ is null, ensure that saved registers are copied from the local
+ variable that was used to obtain them.
+
+Sat Dec 19 09:55:09 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * mips-tdep.c (mips32_heuristic_proc_desc): Clear temp_saved_regs
+ on restart. Fixes problem with backtracing through functions that
+ use virtual frame pointers.
+
+Fri Dec 18 14:23:34 1998 Andrew Cagney <cagney@chook>
+
+ * mips-tdep.c (mips_push_arguments): Don't left-shift small
+ structs being passed in a register when an O64 target.
+
+ * config/mips/tm-mips.h (enum mips_fpu_type, mips_fpu): Move to
+ mips-tdep.c.
+
+ * mips-tdep.c (mips_fpu_string): Delete variable.
+ (mips_fpu_type_auto): New variable.
+ (mips_fpu_type): Rename mips_fpu.
+ (_initialize_mips_tdep): Delete initialization of mips_fpu et.al.
+ Rewrite ``set mipsfpu'' command set.
+ (set_mipsfpu_command, show_mipsfpu_command,
+ set_mipsfpu_single_command, set_mipsfpu_double_command,
+ set_mipsfpu_none_command, set_mipsfpu_auto_command): New
+ functions, handle commands.
+ (mips_push_arguments, mips_push_dummy_frame, mips_pop_frame,
+ mips_extract_return_value): Update.
+
+Thu Dec 17 02:15:40 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * configure.tgt (gdb_target): Identify mips64*vr4100*-*-elf* as
+ vr4100.
+
+Thu Dec 17 01:34:36 1998 Andrew Cagney <cagney@chook>
+
+ * gdbtypes.c (build_gdbtypes): New function.
+ (_initialize_gdbtypes): Call.
+
+Wed Dec 16 11:47:00 1998 Andrew Cagney <cagney@chook>
+
+ * gdbarch.c (show_architecture): Use TARGET_ARCHITECTURE.
+ * gdbarch.h, gdbarch.c: Fix typo's. Use struct's in preference to
+ types.
+ * gdbarch.h, gdbarch.c (gdbarch_debug): Add ``set archdebug'' to
+ command set.
+
+Tue Dec 15 23:46:40 1998 Andrew Cagney <cagney@chook>
+
+ * config/mips/tm-*.h: (TARGET_BYTE_ORDER_DEFAULT,
+ TARGET_BYTE_ORDER_SELECTABLE_P): Replace TARGET_BYTE_ORDER and
+ TARGET_BYTE_ORDER_SELECTABLE.
+
+1998-12-14 Anthony Thompson (athompso@cambridge.arm.com)
+
+ * remote-rdp.c (rdp_init): Don't discard first character on reset.
+ (translate_open_mode): Define table.
+ (exec_swi): Handle SWI_Clock. SWI_Open now handles stdin/stdout.
+ SWI_Write returns number of bytes not written. SWI_Read does the
+ same. SWI_Seek should return success/failure flag. Fix SWI_Flen.
+
+1998-12-14 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * config/i386/nbsd.mh, config/m68k/nbsd.mh, config/ns32k/nbsd.mh
+ (XDEPFILES): Add ser-tcp.o.
+
+Mon Dec 14 14:46:13 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * monitor.c (monitor_expect, monitor_printf_noecho,
+ monitor_printf): Always compile EXTRA_RDEBUG code.
+ (RDEBUG): Ditto.
+
+ From Michael Meissner <meissner@cygnus.com>:
+ * ppcbug-rom.c (init_ppc_cmds): Cleanup formatting.
+
+1998-12-08 Michael Meissner <meissner@cygnus.com>
+
+ * monitor.c (monitor_printable_string): New function to convert a
+ string into a printable representation.
+ (monitor_error): Call error after converting string into printable
+ format.
+ (monitor_printf{,_noecho}): If EXTRA_RDEBUG is defined, convert
+ string into printable form before printing.
+ (monitor_expect): Ditto.
+ (monitor_read_memory{,_single}): Call monitor_error, not error.
+ (monitor_read_memory): Return immediately if length is 0.
+
+ * ppcbug-rom.c (init_ppc_cmds): Fill in dump_registers field,
+ which is now required.
+
+Mon Dec 14 11:01:39 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Consolidate the semi-dynamic target system
+ dependant GDB parameters.
+ (set_gdbarch_from_file): Combine set_architecture_from_file and
+ set_byte_order_from_file.
+ * top.c, defs.h, printcmd.c: Delete them from here.
+ * Makefile.in: Add gdbarch.[ch].
+ * exec.c (exec_file_command): Call set_gdbarch_from_file.
+
+Sun Dec 13 09:52:51 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (TARGET_PRINT_INSN_INFO, TARGET_PRINT_INSN): Define.
+ (TARGET_ARCHITECTURE, TARGET_ARCHITECTURE_AUTO): Define.
+ (TARGET_BYTE_ORDER_AUTO): Define.
+ (TARGET_BYTE_ORDER_SELECTABLE_P): Provide default. Replaces
+ TARGET_BYTE_ORDER_SELECTABLE. Handle compat issues.
+ (BITS_BIG_ENDIAN): Simplify.
+ (TARGET_FLOAT_FORMAT): Ditto.
+ (TARGET_DOUBLE_FORMAT):
+
+ * remote-e7000.c, sh-tdep.c, printcmd.c, remote-sim.c,
+ remote-rdi.c, sparc-tdep.c: Update.
+
+ * config/powerpc/tm-ppcle-eabi.h, config/rs6000/tm-rs6000.h,
+ config/powerpc/tm-ppc-eabi.h, config/mn10300/tm-mn10300.h:
+ Convert.
+
+Sat Dec 12 09:28:13 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * frame.h (struct frame_info): Add CORE_ADDR *saved_regs and
+ struct frame_extra_info *extra_info.
+ (frame_obstack_alloc, frame_saved_regs_zalloc): Prototype.
+ (SIZEOF_FRAME_SAVED_REGS): Provide default.
+ (FRAME_INIT_SAVED_REGS): Provide default.
+ (struct frame_saved_regs): Deprecate.
+ (EXTRA_FRAME_INFO): Deprecate.
+
+ * blockframe.c (frame_obstack_alloc, frame_saved_regs_zalloc): New
+ function.
+ (generic_get_saved_register): Use FRAME_INIT_SAVED_REGS and
+ frame->saved_regs.
+ (frame_cache_obstack): Make static.
+ (get_frame_saved_regs): Deprecate. Copy the saved regs into the
+ frame buffer.
+
+ * stack.c (frame_info): Rewrite using frame->saved_regs and
+ FRAME_INIT_SAVED_REGS.
+ * findvar.c (find_saved_register): Ditto.
+
+ * config/mn10300/tm-mn10300.h (EXTRA_FRAME_INFO): Delete.
+ (FRAME_FIND_SAVED_REGS): Replace with FRAME_INIT_SAVED_REGS. No-op.
+ * mn10300-tdep.c: Update.
+ (analyze_dummy_frame): New function.
+ (struct frame_extra_info): Define.
+ (mn10300_init_extra_frame_info): Update.
+
+ * config/rs6000/tm-rs6000.h: (EXTRA_FRAME_INFO): Delete.
+ (FRAME_FIND_SAVED_REGS): Replace with FRAME_INIT_SAVED_REGS.
+ (FRAME_ARGS_ADDRESS): Replace with function.
+
+ * rs6000-tdep.c (frame_get_saved_regs): Rename from
+ frame_get_cache_fsr.
+ (rs6000_init_extra_frame_info): New function.
+ (rs6000_frame_init_saved_regs): Call frame_get_saved_regs.
+ (FUNCTION_START_OFFSET): Delete references, was ZERO.
+ (rs6000_frame_args_address): New function.
+ (frame_initial_stack_address): Update
+
+ * config/mips/tm-mips.h (EXTRA_FRAME_INFO): Remove saved_regs.
+ (FRAME_INIT_SAVED_REGS): Rename FRAME_FIND_SAVED_REGS, update.
+ * mips-tdep.c (mips_find_saved_regs, read_next_frame_reg,
+ init_extra_frame_info, mips_pop_frame): Update.
+ * config/alpha/tm-alpha.h (FRAME_INIT_SAVED_REGS,
+ EXTRA_FRAME_INFO), alpha-tdep.c (alpha_find_saved_regs,
+ alpha_pop_frame, init_extra_frame_info): Ditto.
+
+ * i960-tdep.c, m88k-tdep.c, h8300-tdep.c: Update.
+ * config/sparc/tm-sparc.h, config/a29k/tm-a29k.h: Define
+ FRAME_INIT_SAVED_REGS as no-op.
+
+ * z8k-tdep.c (z8k_init_frame_saved_regs): Rename
+ get_frame_saved_regs.
+ (examine_frame, z8k_skip_prologue): Update.
+ * config/z8k/tm-z8k.h (FRAME_INIT_SAVED_REGS): Define.
+
+1998-12-11 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * i386-stub.c (handle_exception): Add support for 'P' command.
+ (NUMREGS): New macro.
+
+Fri Dec 11 09:07:05 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * i386b-nat.c: Include "expression.h".
+
+ * symtab.h: Don't include "gnu-regex.h".
+
+ * solib.c (solib_add_common_symbols): Cast parameters passed to
+ make_cleanup to use the new make_cleanup_func typedef.
+
+ * inftarg.c: Include "wait.h" after, rather than before, <wait.h>.
+ "wait.h" was defining all WIF* macro's instead of filling in those
+ that <wait.h> missed.
+
+Fri Dec 11 09:52:04 1998 Andrew Cagney <cagney@chook>
+
+ * mipsm3-nat.c, hppah-nat.c, infptrace.c, i386gnu-nat.c,
+ hppab-nat.c, core-aout.c, arm-xdep.c, alpha-nat.c, altos-xdep.c,
+ pyr-xdep.c, remote-st.c, remote-os9k.c, tahoe-tdep.c, pyr-tdep.c,
+ vax-tdep.c: Replace reg_name with REGISTER_NAME.
+
+Thu Dec 10 15:19:40 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Jim Blandy <jimb@cygnus.com>,
+ Edith Epstein <eepstein@cygnus.com>, Elena Zannoni
+ <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David
+ Taylor <taylor@cygnus.com>, as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * annotate.c (annotate_catchpoint): New function.
+
+ * annotate.h (annotate_catchpoint): declare it; add new includes
+ (symtab.h and gdbtypes.h).
+
+ * buildsym.h: add external var processing_hp_compilation.
+
+ * coff-solib.h:
+ (SOLIB_REMOVE_INFERIOR_HOOK): new macro. defined to 0.
+ functionality not implemented for coff.
+ (SOLIB_CREATE_CATCH_LOAD_HOOK): New macro; generate error msg for coff.
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK): ditto.
+ (SOLIB_HAVE_LOAD_EVENT): ditto.
+ (SOLIB_LOADED_LIBRARY_PATHNAME): ditto.
+ (SOLIB_HAVE_UNLOAD_EVENT): ditto.
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME): ditto.
+ (SOLIB_IN_DYNAMIC_LINKER): ditto.
+ (SOLIB_RESTART): ditto.
+
+ * complaints.h: add ifdef...endif pair at beginning and end of file.
+
+ * dstread.c (dst_symfile_read): the parameter to fileno
+ must be of type FILE *. So cast abfd->iostream in the
+ call to fileno must be cast as a FILE *, not a GDB_FILE *.
+ This will work because abfd->iostream is declared and
+ given a value in bdf and bfd will continue to use FILE
+ rather than GDB_FILE.
+
+ * dwarf2read.c (dwarf_bool_name): change parameter from bool
+ to mybool. sigh.
+
+ * expression.h: include symtab.h
+
+ * frame.h (print_only_stack_frame, show_stack_frame,
+ show_frame_info): add prototypes.
+
+ * gdbcmd.h (togglelist, stoplist): declare.
+
+ * gdbcore.h (read_memory_string): declare it.
+ (exec_file_attach): add prototype.
+
+ * inflow.c (terminal_is_ours): make non static.
+
+ * minsyms.c: minor spacing change.
+
+ * parser-defs.h (parse_nested_classes_for_hpacc): add prototype.
+ (find_template_name_end): add prototype.
+
+ * scm-lang.c (scm_unpack): cast svalue to (int).
+
+ * top.h: declare it.
+
+ * valprint.h (print_binary_chars): new prototype definition.
+ (print_octal_chars): new prototype definition.
+ (print_decimal_chars): new prototype definition.
+
+Thu Dec 10 07:14:56 1998 Andrew Cagney <cagney@chook>
+
+ * config/arm/tm-arm.h, arm-tdep.c: Replace REGISTER_NAMES with
+ REGISTER_NAME.
+ * mn10300-tdep.c, config/mn10300/tm-mn10300.h: Ditto.
+ * sh-tdep.c, config/sh/tm-sh.h: Ditto.
+
+ * defs.h (REGISTER_NAME): Provide default for old targets.
+ * defs.h, infcmd.c: Rename reg_names to gdb_register_names.
+
+ * tracepoint.c, target.c, parse.c, infcmd.c, remote-udi.c,
+ expprint.c, infcmd.c, printcmd.c, eval.c, stack.c, findvar.c,
+ remote-udi.c, config/alpha/tm-alpha.h, remote-sim.c, d30v-tdep.c,
+ config/mips/tm-mips.h, hppa-tdep.c: Use REGISTER_NAME.
+
+1998-12-08 James E Wilson <wilson@wilson-pc.cygnus.com>
+
+ * config/i960/mon960.mt (SIM_OBJS, SIM): Define.
+
+Tue Dec 8 16:49:24 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Add mentions of newly-added configurations.
+
+1998-12-08 Philippe De Muyter <phdm@macqel.be>
+
+ * config/xm-aix4.h (SIGWINCH_HANDLER): Function `aix_resize_window'
+ must accept a signal number as parameter.
+ * config/rs6000/xm-rs6000.h (SIGWINCH_HANDLER): Ditto.
+ * utils.c (initialize_utils): Give a parameter to `SIGWINCH_HANDLER'.
+
+ * inferior.h (register_valid): Variable's type is `SIGNED char', not
+ `char'.
+ * findvar.c (register_valid): Ditto.
+
+ * defs.h (make_cleanup_func): Protect parameter list by `PARAMS'.
+ * gdbthread.h (unbind_target_thread_vector): Likewise.
+
+Tue Dec 8 15:09:44 1998 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ Merged in m68k-linux patch from Andreas Schwab
+
+ 1998-12-01 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * Makefile.in, configure.host, configure.tgt: Add support for
+ m68k-linux.
+ * config/m68k/linux.mh: New file.
+ * config/m68k/linux.mt: New file.
+ * config/m68k/nm-linux.h: New file.
+ * config/m68k/tm-linux.h: New file.
+ * config/m68k/xm-linux.h: New file.
+ * gdb/m68klinux-nat.c: New file.
+ * gdbserver/low-linux.c: Add support for m68k-linux.
+ * gdb/config/m68k/tm-m68k.h (NUM_FREGS): New macro.
+
+1998-12-07 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/i386/xm-cygwin.h: Remove REQUEST_QUIT definition.
+ * config/powerpc/xm-cygwin.h: Ditto.
+
+1998-12-07 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * rs6000-tdep.c (pop_frame): Correctly find the registers saved in
+ the stack frame. Their offset from the previous stack frame is in
+ fdata.gpr_offset and fdata.fpr_offset, not fdata.offset.
+ (gdb.base/return.exp)
+ * config/rs6000/tm-rs6000.h: Doc fixes.
+
+1998-12-03 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (monitor_read_memory): Zero out pattern buffers
+ before calling re_search.
+ (parse_register_dump): Ditto.
+
+Thu Dec 3 10:37:22 EST 1998 Zdenek Radouch (radouch@cygnus.com)
+
+ FR30 updates - still very preliminary.
+ * configure.tgt
+ * fr30-tdep.c
+ * config/fr30/tm-fr30.h
+
+Thu Dec 3 16:30:35 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ax-gdb.c: Include target.h.
+
+Tue Dec 3 10:59:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ax-gdb.c (_initialize_ax_gdb), i960-tdep.c (pop_frame),
+ monitor.c (flush_monitor_dcache, longlongendswap), remote-array.c
+ (hexword2ascii), w89k-rom.c (init_w89k_cmds), z8k-tdep.c
+ (init_frame_pc, extract_return_value): Make return type void.
+ * monitor.c (monitor_write_even_block): Make return type explicit.
+ (monotor_read_memory_block): Delete function.
+ * monitor.h: Update.
+ * remote.c (remote_get_threadlist, remote_update_threads),
+ remote-array.c (array_get_packet), remote-rdi.c (Fail): Always
+ return a value.
+ * m32r-tdep.c (m32r_fix_call_dummy): From Michael Snyder, void
+ function.
+ * jv-valprint.c (java_val_print): From Stu Grossman. Return 0 by
+ default.
+
+Wed Dec 2 15:11:38 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c: Move default definition of
+ TARGET_VIRTUAL_FRAME_POINTER from here to target.h.
+ * target.h: Add default definition of TARGET_VIRTUAL_FRAME_POINTER.
+ * ax-gdb.c (gen_frame_args_address, gen_frame_locals_address):
+ use TARGET_VIRTUAL_FRAME_POINTER to determine frame pointer.
+ (gen_trace_for_expr): new argument, address of tracepoint,
+ gets passed to new_agent_expr and added to struct agent_expr.
+ (is_nontrivial_conversion): call to new_agent_expr now requires
+ a dummy argument. (agent_command): use get_current_frame() to
+ get current PC scope; pass it to gen_trace_for_expr.
+ * ax-general.c (new_agent_expr): new argument, address of
+ tracepoint; store it in new field of struct agent_expr.
+ * ax.h (struct agent_expr): add new field for tracepoint address.
+ * ax-gdb.h: change prototypes to match above changes.
+
+ * m32r-tdep.c (decode_prologue): If no branch or push fp is found,
+ but there's a stack adjust, then use that as the end of prologue.
+ (m32r_skip_prologue): don't skip past the first line if there is
+ line info. (m32r_virtual_frame_pointer): new function.
+ (m32r_fix_call_dummy): no return value needed.
+
+Tue Dec 1 10:59:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ocd.c (remote_timeout), (BDM_BREAKPOINT), monitor.c (readchar),
+ remote.c: Cleanup closing of open comments.
+
+Mon Nov 30 16:04:03 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/fr30/tm-fr30.h (INNER_THAN): Add parameters.
+
+Mon Nov 30 11:18:48 1998 Andrew Cagney <cagney@chook>
+
+ * frame.h (FRAME_CHAIN_VALID): Default to
+ default_frame_chain_valid.
+ * blockframe.c (default_frame_chain_valid): New function.
+
+ * frame.h (FRAME_CHAIN_VALID_ALTERNATIVE): Delete references
+ * blockframe.c (alternate_frame_chain_valid): New function.
+ * config/mips/tm-mipsv4.h, config/m88k/tm-delta88v4.h,
+ config/m68k/tm-monitor.h, config/m68k/tm-m68kv4.h,
+ config/i386/tm-i386v4.h, config/i386/tm-i386nw.h,
+ config/h8300/tm-h8300.h: Update.
+
+ * blockframe.c (nonnull_frame_chain_valid): New function.
+ * config/m68k/tm-os68k.h, config/m68k/tm-vx68.h,
+ config/m68k/tm-apollo68b.h, config/i960/tm-vx960.h,
+ config/arc/tm-arc.h: Update FRAME_CHAIN_VALID.
+
+ * hppa-tdep.c (frame_chain_valid, hppa_frame_chain_valid),
+ remote-vx29k.c (get_fp_contents, vx29k_frame_chain_valid),
+ arm-tdep.c (frame_chain_valid, arm_frame_chain_valid): Rename
+ functions so that they are name space clean.
+ * config/pa/tm-hppa.h, config/a29k/tm-vx29k.h,
+ config/arm/tm-arm.h: Update FRAME_CHAIN_VALID.
+
+ * gould-tdep.c (gould_frame_chain_valid), d30v-tdep.c
+ (d30v_frame_chain_valid), d10v-tdep.c (d10v_frame_chain_valid):
+ New functions.
+ * config/gould/tm-np1.h, config/gould/tm-pn.h,
+ config/d30v/tm-d30v.h, config/d10v/tm-d10v.h: Update
+ FRAME_CHAIN_VALID.
+
+Sun Nov 29 11:18:37 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * z8k-tdep.c (z8k_addr_bits_remove), w65-tdep.c
+ (w65_addr_bits_remove), h8500-tdep.c (h8500_addr_bits_remove),
+ m88k-tdep.c (m88k_addr_bits_remove): Function to clean up an
+ address.
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/m88k/tm-m88k.h,
+ config/h8500/tm-h8500.h: Define ADDR_BITS_REMOVE to call targets
+ corresponding function.
+ * z8k-tdep.c (saved_pc_after_call): Update.
+
+Sat Nov 28 12:24:31 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h,
+ config/v850/tm-v850.h, config/tahoe/tm-tahoe.h,
+ config/sparc/tm-sparc.h, config/sh/tm-sh.h,
+ config/rs6000/tm-rs6000.h, config/pyr/tm-pyr.h,
+ config/pa/tm-hppa.h, config/ns32k/tm-umax.h,
+ config/ns32k/tm-merlin.h, config/none/tm-none.h,
+ config/mn10300/tm-mn10300.h, config/mn10200/tm-mn10200.h,
+ config/mips/tm-mips.h, config/m88k/tm-m88k.h,
+ config/m68k/tm-m68k.h, config/m32r/tm-m32r.h,
+ config/i960/tm-i960.h, config/i386/tm-i386.h,
+ config/h8500/tm-h8500.h, config/h8300/tm-h8300.h,
+ config/gould/tm-pn.h, config/gould/tm-np1.h, config/arm/tm-arm.h,
+ config/convex/tm-convex.h, config/d10v/tm-d10v.h,
+ config/alpha/tm-alpha.h, config/a29k/tm-a29k.h: Add parameters to
+ macro INNER_THAN.
+
+ * valops.c (push_word, value_push, call_function_by_hand),
+ breakpoint.c (bpstat_stop_status), blockframe.c
+ (generic_push_dummy_frame, generic_frame_chain_valid), inferior.h
+ (PC_IN_CALL_DUMMY), infrun.c (wait_for_inferior): Update use of
+ INNER_THAN.
+
+Fri Nov 27 11:00:25 1998 Andrew Cagney <cagney@chook>
+
+ * target.h (one_stepped): Move global from here.
+ * infrun.c (singlestep_breakpoints_inserted_p): To here. Rename.
+ Make static.
+ (wait_for_inferior): Update.
+ (resume): Update. Set variable after call to SOFTWARE_SINGLE_STEP.
+
+ * target.h (NO_SINGLE_STEP): Replace with SOFTWARE_SINGLE_STEP_P
+ and SOFTWARE_SINGLE_STEP.
+ * config/sparc/tm-sparc.h, config/rs6000/tm-rs6000.h,
+ config/arc/tm-arc.h: Update.
+ * rs6000-tdep.c (rs6000_software_single_step), sparc-tdep.c
+ (sparc_software_single_step), arc-tdep.c (arc_single_step): New
+ functions. Replace function single_step.
+
+ * config/mips/tm-mips.h (STEP_SKIPS_DELAY_P): Define.
+ * infrun.c (proceed): Cleanup.
+
+Thu Nov 26 11:19:15 1998 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/alpha/tm-alpha.h (ABOUT_TO_RETURN): Replace macro.
+ * alpha-tdep.c (alpha_about_to_return): With new function.
+ (heuristic_proc_start): Update.
+ * config/mips/tm-mips.h (ABOUT_TO_RETURN), mips-tdep.c
+ (heuristic_proc_start, mips_about_to_return): Ditto.
+ * config/ns32k/tm-merlin.h (ABOUT_TO_RETURN),
+ config/ns32k/tm-umax.h (ABOUT_TO_RETURN), ns32k-tdep.c
+ (ns32k_about_to_return, ns32k_get_enter_addr): Ditto.
+
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h,
+ config/tahoe/tm-tahoe.h, config/sparc/tm-sparc.h,
+ config/sh/tm-sh.h, config/rs6000/tm-rs6000.h, config/pyr/tm-pyr.h,
+ config/pa/tm-hppa.h, config/m88k/tm-m88k.h, config/m68k/tm-m68k.h,
+ config/i960/tm-i960.h, config/i386/tm-i386.h,
+ config/h8500/tm-h8500.h, config/h8300/tm-h8300.h,
+ config/gould/tm-pn.h, config/gould/tm-np1.h,
+ config/convex/tm-convex.h, config/arm/tm-arm.h,
+ config/arc/tm-arc.h, config/a29k/tm-a29k.h: Delete macro
+ ABOUT_TO_RETURN.
+ * config/w65/tm-w65.h (RTL, RTS): Delete macros.
+ * h8500-tdep.c (about_to_return): Delete function.
+
+Thu Nov 26 11:19:15 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_breakpoint_from_pc): Change big_breakpoint
+ and little_breakpoint to char[] from char*.
+ * remote-array.c (array_insert_breakpoint): Change bp_addr to
+ CORE_ADDR type.
+
+Wed Nov 25 00:13:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * vx-share/xdr_ld.c (xdr_ldtabl): Cast second arg to char**
+ instead of char*.
+
+ * configure.tgt (v850): Only build v850ice when cygwin and gui.
+ * configure.in: Add parameter to --enable-build-warnings.
+ * configure: Re-build.
+
+ * c-exp.y (parse_number): Rewrite shift to pacify GCC.
+
+ * config/i960/tm-i960.h (BREAKPOINT): Delete definition - simply
+ wrong.
+
+ * monitor.c (compile_pattern): Make val const char*.
+ (monitor_wait_cleanup): Make old_timeout void*, pointing at
+ old_timeout.
+ (monitor_wait): Update.
+
+ * remote-udi.c, remote-sim.c, remote-e7000.c, hppa-tdep.c,
+ remote-mips.c, sparcl-tdep.c, xcoffread.c: Cast parameters passed
+ to make_cleanup to use the new make_cleanup_func typedef.
+
+ * alpha-tdep.c (MASK): Use LONGEST to avoid arithmetic overflow.
+
+ * config/a29k/tm-a29k.h (TRANSPARENT): Rename macro to
+ TRANSPARENT_FRAME. Avoid name-space clash.
+ * a29k-tdep.c (init_frame_info): Update.
+
+Wed Nov 25 20:37:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_breakpoint_from_pc): Change big_breakpoint
+ and little_breakpoint to char[] from char*.
+ * mem-break.c (memory_insert_breakpoint,
+ memory_remove_breakpoint): Pass address of bplen.
+ * remote-array.c (array_insert_breakpoint): Change bp_addr to
+ CORE_ADDR type.
+
+Tue Nov 24 15:46:33 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/mn10300/tm-mn10300.h (TARGET_VIRTUAL_FRAME_POINTER):
+ new target macro.
+ * mn10300-tdep.c (mn10300_virtual_frame_pointer): new function.
+ * tracepoint.c (encode_actions): Use the new target macro to
+ determine the virtual frame pointer, for collecting locals/args.
+ (add_local_symbols, collect_symbol): add a register/offset pair of
+ arguments so that the virtual frame pointer can be passed in.
+
+1998-11-24 Felix Lee <flee@cygnus.com>
+
+ * procfs.c (procfs_wait): handle syscall events first.
+
+ * procfs.c (GDB_GREGSET_TYPE, GDB_FPREGSET_TYPE): new macros.
+ * config/sparc/xm-sun4sol2.h: use them.
+ * core-sol2.c: don't #undef gregset_t and fpregset_t.
+ * sol-thread.c: ditto.
+ * sparc-tdep.c: ditto.
+
+Tue Nov 24 14:13:10 1998 Andrew Cagney <cagney@chook>
+
+ * breakpoint.c (memory_breakpoint_size): Delete global.
+ (read_memory_nobpt): Determine real breakpoint address and size
+ using BREAKPOINT_FROM_PC.
+
+ * defs.h (breakpoint_from_pc_fn): BREAKPOINT_FROM_PC function
+ template.
+ * target.h, mem-break.c (memory_breakpoint_from_pc):
+ Rewrite. Always define. Return NULL when memory breakpoints are
+ not supported.
+ (memory_insert_breakpoint, memory_remove_breakpoint): Call
+ BREAKPOINT_FROM_PC.
+ * target.h (BREAKPOINT_FROM_PC): Provide default.
+ * gdbint.texinfo (BREAKPOINT_FROM_PC): Document.
+
+ * config/rs6000/tm-rs6000.h (BREAKPOINT): Delete macro.
+ (BREAKPOINT_FROM_PC): Define.
+ ({BIG,LITTLE}_BREAKPOINT): Move macros from here.
+ * rs6000-tdep.c: To here.
+ (rs6000_breakpoint_from_pc): New function.
+
+ * config/mn10300/tm-mn10300.h (BREAKPOINT): Delete macro.
+ (BREAKPOINT_FROM_PC): Define, call.
+ * mn10300-tdep.c (mn10300_breakpoint_from_pc): New function.
+
+ * config/mips/tm-mips.h ({BIG,LITTLE}_BREAKPOINT,
+ IDT_{BIG,LITTLE}_BREAKPOINT, PMON_{BIG,LITTLE}_BREAKPOINT,
+ MIPS16_{BIG,LITTLE}_BREAKPOINT): Move macros from here.
+ * mips-tdep.c: To here.
+
+ * config/arm/tm-arm.h ({BIG,LITTLE}_BREAKPOINT): Delete macros.
+ ({ARM,THUMB}_{BE,LE}_BREAKPOINT): Move macros from here.
+ * arm-tdep.c: To here.
+
+ * remote-array.c (memory_breakpoint_size): Delete variable.
+ (array_insert_breakpoint): Obtain breakpoint size using
+ BREAKPOINT_FROM_PC.
+ * remote-st.c (memory_breakpoint_size, st2000_insert_breakpoint):
+ Ditto.
+ * remote-os9k.c (memory_breakpoint_size,
+ rombug_insert_breakpoint): Ditto.
+ * remote-e7000.c (memory_breakpoint_size): Ditto.
+
+Mon Nov 23 11:38:40 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * symfile.c (deduce_language_from_filename): rewrite so as to
+ work from a table of filename extensions, modifiable by the user.
+ (filename_language_table): new data structure.
+ (set_ext_lang_command): new function for new command, "set
+ extension-language". (info_extension_language_command): new
+ function for new command "info extension-languages".
+ (add_filename_language, init_filename_language_table): new
+ support functions for the above.
+ * language.c (language_enum): new function. Support for above.
+
+Mon Nov 23 10:47:54 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * config/sh/tm-sh.h, config/mn10200/tm-mn10200.h,
+ config/m32r/tm-m32r.h, config/arm/tm-arm.h, config/i960/tm-i960.h,
+ config/gould/tm-np1.h, config/d10v/tm-d10v.h,
+ config/v850/tm-v850.h, config/pa/tm-hppa.h, config/a29k/tm-a29k.h,
+ config/mn10300/tm-mn10300.h, config/mips/tm-mips.h
+ (USE_STRUCT_CONVENTION): Cleanup, define macro as function.
+
+ * sh-tdep.c (sh_use_struct_convention), mn10200-tdep.c
+ (mn10200_use_struct_convention), i960-tdep.c
+ (i960_use_struct_convention), gould-tdep.c
+ (gould_use_struct_convention), d10v-tdep.c
+ (d10v_use_struct_convention), v850-tdep.c
+ (v850_use_struct_convention), hppa-tdep.c
+ (hpha_use_struct_convention), m32r-tdep.c
+ (m32r_use_struct_convention), arm-tdep.c
+ (arm_use_struct_convention), mn10300-tdep.c
+ (mn10300_use_struct_convention), a29k-tdep.c
+ (a29k_use_struct_convention), mips-tdep.c
+ (mips_use_struct_convention): New functions
+
+ * value.h, values.c (generic_use_struct_convention): New function,
+ replace macro.
+ * values.c (USE_STRUCT_CONVENTION): Macro defaults to function
+ generic_use_struct_convention.
+
+Sat Nov 21 17:15:40 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * breakpoint.c (bpstat_stop_status): Do not increment hit_count
+ of breakpoint if condition is not true.
+
+ * coffread.c (coff_symtab_read): Discard C_LABEL's that are not
+ function entry points, to avoid getting them in the stack dump
+ instead of the actual function.
+
+ * config/m68k/delta68.mh (NAT_FILE): Undo 1998-08-18 change;
+ without NAT_FILE definition, configure will assume that GDB cannot
+ run native.
+ * config/m68k/nm-delta68.h (KERNEL_U_SIZE): New macro.
+ * delta68-nat.c (kernel_u_size): New function.
+
+Fri Nov 20 10:13:03 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * buildsym.c (end_symtab): Cleanup PROCESS_LINENUMBER_HOOK.
+
+Thu Nov 19 15:21:04 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * rdi-share/host.h: if compiling under Cygwin, make sure new
+ preprocessor define is defined. Define it if not.
+ * rdi-share/hostchan.h: ditto
+ * rdi-share/aclocal.m4: regenerate
+ * rdi-share/configure: regenerate
+
+Thu Nov 19 14:43:44 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: switch back to checking __CYGWIN32__
+ * configure: regenerate
+
+Thu Nov 19 09:53:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * exec.c (exec_file_command): Cleanup. Replace #if
+ NEED_TEXT_START_END with if().
+ * config/pa/nm-hppah.h (NEED_TEXT_START_END): Redefine to be 1.
+ * config/convex/tm-convex.h (NEED_TEXT_START_END): Ditto.
+ * config/gould/tm-np1.h (NEED_TEXT_START_END): Ditto.
+ * config/a29k/tm-a29k.h (NEED_TEXT_START_END): Ditto.
+
+Thu Nov 19 13:06:22 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * main.c: Wait until more time has passed before calling
+ new cygwin_ funcs, revert back to the cygwin32_ ones for now.
+ * win32-nat.c: Ditto.
+
+Wed Nov 18 15:03:17 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * 29k-share/udi/udip2soc.c (UDIConnect): Replace sys_errlist with
+ strerror.
+
+Mon Nov 16 14:17:05 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * defs.h: if compiling under Cygwin, define __CYGWIN__ if
+ __CYGWIN32__ is defined and __CYGWIN__ isn't for backwards
+ compatibility.
+
+Fri Nov 13 00:15:08 1998 Geoffrey Noer <noer@cygnus.com>
+
+ Changes to account for name change from cygwin32 to cygwin and
+ clean up Win32-related ifdefs.
+
+ * configure.tgt: check for cygwin* instead of cygwin32.
+ New cygwin gdb_target variable loses the "32".
+ * configure.host: check for cygwin* instead of cygwin32.
+ New cygwin gdb_host variable loses the "32".
+ * configure.in: test __CYGWIN__ instead of __CYGWIN32__,
+ rename gdb_cv_os_cygwin32 variable to drop the "32". Call
+ AM_EXEEXT instead of AC_EXEEXT since that isn't in a released
+ autoconf yet.
+ * configure: regenerate.
+
+ * main.c: drop "32" from cygwin_ funcs, include sys/cygwin.h where
+ cygwin path conv protos live, instead of adding a proto here for
+ them here.
+ * {main.c, ser-tcp.c, ser-unix.c, top.c}: check __CYGWIN__
+ instead of __CYGWIN32__.
+ * source.c: thoughout, check _WIN32 instead of WIN32.
+
+ * config/i386/cygwin32.mh: delete.
+ * config/i386/cygwin.mh: new file, was cygwin32.mh.
+ * config/i386/cygwin32.mt: delete.
+ * config/i386/cygwin.mt: new file, was cygwin32.mt.
+ * config/i386/tm-cygwin32.h: delete.
+ * config/i386/tm-cygwin.h: new file, was tm-cygwin32.h.
+ * config/i386/xm-cygwin32.h: delete.
+ * config/i386/xm-cygwin.h: new file, was xm-cygwin32.h.
+ * config/i386/xm-windows.h: #include xm-cygwin.h now.
+ * config/powerpc/cygwin32.mh: delete.
+ * config/powerpc/cygwin.mh: new file, was cygwin32.mh.
+ * config/powerpc/cygwin32.mt: delete.
+ * config/powerpc/cygwin.mt: new file, was cygwin32.mt.
+ * config/powerpc/tm-cygwin32.h: delete.
+ * config/powerpc/tm-cygwin.h: new file, was tm-cygwin32.h.
+ * config/powerpc/xm-cygwin32.h: delete.
+ * config/powerpc/xm-cygwin.h: new file, was xm-cygwin32.h.
+
+ * rdi-share/aclocal.m4: regenerate with aclocal.
+ * rdi-share/configure: regenerate with autoconf.
+ * rdi-share/{host.h, hostchan.c, hostchan.h, serdrv.c, serpardr.c,
+ unixcomm.c}: check __CYGWIN__ instead of __CYGWIN32__.
+
+Thu Nov 12 17:19:43 1998 John Metzler <jmetzler@cygnus.com>
+
+ * remote.c (remote_get_threadinfo): Support for remote
+ multithread debugging.
+ (remote_get_threadlist): get a partial list of threads
+ (remote_threadlist_iterator): Step through all the threads
+ (init_remote_threadtests): Optional builtin unit test commands.
+
+ * thread.c (bind_target_thread_vector): Implementa a more dynamic
+ way of accessing target specific thread info functions than
+ FIND_NEW_THREADS.
+ (target_thread_info): Function to get extended thread information.
+
+ * gdbthread.h: Export internal data structures corresponding to
+ external detailed thread info response. This is more like a 'ps'
+ command than what might be expected of host based threads. This
+ is for embedded systems.
+
+Wed Nov 11 15:47:00 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c (proc_set_exec_trap): don't set PR_ASYNC or PR_FORK
+ in the child process for UnixWare (causes processes forked by
+ the debuggee to hang).
+
+Mon Nov 9 12:00:36 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config/fr30/fr30.mt: New file.
+ * config/fr30/tm-fr30.h: New file.
+
+1998-11-05 Jim Wilson <wilson@cygnus.com>
+
+ * remote-vx.c (net_read_registers, net_write_registers,
+ vx_xver_memory, vx_resume, vx_attach, vx_detach, vx_kill):
+ Change errno to errno_num.
+ * vx-share/xdr_ptrace.c (xdr_ptrace_return): Likewise.
+ * vx-share/xdr_ptrace.h (struct ptrace_return): Likewise.
+
+Thu Nov 5 08:41:33 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * top.c (gdb_readline): Allow CRLF line termination on systems
+ which define CRLF_SOURCE_FILES.
+ * win32-nat.c: 1) Add thread support, 2) fix ability to attach to
+ a running process, and 3) implement limited support for cygwin
+ signals.
+ (thread_rec): New function.
+ (child_add_thread): Ditto.
+ (child_init_thread_list): Ditto.
+ (child_delete_thread): Ditto.
+ (do_child_fetch_inferior_registers): Ditto.
+ (do_child_store_inferior_registers): Ditto.
+ (handle_output_debug_string): Ditto.
+ (child_fetch_inferior_registers): Use do_* function to perform
+ operation.
+ (child_store_inferior_registers): Ditto.
+ (child_continue): Ditto.
+ (child_thread_alive): Ditto.
+ (cygwin_pid_to_str): Ditto.
+ (handle_load_dll): Reorganize, add first attempt at reading
+ dll names from attached processes. Change info messages to provide
+ more information when dll is already loaded.
+ (handle_exception): Changes mandated by new thread-aware structures.
+ (child_wait): Track thread creation/destruction. Handle cygwin
+ signals.
+ (child_create_inferior): Ditto.
+ (child_resume): Ditto.
+ (child_kill_inferior): Ditto. Close child process handle to avoid a
+ handle leak.
+ (child_ops): Fill out child_ops fields that deal with threads.
+ * config/i386/tm-cygwin32.h: Declare function and macro needed
+ for converting a cygwin "pid" to a string.
+ * config/i386/xm-cygwin32.h: define HAVE_SIGSETMASK as 0 since
+ sigsetmask is not defined in cygwin.
+
+Thu Nov 5 08:38:18 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Remove obsolete PPC conditionals.
+
+Wed Nov 4 18:44:31 1998 Dave Brolley <brolley@cygnus.com>
+
+ * configure.tgt: Add fr30-*-elf*.
+
+1998-11-03 Jim Wilson <wilson@cygnus.com>
+
+ * c-exp.y (parse_number): Check TARGET_LONG_LONG_BIT when setting
+ high_bit to avoid undefined negative shift.
+
+Mon Nov 2 15:26:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: Check cygwin* instead of cygwin32*.
+ * configure: regenerate
+
+Thu Oct 29 10:04:20 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ [Support for trace debugging: registers that were not collected.]
+ * remote.c (remote_fetch_registers): accept 'xxxx' in the register
+ packet, with the meaning "register value is not available".
+ Set register_valid to -1, which will connote "no value available".
+ * findvar.c (read_relative_register_raw_bytes): return failure if
+ register_valid == -1. (value_of_register): return failure if
+ register_valid == -1. (read_var_value): return error if
+ value_of_register fails for a register variable.
+ (value_from_register): return failure if register_valid == -1.
+ * eval.c (evaluate_subexp_standard): return error if
+ value_of_register fails for a register used in an expression.
+ * infcmd.c (do_registers_info): display "value not available"
+ for registers for which register_valid == -1.
+
+ * tracepoint.c (set_raw_tracepoint): just save the filename as is
+ from the symbol table, rather than trying to prepend the dir name.
+ Also save the bfd section. (tracepoints_info): use the section
+ when looking up the function name.
+ * tracepoint.h: add section field to tracepoint struct.
+
+Wed Oct 28 08:01:38 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparcl-tdep.c (send_resp, sparclite_serial_start,
+ sparclite_serial_write): Use remote_timeout instead of hardcoded
+ two second timeout.
+ (download): Fix adjustment of a.out load addresses.
+
+Wed Oct 28 12:32:58 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (--enable-build-warnings): Finish rename from
+ --enable-warnings.
+ (enable-build-warnings): Add -Wpointer-arth, allow =* for
+ sim/common compatibility.
+ * configure: Re-generate.
+
+Wed Oct 21 08:44:30 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * 29k-share/udi/udip2soc.c: Replace sys_errlist with strerror().
+
+Thu Oct 22 09:56:55 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/rs6000/aix4.mh (NATDEPFILES): Move xcoffread.o from here.
+ * config/rs6000/aix4.mt (TDEPFILES): To here.
+
+Wed Oct 21 10:02:31 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * rdi-share/unixcomm.c: Provide definitions of SERPORT and PARPORT
+ on BSD hosts.
+
+1998-10-19 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (AM_EXEEXT): Use AC_EXEEXT instead.
+ * configure: Regenerated.
+
+Sat Oct 17 17:39:23 1998 Felix Lee <flee@cygnus.com>
+
+ * core-sol2.c: #include <sys/types.h>, for sol2.7 weirdness.
+
+Fri Oct 16 15:31:38 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c (decode_prologue): Return failure if we reach
+ the end of the function without finding the end of the prologue.
+
+1998-10-16 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * command.c copying.c copying.awk core-aout.c core-regset.c
+ corelow.c dcache.c i386-tdep.c i386v4-nat.c i387-tdep.c
+ infcmd.c infptrace.c infrun.c remote.c solib.c symfile.c
+ symmisc.c valarith.c: Add prototypes.
+
+ * defs.h: Add prototype for utils.c::do_run_cleanups.
+
+ * gdbtypes.c: Add prototypes.
+ (make_pointer_type): Add braces to remove nested if-else ambiguity.
+ (make_reference_type): Ditto.
+
+ * printcmd.c (printf_command): Initialize 'f' and 'string' at
+ function startup to suppress possibly-used-before-initialized warning.
+
+ * remote-utils.c: Add prototypes.
+ (sr_pollchar): Add braces to remove nested if-else ambiguity.
+
+ * ser-tcp.c: Add prototypes.
+ (wait_for): Add braces to remove nested if-else ambiguity.
+ (tcp_readchar): Ditto.
+
+ * ser-unix.c: Add prototypes.
+ (get_tty_state): Don't define errno here.
+ (hardwire_readchar): Only define 't' if we are compiling in a Cygwin
+ environment.
+
+ * symtab.c: Add prototypes.
+ (find_methods): Add braces to remove nested if-else ambiguity.
+ (search_symbols): Set 'i' to an initial value to suppress a
+ possibly-used-before-initialized warning.
+
+ * valops.c: Add prototypes.
+ (value_cast): Set 'eltype2' to an initial value to suppress a
+ possibly-used-before-initialized warning.
+ (value_of_variable): Add braces to remove nested if-else ambiguity.
+ (value_of_this): Ditto.
+
+ * valprint.c: Add prototypes.
+ (print_floating): Add braces to remove nested if-else ambiguity.
+
+Thu Oct 15 19:50:48 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * tm-sp64.h (SETUP_ARBITRARY_FRAME, FRAME_SPECIFICATION_DYADIC):
+ Remove, nevermore used.
+
+Thu Oct 15 16:55:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.c: Include "wait.h" after, rather than before, <wait.h>.
+ "wait.h" was defining all WIF* macro's instead of filling in those
+ that <wait.h> missed.
+
+1998-10-14 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * defs.h: Move _initialize_printcmd, _initialize_stack,
+ _initialize_blockframe out of here and in to their respective .c
+ files.
+ * blockframe.c: Move _initialize_blockframe prototype to here.
+ * printcmd.c: Move _initialize_printcmd prototype to here.
+ * stack.c: Move _initialize_stack prototype to here.
+
+ * source.c, symtab.h: Move _initialize_source prototype to the .c
+ file.
+ * values.c, value.h: Move _initialize_values prototype to the .c file.
+ * gdbthread.h, thread.c: Move _initialize_thread prototype to the .c
+ file.
+ * breakpoint.c, breakpoint.h: Move _initialize_breakpoint prototype
+ to the .c file.
+
+ * abug-rom.c alpha-nat.c alpha-tdep.c annotate.c ax-gdb.c bcache.c:
+ Standardize comments for the prototype section of these files.
+
+ * configure.in: Look in libc for wctype before looking for it in libc.
+
+Tue Oct 13 18:56:51 1998 Felix Lee <flee@cygnus.com>
+
+ * sol-thread.c (ps_pstop, etc): simple test for proc_service.h
+ version didn't work for sol2.6; pushed it to autoconf.
+ * configure.in (gdb_cv_proc_service_is_old): new test.
+ * acconfig.h (PROC_SERVICE_IS_OLD): new define.
+ * configure, config.in: regenerate.
+
+1998-10-13 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * blockframe.c (find_pc_sect_partial_function): Add braces to avoid
+ possible nested-if confusion.
+ * breakpoint.c (breakpoint_here_p): Ditto.
+ (breakpoint_inserted_here_p): Ditto.
+ (breakpoint_thread_match): Ditto.
+
+ * gnu-regex.c: Define _REGEX_RE_COMP only if it isn't already defined.
+ * gnu-regex.h: Define _REGEX_RE_COMP to pick up old compatability
+ prototypes.
+
+ * symtab.h: Add prototype for _initialize_source.
+ * value.h: Add prototype for _initialize_value.
+
+ * defs.h: Include sys/types.h or stddef.h to get size_t.
+ (make_cleanup): Add make_cleanup_func typedef and switch to using
+ a prototype for this function.
+ (mfree): Add prototypes for mmalloc, mrealloc, mfree if we aren't
+ using mmalloc.
+
+ * ax-gdb.c breakpoint.c coffread.c corelow.c dbxread.c
+ dwarf2read.c dwarfread.c elfread.c eval.c exec.c infcmd.c infrun.c
+ mipsread.c nlmread.c os9kread.c parse.c printcmd.c symfile.c
+ symmisc.c symtab.c thread.c top.c tracepoint.c typeprint.c
+ valops.c: Cast parameters passed to make_cleanup to use the new
+ make_cleanup_func typedef.
+
+Tue Oct 13 00:51:48 1998 Felix Lee <flee@cygnus.com>
+
+ * sol-thread.c (ps_pstop, etc): different solaris versions have
+ slightly different prototypes in proc_service.h; compensate.
+
+1998-10-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in (AWK): Unused; remove.
+ * configure.in: Remove unused autoconf checks for MINIX, memcpy,
+ poll, select, strings.h.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+
+1998-10-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Check for sys/debugreg.h, asm/debugreg.h.
+ * i386v-nat.c: Include asm/debugreg.h, sys/debugreg.h if it is not
+ present.
+
+Sun Oct 11 12:08:07 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Do not adjust the
+ address range of a compilation unit without children.
+
+ * mdebugread.c (parse_partial_symbols): Fix handling of stabs
+ continuations, use xmalloc and xrealloc.
+
+Fri Oct 9 18:14:43 1998 Mark Alexander <marka@cygnus.com>
+
+ * rs6000-tdep.c: Don't include tm.h twice.
+
+1998-10-08 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Remove calls to {pre,post}_add_symbol_hooks.
+ There should be sufficient information/hooks now to eliminate
+ this hack.
+
+ * exec.c (file_command): Add a new hook here to inform ui's
+ when the exec file has changed. Adding it here allows the
+ ui to be informed after symbol reading.
+
+ * gdbcore.h: Add declaration of file_changed_hook.
+
+Thu Oct 8 08:40:42 1998 Mark Alexander <marka@cygnus.com>
+
+ * rs6000-tdep.c (get_saved_register): Define only if
+ USE_GENERIC_DUMMY_FRAMES is defined.
+
+1998-10-06 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ Eliminate a few warnings from the compiler.
+ * breakpoint.h: Add prototype.
+ * breakpoint.c (do_enable_breakpoint): cast mem_cnt, i to (void).
+ * configure.in: Check if strdup declaration is necessary.
+ * configure: Regenerated.
+ * defs.h: Add prototypes.
+ * gdb_string.h: Only define strdup if necessary.
+ * gdbthread.h: Add prototypes.
+ * printcmd.c: Add prototyptes.
+ (disassemble_command): Remove unused variable 'section'.
+ * symtab.c: Add prototypes.
+ * symtab.h: Include gnu-regex.h, add prototype.
+ * thread.c: Add prototype.
+
+Mon Oct 5 19:44:39 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ From David Purves <purves@apogee.com>:
+ * stabsread.c (rs6000_builtin_type): Create a complex float instead
+ of an error.
+ (read_sun_floating_type): Similarly.
+ (read_range_type): Create a complex float if self_subrange is
+ true.
+
+Fri Oct 2 19:42:31 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * c-lang.c (emit_char c_printchar c_printstr), c-lang.h (c_printstr)
+ ch-lang.c (chill_printstr chill_printchar) c-valprint.c (c_val_print)
+ ch-valprint.c (chill_val_print) expprint.c (print_subexp) f-lang.c
+ (f_printstr f_printchar emit_char) f-valprint.c (f_val_print)
+ jv-lang.c (java_printchar java_emit_char) jv-valprint.c
+ (java_value_print java_val_print) language.c (unk_lang_printchar
+ unk_lang_printstr unk_lang_emit_char) language.h (struct
+ language_defn LA_PRINT_STRING LA_EMIT_CHAR) m2-lang.c (m2_printstr
+ m2_printchar emit_char) printcmd.c (print_formatted) scm-lang.c
+ (scm_printstr) valprint.c (val_print_string) value.h
+ (val_print_string): Add emit_char routines to language_desc struct
+ to allow finer control over language specific character output issues.
+ Add character width arg to printstr routines to allow handling of
+ wchar_t/Unicode strings. Fix c_printstr to handle wide characters.
+ Supply width argument to LA_PRINT_STRING and val_print_string.
+
+ * jv-lang.c (java_object_type dynamics_objfile java_link_class_type
+ get_dynamics_objfile get_java_object_type) jv-lang.h
+ (get_java_object_type): Make lots of things static.
+
+ * expprint.c (dump_prefix_expression dump_subexp): Move opcode name
+ printing to common routine (op_name).
+ * (dump_subexp): Add support for OP_SCOPE.
+
+Fri Oct 2 16:25:54 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host (i[3456]86-*-windows): Remove, no longer used.
+ * mswin: Remove directory, no longer used.
+
+Fri Oct 2 18:52:20 1998 Fernando Nasser <fnasser@cygnus.com>
+
+ * sol-thread.c: Fixed prototypes and calls to supply_fpregset and
+ fill_fpregset
+
+1998-10-02 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_interrupt): Rewrite to use remote_stop.
+ (remote_interrupt_twice): Remove. remote_stop now handles it.
+ (remote_stop): New function which handles interrupting the
+ remote target so that CLUI and GUI use the same core functions
+ to achieve the same goal.
+ (remote_wait): Change to handle remote_stop properly.
+ [interrupted_already]: New static global to help remote_stop.
+ [remote_ops, extended_remote_ops]: Add remote_stop for to_stop member.
+
+ * target.c: Rename static function "ignore" to "target_ignore" and
+ export it so that gdb can determin if some target vector member is
+ actually not defined. Replace all occurances of ignore.
+
+ * target.h: Export target_ignore.
+
+Fri Oct 2 03:51:48 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * target.c (target_xfer_memory): Handle requests with zero
+ transfer length right away.
+
+ * values.c (unpack_double): Set up code, length and signedness of
+ type _after_ checking for typedef.
+
+Thu Oct 1 15:39:27 EDT 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * breakpoint.c (bpstat_stop_status): Do not consider an
+ untripped watchpoint as a "hit".
+
+Thu Oct 1 20:52:39 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * exec.c (exec_file_command), convex-tdep.c (exec_file_command),
+ arm-xdep.c (exec_file_command), remote-rdp.c
+ (remote_rdp_create_inferior), remote-os9k.c
+ (rombug_create_inferior), remote-mm.c (mm_create_inferior),
+ remote-eb.c (eb_create_inferior), remote-es.c
+ (es1800_create_inferior), remote-rdi.c (arm_rdi_create_inferior),
+ remote-sim.c (gdbsim_create_inferior), remote-utils.c
+ (gr_create_inferior), remote-st.c (st2000_create_inferior),
+ remote-nindy.c (nindy_create_inferior), remote-hms.c
+ (hms_create_inferior), remote-e7000.c (e7000_create_inferior),
+ remote-array.c (array_create_inferior), remote-adapt.c
+ (adapt_create_inferior): Replace "exec" with "executable" in
+ messages.
+
+1998-09-25 Keith Seitz <keiths@cygnus.com>
+
+ * rdi-share/unixcomm.c: If using cygwin32, also use the SERPORT and
+ PARPORT defines for win32.
+ (Unix_MatchValidSerialDevice): For cygwin32, valid serial port names
+ start with "com", not "/dev/tty".
+ (Unix_OpenSerial): Do not use O_NONBLOCK on cygwin32.
+
+ * rdi-share/devsw.c (DevSW_Close): Free the device's state
+ (SwitcherState) so that the device may be reopened.
+
+ * remote-rdi.c (mywritec): Send all output through gdb's *_unfiltered
+ functions, ignoring non-ASCII chars, so that non-tty UI's can snarf
+ the output from fputs_hook.
+ (mywrite): Ditto.
+ (arm_rdi_open): Set inferior_pid.
+ (arm_rdi_detach): Pop the target off the target stack so that
+ users can attach and detach multiple times.
+ (arm_rdi_close): Close the opened device and reset inferior_pid, too.
+
+1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Change --enable-warnings to --enable-build-warnings.
+ * configure: Updated.
+
+1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (WARN_CFLAGS): Add -Wmissing-prototypes.
+ * configure: Regenerated.
+
+1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Add --enable-warnings.
+ Adjust whitespace of other --with and --enable options so that
+ configure --help lines up correctly.
+ * aclocal.m4: Ditto.
+ * Makefile.in (WARN_CFLAGS): Add. Set by configure.
+ * configure: Regenerated.
+
+Thu Sep 24 15:44:34 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-rdi.c: Fix formatting, remove some commented-out code.
+ (init_rdi_ops): Omit needless initializations.
+
+Wed Sep 23 18:21:03 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_address_masked): New function - mask address
+ according to REMOTE_ADDRESS_SIZE.
+ (remote_address_size): New global.
+ (hexnumstr): New function - convert arbitrary unsigned to hex.
+ (remote_write_bytes, remote_read_bytes): Use hexnumstr to
+ construct packet address. Mask address when necessary.
+ (_initialize_remote): Add "set remoteaddresssize" command, set
+ REMOTE_ADDRESS_SIZE variable.
+
+ * NEWS: Update.
+
+Wed Sep 23 18:08:52 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (_initialize_remote, packet_command, print_packet):
+ Pretty print code.
+
+Wed Sep 23 12:32:54 1998 <cagney@amy.cygnus.com>
+
+ * remote.c (packet_command): Test REMOTE_DESC to determine if
+ remote connection is open.
+
+Tue Sep 22 22:27:24 1998 Mark Alexander <marka@cygnus.com>
+
+ Patch from Dawn Perchik <dawn@cygnus.com>:
+ * rs6000-tdep.c (pop_frame): Handle generic dummy frames.
+ (push_arguments): Likewise.
+ (frame_saved_pc): Likewise.
+ (rs6000_frame_chain): Likewise.
+ (ppc_push_return_address): New function.
+ (get_saved_register): New function.
+ * config/powerpc/tm-ppc-eabi.h: Add generic dummy frame macros.
+
+Mon Sep 21 19:29:32 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * defs.h utils.c (fputc_filtered): New function. Does the obvious...
+ * jv-lang.c (java_printchar): Fix output of chars > 0xff. Fold
+ java_emit_char into java_printchar.
+ * language.h (PRINT_LITERAL_FORM): Reformat for readability.
+
+Mon Sep 21 14:38:03 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/arm/tm-arm.h (*_BREAKPOINT): Define both little endian
+ and big endian breakpoint patterns.
+
+ * arm-tdep.c (arm_break_point_from_pc): Insert either big endian
+ or little endian breakpoints depending upon target byte order.
+
+Fri Sep 18 07:53:08 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sol-thread.c (sol_thread_notice_signals): Use PIDGET when
+ passing pid down to procfs_notice_signals.
+
+Wed Sep 16 14:57:14 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * stabsread.c (resolve_symbol_reference): Return 1 on success, 0 on
+ failure.
+ * (define_symbol): Check return value from resolve_symbol_reference,
+ and drop symbol if it fails.
+
+Tue Sep 15 15:24:16 1998 Stu Grossman <grossman@fencer.cygnus.com>
+
+ * stabsread.c: Make all complaints static.
+ * Fix formatting of live range splitting code.
+ * (resolve_symbol_reference define_symbol resolve_live_range): Change
+ errors to complaints so that bad live range symbols won't abort the
+ entire symbol table. Handle errors by aborting just the current
+ symbol.
+ * (ref_init): Goes away. Folded into ref_add().
+ * (REF_MAP_SIZE): Put parens around parameter so that args like
+ `1 + 2' get handled correctly (yes, this was a real bug).
+ * (ref_add): Remove check for allocation failures. Not necessary
+ when using xrealloc(). Fix pointer arithmetic problem when clearing
+ memory. This and the previous patch prevent random SEGV's when there
+ are lots of live range symbols.
+
+Tue Sep 15 14:02:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * remote-rdi.c: Prevent multiple attempts to close the remote
+ connection.
+
+Tue Sep 15 10:24:17 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (examine_i_type): New static - type for instructions.
+ (do_examine): For "i" format, specify examine_i_type.
+ (do_examine): Call value_at_lazy instead of value_at so that
+ examine data is only fetched if it is used.
+ (x_command): If examine data was not fetched, set convenience
+ variable "__" to void.
+ (_initialize_printcmd): Initialize examine_i_type.
+
+Sun Sep 13 01:34:59 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c (find_pc_sect_partial_function): use bfd section
+ of msymbol for end of section comparison.
+
+Fri Sep 11 14:02:49 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c: clean up several unused variables and such.
+
+Fri Sep 11 12:38:34 EDT 1998 Zdenek Radouch (radouch@cygnus.com)
+
+ * arm-tdep.c (arm_push_arguments): fixed frame construction
+
+Thu Sep 10 20:51:23 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): guard against NULL.
+
+Wed Sep 9 19:37:36 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dbxread.c (IGNORE_SYMBOL): Remove definition, is never used.
+ * os9kread.c: Remove comment mentioning IGNORE_SYMBOL.
+
+Wed Sep 9 11:39:05 1998 Ron Unrau <runrau@cygnus.com>
+
+ * blockframe.c(find_pc_sect_partial_function): look for min syms in
+ the same section when trying to guess the end of a function.
+ * symfile.c(list_overlays_command): use print_address_numeric
+ * remote-sim.c: export simulator_command
+
+1998-09-08 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * breakpoint.c (bpstat_stop_status): Declare a bp match if the
+ current fp matches the bp->fp OR if the current fp is less than
+ the bp->fp if we're looking at a bp_step_resume breakpoint.
+
+Tue Sep 8 19:42:58 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * symtab.h (struct symtab): Remove EXTRA_SYMTAB_INFO hook,
+ not currently used.
+ * symfile.c (allocate_symtab): Deprecate use of
+ INIT_EXTRA_SYMTAB_INFO here.
+
+Fri Sep 4 15:33:25 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * README: Update remote debugging and testsuite info.
+
+Thu Sep 3 13:50:20 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h (FP_REGNUM): Redefine to be a
+ pseudo-register, not the same as a3.
+ (D2_REGNUM, D3_REGNUM, A2_REGNUM, A3_REGNUM): Define.
+ * mn10300-tdep.c (fix_frame_pointer): New function.
+ (set_movm_offsets): Use register number macros instead of
+ hard-coded constants.
+ (mn10300_analyze_prologue): Fix to handle redefinition of FP_REGNUM.
+ (mn10300_frame_chain): Fix to handle redefinition of FP_REGNUM;
+ use register number macros instead of hard-coded constants;
+ add missing parameter to call of mn10300_analyze_prologue.
+ (mn10300_frame_saved_pc): Use register number macros instead of
+ hard-coded constants.
+
+Tue Sep 1 12:04:57 EDT 1998 Zdenek Radouch (radouch@cygnus.com)
+
+ Changes to support/fix ARM/ELF port. Use MAKE_MSYMBOL_SPECIAL for
+ both ELF and COFF;
+ * elfread.c (elf_symtab_read): use ELF specific macro
+ * coffread.c (coff_symtab_read): use COFF_MAKE_MSYMBOL_SPECIAL()
+ * arm-tdep.c: separate COFF and ELF thumb processing
+ disable --mapcs-float processing
+ * dwarf2read.c: Disabled building of minimal symbols
+ * config/arm/tm-arm.h: new macros for distinguishing arm/thumb
+ * config/mips/tm-mips.h: use ELF specific macro
+
+Mon Aug 31 15:42:10 1998 Tom Tromey <tromey@cygnus.com>
+
+ * top.c (context_hook): Define.
+
+Tue Aug 25 13:21:58 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * ax-gdb.c (gen_var_ref): Allow for typedef types.
+ (gen_cast, gen_bitfield_ref, gen_expr, gen_deref): ditto.
+
+Mon Aug 24 18:29:03 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (collect_symbol): Handle register doubles that
+ are stored in two registers.
+
+Mon Aug 24 14:39:08 1998 Mark Alexander <marka@cygnus.com>
+
+ * sh-stub.c (undoSStep): Improve comment.
+ * sparc-tdep.c (sparc_extract_struct_value_address): Simplify to use
+ same method on both 32-bit and 64-bit machines.
+ * sparcl-tdep.c (sparclite_check_watch_resources): Simulator doesn't
+ support hardware breakpoints.
+ * config/sparc/tm-sparc.h (CALL_DUMMY): Improve comments.
+
+1998-08-20 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * rdi-share/Makefile.am (INCLUDES): Fix typeo.
+ * rdi-share/Makefile.in: Regenerated.
+
+1998-08-19 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * rdi-share/Makefile.am: Use just `INCLUDES' not `libname_INCLUDES'.
+ * rdi-share/Makefile.in: Regenerated.
+
+1998-08-19 Keith Seitz <keiths@cygnus.com>
+
+ * v850ice.c (v850ice_stop): New function to stop the ICE.
+ (v850ice_load) Pass filename to ICE DLL.
+ (ice_stepi, ice_nexti, ice_cont): Do not directly call the gdb
+ commands -- let the GUI do it so that it can retain control
+ of the display.
+
+Wed Aug 19 15:53:52 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * i386v4-nat.c: Include sys/reg.h if present.
+
+Wed Aug 19 03:07:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/alpha/alpha-linux (XDEPFILES): Build ser-tcp.
+
+1998-08-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * symtab.c (decode_line_1): For minimal symbol, SKIP_PROLOG to
+ make sure we stop after the frame pointer is locaded and backtrace
+ prints an accurate stack. Complements changes made on Mon Jul 27
+ 10:45:56 1998
+ (decode_line_2): Replaced the whitespace after ">" in a prompt
+ which has been taken away by changes made on Sun Jul 19 02:11:45
+ 1998
+
+1998-08-18 Keith Seitz <keiths@cygnus.com>
+
+ * stack.c: Define new hook, selected_frame_level_changed_hook, which
+ will be called whenever the selected stack level changes.
+ (select_frame): Call the selected_frame_level_changed_hook.
+
+Tue Aug 18 18:03:42 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Pass serial device name to
+ Adp_OpenDevice, and include it in error reports.
+
+1998-08-18 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Add more header files to AC_CHECK_HEADERS.
+ * configure: Regenerated.
+
+ * command.c: Include wait.h or sys/wait.h if present.
+ * inftarg.c: Ditto.
+ * core-aout.c: Include ptrace.h or sys/ptrace.h if present, based
+ on autoconf test.
+ * infptrace.c: Ditto.
+
+ * expprint.c: Include ctype.h for isprint prototype.
+ * i386aix-nat.c: Include sys/reg.h if autoconf says it is present.
+ * i386v-nat.c: Include ptrace.h, sys/ptrace.h, and sys/reg.h if
+ present, based on autoconf test.
+
+ * utils.c: Include curses.h and term.h if present.
+ (puts_debug): Change 'carriage_return' local variable to return_p
+ to avoid name clash.
+
+ * config/m68k/nm-apollo68b.h: Don't define PTRACE_IN_WRONG_PLACE,
+ determine it with autoconf.
+ * config/i386/nm-linux.h: Don't define NO_SYS_REG_H, determine it
+ with autoconf.
+ * config/i386/nm-i386sco.h: Don't define NO_PTRACE_H, determine it
+ with autoconf.
+ * config/i386/nm-i386v.h: Ditto.
+ * config/i386/nm-symmetry.h: Ditto.
+ * config/m88k/xm-cxux.h: Ditto.
+ * config/m88k/xm-dgux.h: Ditto.
+
+ * config/m68k/delta68.mh (NAT_FILE): nm-delta68.h no longer necessary.
+ * config/m68k/nm-delta68.h: Removed.
+
+Fri Aug 14 11:14:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (set_movm_offsets): Change second argument to
+ be the actual args to movm itself. All callers changed. Only set
+ fi->fsr.regs[x] if reg X is saved by the movm instruction.
+
+Fri Aug 14 04:18:23 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sol-thread.c (lwp_to_thread): Fix error message for failing
+ td_ta_map_lwp2thr call.
+ (ps_lgetLDT): Mask off upper bits in GS register when comparing
+ with selector.
+
+Wed Aug 12 16:30:01 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote-sim.c (simulator_command): Reset register cache after
+ simulator command.
+
+Wed Aug 12 09:00:26 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * expprint.c (dump_prefix/postfix_expression): Don't try to print
+ type expressions.
+
+Tue Aug 11 11:33:25 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * c-typeprint.c (c_print_type): Don't crash if varstring is null.
+ * expprint.c expression.h (dump_expression): Rename to
+ dump_prefix_expression.
+ * Print out the expression in normal form. Call print_longest
+ instead of trying to do it ourselves.
+ * (dump_postfix_expression): New function, prints out the expression
+ with indentation and better formatting and interpretation.
+ * parse.c (parse_exp_1): Put calls to dump expressions under ifdef
+ MAINTENANCE_CMDS and expressiondebug variable.
+
+Thu Aug 6 13:20:02 1998 Ron Unrau <runrau@cygnus.com>
+
+ * infrun.c (wait_for_inferior): use stop_func_name instead of
+ stop_func_start to decide that no debug info exists.
+
+Thu Jul 30 13:53:50 1998 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mask_address_p): New variable.
+ (mips_addr_bits_remove): Test mask_address_p to decide whether
+ to mask off the upper 32 bits of addresses.
+ (_initialize_mips_tdep): Add command to set mask_address_p.
+ (mips_call_dummy_address): New function.
+ * config/mips/tm-mips.h (CALL_DUMMY_ADDRESS): Redefine to
+ call mips_call_dummy_address.
+
+1998-07-29 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * symfile.c (add_symbol_file_command): Test for the from_tty
+ parameter and avoid query when not interactive.
+
+Mon Jul 27 16:11:42 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (remote_set_transparent_ranges): new function.
+ Send the start and end addresses of all loadable read-only
+ sections down to the trace target, so that it can treat them
+ as "transparent" (ie. don't care if they were collected or not).
+
+Mon Jul 27 15:38:07 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Undo previous fix
+ for setting frame address in optimized code; made unnecessary
+ by compiler fixes.
+
+Mon Jul 27 10:45:56 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * symtab.c (decode_line_1): For minimal symbol, call
+ find_pc_sect_line() to make sure the line number gets set
+ properly.
+ (print_symbol_info): Redeclare function void.
+
+1998-07-27 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/d10v/tm-d10v.h (REGISTER_NAMES): sp -> r15. The
+ stack pointer et al are synthesized from the SP_REGNUM (etc)
+ defines and should not be mentioned in REGISTER_NAMES.
+
+Fri Jul 24 14:41:19 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (encode_actions): Treat register names and simple
+ variable names as special cases and don't convert them to byte-
+ codes: these things can be collected far more efficiently
+ without invoking the bytecode interpreter.
+
+Fri Jul 24 13:32:46 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/i386/tm-i386.h (STORE_STRUCT_RETURN): Make it
+ work on hosts of any endianness.
+ * config/i386/tm-i386v.h: Ditto.
+
+Fri Jul 24 07:41:12 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10300-tdep.c (set_movm_offsets): New helper function
+ for mn10300_analyze_prologue.
+ (mn10300_analyze_prologue): Simplify by factoring out common code.
+ Fix bugs in setting frame address for optimized code.
+ Use read_memory_nobpt instead of target_read_memory.
+
+Thu Jul 23 17:01:17 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (collect_symbol): handle LOC_ARG case.
+
+Thu Jul 23 15:07:40 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * sparc-tdep.c (sparc_init_extra_frame_info): Recognize when we're
+ in a function prologue before the SAVE instruction.
+ (sparc_frame_saved_pc): Ditto.
+ * config/sparc/tm-sparc.h (EXTRA_FRAME_INFO): Add in_prologue flag.
+
+Thu Jul 23 14:58:09 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * i386-tdep.c (i386_get_frame_setup): Recognize function
+ prologues in code compiled with -fcheck-stack.
+
+Thu Jul 23 14:49:27 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-mips.c (remote_mips_insert_hw_breakpoint,
+ remote_mips_remove_hw_breakpoint): New functions for hardware
+ breakpoints on LSI targets.
+ * config/mips/tm-embed.h (target_remove_hw_breakpoint,
+ target_insert_hw_breakpoint): Define to call
+ remote_mips_insert_hw_breakpoint and remote_mips_remove_hw_breakpoint,
+ respectively.
+
+1998-07-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * source.c (print_source_lines): Print "No such file or directory"
+ just once.
+ (directory_command): same as above; resets if user issues dir.
+
+Sun Jul 19 02:11:45 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * symtab.c (decode_line_2): Instead of printing a prompt
+ and calling command_line_input() without a prompt, just
+ call it with the proper args. This makes the GUI work too.
+
+Fri Jul 17 9:26:50 1998 Ron Unrau <runrau@cygnus.com>
+
+ * blockframe.c (find_pc_sect_partial_function): allow for the possi-
+ bility of multiple symbols at the same address when finding high.
+ * breakpoint.c (resolve_sal_pc): if the function based section lookup
+ fails, try getting the section from the minimal symbol table.
+ * parse.c (write_exp_msymbol): use symbol_overlayed_address to get
+ the LMA of a minimal symbol if unmapped.
+ * symtab.c (find_line_symtab): change interface to return symtab
+ containing the best linetable found.
+ (decode_line_1): use find_line_symtab to set val.symtab. This should
+ improve support for source files with multiple symtabs.
+
+Wed Jul 15 11:51:33 1998 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Fix violations of GNU coding standard.
+
+ * breakpoint.c: Export delete_command.
+
+ * infcmd.c: Export continue_command, stepi_command, and nexti_command.
+
+ * Makefile.in: Add target for v850ice.o.
+
+ * configure.tgt: Add cygwin32 dependencies for v850 ice.
+
+Wed Jul 15 10:58:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * tracepoint.c (set_raw_tracepoint): Cope with symbols that do not
+ have an associated directory.
+
+Mon Jul 13 15:21:04 1998 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (puts_debug): Display non-printable characters in hex
+ instead of octal.
+
+Thu Jul 9 16:16:47 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (mn10300_generic_register_names): New variable.
+ (set_machine_hook): New function. Copy the appropriate register
+ names into reg_names.
+ (_initialize_mn10300_tdep): Set up to call set_machine_hook.
+ * tm-mn10300 (NUM_REGS): Bump to 32.
+ (REGISTER_NAMES): Updated accordingly.
+
+
+Tue Jul 7 7:40:13 1998 Ron Unrau <runrau@cygnus.com>
+
+ * symtab.c (find_pc_sect_psymbol): allow case where textlow is 0
+
+Thu Jul 2 15:57:58 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * breakpoint.c (resolve_sal_pc): Accept absence of innermost
+ Lexical block for breakpoint resolution.
+
+Thu Jul 2 10:22:00 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): Go ahead and read the .mdebug
+ section, but just don't add a 2nd minimal symbol if this is an .mdebug
+ section in an ELF file.
+
+1998-07-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * Makefile.in (ax-general.o): Depend on $(defs_h) too.
+ (ax_h): Bother to define this.
+
+Mon Jun 29 19:01:18 1998 Jim Wilson <wilson@cygnus.com>
+
+ * gnu-regex.c (re_comp): Add cast to char * before gettext calls.
+
+Sun Jun 28 11:35:48 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ Improve support for SunPro F77.
+ * dbxread.c (end_psymtab, process_one_symbol): Handle minimal
+ symbols with trailing underscore names.
+ * minsyms.c (find_stab_function_addr): Ditto.
+ * dbxread.c (process_one_symbol): Ignore N_ALIAS for now.
+ * partial-stab.h (case N_ALIAS): Ditto.
+ * stabsread.c (read_sun_builtin_type): Handle boolean types.
+
+Fri Jun 26 14:03:01 1998 Keith Seitz <keiths@cygnus.com>
+
+ * symtab.h (enum namespace): Add new namespaces FUNCTIONS_NAMESPACE,
+ TYPES_NAMESPACE, METHODS_NAMESPACE, and VARIABLES_NAMESPACE used by
+ new search_symbols.
+ Add prototype for search_symbols and free_search_symbols.
+
+ * symtab.c (list_symbols): Rewrite to use new search_symbols.
+ (file_matches): New helper function for search_symbols.
+ (free_search_symbols): New function which frees data returned from
+ search_symbols.
+ (print_symbol_info): New helper function which prints info about a
+ matched symbol to stdout. Extracted from old list_symbols.
+ (print_msymbol_info): New helper function which prints info about
+ a matched msymbol to stdout. Extracted from old list_symbols.
+ (symtab_symbol_info): Extracted from old list_symbols.
+ (variables_info): Use symtab_symbol_info.
+ (functions_info): Use symtab_symbol_info.
+ (types_info): Use symtab_symbol_info.
+ (rbreak_command): Rewrite to use new search_symbols.
+
+Thu Jun 25 22:38:32 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Use 128-bit stack frame
+ alignment for inferior calls.
+
+Wed Jun 24 23:17:12 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Fix calculation
+ of jsr target address.
+
+Tue Jun 23 19:37:46 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/mn10200/tm-mn10200.h (SAVED_PC_AFTER_CALL): Don't
+ zero upper byte of address.
+
+Tue Jun 23 17:32:26 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * rs6000-tdep.c (pop_dummy_frame): use memcpy.
+ (push_arguments): use memset.
+ (various other places): fix up indentation and long lines.
+
+Tue Jun 23 11:58:35 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in: s/lXext/-lXext/ for Jillian's change.
+
+Tue Jun 23 11:14:04 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * source.c (find_source_lines): fix indentation.
+
+ * config/mips/tm-irix5.h: Modify to work better on irix 6, by
+ making FP registers 8 bytes instead of 4.
+ REGISTER_BYTES: redefine. REGISTER_BYTE(): redefine.
+ REGISTER_VIRTUAL_TYPE: redefine. MIPS_LAST_ARG_REGNUM: redefine.
+ * irix5-nat.c (fetch_core_registers): read 8 bytes per FP register.
+ * mips-tdep.c (FP_REGISTER_DOUBLE): new macro to distinguish
+ targets with 8-byte FP registers (don't use TARGET_MIPS64).
+ (STACK_ARGSIZE): new macro, how much space is taken up on the
+ stack for each function argument (don't use TARGET_MIPS64).
+ (mips_push_arguments): modify logic to work better on Irix 6
+ (n32 ABI).
+
+Tue Jun 23 12:29:53 1998 Jillian Ye <jillian@cygnus.com>
+
+ * configure.in: Add -lXext to mips_extra_libs
+ * configure: Regenerated.
+
+Sun Jun 21 09:31:12 1998 Ron Unrau (runrau@cygnus.com)
+
+ * symtab.c (find_line_pc): assumed that a PC of 0 is illegal.
+ Changed to pass PC as arg and return 1 if valid (0 otherwise).
+ * symtab.h: Change prototype to match.
+ * symtab.c (find_line_pc_range): Use new interface.
+ * breakpoint.c (resolve_sal_pc): Ditto.
+
+Wed Jun 17 15:50:00 1998 Ron Unrau (runrau@cygnus.com)
+
+ * parse.c (target_map_name_to_register): Check target specific
+ aliases *first* so that it can over-ride architectural names
+
+Wed Jun 17 17:13:38 1998 Said Ziouani (saidz@park-street.cygnus.com)
+
+ * remote-sds.c (sds_start_remote): Fix printf call.
+
+Tue Jun 16 16:32:08 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Fix null pointer
+ crash when in "start".
+
+Tue Jun 16 14:38:40 1998 Ron Unrau (runrau@cygnus.com)
+
+ * dbxread.c: reset function_start_offset after a finishing N_FUN
+ is seen.
+ * remote-sim.c: allow TARGET_REDEFINE_DEFAULT_OPS to override
+ target vectors as needed.
+
+Sun Jun 14 08:46:25 1998 Ron Unrau (runrau@cygnus.com)
+
+ * partial-stab.h: 'F' and 'f' type N_FUN psymbols should pass
+ CUR_SYMBOL_VALUE as CORE_ADDR instead of long
+ * buildsym.[ch]: export pending_blocks list
+
+Sat Jun 13 13:02:32 1998 Dawn Perchik (dawn@cygnus.com)
+
+ * remote.c: Fix remote help string to match that of help.exp.
+
+Fri Jun 12 14:22:55 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in (LIBS): Add -lw to the list of libraries if needed.
+
+Thu Jun 11 15:05:10 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * btowc.c: Removed.
+ * configure.in: Don't see if we need to replace btowc().
+ * Makefile.in: Don't include LIBOBJS.
+ * configure: Regenerated.
+ * gnu-regex.c (regex_compile): Only support i18n [:foo:] if
+ we have btowc().
+
+Wed Jun 10 15:39:14 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * c-exp.y: Fix problems with parsing "'foo.bar'::func".
+ Some languages allow symbols with dots.
+
+ * gdbtypes.c (check_stub_method): Cosmetic. Use more descriptive
+ names for parameters.
+
+ * jv-exp.y: Parser now accepts primitive types.
+ * (parse_number): Use correct ifdef for scanf long double support.
+ * jv-lang.c (java_array_type): Initial cut at array support.
+
+ * language.c language.h (set_language): Now returns previous language.
+
+ * symtab.c (find_methods): Make static. Cosmetic changes, including
+ indentation, and adding descriptive comments. Move local variable
+ defs into the block they are used in.
+ * Don't call check_stub_method any more. Use gdb_mangle_name to
+ generate the full method name. find_method doesn't need all the other
+ goobldegook that check_stub_method does.
+ * (gdb_mangle_name): Use more descriptive names for parameters. Fix
+ comment.
+ * (lookup_partial_symbol lookup_block_symbol): Check for java to
+ ensure we can find mangled names.
+ * (decode_line_1): Move local variable defs into the block they are
+ used in. (Improves code readability.)
+
+Wed Jun 10 18:04:35 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gdbtypes.c (get_discrete_bounds): Assign unsigned type flag for
+ all-positive enum.
+ (create_set_type): Ditto for all-positive set values.
+ * values.c (unpack_field_as_long): Check for typedef in struct
+ field unpacking.
+
+Wed Jun 10 14:06:05 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in: Add some tests for gnu-regex.c's benefit.
+ See if btowc() function is provided in C library.
+ * configure, config.in: Regenerated.
+ * Makefile.in (CLIBS, CDEPS): Add @LIBOBJS@ to build btowc.c
+ if necessary.
+ * btowc.c: New file.
+
+ * gnu-regex.c: Reorder wchar.h and wctype.h includes for Solaris'
+ benefit.
+ Drop namespace preserving defines for now.
+
+Wed Jun 10 11:53:42 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gnu-regex.c: Include "gnu-regex.h", not "regex.h".
+
+Wed Jun 10 11:34:07 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gnu-regex.c, gnu-regex.h: Change LGPL license to GPL license
+ to stay consistent with the rest of GDB.
+
+Wed Jun 10 11:27:39 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gnu-regex.c, gnu-regex.h: Update to current FSF (glibc) versions.
+
+Wed Jun 10 10:58:18 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * printcmd.c (disassemble_command): move overlay mapping code
+ "up" into find_pc_partial_function.
+ * blockframe.c (find_pc_partial_function): adjust start address
+ and end address for overlays (mapped vs. unmapped addresses),
+ so that all callers of this function may benefit.
+ * m32r-tdep.c (m32r_skip_prologue): adjust indentation.
+
+Mon Jun 8 16:08:10 1998 Ron Unrau <runrau@cygnus.com>
+
+ * objfiles.c (add_to_objfile_sections): All targets to define
+ TARGET_KEEP_SECTION to permit them to retain bfd sections that
+ GDB would otherwise have discarded.
+
+Fri Jun 5 13:56:19 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * dbxread.c (read_dbx_symtab): Don't lower texthigh for last psymtab.
+
+Thu Jun 4 18:35:04 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (init_extended_remote_ops): Make extended_remote_ops
+ by copying from remote_ops, move it and init_remote_ops to
+ usual place at end of file, remove "void" from arg lists.
+
+Thu Jun 4 17:51:06 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_fix_call_dummy): Byte-swap the call dummy
+ on bi-endian machines.
+ (sparc_extract_return_value): Handle values smaller than int on
+ machines with little-endian data.
+ (sparc_target_architecture_hook): Set bi_endian flag.
+
+Thu Jun 4 12:14:48 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * printcmd.c (disassemble_command): Fix off-by-one error for
+ disassembling functions in unmapped overlay sections.
+
+Thu Jun 4 10:15:03 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c: merged.
+
+ - Jim Blandy <jimb@zwingli.cygnus.com>
+ (print_packet, remote_packet_command): New functions.
+ (_initialize_remote): Register the remote-packet command.
+ - David Taylor <taylor@texas.cygnus.com>
+ (_initialize_remote): remote-compare is now
+ compare-sections.
+ - Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+ (remote_compare_command): added warning, issued in case
+ of mismatch only.
+
+Thu Jun 4 08:25:38 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (remote_compare_command): New function, new command.
+ Compare object file binary image with corresponding memory on
+ remote target. Report differences.
+
+Tue Jun 2 19:05:04 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_target_architecture_hook): Set target
+ byte order only when it's selectable.
+
+Tue Jun 2 02:01:56 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_target_architecture_hook): New function to
+ set endianness based on machine type.
+ (_initialize_sparc_tdep): Initialize target_architecture_hook.
+ (sparc_print_register_hook): Print PSR and FPSR in fancy format
+ on 32-bit machines.
+ * config/sparc/tm-sparc.h (PRINT_REGISTER_HOOK): Redefine to
+ call sparc_print_register_hook instead of using inline code.
+ * config/sparc/tm-sp64.h (PRINT_REGISTER_HOOK): Remove.
+
+Thu May 28 17:19:14 1998 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Check for NULL from getenv on CYGWIN32.
+
+Thu May 28 09:41:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * monitor.c (monitor_vsprintf): Handle %%. Patch courtesy of
+ Felix Lee (flee@cygnus.com)
+
+Thu May 28 00:27:35 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * mips-tdep.c (mips_push_dummy_frame): Fix calculation of
+ PROC_REG_OFFSET and PROC_FREG_OFFSET.
+
+Mon Apr 27 14:37:49 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/v850/tm-v850.h (REGISTER_BYTE): FP_REGNUM and
+ FP_RAW_REGNUM use the same register location.
+
+ * v850-tdep.c (v850_scan_prologue): Use FP_RAW_REGNUM instead of
+ FP_REGNUM.
+ (v850_frame_chain): Ditto.
+
+ * config/v850/tm-v850.h (REGISTER_NAMES): Add "fp".
+ (NUM_REGS): Update.
+ (FP_REGNUM): Update.
+ (FP_RAW_REGNUM): Define.
+
+Wed May 27 14:22:31 1998 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Convert the path returned from getenv to a posix
+ path on cygwin32 hosts.
+
+Mon May 25 13:31:27 1998 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_open_1): If an error occurs starting the remote,
+ pop the target AND return.
+
+Sat May 23 02:23:09 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * dwarf2read.c (read_subroutine_type): Set TYPE_FLAG_PROTOTYPED
+ on C++ functions.
+ * valops.c (value_arg_coerce): Add new argument to indicate whether
+ the function has a prototype, handle integer and float promotions
+ accordingly.
+ (call_function_by_hand): Always call value_arg_coerce, pass down
+ prototype information.
+
+Fri May 22 10:56:36 1998 John Metzler <jmetzler@cygnus.com>
+
+ * remote.c (_initialize_remote): Typo extended__remote
+
+Thu May 21 13:14:25 1998 John Metzler <jmetzler@cygnus.com>
+
+ * gnu-nat.c (init_gnu_ops): Initialization of target ops by assignment.
+ (_initialize_gnu_nat): Call new init
+ * mac-nat.c (init_child_ops): Ditto.
+ (_initialize_mac_nat): Ditto.
+ * monitor.c (init_base_monitor_ops): Ditto.
+ (_initialize_remote_monitors): Ditto.
+ * ppc-bdm.c (init_bdm_ppc_ops): Ditto.
+ (_initialize_bdm_ppc): Ditto.
+ * remote-adapt.c (init_adapt_ops): Ditto.
+ (_initialize_remote_adapt): Ditto.
+ * remote-array.c (init_array_ops): Ditto.
+ (_initialize_array): Ditto.
+ * remote-bug (init_bug_ops): Ditto.
+ (_initialize_remote_bug): Ditto.
+ * remote-e7000.c (init_e7000_ops): Ditto.
+ (_initialize_remote_e7000): Ditto.
+ * remote-eb.c (init_eb_ops): Ditto.
+ (_initialize_remote_eb): Ditto.
+ * remote-es.c (init_es1800_ops): Ditto.
+ (init_es1800_child_ops): Ditto.
+ (_initialize_es1800): Ditto.
+ * remote-hms.c (init_hms_ops): Ditto.
+ (_initialize_remote_hms): Ditto.
+ * remote-mm.c (init_mm_ops): Ditto.
+ (_initialize_remote_mm): Ditto.
+ * remote-nindy.c (init_nindy_ops): Ditto.
+ (_initialize_nindy): Ditto.
+ * remote_nrom.c (init_nrom_ops): Ditto.
+ (_initialize_remote_nrom): Ditto.
+ * remote-os9k (init_rombug_ops): Ditto.
+ (_initialize_remote_os9k): Ditto.
+ * remote-rdi.c (init_rdi_ops): Ditto.
+ (_initialize_remote_rdi): Ditto.
+ * remote-rdp.c (init_remote_rdp_ops): Ditto.
+ (_initialize_remote_rdp): Ditto.
+ * remote-sds.c (init_sds_ops): Ditto.
+ (_initialize_remote_sds): Ditto.
+ * remote-sim.c (init_gdbsim_ops): Ditto.
+ (_initialize_remote_sim): Ditto.
+ * remote-st.c (init_st2000_ops): Ditto.
+ (_initialize_remote_st2000): Ditto.
+ * remote-udi.c (init_udi_ops): Ditto.
+ (_initialize_remote_udi): Ditto.
+ * remote-vx.c (init_vx_ops): Ditto.
+ (init_vx_run_ops): Ditto.
+ (_initialize_vx): Ditto.
+ * remote.c (init_remote_ops): Ditto.
+ (init_extended_remote_ops): Ditto.
+ (_initialize_remote): Ditto.
+ * sparcl-tdep.c (init_sparclite_ops): Ditto.
+ (_initialize_sparcl_tdep): Ditto.
+ * v850ice.c (init_850ice_ops): Ditto.
+ (_initialize_v850ice): Ditto.
+ * win32-nat.c (init_child_ops): Ditto.
+ (_initialize_inftarg): Ditto.
+
+1998-05-21 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (const_var_ref): Don't handle function names. I don't
+ want to implement all the "usual unary conversion" rules for
+ constants.
+ (gen_usual_unary): Turn "function" values into "pointer to
+ function" values, in accordance with ANSI.
+ (gen_deref): Don't do the usual unary conversions here. Let the
+ caller do it. Note that dereferencing a function pointer yields
+ a function designator, which we call an rvalue, not an lvalue.
+ (gen_address_of): Handle functions specially.
+ (gen_struct_ref): Perform the usual unary conversions before
+ calling gen_deref.
+ (gen_expr): In case for the prefix '*' operator, call
+ gen_usual_unary manually.
+
+Wed May 20 15:29:41 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips/tm-tx39.h (MIPS_DEFAULT_FPU_TYPE): Defined as MIPS_FPU_NONE.
+ * mips/tm-tx39l.h: Same.
+
+Wed May 20 10:12:11 1998 John Metzler <jmetzler@cygnus.com>
+
+ * m32r-tdep.c (decode_prologue): Handle frames compiled with -Os.
+ Split out as separate function called by skip prologue and scan
+ prologue. new formula handles optimization in which the prologue
+ is interleaved with the body of the function. Also recognizes new
+ variations of prologue encoding. Use of frame pointer is
+ essential to debugging, -fno-omit-frame-pointer
+ (m32r_skip_prologue): Call decode prologue, ignore line info
+ (m32r_scan_prologue): Call decode prologue, ignore line info.
+
+Tue May 19 17:23:54 1998 John Metzler <jmetzler@cygnus.com>
+
+ * w89k-rom.c (_initialize_w89k): Call new init function
+ (init_w89k_cmds): Convert to dynamic initialization of monitor_ops
+ data structure for forward compatability with additions to the
+ data structure.
+ * dbug-rom.c (_initialize_dbug_rom): ditto
+ (init_dbug_cmds): ditto
+ * m32r-rom.c (_initialize_m32r_rom): ditto
+ (init_m32r_cmds): ditto
+
+Tue May 19 14:54:11 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (memrange_cmp): use const void * args to avoid
+ ANSI compiler warnings.
+
+1998-05-19 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (gen_fetch, gen_var_ref, gen_deref, find_field,
+ gen_bitfield_ref, gen_expr): Call error, not abort.
+ * ax-general.c (read_const, generic_ext, ax_trace_quick,
+ ax_label, ax_const_d, ax_reg, ax_print): Same.
+
+ * tracepoint.c: Remove the $(...) syntax for memranges.
+ (validate_actionline, encode_actions, trace_dump_command): Remove
+ clauses for the $(...) syntax.
+ (parse_and_eval_memrange): Function deleted.
+ (_initialize_tracepoint): Update function description.
+
+ * ax-gdb.c (_initialize_ax_gdb): Make the "agent" command a
+ subcommand of "maintenance", as it should have been from the
+ beginning. #include "gdbcmd.h", to get the declaration for
+ maintenancelist.
+ * Makefile.in: Document that dependency.
+
+Tue May 19 12:00:58 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * tracepoint.c (get_tracepoint_by_number): new function, to access
+ traceframe_number for use of the GUI.
+
+ * tracepoint.h: added prototype for get_traceframe_number.
+
+Mon May 18 13:34:27 1998 Keith Seitz <keiths@cygnus.com>
+
+ * dbxread.c (process_one_symbol): If block addresses are relative to
+ function start addresses, reset function_start_address whenever a new
+ source file is seen.
+
+Mon May 18 13:04:27 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (get_tracepoint_by_number): make sure to advance
+ arg pointer even if we fail to parse a useful number. Otherwise,
+ since this function is called in a loop, it may loop forever!
+ Also change strtol call to allow arbitrary radix.
+ (map_args_over_tracepoints (and other places)): add QUIT; call
+ to loop, to allow breakout using control-C. Not all loops were
+ analyzed to make sure they could terminate cleanly, but even
+ terminating with a messed-up tracepoint list would be better
+ than not terminating at all!
+ (tdump_command): check to see if we're connected to a trace-
+ capable target (currently only "remote") before doing anything
+ else.
+
+Sat May 16 22:21:48 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/d30v/tm-d30v.h (INIT_FRAME_PC_FIRST): Fill in PC into
+ frame struct before extracting saved register offsets.
+
+Fri May 15 22:47:45 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (encode_actions): fix typo in printf format string.
+
+1998-05-15 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Implement a few more tracing operators: ^ | & ~ !
+ * ax-gdb.c (gen_integral_promotions, gen_logical_not,
+ gen_complement): New functions.
+ (gen_binop): New argument MAY_CARRY, indicating whether we need to
+ correct the upper bits of the value after performing the
+ operation. Callers changed.
+ (gen_expr): Handle BINOP_BITWISE_AND, BINOP_BITWISE_IOR, and
+ BINOP_BITWISE_XOR here as well, by calling gen_binop. Handle
+ UNOP_LOGICAL_NOT, UNOP_COMPLEMENT.
+
+ * ax-gdb.c (gen_conversion): Reworked to avoid some unnecessary
+ sign extension.
+
+ * ax-gdb.c (gen_usual_arithmetic): Renamed from gen_usual_binary,
+ to match the ANSI C standard better. Callers changed.
+
+ * ax-gdb.c (gen_traced_pop): Add prototyped declaration.
+
+Fri May 15 18:18:38 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (stringify_collections_list): return a collection
+ of strings rather than a single string.
+ (free_actions_list): new function.
+ (encode_actions): process collection of strings returned by
+ stringify_collections_list.
+
+1998-05-15 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (gen_traced_pop): New function.
+ (gen_expr): Call it for comma operator.
+ (gen_trace_for_expr): Call it, instead of writing it out.
+
+ Add facilities for sending arbitrary packets to the remote agent.
+ There are a bunch of improvements to make (make it generic; handle
+ 'O' replies properly), but I just want to get this onto the branch.
+ * remote.c (print_packet, remote_packet_command): New functions.
+ (_initialize_remote): Register the remote-packet command.
+
+Thu May 14 17:52:31 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * tracepoint.c: move actionline_type definition to tracepoint.h.
+ (validate_actionline): make non static.
+
+ * tracepoint.h: move actioline_type definition from tracepoint.c.
+ (validate_actionline) moved prototype from tracepoint.c.
+
+Thu May 14 11:49:18 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (validate_actionline): add additional error
+ checking, remove some dead code.
+ (encode_actions): additional cleanups.
+ (trace_find_command): remove some dead code.
+ (trace_find_pc_command): ditto.
+ (trace_find_tracepoint_command): ditto.
+ (trace_find_line_command): ditto.
+ (trace_find_range_command): ditto.
+ (trace_find_outside_command): ditto.
+
+Thu May 14 5:51:00 1998 Ron Unrau <runrau@cygnus.com>
+
+ * symtab.c (decode_line_1): set section for "break *<addr>"
+
+Wed May 13 20:58:02 1998 Mark Alexander <marka@cygnus.com>
+
+ * corefile.c (reopen_exec_file): Reopen the exec file if
+ it has changed.
+
+Wed May 13 15:22:02 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (fetch_instruction): New function.
+ (single_step, sparc_init_extra_frame_info, examine_prologue):
+ Use fetch_instruction instead of read_memory_integer
+ to ensure that instructions are always read as big-endian.
+
+Wed May 13 14:42:21 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add AC_FUNC_ALLOCA.
+ * defs.h: Check HAVE_ALLOCA_H rather than sparc. Add _AIX pragma
+ alloca.
+ * configure: Rebuild.
+ * Makefile.in (jv-lang.o, jv-typeprint.o, jv-valprint.o): New
+ targets.
+
+Wed May 13 11:19:08 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (trace_command): Remove old diagnostic code that was
+ preventing tracepoints from being defined with a full-path filename.
+
+Tue May 12 13:17:35 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * stabsread.c (read_one_struct_field): Check for typedef in type
+ tree before clearing bitfield information.
+
+1998-05-11 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (gen_binop): New function, based on gen_mul, to replace
+ gen_mul and gen_div, and handle `%' op as well. Correctly tests
+ type of arguments.
+ (gen_expr): Factor out common code in binary arithmetic operators.
+ Add support for `%'.
+ (gen_mul, gen_div): Removed.
+
+Thu May 7 14:49:38 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve
+ %o0-%o5 as 64-bit values; compensate for stack bias.
+ (USE_STRUCT_CONVENTION): We only pass pointers to structs
+ if they're larger than 32 bytes.
+ (REG_STRUCT_HAS_ADDR): Ditto.
+
+ * sparc-tdep.c (sparc_init_extra_frame_info): Use read_sp()
+ instead of read_register. If the target is a sparc64 and the frame
+ pointer is odd, compensate for the stack bias.
+ (get_saved_register): Use read_sp().
+ (DUMMY_STACK_REG_BUF_SIZE): Use FP_REGISTER_BYTES.
+ (sparc_push_dummy_frame): Use read_sp()/write_sp(). On sparc64,
+ save the PC, NPC, CCR, FSR, FPRS, Y and ASI registers.
+ (sparc_frame_find_saved_regs): Use read_sp(). Read the PC, NPC,
+ CCR, FSR, FPRS, Y and ASI registers from the frame, if it's a
+ dummy frame.
+ (sparc_pop_frame): Use write_sp(). If the target is a sparc64 and
+ the FP is odd, compensate for stack bias.
+ (sparc_store_return_value): Right-justify the return value before
+ writing it to %o0.
+ (sparc_fix_call_dummy): Don't NOP out part of the call dummy on
+ sparc64.
+ (sparc64_read_sp, sparc64_read_fp, sparc64_write_sp,
+ sparc64_write_fp, sp64_push_arguments,
+ sparc64_extract_return_value): New functions to support the
+ sparc64 ABI.
+
+ * dwarfread.c (handle_producer): Set processing_gcc_compilation to
+ the right version number.
+
+ * dwarf2read.c (read_file_scope): Assume we're processing
+ GCC2 output.
+
+Wed May 6 16:34:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c: Include gdb_stat.h.
+
+Mon May 4 18:34:01 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * ax-gdb.c (gen_mul): new function; (gen_div): new function;
+ (gen_expr): add support for * and / operators, call gen_mul and
+ gen_div as appropriate.
+
+Mon May 4 16:24:22 1998 Mark Alexander <marka@cygnus.com>
+
+ * defs.h (make_run_cleanup): Declare.
+ * solib.c (find_solib): Pass correct number of arguments to
+ make_run_cleanup.
+
+Mon May 4 07:08:25 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (trace_actions_command): actions command must set
+ step_count to zero (in case previous actions have set it but the
+ new set does not).
+
+Sat May 2 09:35:07 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * ocd.h: Add new flags, function codes, and processor types to
+ support new Wiggler capabilities.
+ * (ocd_write_bytes_size): New function to allow atomic writes of
+ memory in sizes larger than a byte.
+
+ * ser-unix.c (baudtab): Add 57600, 115200, 230400, and 460800 baud.
+
+Fri May 1 19:51:32 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * stabsread.c (read_one_struct_field): Do not override supplied
+ bitfield size for a range type value.
+
+ * gdbtypes.c (create_range_type): For a range with positive
+ lower limit, declare range type as unsigned.
+
+Fri May 1 10:58:34 1998 John Metzler <jmetzler@cygnus.com>
+
+ * monitor.c: Turn off debug
+
+Fri May 1 09:29:56 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * breakpoint.c (delete_command): Skip internal breakpoints when
+ all breakpoints are requested.
+
+ * stabsread.c (define_symbol): Record parameter types from Sunpro
+ function stabs in the TYPE_FIELDS of the function type.
+
+Thu Apr 30 15:59:54 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (config-check-targets, config-check-hosts): Removed.
+
+1998-04-30 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.in (maintainer-clean):
+ Don't get ahead of yourself and delete Makefile
+ before running `make'.
+ (local-maintainer-clean, do-maintainer-clean): New rules.
+
+Wed Apr 29 14:02:59 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * ax-gdb.c (gen_add): when adding a pointer and an int, use
+ the size of the pointer, not the int (typo) to decide how
+ to extend the result.
+
+Wed Apr 29 10:20:40 1998 John Metzler <jmetzler@cygnus.com>
+
+ * monitor.h: Defined additional hooks for dmpregs, configure_hooks
+ and wait_filter. These additions require that all ROM monitor
+ interfaces be recoded to initialize monitor ops using assignments
+ rather than static structure initialization. Added new bits to
+ flags MO_EXACT_DUMPADDR, MO_HAS_BLOCKWRITES.
+
+ * monitor.c (RDEBUG): Conditional tracing throughout the file.
+ (fromhex): Now recognized upper cse hex digits
+ (monitor_printf_noecho):
+ (monitor_readchar): Tracing interferes with input timing.
+ (monitor_open): Register different memory write functions with
+ dcache_init if MO_HAS_BLOCKWRITES.
+ (flush_monior_dcache): Added as an additional utilty.
+ (monitor-resume): Call continue hook if one has been supplied.
+ (monitor_wait_filter): New function Factored out of monitor wait
+ and used if alternate wait-filter has not been provided.
+ (monitor_wait): call alternate wait filter if provided. Call
+ monitor_dump_regs, a new function factored out from inline code.
+ (monitor_dump_block): A new function used as a utility when
+ monitors must dump several blocks of registers using different
+ commands.
+ (monitor_dump_regs): Call alternate function if provided. Uses new
+ hook in monitor.h.
+ (monitor_write_memory): Engage previouly added hook
+ MO_FILL_USES_ADDR.
+ (monitor_write_even_block): new function supports writing long
+ blocks of 4byte words.
+ (longlongendswap): new internal function
+ (monitor_write_memory_longlongs): new function writes large blocks
+ using command to enter a long long.
+ (monitor_write-memory_block): new Function figures out which block
+ mod to use.
+ (monitor_read_memory): Can now handle dump formats in which the bytes
+ preceeding the requested data is not printed.
+
+Tue Apr 28 19:41:33 1998 Tom Tromey <tromey@cygnus.com>
+
+ * tracepoint.c (memrange_cmp): Another typo fix; `memrbnge' ->
+ `memrange'.
+
+ * tracepoint.c (memrange_cmp): Fixed typo in function intro.
+
+Tue Apr 28 17:41:20 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * symfile.c (overlay_auto_command): Add forgotten parameter
+ definitions.
+ (overlay_manual_command, overlay_off_command): Likewise.
+ (overlay_load_command): Likewise.
+ * tracepoint.c (memrange_cmp): Parameters have type void *, not
+ struct memrange *.
+
+Tue Apr 28 11:08:25 1998 John Metzler <jmetzler@cygnus.com>
+
+ * rom68k-rom.c (_initialize_rom68k): Fix unresolved init_rom_68kcmds.
+
+Mon Apr 27 14:32:21 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/sparc/tm-sparc.h (CALL_DUMMY): Shorten it drastically,
+ make it work on the simulator.
+ (FIX_CALL_DUMMY): Convert to function call instead of inline code.
+ (sparc_fix_call_dummy): Declare.
+ * sparc-tdep.c (sparc_fix_call_dummy): New function, taken from
+ old FIX_CALL_DUMMY macro, with additional fixes for simulator.
+ (sparc_push_dummy_frame): Set registers differently on simulator
+ to prevent corrupted register window save areas.
+
+Mon Apr 27 13:46:40 1998 John Metzler <jmetzler@cygnus.com>
+
+ * rom68k-rom.c (_initialize_rom68k, init_rom68k_cmds):
+ Convert all static initializations of monitor ops structures to
+ executable initializations in order that additions to the data
+ structure definition can me made without repeating this editing
+ exercise.
+ * abug-rom.c (_initialize_abug_rom, init_abug-cmds): Ditto.
+ * cpu32bug-rom.c (_initialize_cpu32bug_rom, init_cpu32bug_cmds): Ditto.
+ * mon960-rom.c (initialize_mon960, init_mon960_cmds): Ditto.
+ * op50-rom.c (initialize_op50n, init_op50n_cmds): Ditto.
+ * ppcbug-rom.c (_initialize_ppcbug_rom, init_ppc_cmds): Ditto.
+ * sh3-rom.c (_initialize_sh3_rom, init_sh3_cmds): Ditto.
+ * sparclet-rom.c (_initialize_sparclet, init_sparclet_cmds): Ditto.
+ * remote-est.c (_initialize_est, init_est_cmds): Ditto.
+ * remote-hms.c ( _initialize_remote_hms, init_hms_cmds): Ditto.
+
+Mon Apr 27 10:43:04 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gdb_string.h (strdup): Don't specify arguments in prototype.
+
+Sun Apr 26 07:57:21 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * rs6000-nat.c (vmap_ldinfo): Issue warning instead of error if
+ fstat on ldinfo_fd fails. Use objfile->obfd instead of vp->bfd
+ to check for reference to the same file.
+
+ * target.c (target_read_string): Handle string transfers at the
+ end of a memory section gracefully.
+
+Fri Apr 24 17:18:56 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: enable EXEEXT setting
+
+Fri Apr 24 11:53:49 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (add_local_symbols): change type of type from
+ char to int so that type shows up as 'A' or 'L' not 0.
+
+Thu Apr 23 16:37:20 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * README: Minor changes for 4.17 release.
+
+Thu Apr 23 15:44:39 1998 Per Bothner <bothner@cygnus.com>
+
+ * symfile.c (deduce_language_from_filename): .class implies java.
+
+Thu Apr 23 12:52:21 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * configure.in (strerror): Check if function must be declared.
+ * acconfig.h (NEED_DECLARATION_STRERROR): New define slot.
+ * gdb_string.h (strerror): Function declaration issued if
+ NEED_DECLARATION_STRERROR.
+ * configure, config.in: Files regenerated.
+
+Thu Apr 23 12:27:43 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * symfile.c (simple_overlay_update_1): Do not prefix array address
+ by `&'.
+ * bcache.h (BCACHE_DATA_ALIGNMENT): Ditto.
+ * tracepoint.c (encode_actions): Ditto.
+ * language.c, complaints.c, utils.c (varargs.h): Do not include that
+ file here, it is already included indirectly by defs.h.
+ * dbxread.c (dbx_symfile_init, process_one_symbol): Cast xmalloc return
+ value to the appropriate pointer type.
+ * utils.c (floatformat_from_doublest): Ditto.
+ * tracepoint.c (read_actions, _initialize_tracepoint): Ditto.
+ (add_memrange): Likewise with xrealloc return value.
+ * stabsread.c (ref_add): Ditto.
+ * coffread.c (coff_symfile_init): Likewise for xmmalloc return value.
+ * elfread.c (elf_symfile_read): Ditto.
+ * os9kread.c (os9k_symfile_init): Ditto.
+
+Thu Apr 23 00:32:08 1998 Tom Tromey <tromey@cygnus.com>
+
+ * config.in: Rebuilt.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_STPCPY, HAVE_GETTEXT,
+ HAVE_LC_MESSAGES): Define.
+
+Wed Apr 22 15:38:56 1998 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Rebuilt.
+ * configure.in: Call CY_GNU_GETTEXT.
+ * Makefile.in (top_builddir): New macro.
+ (INTL): Define to @INTLLIBS@.
+ (INTL_DEPS): New macro.
+ (CDEPS): Reference INTL_DEPS, not INTL.
+
+Wed Apr 22 12:58:23 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Handle missing shared libraries during the examination of a core
+ dump gracefully.
+ * solib.c (find_solib): Use catch_errors around call to
+ solib_map_sections. Use warning instead of error if reading of
+ the shared library name fails.
+ (solib_map_sections): Change return and argument types to make
+ it callable from catch_errors.
+ (symbol_add_stub): Avoid GDB core dump if solib->abfd is NULL.
+ * irix5-nat.c, osfsolib.c (xfer_link_map_member, solib_map_sections,
+ symbol_add_stub): Ditto.
+
+Wed Apr 22 14:34:49 1998 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (INTL*): Add support to link in the intl library,
+ and to add -I options to its source and object directories.
+ (INTERNAL_CFLAGS): Ditto.
+ (C{LIBS,DEPS}): Ditto.
+
+Tue Apr 21 11:20:54 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-tdep.c (gdb_print_insn_mips): Disassemble MIPS instructions
+ with subtarget-specific `mach', rather than fixed default.
+ * config/mips/tm-mips.h (TM_PRINT_INSN_MACH): New macro, default
+ disassembly `mach'.
+
+Mon Apr 20 15:35:03 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * coffread.c (decode_base_type): Treat a long field with size greater
+ than TARGET_LONG_BIT as long long.
+ * values.c (value_from_longest): Print code value in error message.
+
+Mon Apr 20 15:32:21 1998 Mark Kettenis <kettenis@phys.uva.nl>
+
+ * gdb/gdb_string.h (strdup): Declare only if not defined as a
+ macro.
+
+Mon Apr 20 14:18:45 1998 J. Kean Johnston <jkj@sco.com>
+
+ * procfs.c: Added replacement macros for LWP stuff. Fixed support
+ for UnixWare / SVR4.2MP targets and any targets which use
+ multi-file /proc entries. Fixed support for hardware watchpoints.
+ * solib.c: SCO needs some of the same code as SunOS. Change
+ preprocessor conditionals.
+
+ * config/i386/i386sco5.mt: New file.
+ * config/i386/tm-i386sco5.h: New file.
+ * config/i386/i386sco5.mh (NATDEPFILES): add i386v-nat.o.
+ * config/i386/nm-i386v42mp.h
+ (TARGET_HAS_HARDWARE_WATCHPOINTS): define.
+ Add other macros for hardware assisted watchpoints.
+ * config/i386/nm-i386sco5.h: Correct attributions.
+ (TARGET_HAS_HARDWARE_WATCHPOINTS): define.
+ * config/i386/nm-linux.h (target_remote_watchpoint): Pass
+ 'type' through to i386_insert_watchpoint.
+
+Mon Apr 20 14:12:30 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Don't add signalled processes
+ as new threads.
+ * procfs.c (wait_fd): Note if LWP has exited.
+ (procfs_wait): use GETPID to get process ID.
+
+Sat Apr 18 15:21:04 1998 Stan Cox <scox@cygnus.com>
+
+ * configure.tgt: Added sparc86x support.
+
+Thu Apr 16 13:13:24 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * rdi-share/etherdrv.c (EthernetWrite): Use strerror to get
+ error string if in an ANSI C-ish environment.
+
+Wed Apr 15 18:59:48 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (SPARC_HAS_FPU): Define.
+ (sparc_extract_return_value): New function, required to handle
+ machines without floating point.
+ (sparc_store_return_value): Ditto.
+ * config/sparc/tm-sparc.h (EXTRACT_RETURN_VALUE): Call
+ sparc_extract_return_value instead of using inline code.
+ (sparc_extract_return_value): Declare.
+ (STORE_RETURN_VALUE): Call sparc_store_return_value instead
+ of using inline code.
+ (sparc_store_return_value): Declare.
+
+Wed Apr 15 12:19:42 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * solib.c (enable_break): Only call warning once
+ instead of three times.
+
+Tue Apr 14 16:52:59 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_extract_struct_value_address): Make it
+ work correctly on little-endian hosts.
+ (sparc_push_arguments): New function.
+ (gdb_print_insn_sparc): New function.
+ (_initialize_sparc_tdep): Make gdb_print_insn_sparc the default
+ disassembler, so that SPARClite-specific instructions will
+ be recognized.
+ * sparcl-tdep.c (readchar): Print debugging information.
+ (debug_serial_write): New function, a replacement for SERIAL_WRITE
+ that prints debugging information.
+ * config/sparc/tm-sparc.h (PUSH_ARGUMENTS): Define.
+ (sparc_push_arguments): Declare.
+
+Tue Apr 14 15:43:49 1998 John Metzler <jmetzler@cygnus.com>
+
+ * gdbcfgxref (xref_menu): Call new regex and wild card searches
+ Now you can type in a specific triple like mips64-vr4300-elf or
+ somthing like mips*.h
+ (triple_search, wildcardsearch): The new functions
+
+Mon Apr 13 16:28:07 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * utils.c (warning): added call to warning_hook
+
+ * source.c (find_source_lines): modified to call warning in case
+ of source vs. executable time stamp mismatch. Simplified object
+ file check. Initialized mtime to 0.
+
+ * defs.h: added warning_hook prototype
+
+ * top.c: added warning_hook prototype.
+
+Mon Apr 13 09:54:08 1998 Keith Seitz <keiths@andros.cygnus.com>
+
+ * config/sparc/tm-sun4os4.h (IS_STATIC_TRANSFORM_NAME): Add missing
+ definition.
+
+Fri Apr 10 22:36:28 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Update support for x86 Solaris 2.
+ * config/i386/tm-i386sol2.h, nm-i386sol2.h: New configuration
+ files for x86 Solaris 2.
+ * config/i386/i386sol2.mt, i386sol2.mh: Use them.
+ * config/sparc/tm-sun4sol2.h (PROCFS_GET_CARRY): New macro, extract
+ carry flag from a given regset.
+ (IS_STATIC_TRANSFORM_NAME): New macro, check if a symbol name
+ is a SunPro transformed name.
+ * i386-tdep.c (sunpro_static_transform_name): New function to
+ extract the source name from a SunPro transformed name.
+ * inferior.h (procfs_first_available, procfs_get_pid_fd):
+ Add prototypes.
+ * infrun.c (wait_for_inferior): Handle breakpoint hit in
+ signal handler without intervening stop in sigtramp.
+ * procfs.c (procfs_lwp_creation_handler): Use PROCFS_GET_CARRY
+ instead of direct access to the status register.
+ (procfs_get_pid_fd): New function, returns procfs fd for a given pid.
+ * sol-thread.c (ps_lgetLDT): New function, returns LDT for a given
+ lwpid.
+ (sol_find_new_threads): Handle failed libthread_db initialization
+ gracefully.
+ * stabsread.c (define_symbol): Use IS_STATIC_TRANSFORM_NAME
+ to check for a SunPro transformed symbol name.
+
+Fri Apr 10 10:35:35 1998 John Metzler <jmetzler@cygnus.com>
+
+ * utils.c (fmthex): A formatting function for hexdumps
+
+ * mips-tdep.c (unpack_mips16): Fixed instruction decoding, lots of
+ bit pattern interpretations. mips_fetch_instruction does not work
+ for 16 bit instructions. Some confusion remains about sign
+ extension in backward branches.
+ (mips32_relative_offset): Sign extension
+ (mips32_next_pc): Major debugging, bit pattern interpretation
+ (print_unpack): debugging printf
+ (fetch_mips_16): new funtion, key on PC low bit, not symbol table
+ (mips16_next_16): Initial major debugging of this function. Lots
+ of bit pattern mistakes.
+ (mips_next_pc): key on low bit of PC, not symbol table.
+ * symfile.c (generic_load): Added a download verification which
+ reads back the loaded code. Download chunk size is now a defined
+ macro. Fixed a bug in which downloading slips into loading one
+ byte at a time. Lower level functions in monitor.c can load long
+ sequences of bytes and make use of these fixups. Referencing
+ bfd-start_address directly was incorrectly getting zero for start.
+
+Thu Apr 9 19:20:32 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-tdep.c (do_fp_register_row): Use alloca rather than arrays
+ with dynamic size.
+
+Wed Apr 8 19:21:42 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * top.c (print_gdb_version): Print 1998 now.
+
+Wed Apr 8 16:57:22 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * source.c: Remove obsolete decl of strstr().
+
+Wed Apr 8 16:47:33 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * solib.c (solib_create_inferior_hook): Remove Ulrich Drepper's
+ patch of March 23 1998.
+ * breakpoint.c (breakpoint_re_set_one): Remove Ulrich Drepper's
+ patch of March 23 1998.
+
+Sat Apr 4 10:05:00 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): If this is an .mdebug
+ section in an ELF file, override a symbol's ECOFF section with its
+ ELF section. Also, fix stabs continuation where a stabs string
+ continues for more than one continuation.
+
+Mon Apr 6 09:17:48 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Specify dimention of valbuf
+ using MAX_REGISTER_RAW_SIZE.
+
+Sat Apr 4 10:05:00 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * infrun.c: Fix prototype of signals_info to match static funtion.
+
+Thu Apr 2 12:47:41 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * sol-thread.c (sol_thread_store_registers): Save & restore new
+ value of single updated register to prevent accidental clobbering.
+
+Wed Apr 1 22:01:09 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/sparc/tm-sparclite.h (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ * config/sparc/sparclite.mt: Link in the erc32 simulator.
+
+Wed Apr 1 16:30:49 1998 Ian Dall <Ian.Dall@dsto.defence.gov.au>
+
+ * ns32k-tdep.c (flip_bytes, ns32k_localcount,
+ ns32k_get_enter_addr, sign_extend): Restore functions mysteriously
+ deleted.
+
+ * ns32knbsd-nat.c: New (?) file to support fetching and storing
+ registers on NetBSD hosts.
+
+ * nbsd.mh (NATDEPFILES): put ns32knbsd-nat.o instead of
+ ns32k-nat.o
+
+ * ns32km3-nat.c (reg_offset): Get order of floating point
+ registers correct. Add extra 32382 register offsets.
+ (REG_ADDRESS): define to point at correct part of thread
+ state. Use calls to "warning" instead of "message".
+
+ * tm-nbsd.h, tm-ns32km3.h (REGISTER_NAMES, NUM_REGS,
+ REGISTER_BYTES, REGISTER_BYTE): redefine allowing for 32382
+ fpu registers.
+
+Wed Apr 1 13:43:07 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * NEWS: m68k-motorola-sysv host support added.
+ * coffread.c (coff_start_symtab): Accept the filename as an argument,
+ set it here. Callers updated.
+
+Wed Apr 1 23:13:23 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (REGISTER_VIRTUAL_TYPE): Handle 32 bit SR,
+ FSR and FIR registers.
+ (REGISTER_VIRTUAL_SIZE): Compute using REGISTER_VIRTUAL_TYPE.
+ (REGISTER_RAW_SIZE): Define using REGISTER_VIRTUAL_SIZE.
+
+ * config/mips/tm-mips64.h: Ditto.
+
+Tue Mar 31 21:30:39 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-tdep.c (gdb_print_insn_arm): Attach a fake Thumb symbol
+ vector to the info structure when disassembling thumb
+ instructions.
+
+ * coffread.c (coff_symtab_read, read_one_sym,
+ process_coff_symbol): Support Thumb symbol types.
+
+ * dbxread.c (process_one_symbol): Call SMASH_TEXT_ADDRESS (if it
+ is defined) for function symbols.
+
+Tue Mar 31 16:39:28 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (get_tracepoint_by_number): change warning to note.
+ (delete_trace_command): suppress y/n query if no tracepoints, or
+ if not from_tty. (trace_pass_command): reject junk at end of args.
+ (read_actions): an action list consisting only of "end" is discarded.
+ (validate_actionline (for collect command)): an argument beginning
+ with a dollar_sign but not recognized as a special argument is
+ parsed like any other expression -- if it isn't a register name,
+ it's rejected. Also reject an empty argument to while-stepping.
+ (trace_find_command): reject a negative frame number argument.
+ (_initialize_tracepoint): set $traceframe initially to -1.
+
+Mon Mar 30 16:42:12 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * rdi-share/Makefile.am, rdi-share/aclocal.m4,
+ rdi-share/configure: New files.
+ * rdi-share/configure.in: Rewritten to be an autoconf input file.
+ * rdi-share/Makefile.in, rdi-share/configure: Generated by
+ automake/autoconf.
+ * rdi-share/dbg_hif.h, etherdrv.c, hostchan.c: Use autoconf tests
+ to check environment.
+
+Sun Mar 29 15:17:16 1998 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c (trace_start_command): Set trace_running_p.
+ (trace_stop_command): Clear trace_running_p.
+
+Sat Mar 28 15:19:48 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Update for 4.17 release.
+
+Fri Mar 27 10:15:50 1998 David Taylor <taylor@tito.cygnus.com>
+
+ * tracepoint.c (parse_and_eval_memrange): Fix memory leaks.
+ (encode_actions): Use the new gen_trace_for_expr function
+ instead of expr_to_address_and_size; collect registers when
+ using expressions. (clear_collection_list): Fix memory leak.
+
+1998-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.h (gen_trace_for_expr): Add prototype.
+
+Thu Mar 26 17:24:23 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (validate_actionline): Fix memory leak.
+ (encode_actions): Fix memory leak.
+
+Thu Mar 26 16:16:55 1998 David Taylor <taylor@tito.cygnus.com>
+
+ * tracepoint.c (trace_mention): New function.
+ (trace_command): Call it.
+
+1998-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-general.c (ax_reqs): New function.
+ * ax.h (enum agent_flaws, struct agent_reqs): New types.
+ (agent_reqs): New extern prototype. Well, actually, this was
+ there before, due to a premature checkin.
+ (struct aop_map): Add new `data_size' member.
+ * ax-general.c (aop_map): Supply its value.
+ * ax-gdb.c (agent_command): Call ax_reqs, for testing.
+
+ * ax-general.c (ax_print): If we encounter an invalid or
+ incomplete opcode, don't abort; just print an error message.
+
+ * ax-gdb.c: Generate trace bytecodes, as appropriate.
+ (trace_kludge): New variable.
+ (gen_fetch, gen_bitfield_ref): Emit trace bytecodes, if asked
+ nicely.
+ (expr_to_agent): Ask for no trace bytecodes.
+ (gen_trace_for_expr): New function.
+ (agent_command): Call it, and display the result appropriately ---
+ no struct axs_value, so no type or kind information.
+
+ * ax-gdb.c: Use TARGET_CHAR_BIT throughout, not HOST_CHAR_BIT.
+
+Thu Mar 26 22:29:28 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * tracepoint.c (trace_status_command): Recognize a boolean return
+ value from the stub to indicate whether trace experiment is
+ running. Export this value as a global state variable.
+ (trace_running_p) for use by the GUI. (from Michael Snyder)
+ (trace_pass_command) added call to modify_tracepoint_hook.
+
+ * tracepoint.h export trace_running_p.
+
+Thu Mar 26 13:08:01 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (validate_actionline): do not error out if
+ exp->elts[0].opcode is not on short line -- let
+ expr_to_address_and_size handle it.
+
+1998-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * tracepoint.c: Include "ax.h", not "agentexpr.h".
+
+ * tracepoint.c (encode_actions): Call expr_to_address_and_size,
+ not simply expr_to_agent.
+
+ * ax-general.c: Comment out code in progress, so everyone else can
+ at least compile.
+
+ * gdbtypes.c: Doc fix.
+
+ * ax.h, ax-gdb.h, ax-general.c, ax-gdb.c: New files.
+ * Makefile.in (REMOTE_OBJS): Add ax-general.o and ax-gdb.o.
+ (SFILES): Add ax-general.c, ax-gdb.c.
+ (ax_h): New variable.
+ (ax-general.o, ax-gdb.o): New rules.
+
+
+Tue Mar 24 16:22:40 1998 Stu Grossman <grossman@bhuna.cygnus.co.uk>
+
+ * Makefile.in: Derive SHELL from configure.
+ * config/d10v/d10v.mt config/m32r/m32r.mt
+ config/mn10200/mn10200.mt config/mn10300/mn10300.mt
+ config/d30v/d30v.mt: Remove -lm from SIM. This prevents
+ dependency checking of -lm (under NT native builds). (It is
+ automatically added by configure if it exists.)
+ * doc/configure mswin/configure nlm/configure
+ testsuite/gdb.base/configure testsuite/gdb.c++/configure
+ testsuite/gdb.chill/configure testsuite/gdb.disasm/configure
+ testsuite/gdb.stabs/configure testsuite/gdb.threads/configure:
+ Regenerate with autoconf 2.12.1 to fix shell issues for NT native
+ builds.
+
+Mon Mar 23 18:10:57 1998 Ulrich Drepper (drepper@cygnus.com)
+
+ * solib.c (solib_create_inferior_hook): Rewrite previous
+ change to check the type of file via BFD.
+
+Mon Mar 23 13:52:28 1998 Ulrich Drepper (drepper@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Treat bp_shlib_events
+ like bp_breakpoints.
+ * solib.c (solib_create_inferior_hook): Relocate section addresses
+ if the alleged start address doesn't agree with the PC.
+
+Sat Mar 21 19:34:49 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ merged changes from Foundry (list follows by file/author):
+
+ - Tom Tromey <tromey@cygnus.com>
+ * Makefile.in (gdbres.o): New target.
+ (WINDRES): New define.
+ * configure: Rebuilt.
+ * configure.in (WINDRES): Define.
+ (CONFIG_OBS): Include gdbres.o on Windows.
+ * gdbtool.ico: New file.
+ * gdb.rc: New file.
+
+ * ser-unix.c
+ - Keith Seitz <keiths@onions.cygnus.com>
+ (wait_for): Don't reset the timeout_remaining for CYGWIN32,
+ since we now effectively poll the serial port.
+ Don't reset the current_timeout, either, since this member is used
+ by hardwire_readchar to track the timeout and call the ui_loop_hook.
+ (hardwire_readchar): Poll the serial port for Cygwin32. We timeout
+ every second, update the UI, and loop around doing this until we
+ have hit the real timeout or we get data or an error. This will
+ allow the UI to stay active while gdb is "blocked" talking to the
+ target.
+ - Martin M. Hunt <hunt@cygnus.com>
+ (wait_for): Do reset current_timeout because it is only used to
+ keep track of what the current timeout for the scb is.
+
+ * top.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (quit_confirm): Change exit message again
+ for GUI.
+ (pc_changed_hook): Add prototype.
+ - Tom Tromey <tromey@cygnus.com>
+ (quit_confirm): Added missing `else'.
+ (quit_confirm): Special-case message if init_ui_hook is
+ set.
+
+ * symtab.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (find_pc_sect_line): If no symbol information
+ is found, return correct pc anyway.
+ (find_methods): Comment out an apparently
+ bogus error message because it messes up Foundry.
+
+ * serial.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (_initialize_serial): Add a description of
+ "set remotelogbase".
+
+ * findvar.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (write_register_gen): Add call to
+ pc_changed_hook if the PC is being changed.
+
+ * defs.h
+ - Martin M. Hunt <hunt@cygnus.com>
+ (pc_changed_hook): Define.
+
+ * command.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (do_setshow_command): If no arguments are supplied,
+ don't dump core, instead print out an error message.
+
+ * breakpoint.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ Make set_raw_breakpoint, set_breakpoint_count,
+ and breakpoint_count non-static so they are accessible from
+ elsewhere.
+ (enable_breakpoint): Enable breakpoint
+ with same disposition instead of changing all breakpoints
+ to donttouch.
+
+ * annotate.h
+ - Keith Seitz <keiths@onions.cygnus.com>
+ Add declarations for annotation hooks.
+
+ * annotate.c
+ - Keith Seitz <keiths@onions.cygnus.com>
+ Add hooks: annotate_starting_hook, annotate_stopped_hook,
+ annotate_signalled_hook, annotate_exited_hook.
+ (annotate_starting): If hook exists, call it instead.
+ (annotate_stopped): If hook exists, call it instead.
+ (annotate_exited): If hook exists, call it instead.
+ (annotate_signalled): If hook exists, call it instead.
+
+Fri Mar 20 14:45:36 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * gdbserver/Makefile.in: add dependency on XM_CLIBS.
+ * gdbserver/low-sim.c (registers) force into alignment.
+ (create_inferior): Fix typo on new_argv; add abfd arg to
+ sim_open, sim_create_inferior. Add reg_size arg to
+ sim_fetch_register, sim_store_register. Make simulator
+ take a single-step to get into a known running state.
+ * gdbserver/gdbreplay.c: include fcntl.h for def'n of F_SETFL.
+ * gdbserver/server.c: Add remote_debug variable to control
+ debug output.
+ * gdbserver/server.h: Add prototypes for enable/disable_async_io.
+ * gdbserver/remote-utils.c: add verbose debugging output controlled
+ by "remote_debug" variable. Add call to "disable_async_io()"
+ to avoid being killed by async SIGIO signals.
+ * config/m32r/m32r.mt: define GDBSERVER_(LIBS and DEPFILES),
+ so that gdbserver can be built with the m32r simulator.
+
+Fri Mar 20 09:04:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbtypes.h (builtin_type_{,u}int{8,16,32,64}): New gdb builtin
+ types.
+
+ * gdbtypes.c (_initialize_gdbtypes): Initialize new types.
+
+ * mips-tdep.c (do_gp_register_row): Pad register value when GP
+ register is smaller than MIPS_REGSIZE.
+
+ * findvar.c (value_of_register): When raw and virtual register
+ values identical, check that sizes are consistent.
+
+Thu Mar 19 11:32:15 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * minsyms.c (compare_minimal_symbols): If addresses are identical,
+ then compare on names. Sorted list should have symbols with
+ identical addresses AND names adjacent, so dups can be discarded.
+
+Wed Mar 18 12:50:17 1998 Jeff Law (law@cygnus.com)
+
+ * stabsread.c (define_symbol): Don't look for ',' as a LRS
+ indicator.
+
+Wed Mar 18 10:34:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * rdi-share/etherdrv.c: Set sys_errlist[] as char * not const char *.
+
+Fri Mar 13 15:43:53 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/xm-mips.h (CC_HAS_LONG_LONG): Undefine for Ultrix
+ when compiling with native cc, the compiler has broken long long
+ support.
+
+Fri Mar 13 15:37:02 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/m68k/xm-sun3os4.h: Remove malloc declarations, they
+ are handled via autoconf now.
+ * remote.c (remote_ops, extended_remote_ops): Replace static
+ forward declaration by moving the static definition to the top of
+ the file, for old K&R compilers.
+ * tracepoint.c (collect_symbol, trace_start_command):
+ Replace ANSI string concatenation with K&R compatible simple string.
+
+1998-03-11 Fred Fish <fnf@ninemoons.com>
+
+ * source.c (select_source_symtab): Don't reach error if we have
+ a current_source_symtab from reading in partial symbol table.
+
+Fri Mar 6 13:10:27 1998 Fred Fish <fnf@cygnus.com>
+
+ * utils.c (quit): Call SERIAL_DRAIN_OUTPUT rather than
+ SERIAL_FLUSH_OUTPUT.
+ * serial.h (struct serial_ops): Add drain_output, pointer to
+ function that waits for output to drain.
+ (SERIAL_DRAIN_OUTPUT): Macro to wait for output to drain.
+ * ser-unix.c (hardwire_drain_output): New function and prototype.
+
+ * ser-unix.c (hardwire_ops): Add entry for drain_output function.
+ * ser-tcp.c (tcp_ops): Ditto.
+ * ser-ocd.c (ocd_ops): Ditto.
+ * ser-mac.c (mac_ops): Ditto.
+ * ser-go32.c (dos_ops): Ditto.
+ * ser-e7kpc.c (e7000pc_ops): Ditto.
+
+Thu Mar 5 16:07:41 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * sparcl-tdep.c: fix #endif comments
+
+Thu Mar 5 15:10:35 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (BISON): Configure substitutes in @YACC@, not @BISON@.
+
+Thu Mar 5 14:42:41 1998 Keith Seitz <keiths@onions.cygnus.com>
+
+ * ocd.c (ocd_open): If we fail ocd_start_remote, make sure we
+ error () so that we abort out of bdm_ppc_open.
+
+Wed Mar 4 16:53:52 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * serial.c (_initialize_serial): Add a description of
+ "set remotelogbase".
+
+ * command.c (do_setshow_command): If no arguments are supplied,
+ don't dump core, instead print out an error message.
+
+Wed Mar 4 01:39:08 1998 Ron Unrau <runrau@cygnus.com>
+
+ * elfread.c (elf_symtab_read): merge SYMBOL_IS_SPECIAL into
+ MAKE_MSYMBOL_SPECIAL
+ * config/mips/tm-mips.h: ditto
+
+Tue Mar 3 17:19:08 1998 John Metzler <jmetzler@cygnus.com>
+
+ * dwarfread.c (read_tag_pointer_type): Pointer sizes now come from
+ TARGET_PTR_BIT rather from sizeof(char *) on host.
+
+Tue Mar 3 14:37:02 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-nat.c (fetch_osf_core_registers): Renamed from
+ fetch_aout_core_registers.
+ (alpha_osf_core_fns): Renamed from alpha_aout_core_fns, change
+ flavour to bfd_target_unknown_flavour for OSF core files.
+
+Mon Mar 2 17:44:13 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * breakpoint.c (_initialize_breakpoint): Make "en" an alias
+ for "enable" (so that it doesn't conflict with "end").
+
+Mon Mar 2 17:04:25 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile (VERSION): Bump to 4.17.1.
+
+Mon Mar 2 16:59:15 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * rdi-share/etherdrv.c (sys_errlist): Add correct decl for Linux.
+
+Mon Mar 2 16:51:44 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (YYFILES): Remove in maintainer-clean, not distclean.
+
+Mon Mar 2 16:47:11 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * Makefile.in (distclean): Add `rm $(YYFILES)'.
+
+Mon Mar 2 16:45:48 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * coffread.c (coff_read_enum_type): Set TYPE_FLAG_UNSIGNED if enum
+ is unsigned.
+
+Sun Mar 2 15:16:13 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.host, configure.tgt: Add sparc-linux.
+ * sparc-nat.c: Include <asm/reg.h> not <machine/reg.h> for Linux.
+ * config/sparc/*linux*: New files.
+
+Mon Mar 2 12:12:41 1998 Anthony Thompson (athompso@cambridge.arm.com)
+
+ * arm-tdep.c (gdb_print_insn_arm): Call print_insn_big_arm
+ if we're big endian; else call print_insn_little_arm.
+
+Mon Feb 24 11:24:57 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (BISON): Don't even pretend to use yacc.
+ (c-exp.tab.o): Use bison -o to use a unique intermediate file.
+ (f-exp.tab.o, m2-exp.tab.o): Likewise.
+ (jv-exp.tab.o): Likewise.
+
+Tue Feb 24 03:32:59 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_fetch_register): Don't abort when the
+ register size is wrong.
+
+Thu Feb 19 16:49:48 1998 John Metzler <jmetzler@cygnus.com>
+
+ * target.c (debug_to_fetch_registers,debug_to_store_registers,
+ debug-to_insert_breakpoint,debug_to_remove_breakpoint): tracing
+ 64 bit targets crashed long long printfs.
+
+Tue Feb 17 16:36:22 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * symfile.c (read_target_int_array): rename read_target_long_array
+ and force the sizeof an ovly_table element to sizeof(long),
+ instead of sizeof(int).
+
+Tue Feb 17 18:05:05 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote-mips.c (mips_request): Use unsigned long during parsing
+ returned value from monitor, to prevent accidental sign extension.
+
+Tue Feb 17 14:28:33 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * acconfig.h: FORCE_MMCHECK changed to MMCHECK_FORCE.
+ * configure.in: Ditto.
+ * configure: Regenerated.
+
+Tue Feb 17 14:07:34 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * gdbtypes.c (check_typedef): Do not try to resolve the length of
+ a type which has TYPE_FLAG_TARGET_STUB set, if the target type has
+ set TYPE_FLAG_TARGET_STUB as well.
+
+Tue Feb 17 14:32:18 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register):
+ Pass register size to sim_{fetch,store}_register. Check nr of
+ register bytes transfered is correct.
+
+Mon Feb 16 14:05:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-d10v.c (remote_d10v_open): Call push_remote_target
+ instead of open_remote_target.
+
+ * remote.c (remote_xfer_memory): Use REMOTE_TRANSLATE_XFER_ADDRESS
+ to translate addr/size when defined.
+ (open_remote_target): Delete.
+
+ * target.h (open_remote_target): Delete.
+
+ * config/d10v/tm-d10v.h (REMOTE_TRANSLATE_XFER_ADDRESS): Define.
+
+Mon Feb 16 14:05:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_extract_return_value): Wierd. GCC wants to
+ return odd sized register quantities with only half of the first
+ register used!
+
+ * config/d10v/tm-d10v.h (USE_STRUCT_CONVENTION): Use stack when
+ size > 8.
+
+Mon Feb 16 14:05:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (USE_STRUCT_CONVENTION): Define. True when
+ sizeof type > 1.
+
+Sun Feb 15 16:10:50 1998 Ron Unrau <runrau@cygnus.com>
+
+ * parse.c (write_dollar_variable): call new function
+ target_map_name_to_register to allow targets to define their own
+ register name aliases.
+ * infcmd.c (registers_info): use target_map_name_to_register so that
+ "print $reg" and "info reg $reg" use the same register name aliases.
+
+Fri Feb 13 16:40:30 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/i386/i386mk.mt (OBJFORMATS): Delete, no longer used.
+ * config/i386/xm-i386mk.h: Fix an include.
+ * config/pyr/tm-pyr.h (PC_INNER_THAN): Remove, never used.
+
+Thu Feb 12 16:12:07 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote-mips.c (mips_enter_debug): Sleep before sending CR to
+ monitor.
+ (mips_exit_debug): Accept any whitespace / verbiage before monitor
+ prompt reappears.
+
+Thu Feb 12 18:25:42 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (show_regs): Avoid use of %llx when printing 8 byte
+ accumulators.
+
+Thu Feb 12 17:10:22 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (value_at): For d10v, make read pointers with
+ read_target_unsigned_integer, keep addresses unsigned.
+ (value_fetch_lazy): Ditto.
+
+Thu Feb 12 12:14:02 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-d10v.c: New file. Layer the d10v GDB->remote memory map
+ on top of the remote serial memory transfer functions.
+
+ * config/d10v/d10v.mt (TDEPFILES): Add remote-d10v.o
+
+ * Makefile.in (remote-d10v.o): Add dependencies.
+
+ * remote.c (remote_open_1): Add arg extended_p, engage extended
+ protocol when extended_p.
+ (remote_open, extended_remote_open): Pass !extended_p /
+ extended_p to remote_open_1.
+
+ * remote.c (open_remote_target), target.h: New function.
+
+Wed Feb 11 08:41:15 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/i386/fbsd.mh (XDEPFILES): Add ser-tcp.o.
+
+Tue Feb 10 17:50:37 1998 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c (tracepoint_operation): Call the modify_tracepoint_hook
+ if it exists.
+ Remove static declaration of free_actions.
+
+ * tracepoint.h: Add declaration of free_actions.
+
+Tue Feb 10 12:17:13 1998 Fred Fish <fnf@cygnus.com>
+
+ * symtab.c (decode_line_1): Revert change that mistakenly
+ removed assignment of sals[0].pc field.
+
+Mon Feb 10 12:37:47 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k/tm-delta68.h (EXTRACT_RETURN_VALUE): Type argument for
+ `REGISTER_CONVERT_TO_VIRTUAL is `TYPE', not
+ `REGISTER_VIRTUAL_TYPE (FP0_REGNUM)';
+ (STORE_RETURN_VALUE): Ditto, and offset for `write_register_bytes'
+ is `REGISTER_BYTE (FP0_REGNUM)', not `FP0_REGNUM'.
+ (FRAME_NUM_ARGS): New macro.
+ * m68k/tm-news.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): Ditto.
+ * delta68-nat.c (clear_insn_cache): New function, forgotten in previous
+ patch.
+
+Mon Feb 9 11:10:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c: Replace references to IMEM_ADDR and DMEM_ADDR with
+ D10V_MAKE_[DI]ADDR and D10V_CONVERT_[ID]ADDR_TO_RAW macros.
+
+ * config/d10v/tm-d10v.h (IMEM_START): Move to 0x01......
+ (DMEM_START): Move to 0x00......
+ (STACK_START): Move to 0x00..7ffe.
+ (D10V_MAKE_IADDR, D10V_MAKE_DADDR): Translate unconditionally.
+
+ * d10v-tdep.c (d10v_xlate_addr): Delete function.
+
+Mon Feb 9 15:10:21 1998 Fred Fish <fnf@cygnus.com>
+
+ * symtab.c (fixup_psymbol_section): Move forward declaration to
+ top of file with other such decls. Make it a static function.
+ * symtab.h: Minor formatting tweaks.
+
+Mon Feb 9 13:14:12 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/a29k-udi.mt, config/i960/vxworks960.mt (REMOTE_OBS):
+ Remove redefinition.
+ * config/i960/tm-i960.h (BREAKPOINT): Define.
+
+Mon Feb 9 15:35:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (init.c): Ignore errors when making init.c. Seems
+ necessary to work around bug in Solaris make.
+
+Sun Feb 6 02:44:28 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k/tm-delta68.h (CPLUS_MARKER): Macro deleted.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Macro defined.
+ (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): Macros modified
+ because floating-point values return via %fp0.
+ (CLEAR_INSN_CACHE): New macro.
+ * m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL): Macro fixed
+ to use DOUBLEST.
+ (REGISTER_CONVERT_TO_RAW): Ditto.
+ * infptrace.c (child_xfer_memory): If CLEAR_INSN_CACHE is defined,
+ call it after having written in child process's memory.
+ * inflow.c (PROCESS_GROUP_TYPE): Macro defined if HAVE_TERMIO.
+ (gdb_has_a_terminal, terminal_ours_1): Functions fixed for HAVE_TERMIO.
+
+Fri Feb 6 16:17:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/mips/tm-mips64.h (TARGET_LONG_BIT): Allow final target to
+ override.
+ (TARGET_LONG_LONG_BIT): Likewise.
+ (TARGET_PTR_BIT): Likewise.
+
+Fri Feb 6 17:42:22 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (D10V_CONVERT_IADDR_TO_RAW,
+ D10V_CONVERT_DADDR_TO_RAW): Define.
+
+ * d10v-tdep.c (d10v_push_arguments): Re-write. Pass arguments in
+ registers, regardless of their size, when they fit.
+
+Thu Feb 5 13:16:36 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_extract_return_value): For function pointers
+ translate address to IMAP area.
+
+ * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Delete dummy from
+ struct.
+ (POP_FRAME): Point at generic_pop_current_frame.
+
+ * d10v-tdep.c (d10v_pop_frame): Delete code handling dummy frames,
+ handled earlier.
+ (d10v_push_return_address): New function.
+ (d10v_pop_dummy_frame): Delete.
+ (d10v_fix_call_dummy): Delete.
+ (d10v_call_dummy_address): Delete.
+
+ * d10v-tdep.c (d10v_init_extra_frame_info): Clear dummy and
+ frameless.
+
+ * d10v-tdep.c (d10v_push_arguments): Keep stack word aligned.
+
+ * config/d10v/tm-d10v.h (EXTRACT_STRUCT_VALUE_ADDRESS): Extract
+ address of structure from first ARG1_REGNUM.
+
+ * d10v-tdep.c (d10v_push_arguments): Force 4 byte args into
+ even-odd register pair. Store 1 and 2 byte args in registers.
+
+ * valops.c (value_fetch_lazy): Ensure that a D10V function pointer
+ is fetched in the correct byte order.
+ (value_at): Ditto. Also ensure data pointers are mapped to data
+ segment.
+
+ * config/d10v/tm-d10v.h (D10V_DADDR_P, D10V_IADDR_P):
+
+ * d10v-tdep.c: Replace 2 with REGISTER_RAW_SIZE.
+ (d10v_pop_frame): Replace R13 with LR_REGNUM.
+ (d10v_push_arguments): Replace R2 with ARG1_REGNUM.
+ (d10v_push_arguments): Replace 6 with ARGN_REGNUM.
+ (d10v_extract_return_value): Access return value with RET1_REGNUM.
+
+ * config/d10v/tm-d10v.h (ARG1_REGNUM, ARGN_REGNUM, RET1_REGNUM):
+ Define.
+ (STORE_RETURN_VALUE): Specify return register using RET1_REGNUM.
+ (STORE_STRUCT_RETURN): Specify ARG1_REGNUM as the struct ptr
+ location.
+
+Thu Feb 5 13:16:36 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (generic_pop_dummy_frame): Flush the frame, no
+ longer valid.
+
+ * blockframe.c (generic_pop_current_frame), frames.h: New
+ function.
+
+Thu Feb 5 17:18:16 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_create_inferior): clear_proceed_status
+ before /re/starting the simulator.
+
+Thu Feb 5 15:55:31 1998 C. M. Heard (heard@vvnet.com)
+
+ * top.c (do_nothing): Remove signal handler after signal is caught.
+
+Thu Feb 5 11:57:06 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (tracepoint_operation): call free_actions instead
+ of free. (free_actions): eliminate some memory leaks for actions.
+ (validate_actionline): pass string arg by reference, so we can
+ change the pointer. Change all memrange collection arguments to
+ canonical form (literal address and size), to enforce early
+ evaluation. Accept UNOP_MEMVAL (assembly variables) for
+ trace collection. (parse_and_eval_memrange): accept expressions
+ for the address and size fields of a memrange (and evaluate
+ them immediately). (several places): use -1 instead of zero
+ to distinguish an absolute memrange from a register-relative one.
+ (encode_actions): add handling for UNOP_MEMVAL (assembly variable).
+
+Wed Feb 4 17:40:21 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (SFILES): add tracepoint.c.
+ (LINTFILES): add @CONFIG_SRCS@.
+ (SOURCES): Ditto.
+ * configure.in (CONFIG_SRCS): Mirror use of CONFIG_OBS.
+ * configure: Regenerated.
+
+Tue Feb 3 16:12:32 1998 Gordon W. Ross (gwr@mc.com)
+
+ * infptrace.c (child_resume): Don't try to step if
+ NO_SINGLE_STEP is defined.
+
+Mon Feb 2 19:06:13 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.16.2.
+
+Mon Feb 2 17:18:25 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha-nat.c (fetch_aout_core_registers): Rename from
+ fetch_core_registers.
+ (fetch_elf_core_registers): New function.
+ (supply_gregset): Use ALPHA_REGSET_BASE.
+ (supply_fpregset): Likewise.
+ (fill_fpregset): Likewise.
+ (alpha_aout_core_fns): Rename from alpha_core_fns.
+ (alpha_elf_core_fns): New.
+ * config/alpha/alpha-linux.mh (NATDEPFILES): solib.o not osfsolib.o.
+ Disable MMALLOC.
+ * config/alpha/nm-linux.h (SVR4_SHARED_LIBS): Define if ELF.
+ (TARGET_ELF64): Likewise.
+ (ALPHA_REGSET_BASE): New.
+ * config/alpha/nm-osf.h (ALPHA_REGSET_BASE): New.
+ * config/alpha/tm-alphalinux.h: Include tm-sysv4.h.
+
+ * solib.c (elf_locate_base): Add TARGET_ELF64 support.
+ (info_sharedlibary_command): Likewise.
+
+ * configure.host: Match alpha*.
+ * configure.tgt: Likewise.
+
+Fri Jan 30 15:11:38 1998 David Taylor <taylor@texas.cygnus.com>
+
+ Changes by <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * infrun.c (IN_SOLIB_DYNSYM_RESOLVE_CODE): new macro for detecting
+ whether we are in the dynamic symbol resolution code
+ (wait_for_inferior): invoke it.
+ * solib.c (in_svr4_dynsym_resolve_code): new function
+ (enable_break): record start and end of the dynamic linker
+ text and plt sections for use in in_svr4_dynsym_resolve_code.
+ * solib.h (IN_SOLIB_DYNSYM_RESOLVE_CODE): add svr4 definition;
+ (in_svr4_dynsym_resolve_code): declare it.
+ * config/nm-gnu.h (solib.h): move inclusion to after definition
+ of SVR4_SHARED_LIBS.
+ * config/nm-sysv4.h (solib.h): ditto.
+ * config/i386/nm-i386sco5.h (solib.h): ditto.
+ * config/i386/nm-linux.h (solib.h): ditto.
+ * config/mips/nm-irix5.h (IN_SOLIB_DYNSYM_RESOLVE_CODE): undefine.
+
+Thu Jan 29 19:39:31 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * coffread.c (coff_symtab_read) [SEM]: Remove code, macro can
+ never be defined.
+ * dbxread.c (process_one_symbol) [BLOCK_ADDRESS_ABSOLUTE]:
+ Remove, no longer needed.
+ * hppa-tdep.c (N_SET_MAGIC): Remove, no longer used.
+ * config/pa/xm-hppab.h (SEEK_SET, SEEK_CUR, SEEK_END): Ditto.
+ * config/mips/tm-mipsm3.h (NUMERIC_REG_NAMES): Ditto.
+ * config/mips/mipsm3.mt (TDEPFILES): Remove mipsread.o.
+
+Wed Jan 28 14:46:52 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ Suggested by Chris Walter <walter@budoe.bu.edu>:
+ * dwarfread.c (set_cu_language): Recognize Fortran.
+ * dwarf2read.c (set_cu_language): Ditto.
+ (read_array_type): Fix language test.
+
+Wed Jan 28 12:51:08 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * blockframe.c (generic_frame_chain_valid): A frame pointer may
+ be valid if it is equal to the frame pointer of its caller (ie.
+ not necessarily strictly INNER_THAN). Allows frameless functions.
+
+Wed Jan 28 11:23:25 1998 Mark Alexander <marka@cygnus.com>
+
+ * monitor.c (monitor_vsprintf): New function to handle
+ printing of large addresses using %A format specifier.
+ (monitor_printf_noecho, monitor_printf): Use monitor_vsprintf
+ instead of vsprintf.
+ * dve3900-rom.c (_initialize_r3900_rom): Use %A instead of %Lx
+ to print addresses.
+
+Tue Jan 27 16:14:23 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in (CONFIG_LDFLAGS): Only add -export-dynamic
+ when using GNU ld.
+
+Mon Jan 26 19:07:46 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * config/alpha/tm-alphalinux.h (alpha_linux_sigtramp_offset):
+ Add closing parenthesis. From HJ Lu.
+
+Mon Jan 26 17:54:45 1998 Mark Alexander <marka@cygnus.com>
+
+ * dve3900-rom.c: Improve performance by using memory commands
+ that print less fluff. Minor cosmetic changes.
+ Eliminate compiler warnings.
+
+Sat Jan 24 23:44:43 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * breakpoint.c (enable_breakpoint): Preserve breakpoint
+ disposition when enabling a breakpoint.
+
+ * symtab.c (find_pc_sect_line): If no symbol information
+ is found, return correct pc anyway.
+
+Fri Jan 23 17:26:22 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host (i[3456]86-*-osf1mk*, mips-*-mach3*,
+ ns32k-*-mach3*): Fix file names.
+ (i[3456]86-*-os9k, m88*-*-mach3*, w65-*-*): Remove config
+ recognition, no source files for these.
+ * configure.tgt (powerpc-*-aix4*): Remove config, now identical
+ to powerpc-*-aix*.
+ * config/powerpc/{aix4.mh,aix4.mt,tm-ppc-aix4.h}: Remove files,
+ no longer needed.
+
+Fri Jan 23 16:49:41 1998 Mark Alexander <marka@cygnus.com>
+
+ * monitor.c (monitor_write, monitor_readchar): New functions.
+ * monitor.h (monitor_write, monitor_readchar): Declare.
+ * dve3900-rom.c: Add support for fast loading on ethernet connections.
+
+Fri Jan 23 07:47:06 1998 Fred Fish <fnf@cygnus.com>
+
+ * config/d10v/tm-d10v.h (CALL_DUMMY): Define as "{ 0 }".
+ (TARGET_READ_FP): Define to d10v_read_fp rather than d10v_read_sp.
+ (TARGET_WRITE_FP): Define to d10v_write_fp rather than d10v_write_sp.
+ (d10v_write_fp, d10v_read_fp): Add prototypes.
+ * symtab.c (decode_line_1): Remove assignment of sals[0].pc field.
+ * symfile.c (simple_overlay_update, simple_overlay_update_1):
+ Ignore the size of overlay sections. This check is redundant anyway.
+ * printcmd.c (print_frame_args): Ditto.
+ * valops.c (value_fetch_lazy): Ditto.
+ * values.c (unpack_long): Ditto.
+ * d10v-tdep.c (d10v_frame_chain, d10v_frame_find_saved_regs,
+ d10v_init_extra_frame_info): Fix some minor bugs so the finish command
+ works properly.
+ (show_regs): Change num1 and num2 types from "long long" to "LONGEST".
+ (d10v_read_fp, d10v_write_fp): New functions.
+ (d10v_push_arguments): Remove unneeded assigns to "val" and "contents".
+ (d10v_push_arguments): Fix for pointers and structs.
+ (d10v_extract_return_value): Fix for pointers and chars.
+
+Tue Jan 20 18:53:18 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (i386-*-mach*, m88*-*-mach3*): Remove config
+ recognition, no source files for these (note that the i386 Mach
+ config is for pre-Mach 3).
+ (mips*-*-mach3*, ns32k-*-mach3*): Fix file names.
+ * config/mips/mipsel64.mt: Remove, never referenced.
+
+Mon Jan 19 14:01:28 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (print_gdb_version): Restore to original message.
+
+Mon Jan 19 13:34:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From cgf@bbc.com (Chris Faylor):
+ * win32-nat.c (child_mourn_inferior): Call ContinueDebugEvent to
+ let the child exit.
+ (child_kill_inferior): Respond to all debug events as the child is
+ terminating.
+
+ * Makefile.in (all): Change gdb dependency to gdb$(EXEEXT).
+ (uninstall): Add $(EXEEXT) to file name to remove.
+ (gdb$(EXEEXT)): Rename target from plain gdb.
+ (gdb1$(EXEEXT)): Rename target from plain gdb1.
+ (clean, mostlyclean): Add $(EXEEXT) to binary names to remove.
+
+1998-01-16 Felix Lee <flee@cygnus.com>
+
+ * top.c (print_gdb_version): delete stutter.
+
+Thu Jan 15 12:29:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Patch from Tony.Thompson@arm.com
+ to prevent spurous error messages on non-ICE targets.
+
+Wed Jan 14 19:27:02 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/mips/{r3900.mt,r3900l.mt,tm-r3900.h,tm-r3900l.h}:
+ Remove, no longer used.
+
+Wed Jan 14 18:11:26 1998 Michael Meissner <meissner@cygnus.com>
+
+ Patch from Jim Wilson.
+ * d30v-tdep.c (d30v_frame_find_saved_regs_offsets): Properly
+ declare void function before use.
+
+ * config/d30v/tm-d30v.h (CALL_DUMMY): Initialize as { 0 }, not {}.
+
+Tue Jan 13 16:38:48 1998 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (--with-mmalloc): Add new configure arg to use the
+ mmalloc package. Default is to not use it.
+ (START_INFERIOR_TRAPS_EXPECTED): Define to the integer 2, not
+ the string "2".
+ * acconfig.h (USE_MMALLOC, FORCE_MMCHECK): Add #undef.
+ * configure: Regenerated.
+ * config.in: Regenerated.
+ * Makefile.in (MMALLOC_DIR, MMALLOC_SRC): Remove.
+ (MMALLOC): Set using configure.
+ (MMALLOC_CFLAGS): Set using configure.
+
+ * config/i386/tm-linux.h (sys_quotactl): Define to 1 rather
+ than just defining it.
+ * mpw-make.sed: Undefine USE_MMALLOC rather than defining NO_MMALLOC.
+ * utils.c (NO_MMALLOC): Use USE_MMALLOC instead.
+ * objfiles.c: ditto.
+ * defs.h: ditto.
+
+ * config/sparc/sun4os4.mh (MMALLOC_CFLAGS): Remove.
+ * config/m68k/sun3os4.mh (MMALLOC_CFLAGS): Remove.
+ * config/i386/cygwin32.mh (MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-osf3.mh (MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-osf2.mh (MMALLOC_CFLAGS): Remove.
+ * gdbserver/Makefile.in (MMALLOC_*): Remove.
+ * config/rs6000/rs6000.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/rs6000/aix4.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/powerpc/aix4.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/powerpc/aix.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/ns32k/ns32km3.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/mips/mipsm3.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/mips/decstation.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/m88k/cxux.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/i386/xm-windows.h (NO_MMALLOC, NO_MMCHECK): Remove.
+ * config/i386/i386mk.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/i386/i386m3.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/i386/i386gnu.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-osf1.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-linux.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+
+Mon Jan 12 11:46:51 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/m68k/tm-m68k.h (REGISTER_VIRTUAL_TYPE): make A0 thru A7
+ default to void pointer type (so that their default radix is hex).
+
+ * symtab.c: move rbreak_command from no_class to class_breakpoint
+ so it will be listed under "help breakpoints".
+
+Sat Jan 10 14:58:04 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * rdi-share/hostchan.c: Remove gettimeofday declaration.
+
+Thu Jan 8 11:03:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * remote-rdp.c: Applied patches submitted by Tony.Thompson@arm.com
+ to implement the Angel remote debugging interface.
+
+ * Makefile.in: Add build rules for remote-rdi.c and
+ rdi-share/libangsd.a.
+
+ * configure.tgt: Updated from source on branch.
+ * config/arm/tm-arm.h: Updated from source on branch.
+ * arm-tdep.c: Updated from source on branch.
+
+ * rdi-share: New directory, RDI library contributed by ARM.
+
+Mon Jan 5 20:21:59 1998 Mark Alexander <marka@cygnus.com>
+
+ * monitor.h (MO_PRINT_PROGRAM_OUTPUT): Define.
+ * monitor.c (monitor_wait): Echo program output.
+ * dve3900-rom.c (_initialize_r3900_rom): Remove MO_HANDLE_NL flag,
+ add MO_PRINT_PROGRAM_OUTPUT flag.
+
+Mon Jan 5 18:21:11 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * top.h (HAVE_SIGSETJMP): define SIGJMP_BUF, SIGSETJMP, and
+ SIGLONGJMP appropriately based on whether HAVE_SIGSETJMP is
+ defined.
+ * top.c (return_to_top_level, catch_errors): use the new macros
+ * main.c (SET_TOP_LEVEL): ditto.
+ * config/xm-sysv4.h (HAVE_SIGSETJMP): Define.
+
+Fri Jan 2 18:48:58 1998 Mark Alexander <marka@cygnus.com>
+
+ * configure.in: Double up brackets in shell case pattern.
+
+Fri Jan 2 17:06:05 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (finish_tfind_command): improved algorithm for
+ deciding when we've "stepped" into a new stack frame.
+ (map_args_over_tracepoints): loop over tracepoint list "safely",
+ since list elements may be deleted during loop.
+ (read_actions): add actions to history list.
+
+For older changes see ChangeLog-97
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/contrib/gdb/gdb/Makefile.in b/contrib/gdb/gdb/Makefile.in
index 77ef7f2..2c6dfb5 100644
--- a/contrib/gdb/gdb/Makefile.in
+++ b/contrib/gdb/gdb/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+# Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
# Free Software Foundation, Inc.
# This file is part of GDB.
@@ -23,12 +23,12 @@ exec_prefix = @exec_prefix@
host_alias = @host_alias@
target_alias = @target_alias@
program_transform_name = @program_transform_name@
-bindir = $(exec_prefix)/bin
-libdir = $(exec_prefix)/lib
+bindir = @bindir@
+libdir = @libdir@
tooldir = $(libdir)/$(target_alias)
-datadir = $(prefix)/lib
-mandir = $(prefix)/man
+datadir = @datadir@
+mandir = @mandir@
man1dir = $(mandir)/man1
man2dir = $(mandir)/man2
man3dir = $(mandir)/man3
@@ -38,11 +38,14 @@ man6dir = $(mandir)/man6
man7dir = $(mandir)/man7
man8dir = $(mandir)/man8
man9dir = $(mandir)/man9
-infodir = $(prefix)/info
-includedir = $(prefix)/include
-docdir = $(datadir)/doc
+infodir = @infodir@
+includedir = @includedir@
-SHELL = /bin/sh
+# This can be referenced by `INTLDEPS' as computed by CY_GNU_GETTEXT.
+top_builddir = .
+
+SHELL = @SHELL@
+EXEEXT = @EXEEXT@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -51,11 +54,20 @@ INSTALL_DATA = @INSTALL_DATA@
AR = @AR@
AR_FLAGS = qv
RANLIB = @RANLIB@
-AWK = @AWK@
+DLLTOOL = @DLLTOOL@
+WINDRES = @WINDRES@
+
+# If the user configured GDB to include the TUI, the name of the tui
+# library goes here.
+TUI_LIBRARY = @TUI_LIBRARY@
+
+# If the user configured GDB to include the TUI, the all-tui
+# target goes here.
+BUILD_TUI = @BUILD_TUI@
# Flags that describe where you can find the termcap library.
# This can be overridden in the host Makefile fragment file.
-TERMCAP = -ltermcap
+TERMCAP = @TERM_LIB@
# If you are compiling with GCC, make sure that either 1) You have the
# fixed include files where GCC can reach them, or 2) You use the
@@ -70,6 +82,8 @@ VPATH = @srcdir@
YACC=@YACC@
+YLWRAP = $(srcdir)/../ylwrap
+
# where to find makeinfo, preferably one designed for texinfo-2
MAKEINFO=makeinfo
@@ -87,17 +101,9 @@ INCLUDE_CFLAGS = -I$(INCLUDE_DIR)
# Where is the "-liberty" library? Typically in ../libiberty.
LIBIBERTY = ../libiberty/libiberty.a
-# Where is the MMALLOC library? Typically in ../mmalloc.
-# Note that mmalloc can still be used on systems without mmap().
-# To use your system malloc, comment out the following defines.
-MMALLOC_DIR = ../mmalloc
-MMALLOC_SRC = $(srcdir)/$(MMALLOC_DIR)
-MMALLOC = $(MMALLOC_DIR)/libmmalloc.a
-# To use your system malloc, uncomment MMALLOC_DISABLE.
-#MMALLOC_DISABLE = -DNO_MMALLOC
-# To use mmalloc but disable corruption checking, uncomment MMALLOC_CHECK
-#MMALLOC_CHECK = -DNO_MMALLOC_CHECK
-MMALLOC_CFLAGS = -I$(MMALLOC_SRC) $(MMALLOC_CHECK) $(MMALLOC_DISABLE)
+# Configured by the --with-mmalloc option to configure.
+MMALLOC = @MMALLOC@
+MMALLOC_CFLAGS = @MMALLOC_CFLAGS@
# Where is the BFD library? Typically in ../bfd.
BFD_DIR = ../bfd
@@ -109,7 +115,21 @@ BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
READLINE_DIR = ../readline
READLINE = $(READLINE_DIR)/libreadline.a
READLINE_SRC = $(srcdir)/$(READLINE_DIR)
-READLINE_CFLAGS = -I$(READLINE_SRC)
+READLINE_CFLAGS = -I$(READLINE_SRC)/..
+
+WARN_CFLAGS = @WARN_CFLAGS@
+
+# Where is the INTL library? Typically in ../intl.
+INTL_DIR = ../intl
+INTL = @INTLLIBS@
+INTL_DEPS = @INTLDEPS@
+INTL_SRC = $(srcdir)/$(INTL_DIR)
+INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC)
+
+# Where is the TUI library? Typically in tui/.
+TUI_DIR=tui
+TUI_SRC = $(srcdir)/$(TUI_DIR)
+TUI_CFLAGS= -I$(TUI_SRC)
# Opcodes currently live in one of two places. Either they are in the
# opcode library, typically ../opcodes, or they are in a header file
@@ -128,8 +148,6 @@ SIM =
ENABLE_CFLAGS= @ENABLE_CFLAGS@
-ENABLE_CLIBS= @ENABLE_CLIBS@
-ENABLE_OBS= @ENABLE_OBS@
# -I. for config files.
# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also.
@@ -158,7 +176,8 @@ CXXFLAGS = -g -O
# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
$(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
- $(BFD_CFLAGS) $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(ENABLE_CFLAGS)
+ $(BFD_CFLAGS) $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) \
+ $(INTL_CFLAGS) $(TUI_CFLAGS) $(ENABLE_CFLAGS) $(WARN_CFLAGS)
# LDFLAGS is specifically reserved for setting from the command line
# when running make.
@@ -166,7 +185,8 @@ INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
# Profiling options need to go here to work.
# I think it's perfectly reasonable for a user to set -pg in CFLAGS
# and have it work; that's why CFLAGS is here.
-INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS)
+INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) @CONFIG_LDFLAGS@ @HLDFLAGS@
+HLDENV = @HLDENV@
# We are using our own version of REGEX now to be consistent across
# machines.
@@ -179,20 +199,23 @@ REGEX1 = gnu-regex.o
# Libraries and corresponding dependencies for compiling gdb.
# {X,T}M_CLIBS, defined in *config files, have host- and target-dependent libs.
# TERMCAP comes after readline, since readline depends on it.
+# MMALLOC comes after anything else that might want an allocation function.
+# LIBIBERTY appears twice on purpose.
# If you have the Cygnus libraries installed,
# you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS='
-INSTALLED_LIBS=-lbfd -lreadline $(TERMCAP) -lopcodes -lmmalloc -liberty \
- $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(ENABLE_CLIBS) @LIBS@
-CLIBS = $(SIM) $(BFD) $(READLINE) $(OPCODES) $(MMALLOC) $(LIBIBERTY) \
- $(ENABLE_CLIBS) $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) \
- $(LIBIBERTY) @LIBS@
+INSTALLED_LIBS=-lbfd -lreadline -lopcodes -liberty \
+ $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
+ -lmmalloc -lintl -liberty
+CLIBS = $(SIM) $(BFD) $(READLINE) $(OPCODES) $(INTL) $(LIBIBERTY) \
+ $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
+ $(MMALLOC) $(LIBIBERTY) $(WIN32LIBS)
CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
- $(OPCODES) $(MMALLOC) $(LIBIBERTY)
+ $(OPCODES) $(MMALLOC) $(INTL_DEPS) $(LIBIBERTY) @CONFIG_DEPS@
ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
-VERSION = 4.16
+VERSION=4.18
DIST=gdb
LINT=/usr/5bin/lint
@@ -214,7 +237,7 @@ SER_HARDWIRE = ser-unix.o
# The `remote' debugging target is supported for most architectures,
# but not all (e.g. 960)
-REMOTE_OBS = remote.o dcache.o remote-utils.o
+REMOTE_OBS = remote.o dcache.o remote-utils.o tracepoint.o ax-general.o ax-gdb.o
# This is remote-sim.o if a simulator is to be linked in.
SIM_OBS =
@@ -239,6 +262,7 @@ FLAGS_TO_PASS = \
"CHILL_LIB=$(CHILL_LIB)" \
"CXX=$(CXX)" \
"CXXFLAGS=$(CXXFLAGS)" \
+ "DLLTOOL=$(DLLTOOL)" \
"RANLIB=$(RANLIB)" \
"MAKEINFO=$(MAKEINFO)" \
"INSTALL=$(INSTALL)" \
@@ -330,22 +354,30 @@ TARGET_FLAGS_TO_PASS = \
# Links made at configuration time should not be specified here, since
# SFILES is used in building the distribution archive.
-SFILES = bcache.c blockframe.c breakpoint.c buildsym.c callback.c c-exp.y \
- c-lang.c c-typeprint.c c-valprint.c ch-exp.c ch-lang.c \
- ch-typeprint.c ch-valprint.c coffread.c command.c complaints.c \
- corefile.c cp-valprint.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 \
+SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
+ buildsym.c c-exp.y c-lang.c c-typeprint.c c-valprint.c \
+ ch-exp.c ch-lang.c ch-typeprint.c ch-valprint.c coffread.c \
+ command.c complaints.c corefile.c cp-valprint.c dbxread.c \
+ demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
+ expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
+ findvar.c gdbarch.c gdbtypes.c infcmd.c inflow.c infrun.c language.c \
+ jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.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 remote-nrom.c scm-exp.c scm-lang.c scm-valprint.c \
- source.c stabsread.c stack.c symfile.c symmisc.c \
- symtab.c target.c thread.c top.c \
- typeprint.c utils.c valarith.c valops.c \
- valprint.c values.c serial.c ser-unix.c mdebugread.c os9kread.c
-
-LINTFILES = $(SFILES) $(YYFILES) init.c
+ printcmd.c remote.c remote-nrom.c scm-exp.c scm-lang.c \
+ scm-valprint.c source.c stabsread.c stack.c symfile.c \
+ symmisc.c symtab.c target.c thread.c top.c tracepoint.c \
+ typeprint.c utils.c valarith.c valops.c valprint.c values.c \
+ serial.c ser-unix.c mdebugread.c os9kread.c \
+ tui/tui.c tui/tui.h tui/tuiCommand.c tui/tuiCommand.h \
+ tui/tuiData.c tui/tuiData.h tui/tuiDataWin.c tui/tuiDataWin.h \
+ tui/tuiDisassem.c tui/tuiDisassem.h tui/tuiGeneralWin.c \
+ tui/tuiGeneralWin.h tui/tuiIO.c tui/tuiIO.h tui/tuiLayout.c \
+ tui/tuiLayout.h tui/tuiRegs.c tui/tuiRegs.h tui/tuiSource.c \
+ tui/tuiSource.h tui/tuiSourceWin.c tui/tuiSourceWin.h \
+ tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h
+
+LINTFILES = $(SFILES) $(YYFILES) @CONFIG_SRCS@ init.c
# "system" headers. Using these in dependencies is a rather personal
# choice. (-rich, summer 1993)
@@ -357,9 +389,11 @@ floatformat_h = $(INCLUDE_DIR)/floatformat.h
bfd_h = $(BFD_DIR)/bfd.h
wait_h = $(INCLUDE_DIR)/wait.h
dis-asm_h = $(INCLUDE_DIR)/dis-asm.h
+remote-sim_h = $(INCLUDE_DIR)/remote-sim.h
dcache_h = dcache.h
-remote_utils_h = $(dcache_h) serial.h target.h remote-utils.h remote-sim.h
+remote_utils_h = $(dcache_h) serial.h target.h remote-utils.h $(remote-sim_h)
+
readline_headers = \
$(READLINE_SRC)/chardefs.h \
@@ -388,9 +422,11 @@ breakpoint_h = breakpoint.h $(frame_h) $(value_h)
command_h = command.h
gdbcmd_h = gdbcmd.h $(command_h)
-defs_h = defs.h xm.h tm.h nm.h config.status config.h
+defs_h = defs.h xm.h tm.h nm.h config.status config.h gdbarch.h
inferior_h = inferior.h $(breakpoint_h)
+tracepoint_h = tracepoint.h
+ax_h = ax.h
# Header files that need to have srcdir added. Note that in the cases
# where we use a macro like $(gdbcmd_h), things are carefully arranged
@@ -400,18 +436,20 @@ inferior_h = inferior.h $(breakpoint_h)
HFILES_NO_SRCDIR = bcache.h buildsym.h call-cmds.h coff-solib.h defs.h \
dst.h environ.h $(gdbcmd_h) gdbcore.h \
- gdb-stabs.h $(inferior_h) language.h minimon.h monitor.h \
+ gdb-stabs.h hpread.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 f-lang.h m2-lang.h \
+ c-lang.h ch-lang.h f-lang.h \
+ jv-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 \
vx-share/dbgRpcLib.h vx-share/ptrace.h vx-share/vxTypes.h \
vx-share/vxWorks.h vx-share/wait.h vx-share/xdr_ld.h \
- vx-share/xdr_ptrace.h vx-share/xdr_rdb.h thread.h \
- dcache.h remote-utils.h remote-sim.h top.h somsolib.h
+ vx-share/xdr_ptrace.h vx-share/xdr_rdb.h gdbthread.h \
+ dcache.h remote-utils.h top.h somsolib.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -432,9 +470,9 @@ POSSLIBS = gnu-regex.c gnu-regex.h
# Makefile.in
DEPFILES = $(TDEPFILES) $(XDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) \
- $(REMOTE_OBS) $(SIM_OBS) $(ENABLE_OBS)
+ $(REMOTE_OBS) $(SIM_OBS) @CONFIG_OBS@
-SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES)
+SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) @CONFIG_SRCS@
# Don't include YYFILES (*.tab.c) because we already include *.y in SFILES,
# and it's more useful to see it in the .y file.
TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \
@@ -444,16 +482,18 @@ TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o stack.o thread.o \
source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
symtab.o symfile.o symmisc.o infcmd.o infrun.o command.o \
- expprint.o environ.o gdbtypes.o copying.o $(DEPFILES) \
+ expprint.o environ.o gdbarch.o gdbtypes.o copying.o $(DEPFILES) \
mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
dbxread.o coffread.o elfread.o \
- dwarfread.o mipsread.o stabsread.o corefile.o \
- c-lang.o ch-exp.o ch-lang.o f-lang.o m2-lang.o \
+ dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \
+ c-lang.o ch-exp.o ch-lang.o f-lang.o \
+ jv-lang.o jv-valprint.o jv-typeprint.o \
+ m2-lang.o \
scm-exp.o scm-lang.o scm-valprint.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 callback.o
+ nlmread.o serial.o mdebugread.o os9kread.o top.o utils.o
OBS = $(COMMON_OBS) $(ANNOTATE_OBS) main.o
@@ -465,11 +505,17 @@ NTSOBS = standalone.o
NTSSTART = kdb-start.o
-SUBDIRS = doc testsuite nlm
+SUBDIRS = doc \
+ testsuite \
+ nlm
# For now, shortcut the "configure GDB for fewer languages" stuff.
-YYFILES = c-exp.tab.c f-exp.tab.c m2-exp.tab.c
-YYOBJ = c-exp.tab.o f-exp.tab.o m2-exp.tab.o
+YYFILES = c-exp.tab.c \
+ jv-exp.tab.c \
+ f-exp.tab.c m2-exp.tab.c
+YYOBJ = c-exp.tab.o \
+ jv-exp.tab.o \
+ f-exp.tab.o m2-exp.tab.o
# Things which need to be built when making a distribution.
@@ -480,7 +526,7 @@ DISTSTUFF = $(YYFILES)
.c.o:
$(CC) -c $(INTERNAL_CFLAGS) $<
-all: gdb
+all: gdb$(EXEEXT)
@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
installcheck:
@@ -517,7 +563,7 @@ install-only:
else \
true ; \
fi ; \
- $(INSTALL_PROGRAM) gdb $(bindir)/$$transformed_name ; \
+ $(INSTALL_PROGRAM) gdb$(EXEEXT) $(bindir)/$$transformed_name$(EXEEXT) ; \
$(INSTALL_DATA) $(srcdir)/gdb.1 $(man1dir)/$$transformed_name.1
@$(MAKE) DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do
@@ -529,7 +575,7 @@ uninstall: force
else \
true ; \
fi ; \
- rm -f $(bindir)/$$transformed_name $(man1dir)/$$transformed_name.1
+ rm -f $(bindir)/$$transformed_name$(EXEEXT) $(man1dir)/$$transformed_name.1
@$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do
# We do this by grepping through sources. If that turns out to be too slow,
@@ -548,10 +594,12 @@ init.c: $(OBS) $(TSOBS)
@rm -f init.c-tmp
@echo '/* Do not modify this file. */' >init.c-tmp
@echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
- @echo 'void initialize_all_files () {' >>init.c-tmp
- @for i in $(OBS) $(TSOBS); do \
- filename=`echo $$i | sed \
- -e '/^Onindy.o/d' \
+ @echo '#include "ansidecl.h"' >>init.c-tmp
+ @echo 'extern void initialize_all_files PARAMS ((void));' >>init.c-tmp
+ @echo 'void initialize_all_files PARAMS ((void)) {' >>init.c-tmp
+ @-echo $(OBS) $(TSOBS) | \
+ tr ' ' '\012' | \
+ sed -e '/^Onindy.o/d' \
-e '/^nindy.o/d' \
-e '/ttyflush.o/d' \
-e '/xdr_ld.o/d' \
@@ -563,23 +611,20 @@ init.c: $(OBS) $(TSOBS)
-e '/version.o/d' \
-e '/^[a-z0-9A-Z_]*_[SU].o/d' \
-e '/[a-z0-9A-Z_]*-exp.tab.o/d' \
- -e 's/\.o/.c/'` ; \
- case $$filename in \
- "") ;; \
- *) sed <$(srcdir)/$$filename >>init.c-tmp -n \
- -e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (); \1 ();}/p' ; ;; \
- esac ; \
- done
+ -e 's/\.o/.c/' \
+ -e 's|\([^ ][^ ]*\)|$(srcdir)/\1|g' | \
+ while read f; do grep '^_initialize_[a-z_0-9A-Z]* *(' $$f 2>/dev/null; done | \
+ sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp
@echo '}' >>init.c-tmp
@mv init.c-tmp init.c
.PRECIOUS: init.c
# Removing the old gdb first works better if it is running, at least on SunOS.
-gdb: $(OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
- rm -f gdb
- $(CC_LD) $(INTERNAL_LDFLAGS) -o gdb \
- init.o $(OBS) $(TSOBS) $(ADD_FILES) $(CLIBS) $(LOADLIBES)
+gdb$(EXEEXT): $(OBS) $(BUILD_TUI) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
+ rm -f gdb$(EXEEXT)
+ $(HLDENV) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) -o gdb$(EXEEXT) \
+ init.o $(OBS) $(TSOBS) $(TUI_LIBRARY) $(ADD_FILES) $(CLIBS) $(LOADLIBES)
nlm: force
rootme=`pwd`; export rootme; $(MAKE) $(TARGET_FLAGS_TO_PASS) DO=all DODIRS=nlm subdir_do
@@ -602,16 +647,21 @@ libgdb-files: $(LIBGDBDEPS) Makefile.in
saber_gdb: $(SFILES) $(DEPFILES) copying.c version.c
#setopt load_flags $(CFLAGS) $(BFD_CFLAGS) -DHOST_SYS=SUN4_SYS
#load ./init.c $(SFILES)
- #unload $(srcdir)/c-exp.y $(srcdir)/m2-exp.y
+ #unload $(srcdir)/c-exp.y
+ #unload $(srcdir)/jv-exp.y
+ #unload $(srcdir)/m2-exp.y
#unload vx-share/*.h
#unload nindy-share/[A-Z]*
- #load c-exp.tab.c m2-exp.tab.c
+ #load c-exp.tab.c
+ #load jv-exp.tab.c
+ #load m2-exp.tab.c
#load copying.c version.c
#load ../opcodes/libopcodes.a
#load ../libiberty/libiberty.a
#load ../bfd/libbfd.a
#load ../readline/libreadline.a
#load ../mmalloc/libmmalloc.a
+ #load ../intl/libintl.a
#load -ltermcap
#load `echo " "$(DEPFILES) | sed -e 's/\.o/.c/g' -e 's, , ../,g'`
echo "Load .c corresponding to:" $(DEPFILES)
@@ -628,25 +678,9 @@ stop-gdb: stop-gdb.o
# gdb and put a copy in gdb1, and you can run it with "gdb gdb1".
# Removing gdb1 before the copy is the right thing if gdb1 is open
# in another process.
-gdb1: gdb
- rm -f gdb1
- cp gdb gdb1
-
-### fixme - this can't be right.
-# This checks the configure.in file versus the config/ directory.
-config-check: config-check-hosts config-check-targets
-config-check-hosts:
- grep gdb_host= $(srcdir)/configure.in | \
- sed -e 's/.*gdb_host=//' -e 's/ ;;$$/.mh/' | sort -u >HOSTconf.o
- (cd $(srcdir)/config; ls *.mh) >HOSTdir.o
- diff -u HOSTconf.o HOSTdir.o
-
-### fixme - nor can this.
-config-check-targets:
- grep gdb_target= $(srcdir)/configure.in | \
- sed -e 's/.*gdb_target=//' -e 's/ ;;$$/.mh/' | sort -u >TARGconf.o
- (cd $(srcdir)/config; ls *.mt) >TARGdir.o
- diff -u HOSTconf.o HOSTdir.o
+gdb1$(EXEEXT): gdb$(EXEEXT)
+ rm -f gdb1$(EXEEXT)
+ cp gdb$(EXEEXT) gdb1$(EXEEXT)
# FIXME. These are not generated by "make depend" because they only are there
# for some machines.
@@ -666,6 +700,13 @@ kdb: $(NTSSTART) $(OBS) $(NTSOBS) $(ADD_DEPS) $(CDEPS)
ld -o kdb $(NTSSTART) $(OBS) $(NTSOBS) init.o $(ADD_FILES) \
-lc $(CLIBS)
+# Have the TUI library depend on a phony target, so we'll always
+# recurse and make sure it's up to date. If it is, then the file will
+# be unchanged, and we won't rebuild it.
+# .PHONY: check-tui
+all-tui:
+ @(cd tui; ${MAKE} ${FLAGS_TO_PASS} all)
+
# Put the proper machine-specific files first, so M-. on a machine
# specific routine gets the one for the correct machine. (FIXME: those
# files go in twice; we should be removing them from the main list).
@@ -689,10 +730,10 @@ tags: TAGS
clean mostlyclean:
@$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(SUBDIRS)" subdir_do
- rm -f *.o $(ADD_FILES) *~ init.c-tmp
+ rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp
rm -f init.c version.c
- rm -f gdb core make.log libgdb-files
- rm -f gdb[0-9]
+ rm -f gdb$(EXEEXT) core make.log libgdb-files
+ rm -f gdb[0-9]$(EXEEXT)
# This used to depend on c-exp.tab.c m2-exp.tab.c TAGS
# I believe this is wrong; the makefile standards for distclean just
@@ -700,21 +741,27 @@ clean mostlyclean:
# functionality described is if the distributed files are unmodified.
distclean: clean
@$(MAKE) $(FLAGS_TO_PASS) DO=distclean "DODIRS=$(SUBDIRS)" subdir_do
- rm -f nm.h tm.h xm.h config.status config.h stamp-h
+ rm -f nm.h tm.h xm.h config.status config.h stamp-h .gdbinit
rm -f y.output yacc.acts yacc.tmp y.tab.h
rm -f config.log config.cache
rm -f Makefile
-maintainer-clean realclean: clean
+maintainer-clean: local-maintainer-clean do-maintainer-clean distclean
+realclean: maintainer-clean
+
+local-maintainer-clean:
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
- @$(MAKE) $(FLAGS_TO_PASS) DO=maintainer-clean "DODIRS=$(SUBDIRS)" subdir_do
- rm -f c-exp.tab.c f-exp.tab.c m2-exp.tab.c
+ rm -f c-exp.tab.c \
+ jv-exp.tab \
+ f-exp.tab.c m2-exp.tab.c
rm -f TAGS $(INFOFILES)
+ rm -f $(YYFILES)
rm -f nm.h tm.h xm.h config.status
- rm -f y.output yacc.acts yacc.tmp
- rm -f config.log config.cache
- rm -f Makefile
+
+do-maintainer-clean:
+ @$(MAKE) $(FLAGS_TO_PASS) DO=maintainer-clean "DODIRS=$(SUBDIRS)" \
+ subdir_do
diststuff: $(DISTSTUFF)
cd doc; $(MAKE) $(MFLAGS) all-doc
@@ -777,28 +824,44 @@ version.c: Makefile
# Makefile.in, but that was a pretty big annoyance.
c-exp.tab.o: c-exp.tab.c
c-exp.tab.c: c-exp.y
- $(YACC) $(YFLAGS) $(srcdir)/c-exp.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/c-exp.y y.tab.c c-exp.tmp -- $(YFLAGS)
-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 > c-exp.new
- -rm y.tab.c
+ -e '/^#line.*y.tab.c/d' \
+ < c-exp.tmp > c-exp.new
+ -rm c-exp.tmp
mv c-exp.new ./c-exp.tab.c
+jv-exp.tab.o: jv-exp.tab.c
+jv-exp.tab.c: jv-exp.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/jv-exp.y y.tab.c jv-exp.tmp -- $(YFLAGS)
+ -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' \
+ -e '/^#line.*y.tab.c/d' \
+ < jv-exp.tmp > jv-exp.new
+ -rm jv-exp.tmp
+ mv jv-exp.new ./jv-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
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/f-exp.y y.tab.c f-exp.tmp -- $(YFLAGS)
-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
+ -e '/^#line.*y.tab.c/d' \
+ < f-exp.tmp > f-exp.new
+ -rm f-exp.tmp
mv f-exp.new ./f-exp.tab.c
# m2-exp.tab.c is generated in objdir from m2-exp.y if it doesn't exist
@@ -807,19 +870,21 @@ f-exp.tab.c: f-exp.y c-exp.tab.c
# else.
m2-exp.tab.o: m2-exp.tab.c
m2-exp.tab.c: m2-exp.y
- $(YACC) $(YFLAGS) $(srcdir)/m2-exp.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/m2-exp.y y.tab.c m2-exp.tmp -- $(YFLAGS)
-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 > m2-exp.new
- -rm y.tab.c
+ -e '/^#line.*y.tab.c/d' \
+ < m2-exp.tmp > m2-exp.new
+ -rm m2-exp.tmp
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 f-exp.tab.c c-exp.tab.c
+.PRECIOUS: jv-exp.tab.c
lint: $(LINTFILES)
$(LINT) $(INCLUDE_CFLAGS) $(LINTFLAGS) $(LINTFILES) \
@@ -856,7 +921,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
dcache.c delta68-nat.c dpx2-nat.c dstread.c exec.c fork-child.c \
go32-xdep.c gould-tdep.c gould-xdep.c h8300-tdep.c h8500-tdep.c \
hp300ux-nat.c hppa-tdep.c hppab-nat.c hppah-nat.c \
- hpread.c \
+ hp-psymtab-read.c hp-symtab-read.c \
i386-tdep.c i386b-nat.c i386mach-nat.c i386v-nat.c \
i386aix-nat.c i386m3-nat.c i386v4-nat.c i386ly-tdep.c \
i387-tdep.c \
@@ -877,7 +942,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
remote-st.c remote-utils.c dcache.c \
remote-udi.c remote-vx.c remote-vx29k.c \
rs6000-nat.c rs6000-tdep.c \
- ser-go32.c ser-tcp.c sh-tdep.c solib.c sparc-nat.c \
+ ser-go32.c ser-ocd.c ser-tcp.c sh-tdep.c solib.c sparc-nat.c \
sparc-tdep.c sparcl-tdep.c sun3-nat.c sun386-nat.c \
symm-tdep.c symm-nat.c \
tahoe-tdep.c ultra3-nat.c ultra3-xdep.c umax-xdep.c \
@@ -886,73 +951,6 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
win32-nat.c \
xcoffread.c xcoffsolib.c z8k-tdep.c
-ALLCONFIG = config/a29k/a29k-kern.mt config/a29k/a29k-udi.mt config/a29k/vx29k.mt\
- config/a29k/a29k.mt config/a29k/ultra3.mh config/a29k/ultra3.mt \
- config/alpha/alpha-osf1.mh config/alpha/alpha-osf2.mh \
- config/alpha/alpha-osf1.mt config/alpha/alpha-nw.mt \
- config/arm/arm.mh config/arm/arm.mt config/convex/convex.mh \
- config/convex/convex.mt config/gould/np1.mh config/gould/np1.mt \
- config/gould/pn.mh config/gould/pn.mt config/h8300/h8300hms.mt \
- config/h8500/h8500hms.mt config/i386/go32.mh config/i386/i386aix.mh \
- config/i386/i386aix.mt config/i386/i386aout.mt config/i386/i386bsd.mh \
- config/i386/i386bsd.mt config/i386/i386lynx.mh \
- config/i386/i386lynx.mt config/i386/i386m3.mh config/i386/i386m3.mt \
- config/i386/i386mach.mh config/i386/i386mk.mh config/i386/i386mk.mt \
- config/i386/i386nw.mt config/i386/i386sco.mh \
- config/i386/i386sco4.mh \
- config/i386/i386sol2.mh config/i386/i386sol2.mt config/i386/i386v.mh \
- config/i386/i386v.mt config/i386/i386v32.mh config/i386/i386v4.mh \
- config/i386/i386v4.mt config/i386/linux.mh config/i386/linux.mt \
- config/i386/ncr3000.mh config/i386/ncr3000.mt config/i386/ptx.mh \
- config/i386/sun386.mh \
- config/i386/sun386.mt config/i386/symmetry.mh config/i386/symmetry.mt \
- config/i386/win32.mh config/i386/win32.mt \
- config/i960/mon960.mt \
- config/i960/nindy960.mt config/i960/vxworks960.mt config/m68k/3b1.mh \
- config/m68k/3b1.mt config/m68k/altos.mh config/m68k/altos.mt \
- config/m68k/amix.mh config/m68k/amix.mt config/m68k/apollo68b.mh \
- config/m68k/apollo68b.mt \
- config/m68k/apollo68v.mh \
- config/m68k/cisco.mt config/m68k/delta68.mh \
- config/m68k/delta68.mt config/m68k/dpx2.mh config/m68k/dpx2.mt \
- config/m68k/es1800.mt config/m68k/hp300bsd.mh \
- config/m68k/hp300bsd.mt config/m68k/hp300hpux.mh \
- config/m68k/hp300hpux.mt config/m68k/isi.mh config/m68k/isi.mt \
- config/m68k/m68klynx.mh config/m68k/m68klynx.mt \
- config/m68k/monitor.mt \
- config/m68k/news.mh config/m68k/news.mt config/m68k/news1000.mh \
- config/m68k/os68k.mt config/m68k/st2000.mt config/m68k/sun2os3.mh \
- config/m68k/sun2os3.mt config/m68k/sun2os4.mh config/m68k/sun2os4.mt \
- config/m68k/sun3os3.mh config/m68k/sun3os3.mt config/m68k/sun3os4.mh \
- config/m68k/sun3os4.mt config/m68k/vxworks68.mt config/m88k/delta88.mh \
- config/m88k/delta88.mt config/m88k/delta88v4.mh \
- config/m88k/delta88v4.mt config/m88k/m88k.mh config/m88k/m88k.mt \
- config/mips/bigmips.mt config/mips/bigmips64.mt \
- config/mips/decstation.mh \
- config/mips/decstation.mt config/mips/idt.mt config/mips/idtl.mt \
- config/mips/idt64.mt config/mips/idtl64.mt \
- config/mips/irix3.mh config/mips/irix3.mt config/mips/irix4.mh \
- config/mips/irix5.mh config/mips/irix5.mt \
- config/mips/littlemips.mh config/mips/littlemips.mt \
- config/mips/mipsel64.mt \
- config/mips/mipsm3.mh config/mips/mipsm3.mt \
- config/mips/mipsv4.mh config/mips/mipsv4.mt \
- config/mips/news-mips.mh config/mips/riscos.mh \
- config/none/none.mh config/none/none.mt config/ns32k/merlin.mh \
- config/ns32k/merlin.mt config/ns32k/ns32km3.mh config/ns32k/ns32km3.mt \
- config/ns32k/umax.mh config/ns32k/umax.mt \
- config/pa/hppabsd.mh config/pa/hppabsd.mt config/pa/hppahpux.mh \
- config/pa/hppahpux.mt config/pyr/pyramid.mh config/pyr/pyramid.mt \
- config/romp/rtbsd.mh config/rs6000/rs6000.mh config/rs6000/rs6000.mt \
- config/sh/sh.mt config/sparc/sparc-em.mt config/sparc/sparclite.mt \
- config/sparc/sparclynx.mh config/sparc/sparclynx.mt \
- config/sparc/sun4os4.mh config/sparc/sun4os4.mt \
- config/sparc/sun4sol2.mh config/sparc/sun4sol2.mt \
- config/sparc/vxsparc.mt config/tahoe/tahoe.mh config/tahoe/tahoe.mt \
- config/vax/vax.mt config/vax/vaxbsd.mh config/vax/vaxult.mh \
- config/vax/vaxult2.mh config/z8k/z8ksim.mt
-
-
udip2soc.o: $(srcdir)/29k-share/udi/udip2soc.c $(udiheaders)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/29k-share/udi/udip2soc.c
@@ -975,7 +973,8 @@ altos-xdep.o: altos-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
annotate.o: annotate.c $(defs_h) annotate.h $(value_h) target.h $(gdbtypes_h)
-arm-tdep.o: arm-tdep.c $(gdbcmd_h) $(gdbcore_h) $(inferior_h) $(defs_h)
+arm-tdep.o: arm-tdep.c $(gdbcmd_h) $(gdbcore_h) $(inferior_h) $(defs_h) \
+ $(gdbcore_h)
bcache.o: bcache.c bcache.h $(defs_h)
@@ -983,13 +982,11 @@ blockframe.o: blockframe.c $(defs_h) $(gdbcore_h) $(inferior_h) \
objfiles.h symfile.h target.h
breakpoint.o: breakpoint.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
- $(inferior_h) language.h target.h thread.h gdb_string.h
+ $(inferior_h) language.h target.h gdbthread.h gdb_string.h
buildsym.o: buildsym.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
objfiles.h symfile.h $(symtab_h) gdb_string.h
-callback.o: callback.c $(defs_h) callback.h
-
c-lang.o: c-lang.c c-lang.h $(defs_h) $(expression_h) $(gdbtypes_h) \
language.h parser-defs.h $(symtab_h)
@@ -1054,12 +1051,12 @@ corefile.o: corefile.c $(dis-asm_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
$(inferior_h) target.h language.h gdb_string.h
corelow.o: corelow.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
- target.h thread.h gdb_string.h
+ target.h gdbthread.h gdb_string.h
cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
$(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h
-dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h
+dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h $(gdbcore_h)
dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
@@ -1070,6 +1067,9 @@ delta68-nat.o: delta68-nat.c $(defs_h)
demangle.o: demangle.c $(defs_h) $(gdbcmd_h) gdb_string.h
+dink32-rom.o: dink32-rom.c monitor.h $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
+ $(inferior_h) target.h serial.h terminal.h
+
dpx2-nat.o: dpx2-nat.c $(defs_h) $(gdbcore_h) gdb_string.h
dstread.o: dstread.c gdb_string.h
@@ -1078,8 +1078,13 @@ dwarfread.o: dwarfread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
$(expression_h) $(gdbtypes_h) language.h objfiles.h symfile.h \
$(symtab_h) gdb_string.h
+dwarf2read.o: dwarf2read.c $(bfd_h) buildsym.h $(defs_h) \
+ $(expression_h) $(gdbtypes_h) language.h objfiles.h symfile.h \
+ $(symtab_h) gdb_string.h
+
elfread.o: elfread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
- gdb-stabs.h objfiles.h symfile.h $(symtab_h) gdb_string.h
+ gdb-stabs.h objfiles.h symfile.h $(symtab_h) gdb_string.h \
+ $(BFD_SRC)/elf-bfd.h $(INCLUDE_DIR)/elf/mips.h
environ.o: environ.c $(defs_h) environ.h $(gdbcore_h) gdb_string.h
@@ -1097,19 +1102,27 @@ findvar.o: findvar.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
gdb_string.h
fork-child.o: fork-child.c $(wait_h) $(defs_h) $(gdbcore_h) \
- $(inferior_h) target.h terminal.h thread.h gdb_string.h
+ $(inferior_h) target.h terminal.h gdbthread.h gdb_string.h
+tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(tracepoint_h) \
+ $(gdbtypes_h) $(expression_h) $(gdbcmd_h) $(value_h) target.h \
+ language.h gdb_string.h $(readline_headers)
+
+gdbarch.o: gdbarch.c $(defs_h) $(bfd_h) $(gdbcmd_h)
gdbtypes.o: gdbtypes.c $(bfd_h) complaints.h $(defs_h) $(expression_h) \
$(gdbtypes_h) language.h objfiles.h symfile.h $(symtab_h) target.h \
$(value_h) gdb_string.h
+gnu-nat.o: process_reply_S.h exc_request_S.h notify_S.h msg_reply_S.h \
+ exc_request_U.h msg_U.h gnu-nat.h
+
go32-xdep.o: go32-xdep.c
-gould-tdep.o: gould-tdep.c $(OP_INCLUDE)/np1.h $(defs_h) $(frame_h) \
- $(gdbcore_h) $(symtab_h)
+# OBSOLETE gould-tdep.o: gould-tdep.c $(OP_INCLUDE)/np1.h $(defs_h) $(frame_h) \
+# OBSOLETE $(gdbcore_h) $(symtab_h)
-gould-xdep.o: gould-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
+# OBSOLETE gould-xdep.o: gould-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
h8300-tdep.o: h8300-tdep.c $(defs_h) $(frame_h) $(symtab_h)
@@ -1123,8 +1136,11 @@ hppa-tdep.o: hppa-tdep.c $(wait_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
$(inferior_h) objfiles.h symfile.h target.h
hppab-nat.o: hppab-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h
+
hppah-nat.o: hppah-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h
+i386gnu-nat.o: gnu-nat.h
+
i386-tdep.o: i386-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
gdb_string.h
@@ -1135,7 +1151,7 @@ i386b-nat.o: i386b-nat.c $(defs_h)
i386ly-nat.o: i386ly-nat.c $(defs_h) $(frame_h) $(inferior_h) target.h
-i386ly-tdep.o: i386ly-tdep.c $(defs_h) $(inferior_h) target.h
+i386ly-tdep.o: i386ly-tdep.c $(defs_h) $(inferior_h) target.h $(gdbcore_h)
i386m3-nat.o: i386m3-nat.c $(defs_h) $(inferior_h) $(floatformat_h) target.h
@@ -1150,19 +1166,19 @@ i387-tdep.o: i387-tdep.c $(floatformat_h) $(defs_h) $(gdbcore_h) \
$(inferior_h) language.h
i960-tdep.o: i960-tdep.c $(floatformat_h) $(defs_h) $(expression_h) \
- $(frame_h) $(gdbtypes_h) $(symtab_h) $(value_h)
+ $(frame_h) $(gdbtypes_h) $(symtab_h) $(value_h) $(gdbcore_h)
infcmd.o: infcmd.c $(defs_h) environ.h $(gdbcmd_h) $(gdbcore_h) \
$(inferior_h) target.h language.h gdb_string.h
inflow.o: inflow.c $(bfd_h) $(command_h) $(defs_h) $(inferior_h) \
- signals.h target.h terminal.h thread.h gdb_string.h
+ signals.h target.h terminal.h gdbthread.h gdb_string.h
infptrace.o: infptrace.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
gdb_string.h $(wait_h) $(command_h)
infrun.o: infrun.c $(wait_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
- $(inferior_h) target.h thread.h gdb_string.h
+ $(inferior_h) target.h gdbthread.h gdb_string.h
inftarg.o: inftarg.c $(wait_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
target.h terminal.h $(command_h)
@@ -1174,6 +1190,18 @@ irix5-nat.o: irix5-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) target.h \
isi-xdep.o: isi-xdep.c
+jv-lang.o: jv-lang.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
+ $(expression_h) parser-defs.h language.h symfile.h objfiles.h \
+ gdb_string.h $(value_h) c-lang.h jv-lang.h $(gdbcore_h)
+
+jv-typeprint.o: jv-typeprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
+ $(value_h) $(INCLUDE_DIR)/demangle.h jv-lang.h gdb_string.h \
+ typeprint.h
+
+jv-valprint.o: jv-valprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
+ $(expression_h) $(value_h) $(INCLUDE_DIR)/demangle.h valprint.h \
+ language.h jv-lang.h c-lang.h
+
language.o: language.c $(bfd_h) $(defs_h) $(expression_h) $(frame_h) \
$(gdbcmd_h) $(gdbtypes_h) language.h parser-defs.h $(symtab_h) \
target.h $(value_h) gdb_string.h
@@ -1189,15 +1217,19 @@ m2-typeprint.o: m2-typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
$(value_h) gdb_string.h
m2-valprint.o: m2-valprint.c $(defs_h) $(gdbtypes_h) $(symtab_h) \
- valprint.h
+ valprint.h m2-lang.h
m3-nat.o: m3-nat.c $(defs_h) $(inferior_h) $(value_h) language.h target.h \
$(wait_h) $(gdbcmd_h) $(gdbcore_h)
-m68k-tdep.o: m68k-tdep.c $(defs_h) $(frame_h) $(symtab_h)
+m68k-tdep.o: m68k-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(value_h) \
+ $(gdbcore_h) gdb_string.h
m68kly-nat.o: m68kly-nat.c $(defs_h) $(frame_h) $(inferior_h) target.h
+m68klinux-nat.o: m68klinux-nat.c $(defs_h) $(frame_h) $(inferior_h) \
+ $(language_h) $(gdbcore_h) $(floatformat_h) target.h
+
m88k-nat.o: m88k-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
m88k-tdep.o: m88k-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
@@ -1218,7 +1250,7 @@ mipsm3-nat.o: mipsm3-nat.c $(defs_h) $(inferior_h)
os9kread.o: os9kread.c buildsym.h complaints.h $(bfd_h) $(defs_h) \
$(expression_h) gdb-stabs.h $(gdbcore_h) $(gdbtypes_h) language.h \
- objfiles.h partial-stab.h stabsread.h symfile.h $(symtab_h) \
+ objfiles.h stabsread.h symfile.h $(symtab_h) \
target.h gdb_string.h
mem-break.o: mem-break.c $(defs_h)
@@ -1260,7 +1292,7 @@ ns32km3-nat.o: ns32km3-nat.c $(defs_h) $(inferior_h)
ttyflush.o: nindy-share/ttyflush.c
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/nindy-share/ttyflush.c
-nindy-tdep.o: nindy-tdep.c $(defs_h) $(frame_h) $(symtab_h)
+nindy-tdep.o: nindy-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbcore_h)
ns32k-tdep.o: ns32k-tdep.c $(bfd_h) $(dis-asm_h) $(defs_h)
@@ -1275,13 +1307,29 @@ somread.o: somread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
somsolib.o: somsolib.c $(defs_h)
+hpux-thread.o: hpux-thread.c $(defs_h) gdbthread.h target.h inferior.h
+ $(CC) -c $(INTERNAL_CFLAGS) -I$(srcdir)/osf-share \
+ -I$(srcdir)/osf-share/HP800 -I/usr/include/dce $(srcdir)/hpux-thread.c
+
+# FIXME!!!
hpread.o: hpread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
gdb-stabs.h objfiles.h symfile.h $(symtab_h) gdb_string.h
+hp-psymtab-read.o: hp-psymtab-read.c hpread.h $(bfd_h) buildsym.h complaints.h \
+ $(defs_h) gdb-stabs.h objfiles.h symfile.h $(symtab_h) gdb_string.h
+
+hp-symtab-read.o: hp-symtab-read.c hpread.h $(bfd_h) buildsym.h complaints.h \
+ $(defs_h) gdb-stabs.h objfiles.h symfile.h $(symtab_h) gdb_string.h
+# END FIXME!!!
+
parse.o: parse.c $(command_h) $(defs_h) $(expression_h) $(frame_h) \
$(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
gdb_string.h
+ppc-bdm.o: ppc-bdm.c $(defs_h) $(gdbcore_h) gdb_string.h $(frame_h) \
+ $(inferior_h) $(bfd_h) symfile.h target.h $(wait_h) $(gdbcmd_h) \
+ objfiles.h gdb-stabs.h serial.h ocd.h
+
ppcbug-rom.o: ppcbug-rom.c monitor.h $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
$(inferior_h) target.h serial.h terminal.h
@@ -1301,11 +1349,25 @@ gnu-regex.o: gnu-regex.c gnu-regex.h $(defs_h) gdb_string.h
remote-adapt.o: remote-adapt.c $(wait_h) $(defs_h) $(gdbcore_h) \
$(inferior_h) target.h terminal.h gdb_string.h
-remote-arc.o: remote-arc.c gdb_string.h
-
remote-array.o: remote-array.c $(wait_h) $(defs_h) $(gdbcore_h) target.h \
gdb_string.h $(command_h) serial.h monitor.h $(remote_utils_h)
+remote-rdi.o: remote-rdi.c $(wait_h) $(defs_h) $(gdbcore_h) \
+ $(inferior_h) gdb_string.h
+
+rdi-share/libangsd.a: force
+ @dir=rdi-share; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ srcroot=`cd $(srcdir); pwd`; export srcroot; \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) all); \
+ else \
+ true; \
+ fi
+
+remote-d10v.o: remote-d10v.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
+ $(inferior_h) $(remote_utils_h) symfile.h terminal.h gdb_string.h
+
remote-rdp.o: remote-rdp.c $(wait_h) $(defs_h) $(gdbcore_h) \
$(inferior_h) gdb_string.h
@@ -1340,8 +1402,12 @@ remote-os9k.o: remote-os9k.c $(defs_h) $(gdbcore_h) $(wait_h) \
$(command_h) monitor.h $(remote_utils_h) $(symtab_h) symfile.h \
objfiles.h gdb-stabs.h gdb_string.h
+remote-sds.o: remote-sds.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
+ $(inferior_h) $(remote_utils_h) symfile.h terminal.h gdb_string.h
+
remote-sim.o: remote-sim.c $(wait_h) $(defs_h) $(gdbcore_h) \
- $(inferior_h) target.h terminal.h gdb_string.h
+ $(inferior_h) target.h terminal.h gdb_string.h \
+ $(INCLUDE_DIR)/callback.h
remote-st.o: remote-st.c $(wait_h) $(defs_h) $(gdbcore_h) serial.h \
target.h gdb_string.h
@@ -1360,6 +1426,10 @@ remote-vx29k.o: remote-vx29k.c $(wait_h) complaints.h $(defs_h) $(gdbcmd_h) \
vx-share/ptrace.h vx-share/xdr_ld.h vx-share/xdr_ptrace.h \
vx-share/xdr_rdb.h gdb_string.h
+ocd.o: ocd.c ocd.h $(gdbcore_h) gdb_string.h $(frame_h) $(inferior_h) \
+ $(bfd_h) symfile.h target.h $(wait_h) $(gdbcmd_h) objfiles.h \
+ gdb-stabs.h $(dcache_h) serial.h
+
remote-utils.o: remote-utils.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
$(inferior_h) $(remote_utils_h) gdb_string.h
@@ -1372,7 +1442,8 @@ remote-nrom.o: remote-nrom.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
rom68k-rom.o: rom68k-rom.c monitor.h $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
$(inferior_h) target.h serial.h terminal.h
-rs6000-nat.o: rs6000-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h
+rs6000-nat.o: rs6000-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h \
+ xcoffsolib.h
rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
target.h xcoffsolib.h
@@ -1381,15 +1452,17 @@ scm-exp.o: $(defs_h) $(value_h) parser-defs.h language.h c-lang.h \
scm-lang.h scm-tags.h
scm-lang.o: $(defs_h) $(value_h) parser-defs.h language.h c-lang.h \
- scm-lang.h scm-tags.h gdb_string.h
+ scm-lang.h scm-tags.h gdb_string.h $(gdbcore_h)
scm-valprint.o: $(defs_h) $(value_h) parser-defs.h language.h \
- scm-lang.h valprint.h
+ scm-lang.h valprint.h $(gdbcore_h)
ser-go32.o: ser-go32.c $(defs_h) serial.h
ser-mac.o: ser-mac.c $(defs_h) serial.h signals.h
+ser-ocd.o: ser-ocd.c $(defs_h) serial.h signals.h gdb_string.h
+
ser-tcp.o: ser-tcp.c $(defs_h) serial.h signals.h gdb_string.h
ser-unix.o: ser-unix.c $(defs_h) serial.h
@@ -1417,7 +1490,7 @@ sparc-nat.o: sparc-nat.c $(bfd_h) $(defs_h) $(inferior_h) $(gdbcore_h) \
target.h
sparc-tdep.o: sparc-tdep.c $(floatformat_h) $(defs_h) $(gdbcore_h) \
- $(inferior_h) objfiles.h symfile.h target.h
+ $(inferior_h) objfiles.h symfile.h target.h gdb_string.h
sparcl-tdep.o: sparcl-tdep.c $(defs_h) $(gdbcore_h) target.h
@@ -1431,7 +1504,12 @@ stabsread.o: stabsread.c $(bfd_h) $(INCLUDE_DIR)/aout/stab.def \
stack.o: stack.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
language.h target.h gdb_string.h
+ax-general.o: ax-general.c $(ax_h) $(defs_h)
+ax-gdb.o: ax-gdb.c $(defs_h) $(symtab_h) symfile.h $(gdbtypes_h) \
+ $(value_h) $(expression_h) $(command_h) $(ax_h) $(gdbcmd_h) ax-gdb.h
+
sun3-nat.o: sun3-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
+
sun386-nat.o: sun386-nat.c $(defs_h) $(inferior_h) $(gdbcore_h)
symfile.o: symfile.c $(breakpoint_h) complaints.h $(defs_h) \
@@ -1439,7 +1517,8 @@ symfile.o: symfile.c $(breakpoint_h) complaints.h $(defs_h) \
language.h objfiles.h symfile.h $(symtab_h) target.h \
gdb_string.h
-symm-tdep.o: symm-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
+symm-tdep.o: symm-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
+
symm-nat.o: symm-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
symmisc.o: symmisc.c $(bfd_h) $(breakpoint_h) $(command_h) $(defs_h) \
@@ -1457,7 +1536,7 @@ tahoe-tdep.o: tahoe-tdep.c $(OP_INCLUDE)/tahoe.h $(defs_h) \
target.o: target.c $(bfd_h) $(defs_h) $(gdbcmd_h) $(inferior_h) \
objfiles.h symfile.h target.h gdb_string.h
-thread.o: thread.c $(defs_h) thread.h $(gdbcmd_h)
+thread.o: thread.c $(defs_h) gdbthread.h $(gdbcmd_h)
top.o: top.c top.h $(bfd_h) $(getopt_h) $(readline_headers) call-cmds.h \
$(defs_h) $(gdbcmd_h) $(inferior_h) language.h signals.h \
@@ -1468,7 +1547,9 @@ typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
$(value_h) gdb_string.h
ultra3-nat.o: ultra3-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
+
ultra3-xdep.o: ultra3-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
+
umax-xdep.o: umax-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
utils.o: utils.c $(bfd_h) $(defs_h) $(expression_h) $(gdbcmd_h) \
@@ -1484,7 +1565,7 @@ valops.o: valops.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
valprint.o: valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
$(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
- $(value_h) gdb_string.h
+ $(value_h) gdb_string.h valprint.h
values.o: values.c $(defs_h) $(expression_h) $(frame_h) $(gdbcmd_h) \
$(gdbcore_h) $(gdbtypes_h) $(symtab_h) target.h $(value_h) \
@@ -1492,7 +1573,7 @@ values.o: values.c $(defs_h) $(expression_h) $(frame_h) $(gdbcmd_h) \
vax-tdep.o: vax-tdep.c $(OP_INCLUDE)/vax.h $(defs_h) $(symtab_h)
-w65-tdep.o : w65-tdep.c
+w65-tdep.o : w65-tdep.c $(gdbcore_h)
win32-nat.o: win32-nat.c $(gdbcmd_h) $(gdbcore_h) $(inferior_h) $(defs_h) \
gdb_string.h
@@ -1518,12 +1599,16 @@ xcoffread.o: xcoffread.c $(bfd_h) $(INCLUDE_DIR)/aout/stab.def \
xcoffsolib.o: xcoffsolib.c $(bfd_h) $(defs_h) xcoffsolib.h
z8k-tdep.o: z8k-tdep.c $(bfd_h) $(dis-asm_h) $(defs_h) $(frame_h) \
- $(gdbcmd_h) $(gdbtypes_h) $(symtab_h)
+ $(gdbcmd_h) $(gdbtypes_h) $(symtab_h) $(gdbcore_h)
c-exp.tab.o: c-exp.tab.c c-lang.h $(defs_h) $(expression_h) \
$(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
$(bfd_h) objfiles.h symfile.h
+jv-exp.tab.o: jv-exp.tab.c jv-lang.h $(defs_h) $(expression_h) \
+ $(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
+ $(bfd_h) objfiles.h symfile.h
+
f-exp.tab.o: f-exp.tab.c f-lang.h $(defs_h) $(expression_h) \
language.h parser-defs.h $(value_h) $(bfd_h) objfiles.h symfile.h
diff --git a/contrib/gdb/gdb/NEWS b/contrib/gdb/gdb/NEWS
index 979a878..e6aaba3 100644
--- a/contrib/gdb/gdb/NEWS
+++ b/contrib/gdb/gdb/NEWS
@@ -1,6 +1,279 @@
What has changed in GDB?
(Organized release by release)
+*** Changes in GDB-4.18:
+
+* New native configurations
+
+HP-UX 10.20 hppa*-*-hpux10.20
+HP-UX 11.x hppa*-*-hpux11.0*
+M68K Linux m68*-*-linux*
+
+* New targets
+
+Fujitsu FR30 fr30-*-elf*
+Intel StrongARM strongarm-*-*
+Mitsubishi D30V d30v-*-*
+
+* OBSOLETE configurations
+
+Gould PowerNode, NP1 np1-*-*, pn-*-*
+
+Configurations that have been declared obsolete will be commented out,
+but the code will be left in place. If there is no activity to revive
+these configurations before the next release of GDB, the sources will
+be permanently REMOVED.
+
+* ANSI/ISO C
+
+As a compatibility experiment, GDB's source files buildsym.h and
+buildsym.c have been converted to pure standard C, no longer
+containing any K&R compatibility code. We believe that all systems in
+use today either come with a standard C compiler, or have a GCC port
+available. If this is not true, please report the affected
+configuration to bug-gdb@gnu.org immediately. See the README file for
+information about getting a standard C compiler if you don't have one
+already.
+
+* Readline 2.2
+
+GDB now uses readline 2.2.
+
+* set extension-language
+
+You can now control the mapping between filename extensions and source
+languages by using the `set extension-language' command. For instance,
+you can ask GDB to treat .c files as C++ by saying
+ set extension-language .c c++
+The command `info extensions' lists all of the recognized extensions
+and their associated languages.
+
+* Setting processor type for PowerPC and RS/6000
+
+When GDB is configured for a powerpc*-*-* or an rs6000*-*-* target,
+you can use the `set processor' command to specify what variant of the
+PowerPC family you are debugging. The command
+
+ set processor NAME
+
+sets the PowerPC/RS6000 variant to NAME. GDB knows about the
+following PowerPC and RS6000 variants:
+
+ ppc-uisa PowerPC UISA - a PPC processor as viewed by user-level code
+ rs6000 IBM RS6000 ("POWER") architecture, user-level view
+ 403 IBM PowerPC 403
+ 403GC IBM PowerPC 403GC
+ 505 Motorola PowerPC 505
+ 860 Motorola PowerPC 860 or 850
+ 601 Motorola PowerPC 601
+ 602 Motorola PowerPC 602
+ 603 Motorola/IBM PowerPC 603 or 603e
+ 604 Motorola PowerPC 604 or 604e
+ 750 Motorola/IBM PowerPC 750 or 750
+
+At the moment, this command just tells GDB what to name the
+special-purpose processor registers. Since almost all the affected
+registers are inaccessible to user-level programs, this command is
+only useful for remote debugging in its present form.
+
+* HP-UX support
+
+Thanks to a major code donation from Hewlett-Packard, GDB now has much
+more extensive support for HP-UX. Added features include shared
+library support, kernel threads and hardware watchpoints for 11.00,
+support for HP's ANSI C and C++ compilers, and a compatibility mode
+for xdb and dbx commands.
+
+* Catchpoints
+
+HP's donation includes the new concept of catchpoints, which is a
+generalization of the old catch command. On HP-UX, it is now possible
+to catch exec, fork, and vfork, as well as library loading.
+
+This means that the existing catch command has changed; its first
+argument now specifies the type of catch to be set up. See the
+output of "help catch" for a list of catchpoint types.
+
+* Debugging across forks
+
+On HP-UX, you can choose which process to debug when a fork() happens
+in the inferior.
+
+* TUI
+
+HP has donated a curses-based terminal user interface (TUI). To get
+it, build with --enable-tui. Although this can be enabled for any
+configuration, at present it only works for native HP debugging.
+
+* GDB remote protocol additions
+
+A new protocol packet 'X' that writes binary data is now available.
+Default behavior is to try 'X', then drop back to 'M' if the stub
+fails to respond. The settable variable `remotebinarydownload'
+allows explicit control over the use of 'X'.
+
+For 64-bit targets, the memory packets ('M' and 'm') can now contain a
+full 64-bit address. The command
+
+ set remoteaddresssize 32
+
+can be used to revert to the old behaviour. For existing remote stubs
+the change should not be noticed, as the additional address information
+will be discarded.
+
+In order to assist in debugging stubs, you may use the maintenance
+command `packet' to send any text string to the stub. For instance,
+
+ maint packet heythere
+
+sends the packet "$heythere#<checksum>". Note that it is very easy to
+disrupt a debugging session by sending the wrong packet at the wrong
+time.
+
+The compare-sections command allows you to compare section data on the
+target to what is in the executable file without uploading or
+downloading, by comparing CRC checksums.
+
+* Tracing can collect general expressions
+
+You may now collect general expressions at tracepoints. This requires
+further additions to the target-side stub; see tracepoint.c and
+doc/agentexpr.texi for further details.
+
+* mask-address variable for Mips
+
+For Mips targets, you may control the zeroing of the upper 32 bits of
+a 64-bit address by entering `set mask-address on'. This is mainly
+of interest to users of embedded R4xxx and R5xxx processors.
+
+* Higher serial baud rates
+
+GDB's serial code now allows you to specify baud rates 57600, 115200,
+230400, and 460800 baud. (Note that your host system may not be able
+to achieve all of these rates.)
+
+* i960 simulator
+
+The i960 configuration now includes an initial implementation of a
+builtin simulator, contributed by Jim Wilson.
+
+
+*** Changes in GDB-4.17:
+
+* New native configurations
+
+Alpha GNU/Linux alpha*-*-linux*
+Unixware 2.x i[3456]86-unixware2*
+Irix 6.x mips*-sgi-irix6*
+PowerPC GNU/Linux powerpc-*-linux*
+PowerPC Solaris powerpcle-*-solaris*
+Sparc GNU/Linux sparc-*-linux*
+Motorola sysV68 R3V7.1 m68k-motorola-sysv
+
+* New targets
+
+Argonaut Risc Chip (ARC) arc-*-*
+Hitachi H8/300S h8300*-*-*
+Matsushita MN10200 w/simulator mn10200-*-*
+Matsushita MN10300 w/simulator mn10300-*-*
+MIPS NEC VR4100 mips64*vr4100*{,el}-*-elf*
+MIPS NEC VR5000 mips64*vr5000*{,el}-*-elf*
+MIPS Toshiba TX39 mips64*tx39*{,el}-*-elf*
+Mitsubishi D10V w/simulator d10v-*-*
+Mitsubishi M32R/D w/simulator m32r-*-elf*
+Tsqware Sparclet sparclet-*-*
+NEC V850 w/simulator v850-*-*
+
+* New debugging protocols
+
+ARM with RDI protocol arm*-*-*
+M68K with dBUG monitor m68*-*-{aout,coff,elf}
+DDB and LSI variants of PMON protocol mips*-*-*
+PowerPC with DINK32 monitor powerpc{,le}-*-eabi
+PowerPC with SDS protocol powerpc{,le}-*-eabi
+Macraigor OCD (Wiggler) devices powerpc{,le}-*-eabi
+
+* DWARF 2
+
+All configurations can now understand and use the DWARF 2 debugging
+format. The choice is automatic, if the symbol file contains DWARF 2
+information.
+
+* Java frontend
+
+GDB now includes basic Java language support. This support is
+only useful with Java compilers that produce native machine code.
+
+* solib-absolute-prefix and solib-search-path
+
+For SunOS and SVR4 shared libraries, you may now set the prefix for
+loading absolute shared library symbol files, and the search path for
+locating non-absolute shared library symbol files.
+
+* Live range splitting
+
+GDB can now effectively debug code for which GCC has performed live
+range splitting as part of its optimization. See gdb/doc/LRS for
+more details on the expected format of the stabs information.
+
+* Hurd support
+
+GDB's support for the GNU Hurd, including thread debugging, has been
+updated to work with current versions of the Hurd.
+
+* ARM Thumb support
+
+GDB's ARM target configuration now handles the ARM7T (Thumb) 16-bit
+instruction set. ARM GDB automatically detects when Thumb
+instructions are in use, and adjusts disassembly and backtracing
+accordingly.
+
+* MIPS16 support
+
+GDB's MIPS target configurations now handle the MIP16 16-bit
+instruction set.
+
+* Overlay support
+
+GDB now includes support for overlays; if an executable has been
+linked such that multiple sections are based at the same address, GDB
+will decide which section to use for symbolic info. You can choose to
+control the decision manually, using overlay commands, or implement
+additional target-side support and use "overlay load-target" to bring
+in the overlay mapping. Do "help overlay" for more detail.
+
+* info symbol
+
+The command "info symbol <address>" displays information about
+the symbol at the specified address.
+
+* Trace support
+
+The standard remote protocol now includes an extension that allows
+asynchronous collection and display of trace data. This requires
+extensive support in the target-side debugging stub. Tracing mode
+includes a new interaction mode in GDB and new commands: see the
+file tracepoint.c for more details.
+
+* MIPS simulator
+
+Configurations for embedded MIPS now include a simulator contributed
+by Cygnus Solutions. The simulator supports the instruction sets
+of most MIPS variants.
+
+* Sparc simulator
+
+Sparc configurations may now include the ERC32 simulator contributed
+by the European Space Agency. The simulator is not built into
+Sparc targets by default; configure with --enable-sim to include it.
+
+* set architecture
+
+For target configurations that may include multiple variants of a
+basic architecture (such as MIPS and SH), you may now set the
+architecture explicitly. "set arch" sets, "info arch" lists
+the possible architectures.
+
*** Changes in GDB-4.16:
* New native configurations
diff --git a/contrib/gdb/gdb/README b/contrib/gdb/gdb/README
index c58bcb7..fd791ce 100644
--- a/contrib/gdb/gdb/README
+++ b/contrib/gdb/gdb/README
@@ -1,9 +1,12 @@
- README for gdb-4.16 release
- Updated 10-Apr-96 by Fred Fish
+ README for gdb-4.18 release
+ Updated 4 Apr 1999 by Jim Blandy
This is GDB, the GNU source-level debugger.
A summary of new features is in the file `NEWS'.
+See the GDB home page at http://www.cygnus.com/gdb/ for up to date
+release information, mailing list links and archives, etc.
+
Unpacking and Installation -- quick overview
==========================
@@ -11,7 +14,7 @@ Unpacking and Installation -- quick overview
In this release, the GDB debugger sources, the generic GNU include
files, the BFD ("binary file description") library, the readline
library, and other libraries all have directories of their own
-underneath the gdb-4.16 directory. The idea is that a variety of GNU
+underneath the gdb-4.18 directory. The idea is that a variety of GNU
tools can share a common copy of these things. Be aware of variation
over time--for example don't try to build gdb with a copy of bfd from
a release other than the gdb release (such as a binutils or gas
@@ -20,8 +23,8 @@ Configuration scripts and makefiles exist to cruise up and down this
directory tree and automatically build all the pieces in the right
order.
-When you unpack the gdb-4.16.tar.gz file, you'll find a directory
-called `gdb-4.16', which contains:
+When you unpack the gdb-4.18.tar.gz file, you'll find a directory
+called `gdb-4.18', which contains:
COPYING config.sub* libiberty/ opcodes/
COPYING.LIB configure* mmalloc/ readline/
@@ -33,7 +36,7 @@ called `gdb-4.16', which contains:
To build GDB, you can just do:
- cd gdb-4.16
+ cd gdb-4.18
./configure
make
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
@@ -45,6 +48,11 @@ argument, e.g., sun4 or decstation.
If you get compiler warnings during this stage, see the `Reporting Bugs'
section below; there are a few known problems.
+GDB requires an ANSI C compiler. If you do not have an ANSI C
+compiler for your system, you may be able to download and install the
+GNU CC compiler. It is available via anonymous FTP from ftp.gnu.org,
+in /pub/gnu/gcc (as a URL, that's ftp://ftp.gnu.org/pub/gnu/gcc).
+
GDB can be used as a cross-debugger, running on a machine of one type
while debugging a program running on a machine of another type. See below.
@@ -52,22 +60,6 @@ while debugging a program running on a machine of another type. See below.
More Documentation
******************
- The GDB 4 release includes an already-formatted reference card,
-ready for printing with PostScript or Ghostscript, in the `gdb'
-subdirectory of the main source directory. (In `gdb-4.16/gdb/refcard.ps'.)
-If you can use PostScript or Ghostscript with your printer, you can
-print the reference card immediately with `refcard.ps'.
-
- The release also includes the source for the reference card. You
-can format it, using TeX, by typing:
-
- make refcard.dvi
-
- The GDB reference card is designed to print in landscape mode on US
-"letter" size paper; that is, on a sheet 11 inches wide by 8.5 inches
-high. You will need to specify this form of printing as an option to
-your DVI output program.
-
All the documentation for GDB comes as part of the machine-readable
distribution. The documentation is written in Texinfo format, which is
a documentation system that uses a single source file to produce both
@@ -76,27 +68,28 @@ formatting commands to create the on-line version of the documentation
and TeX (or `texi2roff') to typeset the printed version.
GDB includes an already formatted copy of the on-line Info version of
-this manual in the `gdb' subdirectory. The main Info file is
-`gdb-VERSION-NUMBER/gdb/gdb.info', and it refers to subordinate files
-matching `gdb.info*' in the same directory. If necessary, you can
-print out these files, or read them with any editor; but they are
-easier to read using the `info' subsystem in GNU Emacs or the
-standalone `info' program, available as part of the GNU Texinfo
-distribution.
+this manual in the `gdb/doc' subdirectory. The main Info file is
+`gdb-4.18/gdb/doc/gdb.info', and it refers to subordinate files matching
+`gdb.info*' in the same directory. If necessary, you can print out
+these files, or read them with any editor; but they are easier to read
+using the `info' subsystem in GNU Emacs or the standalone `info' program,
+available as part of the GNU Texinfo distribution.
If you want to format these Info files yourself, you need one of the
-Info formatting programs, such as `texinfo-format-buffer' or `makeinfo'.
+Info formatting programs, such as `texinfo-format-buffer' or
+`makeinfo'.
If you have `makeinfo' installed, and are in the top level GDB
-source directory (`gdb-4.16', in the case of version 4.16), you can make
+source directory (`gdb-4.18', in the case of version 4.18), you can make
the Info file by typing:
- cd gdb
- make gdb.info
+ cd gdb/doc
+ make info
- If you want to typeset and print copies of this manual, you need TeX,
-a program to print its DVI output files, and `texinfo.tex', the Texinfo
-definitions file.
+ If you want to typeset and print copies of this manual, you need
+TeX, a program to print its DVI output files, and `texinfo.tex', the
+Texinfo definitions file. This file is included in the GDB
+distribution, in the directory `gdb-4.18/texinfo'.
TeX is a typesetting program; it does not print files directly, but
produces output files called DVI files. To print a typeset document,
@@ -110,11 +103,11 @@ without any extension or a `.dvi' extension.
This file tells TeX how to typeset a document written in Texinfo
format. On its own, TeX cannot read, much less typeset a Texinfo file.
`texinfo.tex' is distributed with GDB and is located in the
-`gdb-VERSION-NUMBER/texinfo' directory.
+`gdb-4.18/texinfo' directory.
If you have TeX and a DVI printer program installed, you can typeset
and print this manual. First switch to the the `gdb' subdirectory of
-the main source directory (for example, to `gdb-4.16/gdb') and then type:
+the main source directory (for example, to `gdb-4.18/gdb') and then type:
make gdb.dvi
@@ -130,58 +123,71 @@ preparing GDB for installation; you can then use `make' to build the
a single directory, whose name is usually composed by appending the
version number to `gdb'.
- For example, the GDB version 4.16 distribution is in the `gdb-4.16'
+ For example, the GDB version 4.18 distribution is in the `gdb-4.18'
directory. That directory contains:
-`gdb-4.16/{COPYING,COPYING.LIB}'
+`gdb-4.18/{COPYING,COPYING.LIB}'
Standard GNU license files. Please read them.
-`gdb-4.16/bfd'
+`gdb-4.18/bfd'
source for the Binary File Descriptor library
-`gdb-4.16/config*'
+`gdb-4.18/config*'
script for configuring GDB, along with other support files
-`gdb-4.16/gdb'
+`gdb-4.18/gdb'
the source specific to GDB itself
-`gdb-4.16/include'
+`gdb-4.18/include'
GNU include files
-`gdb-4.16/libiberty'
+`gdb-4.18/libiberty'
source for the `-liberty' free software library
-`gdb-4.16/mmalloc'
+`gdb-4.18/mmalloc'
source for the GNU memory-mapped malloc package
-`gdb-4.16/opcodes'
+`gdb-4.18/opcodes'
source for the library of opcode tables and disassemblers
-`gdb-4.16/readline'
+`gdb-4.18/readline'
source for the GNU command-line interface
-'gdb-4.16/sim'
- source for some simulators (z8000, H8/300, H8/500, etc)
+`gdb-4.18/sim'
+ source for some simulators (ARM, D10V, SPARC, M32R, MIPS, PPC, V850, etc)
+
+`gdb-4.18/intl'
+ source for the GNU gettext library, for internationalization.
+ This is slightly modified from the standalone gettext
+ distribution you can get from GNU.
+
+`gdb-4.18/texinfo'
+ The `texinfo.tex' file, which you need in order to make a printed
+ manual using TeX.
+
+`gdb-4.18/etc'
+ Coding standards, useful files for editing GDB, and other
+ miscellanea.
+
+`gdb-4.18/utils'
+ A grab bag of random utilities.
+
The simplest way to configure and build GDB is to run `configure'
from the `gdb-VERSION-NUMBER' source directory, which in this example
-is the `gdb-4.16' directory.
+is the `gdb-4.18' directory.
First switch to the `gdb-VERSION-NUMBER' source directory if you are
-not already in it; then run `configure'. Pass the identifier for the
-platform on which GDB will run as an argument.
+not already in it; then run `configure'.
For example:
- cd gdb-4.16
- ./configure HOST
+ cd gdb-4.18
+ ./configure
make
-where HOST is an identifier such as `sun4' or `decstation', that
-identifies the platform where GDB will run.
-
- Running `configure HOST' followed by `make' builds the `bfd',
-`readline', `mmalloc', and `libiberty' libraries, then `gdb' itself.
+ Running `configure' followed by `make' builds the `bfd',
+`readline', `mmalloc', and `libiberty' libraries, then `gdb' itself.
The configured source files, and the binaries, are left in the
corresponding source directories.
@@ -189,11 +195,11 @@ corresponding source directories.
does not recognize this automatically when you run a different shell,
you may need to run `sh' on it explicitly:
- sh configure HOST
+ sh configure
If you run `configure' from a directory that contains source
-directories for multiple libraries or programs, such as the `gdb-4.16'
-source directory for version 4.16, `configure' creates configuration
+directories for multiple libraries or programs, such as the `gdb-4.18'
+source directory for version 4.18, `configure' creates configuration
files for every directory level underneath (unless you tell it not to,
with the `--norecursion' option).
@@ -201,11 +207,11 @@ with the `--norecursion' option).
directories in the GDB distribution, if you only want to configure that
subdirectory; but be sure to specify a path to it.
- For example, with version 4.16, type the following to configure only
+ For example, with version 4.18, type the following to configure only
the `bfd' subdirectory:
- cd gdb-4.16/bfd
- ../configure HOST
+ cd gdb-4.18/bfd
+ ../configure
You can install `gdb' anywhere; it has no hardwired paths. However,
you should make sure that the shell on your path (named by the `SHELL'
@@ -233,13 +239,13 @@ directory. If the path to `configure' would be the same as the
argument to `--srcdir', you can leave out the `--srcdir' option; it
will be assumed.)
- For example, with version 4.16, you can build GDB in a separate
+ For example, with version 4.18, you can build GDB in a separate
directory for a Sun 4 like this:
- cd gdb-4.16
+ cd gdb-4.18
mkdir ../gdb-sun4
cd ../gdb-sun4
- ../gdb-4.16/configure sun4
+ ../gdb-4.18/configure sun4
make
When `configure' builds a configuration using a remote source
@@ -260,8 +266,8 @@ called `configure' (or one of its subdirectories).
The `Makefile' that `configure' generates in each source directory
also runs recursively. If you type `make' in a source directory such
-as `gdb-4.16' (or in a separate configured directory configured with
-`--srcdir=PATH/gdb-4.16'), you will build all the required libraries,
+as `gdb-4.18' (or in a separate configured directory configured with
+`--srcdir=PATH/gdb-4.18'), you will build all the required libraries,
and then build GDB.
When you have multiple hosts or targets configured in separate
@@ -291,20 +297,20 @@ abbreviations to full names; you can read the script, if you wish, or
you can use it to test your guesses on abbreviations--for example:
% sh config.sub sun4
- sparc-sun-sunos411
+ sparc-sun-sunos4.1.1
% sh config.sub sun3
- m68k-sun-sunos411
+ m68k-sun-sunos4.1.1
% sh config.sub decstation
- mips-dec-ultrix42
+ mips-dec-ultrix4.2
% sh config.sub hp300bsd
m68k-hp-bsd
% sh config.sub i386v
- i386-unknown-sysv
+ i386-pc-sysv
% sh config.sub i786v
Invalid configuration `i786v': machine `i786v' not recognized
`config.sub' is also distributed in the GDB source directory
-(`gdb-4.16', for version 4.16).
+(`gdb-4.18', for version 4.18).
`configure' options
@@ -319,7 +325,10 @@ for a full explanation of `configure'.
[--prefix=DIR]
[--srcdir=PATH]
[--norecursion] [--rm]
- [--target=TARGET] HOST
+ [--enable-build-warnings]
+ [--target=TARGET]
+ [--host=HOST]
+ [HOST]
You may introduce options with a single `-' rather than `--' if you
prefer; but you may abbreviate option names if you use `--'.
@@ -350,6 +359,17 @@ prefer; but you may abbreviate option names if you use `--'.
`--rm'
Remove the configuration that the other arguments specify.
+`--enable-build-warnings'
+ When building the GDB sources, ask the compiler to warn about any
+ code which looks even vaguely suspicious. You should only using
+ this feature if you're compiling with GNU CC. It passes the
+ following flags:
+ -Wall
+ -Wpointer-arith
+ -Wstrict-prototypes
+ -Wmissing-prototypes
+ -Wmissing-declarations
+
`--target=TARGET'
Configure GDB for cross-debugging programs running on the specified
TARGET. Without this option, GDB is configured to debug programs
@@ -358,12 +378,16 @@ prefer; but you may abbreviate option names if you use `--'.
There is no convenient way to generate a list of all available
targets.
-`HOST ...'
+`--host=HOST'
Configure GDB to run on the specified HOST.
There is no convenient way to generate a list of all available
hosts.
+`HOST ...'
+ Same as `--host=HOST'. If you omit this, GDB will guess; it's
+ quite accurate.
+
`configure' accepts other options, for compatibility with configuring
other GNU tools recursively; but these are the only options that affect
GDB or its supporting libraries.
@@ -372,7 +396,8 @@ GDB or its supporting libraries.
Languages other than C
=======================
-See the GDB manual (doc/gdb.texinfo) for information on this.
+See the GDB manual (gdb/doc/gdb.texinfo) for information on this.
+
Kernel debugging
=================
@@ -391,26 +416,35 @@ remote stubs to be used with remote.c. They are designed to run
standalone on an m68k, i386, or SPARC cpu and communicate properly with
the remote.c stub over a serial line.
-The file rem-multi.shar contains a general stub that can probably
-run on various different flavors of unix to allow debugging over a
-serial line from one machine to another.
+The directory gdb/gdbserver/ contains `gdbserver', a program that
+allows remote debugging for Unix applications. gdbserver is only
+supported for some native configurations, including Sun 3, Sun 4,
+and Linux.
+
+There are a number of remote interfaces for talking to existing ROM
+monitors and other hardware:
-Some working remote interfaces for talking to existing ROM monitors
-are:
remote-adapt.c AMD 29000 "Adapt"
+ remote-array.c Array Tech RAID controller
+ remote-bug.c Motorola BUG monitor
+ remote-d10v.c GDB protocol, talking to a d10v chip
remote-e7000.c Hitachi E7000 ICE
remote-eb.c AMD 29000 "EBMON"
remote-es.c Ericsson 1800 monitor
+ remote-est.c EST emulator
remote-hms.c Hitachi Micro Systems H8/300 monitor
remote-mips.c MIPS remote debugging protocol
remote-mm.c AMD 29000 "minimon"
remote-nindy.c Intel 960 "Nindy"
+ remote-nrom.c NetROM ROM emulator
remote-os9k.c PC running OS/9000
+ remote-rdi.c ARM with Angel monitor
+ remote-rdp.c ARM with Demon monitor
+ remote-sds.c PowerPC SDS monitor
remote-sim.c Generalized simulator protocol
remote-st.c Tandem ST-2000 monitor
remote-udi.c AMD 29000 using the AMD "Universal Debug Interface"
remote-vx.c VxWorks realtime kernel
- remote-z8k.c Zilog Z8000 simulator
Remote-vx.c and the vx-share subdirectory contain a remote interface for the
VxWorks realtime kernel, which communicates over TCP using the Sun
@@ -429,9 +463,9 @@ Reporting Bugs
===============
The correct address for reporting bugs found in gdb is
-"bug-gdb@prep.ai.mit.edu". Please email all bugs, and all requests for
+"bug-gdb@gnu.org". Please email all bugs, and all requests for
help with GDB, to that address. Please include the GDB version number
-(e.g., gdb-4.16), and how you configured it (e.g., "sun4" or "mach386
+(e.g., gdb-4.18), and how you configured it (e.g., "sun4" or "mach386
host, i586-intel-synopsys target"). Since GDB now supports so many
different configurations, it is important that you be precise about this.
If at all possible, you should include the actual banner that GDB prints
@@ -489,10 +523,8 @@ Known bugs:
subsystem that is on the IDO CD, otherwise you will get complaints
that certain files such as `/usr/include/syms.h' cannot be found.
- * Unixware 2.x is not yet supported.
-
* Notes for BSD/386:
- To compile gdb-4.16 on BSD/386, you must run the configure script and
+ To compile gdb-4.18 on BSD/386, you must run the configure script and
its subscripts with bash. Here is an easy way to do this:
bash -c 'CONFIG_SHELL=/bin/bash ./configure'
@@ -514,17 +546,28 @@ the compiler actually outputs or the debugger actually understands.
X Windows versus GDB
=====================
-There is an "xxgdb", which seems to work for simple operations,
-which was posted to comp.sources.x.
+You should check out DDD, the Data Display Debugger. Here's the blurb
+from the DDD web site, http://www.cs.tu-bs.de/softech/ddd:
+
+ The Data Display Debugger (DDD) is a popular graphical user
+ interface for command-line debuggers such as GDB, DBX, JDB, WDB,
+ XDB, the Perl debugger, and the Python debugger. Besides ``usual''
+ front-end features such as viewing source texts, DDD has become
+ famous through its interactive graphical data display, where data
+ structures are displayed as graphs. A simple mouse click
+ dereferences pointers or views structure contents, updated each
+ time the program stops. Using DDD, you can reason about your
+ application by watching its data, not just by viewing it execute
+ lines of source code.
-For those interested in auto display of source and the availability of
-an editor while debugging I suggest trying gdb-mode in GNU Emacs
-(Try typing M-x gdb RETURN). Comments on this mode are welcome.
+Emacs users will very likely enjoy the Grand Unified Debugger mode;
+try typing `M-x gdb RET'.
Those interested in experimenting with a new kind of gdb-mode
should load gdb/gdba.el into GNU Emacs 19.25 or later. Comments
on this mode are also welcome.
+
Writing Code for GDB
=====================
@@ -532,9 +575,7 @@ There is a lot of information about writing code for GDB in the
internals manual, distributed with GDB in gdb/doc/gdbint.texinfo. You
can read it by hand, print it by using TeX and texinfo, or process it
into an `info' file for use with Emacs' info mode or the standalone
-`info' program. In particular, see the nodes Getting Started,
-Debugging GDB, New Architectures, Coding Style, Clean Design, and
-Submitting Patches.
+`info' program.
If you are pondering writing anything but a short patch, especially
take note of the information about copyrights in the node Submitting
@@ -549,24 +590,18 @@ GDB Testsuite
There is a DejaGNU based testsuite available for testing your newly
built GDB, or for regression testing GDBs with local modifications.
-The testsuite is distributed separately from the base GDB distribution
-for the convenience of people that wish to get either GDB or the testsuite
-separately.
-
-The name of the testsuite is gdb-4.16-testsuite.tar.gz. You unpack it in the
-same directory in which you unpacked the base GDB distribution, and it
-will create and populate the directory gdb-4.16/gdb/testsuite.
-Running the testsuite requires the prior installation of DejaGNU, which
-is generally available via ftp. Once DejaGNU is installed, you can run
-the tests in one of two ways:
+Running the testsuite requires the prior installation of DejaGNU,
+which is generally available via ftp; you'll need a pretty recent
+release. Once DejaGNU is installed, you can run the tests in one of
+two ways:
- (1) cd gdb-4.16/gdb (assuming you also unpacked gdb)
+ (1) cd gdb-4.18/gdb (assuming you also unpacked gdb)
make check
or
- (2) cd gdb-4.16/gdb/testsuite
+ (2) cd gdb-4.18/gdb/testsuite
make site.exp (builds the site specific file)
runtest -tool gdb GDB=../gdb (or GDB=<somepath> as appropriate)
diff --git a/contrib/gdb/gdb/TODO b/contrib/gdb/gdb/TODO
index 06bd9ac..fcbcd16 100644
--- a/contrib/gdb/gdb/TODO
+++ b/contrib/gdb/gdb/TODO
@@ -9,6 +9,9 @@ General To Do List
This list is probably not up to date, and opinions vary about the
importance or even desirability of some of the items.
+Add an "info bfd" command that displays supported object formats,
+similarly to objdump -i.
+
START_INFERIOR_TRAPS_EXPECTED need never be defined to 2, since that
is its default value. Clean this up.
diff --git a/contrib/gdb/gdb/abug-rom.c b/contrib/gdb/gdb/abug-rom.c
new file mode 100644
index 0000000..97ff0f8
--- /dev/null
+++ b/contrib/gdb/gdb/abug-rom.c
@@ -0,0 +1,169 @@
+/* Remote debugging interface for ABug Rom monitor for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998 Free Software Foundation, Inc.
+
+ Written by Rob Savoye of Cygnus Support
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+
+/* Prototypes for local functions. */
+
+static void abug_open PARAMS ((char *args, int from_tty));
+
+static void
+abug_supply_register (regname, regnamelen, val, vallen)
+ char *regname;
+ int regnamelen;
+ char *val;
+ int vallen;
+{
+ int regno;
+
+ if (regnamelen != 2)
+ return;
+
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] != 'R')
+ return;
+ regno = PS_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] != 'C')
+ return;
+ regno = PC_REGNUM;
+ break;
+ case 'D':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + D0_REGNUM;
+ break;
+ case 'A':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + A0_REGNUM;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+/*
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes an "A7".
+ */
+
+static char *abug_regnames[NUM_REGS] =
+{
+ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+ "PC",
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops abug_ops;
+
+static char *abug_inits[] = {"\r", NULL};
+
+static struct monitor_ops abug_cmds ;
+
+static void
+init_abug_cmds(void)
+{
+ abug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
+ abug_cmds.init = abug_inits; /* Init strings */
+ abug_cmds.cont = "g\r"; /* continue command */
+ abug_cmds.step = "t\r"; /* single step */
+ abug_cmds.stop = NULL; /* interrupt command */
+ abug_cmds.set_break = "br %x\r"; /* set a breakpoint */
+ abug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
+ abug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
+ abug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
+ abug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
+ abug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
+ abug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
+ abug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ abug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ abug_cmds.setmem.term = NULL; /* setreg.term */
+ abug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ abug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
+ abug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
+ abug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
+ abug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ abug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
+ abug_cmds.getmem.term = NULL; /* getmem.term */
+ abug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ abug_cmds.setreg.cmd = "rm %s %x\r"; /* setreg.cmd (name, value) */
+ abug_cmds.setreg.resp_delim = "="; /* setreg.resp_delim */
+ abug_cmds.setreg.term = "? "; /* setreg.term */
+ abug_cmds.setreg.term_cmd = ".\r" ; /* setreg.term_cmd */
+ abug_cmds.getreg.cmd = "rm %s\r"; /* getreg.cmd (name) */
+ abug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ abug_cmds.getreg.term = "? "; /* getreg.term */
+ abug_cmds.getreg.term_cmd = ".\r" ; /* getreg.term_cmd */
+ abug_cmds.dump_registers = "rd\r"; /* dump_registers */
+ abug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ abug_cmds.supply_register = abug_supply_register; /* supply_register */
+ abug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ abug_cmds.load = "lo 0\r"; /* download command */
+ abug_cmds.loadresp = "\n"; /* load response */
+ abug_cmds.prompt = "135Bug>"; /* monitor command prompt */
+ abug_cmds.line_term = "\r"; /* end-of-line terminator */
+ abug_cmds.cmd_end = NULL; /* optional command terminator */
+ abug_cmds.target = &abug_ops; /* target operations */
+ abug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ abug_cmds.regnames = abug_regnames; /* registers names */
+ abug_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */
+};
+
+static void
+abug_open(args, from_tty)
+ char *args;
+ int from_tty;
+{
+ monitor_open (args, &abug_cmds, from_tty);
+}
+
+void
+_initialize_abug_rom ()
+{
+ init_abug_cmds() ;
+ init_monitor_ops (&abug_ops);
+
+ abug_ops.to_shortname = "abug";
+ abug_ops.to_longname = "ABug monitor";
+ abug_ops.to_doc = "Debug via the ABug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ abug_ops.to_open = abug_open;
+
+ add_target (&abug_ops);
+}
diff --git a/contrib/gdb/gdb/acconfig.h b/contrib/gdb/gdb/acconfig.h
index bb9b991..9ad5020 100644
--- a/contrib/gdb/gdb/acconfig.h
+++ b/contrib/gdb/gdb/acconfig.h
@@ -1,9 +1,95 @@
+/* Whether malloc must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Whether realloc must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_REALLOC
+
+/* Whether free must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_FREE
+
+/* Whether strerror must be declared even if <string.h> is included. */
+#undef NEED_DECLARATION_STRERROR
+@TOP@
+
+/* Define if pstatus_t type is available */
+#undef HAVE_PSTATUS_T
+
+/* Define if prrun_t type is available */
+#undef HAVE_PRRUN_T
+
/* Define if fpregset_t type is available. */
#undef HAVE_FPREGSET_T
/* Define if gregset_t type is available. */
#undef HAVE_GREGSET_T
+/* Define if ioctl argument PIOCSET is available. */
+#undef HAVE_PROCFS_PIOCSET
+
+/* /proc PID entries are directories containing the files
+ ctl as map status */
+#undef HAVE_MULTIPLE_PROC_FDS
+
+/* Define if the `long long' type works. */
+#undef CC_HAS_LONG_LONG
+
+/* Define if the "ll" format works to print long long ints. */
+#undef PRINTF_HAS_LONG_LONG
+
/* Define if the "%Lg" format works to print long doubles. */
#undef PRINTF_HAS_LONG_DOUBLE
+
+/* Define if the "%Lg" format works to scan long doubles. */
+#undef SCANF_HAS_LONG_DOUBLE
+
+/* Define if using Solaris thread debugging. */
+#undef HAVE_THREAD_DB_LIB
+
+/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#undef sys_quotactl
+
+/* Define if you have HPUX threads */
+#undef HAVE_HPUX_THREAD_SUPPORT
+
+/* Define if you want to use the memory mapped malloc package (mmalloc). */
+#undef USE_MMALLOC
+
+/* Define if the runtime uses a routine from mmalloc before gdb has a chance
+ to initialize mmalloc, and we want to force checking to be used anyway.
+ This may cause spurious memory corruption messages if the runtime tries
+ to explicitly deallocate that memory when gdb calls exit. */
+#undef MMCHECK_FORCE
+
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define if you want to use the full-screen terminal user interface. */
+#undef TUI
+
+/* Define if <proc_service.h> on solaris uses int instead of
+ size_t, and assorted other type changes. */
+#undef PROC_SERVICE_IS_OLD
+
+/* If you want to specify a default CPU variant, define this to be its
+ name, as a C string. */
+#undef TARGET_CPU_DEFAULT
+
+/* Set to true if the save_state_t structure is present */
+#define HAVE_STRUCT_SAVE_STATE_T 0
+
+/* Set to true if the save_state_t structure has the ss_wide member */
+#define HAVE_STRUCT_MEMBER_SS_WIDE 0
diff --git a/contrib/gdb/gdb/acinclude.m4 b/contrib/gdb/gdb/acinclude.m4
new file mode 100644
index 0000000..43a0b0d
--- /dev/null
+++ b/contrib/gdb/gdb/acinclude.m4
@@ -0,0 +1,861 @@
+dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
+dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
+
+dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
+sinclude(../bfd/acinclude.m4)
+
+dnl This gets the standard macros, like the TCL, TK, etc ones.
+sinclude(../config/acinclude.m4)
+
+dnl CYGNUS LOCAL: This gets the right posix flag for gcc
+AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
+[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([if running LynxOS])
+AC_CACHE_VAL(ac_cv_os_lynx,
+[AC_EGREP_CPP(yes,
+[/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)])
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(LYNX)
+ AC_MSG_CHECKING([whether -mposix or -X is available])
+ AC_CACHE_VAL(ac_cv_c_posix_flag,
+ [AC_TRY_COMPILE(,[
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+ ], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")])
+ CC="$CC $ac_cv_c_posix_flag"
+ AC_MSG_RESULT($ac_cv_c_posix_flag)
+ else
+ AC_MSG_RESULT(no)
+fi
+])
+
+#
+# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
+# makes configure think it's cross compiling. If --target wasn't used, then
+# we can't configure, so something is wrong. We don't use the cache
+# here cause if somebody fixes their compiler install, we want this to work.
+AC_DEFUN(CY_AC_C_WORKS,
+[# If we cannot compile and link a trivial program, we can't expect anything to work
+AC_MSG_CHECKING(whether the compiler ($CC) actually works)
+AC_TRY_COMPILE(, [/* don't need anything here */],
+ c_compiles=yes, c_compiles=no)
+
+AC_TRY_LINK(, [/* don't need anything here */],
+ c_links=yes, c_links=no)
+
+if test x"${c_compiles}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't compile.)
+fi
+
+if test x"${c_links}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't link.)
+fi
+AC_MSG_RESULT(yes)
+])
+
+AC_DEFUN(CY_AC_PATH_TCLH, [
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+
+no_tcl=true
+AC_MSG_CHECKING(for Tcl private headers. dir=${configdir})
+AC_ARG_WITH(tclinclude, [ --with-tclinclude=DIR Directory where tcl private headers are], with_tclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tclh,[
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" = x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[[7-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[[7-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[[7-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[[7-9]]* 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
+fi
+])
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ AC_MSG_ERROR([Can't find Tcl private headers])
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TCLHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tclh}])
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+AC_SUBST(TCLHDIR)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TCLCONFIG, [
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tclconfig, [ --with-tclconfig=DIR Directory containing tcl configuration (tclConfig.sh)],
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[7-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[7-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ AC_MSG_WARN(Can't find Tcl configuration definitions)
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ AC_MSG_RESULT(found $TCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [
+ . $TCLCONFIG
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_MAJOR_VERSION)
+ AC_SUBST(TCL_MINOR_VERSION)
+ AC_SUBST(TCL_CC)
+ AC_SUBST(TCL_DEFS)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_LIB_FILE)
+
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_EXEC_PREFIX)
+
+ AC_SUBST(TCL_SHLIB_CFLAGS)
+ AC_SUBST(TCL_SHLIB_LD)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+ AC_SUBST(TCL_SHLIB_SUFFIX)
+dnl not used, don't export to save symbols
+ AC_SUBST(TCL_DL_LIBS)
+ AC_SUBST(TCL_LD_FLAGS)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_LD_SEARCH_FLAGS)
+ AC_SUBST(TCL_COMPAT_OBJS)
+ AC_SUBST(TCL_RANLIB)
+ AC_SUBST(TCL_BUILD_LIB_SPEC)
+ AC_SUBST(TCL_LIB_SPEC)
+ AC_SUBST(TCL_LIB_VERSIONS_OK)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
+])
+
+# Warning: Tk definitions are very similar to Tcl definitions but
+# are not precisely the same. There are a couple of differences,
+# so don't do changes to Tcl thinking you can cut and paste it do
+# the Tk differences and later simply substitute "Tk" for "Tcl".
+# Known differences:
+# - Acceptable Tcl major version #s is 7-9 while Tk is 4-9
+# - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h
+# - Computing major/minor versions is different because Tk depends on
+# headers to Tcl, Tk, and X.
+# - Symbols in tkConfig.sh are different than tclConfig.sh
+# - Acceptable for Tk to be missing but not Tcl.
+
+AC_DEFUN(CY_AC_PATH_TKH, [
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+no_tk=true
+AC_MSG_CHECKING(for Tk private headers)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude=DIR Directory where tk private headers are], with_tkinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tkh,[
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" = x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[[4-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[[4-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[[4-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[[4-9]]* 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="")
+fi
+])
+if test x"${ac_cv_c_tkh}" != x ; then
+ no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TKHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
+ # this hack is cause the TKHDIR won't print if there is a "-I" in it.
+ TKHDIR="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIR="# no Tk directory found"
+ AC_MSG_WARN([Can't find Tk private headers])
+ no_tk=true
+fi
+
+AC_SUBST(TKHDIR)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TKCONFIG, [
+#
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
+#
+
+if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tkconfig, [ --with-tkconfig=DIR Directory containing tk configuration (tkConfig.sh)],
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[4-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[4-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ AC_MSG_WARN(Can't find Tk configuration definitions)
+ else
+ no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ AC_MSG_RESULT(found $TKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TKCONFIG, [
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+ AC_SUBST(TK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TK_MAJOR_VERSION)
+dnl AC_SUBST(TK_MINOR_VERSION)
+ AC_SUBST(TK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(TK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_EXEC_PREFIX)
+
+ AC_SUBST(TK_BUILD_INCLUDES)
+ AC_SUBST(TK_XINCLUDES)
+ AC_SUBST(TK_XLIBSW)
+ AC_SUBST(TK_BUILD_LIB_SPEC)
+ AC_SUBST(TK_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLCONFIG, [
+#
+# Ok, lets find the itcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itclconfig
+#
+
+if test x"${no_itcl}" = x ; then
+ # we reset no_itcl in case something fails here
+ no_itcl=true
+ AC_ARG_WITH(itclconfig, [ --with-itclconfig directory containing itcl configuration (itclConfig.sh)],
+ with_itclconfig=${withval})
+ AC_MSG_CHECKING([for Itcl configuration])
+ AC_CACHE_VAL(ac_cv_c_itclconfig,[
+
+ # First check to see if --with-itclconfig was specified.
+ if test x"${with_itclconfig}" != x ; then
+ if test -f "${with_itclconfig}/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclconfig} directory doesn't contain itclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itcl library
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ../itcl/itcl \
+ `ls -dr ../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../itcl \
+ `ls -dr ../../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../../itcl \
+ `ls -dr ../../../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itcl \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ ITCLCONFIG="# no Itcl configs found"
+ AC_MSG_WARN(Can't find Itcl configuration definitions)
+ else
+ no_itcl=
+ ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
+ AC_MSG_RESULT(found $ITCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITCLCONFIG, [
+ if test -f "$ITCLCONFIG" ; then
+ . $ITCLCONFIG
+ fi
+
+ AC_SUBST(ITCL_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITCL_MAJOR_VERSION)
+dnl AC_SUBST(ITCL_MINOR_VERSION)
+ AC_SUBST(ITCL_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITCL_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_EXEC_PREFIX)
+
+ AC_SUBST(ITCL_BUILD_INCLUDES)
+ AC_SUBST(ITCL_BUILD_LIB_SPEC)
+ AC_SUBST(ITCL_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLH, [
+AC_MSG_CHECKING(for Itcl private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
+ if test -f $i/generic/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ AC_MSG_ERROR([Can't find Itcl private headers])
+fi
+if test x"${ac_cv_c_itclh}" != x ; then
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+fi
+# should always be here
+# ITCLLIB="../itcl/itcl/unix/libitcl.a"
+AC_SUBST(ITCLHDIR)
+#AC_SUBST(ITCLLIB)
+])
+
+
+AC_DEFUN(CY_AC_PATH_ITKCONFIG, [
+#
+# Ok, lets find the itk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_itk}" = x ; then
+ # we reset no_itk in case something fails here
+ no_itk=true
+ AC_ARG_WITH(itkconfig, [ --with-itkconfig directory containing itk configuration (itkConfig.sh)],
+ with_itkconfig=${withval})
+ AC_MSG_CHECKING([for Itk configuration])
+ AC_CACHE_VAL(ac_cv_c_itkconfig,[
+
+ # First check to see if --with-itkconfig was specified.
+ if test x"${with_itkconfig}" != x ; then
+ if test -f "${with_itkconfig}/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itkconfig} directory doesn't contain itkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itk library
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ../itcl/itk \
+ `ls -dr ../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../itk \
+ `ls -dr ../../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../../itk \
+ `ls -dr ../../../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itk \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ ITKCONFIG="# no Itk configs found"
+ AC_MSG_WARN(Can't find Itk configuration definitions)
+ else
+ no_itk=
+ ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
+ AC_MSG_RESULT(found $ITKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITKCONFIG, [
+ if test -f "$ITKCONFIG" ; then
+ . $ITKCONFIG
+ fi
+
+ AC_SUBST(ITK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITK_MAJOR_VERSION)
+dnl AC_SUBST(ITK_MINOR_VERSION)
+ AC_SUBST(ITK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_EXEC_PREFIX)
+
+ AC_SUBST(ITK_BUILD_INCLUDES)
+ AC_SUBST(ITK_BUILD_LIB_SPEC)
+ AC_SUBST(ITK_LIB_SPEC)
+])
+
+AC_DEFUN(CY_AC_PATH_ITKH, [
+AC_MSG_CHECKING(for Itk private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itkh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
+ if test -f $i/generic/itk.h ; then
+ ac_cv_c_itkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itkh}" = x ; then
+ ITKHDIR="# no Itk private headers found"
+ AC_MSG_ERROR([Can't find Itk private headers])
+fi
+if test x"${ac_cv_c_itkh}" != x ; then
+ ITKHDIR="-I${ac_cv_c_itkh}"
+fi
+# should always be here
+# ITKLIB="../itcl/itk/unix/libitk.a"
+AC_SUBST(ITKHDIR)
+#AC_SUBST(ITKLIB)
+])
+
+# check for Tix headers.
+
+AC_DEFUN(CY_AC_PATH_TIXH, [
+AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_tixh}" = x ; then
+ for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
+ if test -f $i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_tixh}" = x ; then
+ TIXHDIR="# no Tix private headers found"
+ AC_MSG_ERROR([Can't find Tix private headers])
+fi
+if test x"${ac_cv_c_tixh}" != x ; then
+ TIXHDIR="-I${ac_cv_c_tixh}"
+fi
+AC_SUBST(TIXHDIR)
+])
+
+AC_DEFUN(CY_AC_PATH_TIXCONFIG, [
+#
+# Ok, lets find the tix configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_tix}" = x ; then
+ # we reset no_tix in case something fails here
+ no_tix=true
+ AC_ARG_WITH(tixconfig, [ --with-tixconfig directory containing tix configuration (tixConfig.sh)],
+ with_tixconfig=${withval})
+ AC_MSG_CHECKING([for Tix configuration])
+ AC_CACHE_VAL(ac_cv_c_tixconfig,[
+
+ # First check to see if --with-tixconfig was specified.
+ if test x"${with_tixconfig}" != x ; then
+ if test -f "${with_tixconfig}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tix library
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ../tix \
+ `ls -dr ../tix 2>/dev/null` \
+ ../../tix \
+ `ls -dr ../../tix 2>/dev/null` \
+ ../../../tix \
+ `ls -dr ../../../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ echo "**** Looking at $i"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ echo "**** Other private locations"
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tix \
+ `ls -dr ${srcdir}/../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/${configdir}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ TIXCONFIG="# no Tix configs found"
+ AC_MSG_WARN(Can't find Tix configuration definitions)
+ else
+ no_tix=
+ TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
+ AC_MSG_RESULT(found $TIXCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TIXCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [
+ if test -f "$TIXCONFIG" ; then
+ . $TIXCONFIG
+ fi
+
+ AC_SUBST(TIX_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TIX_MAJOR_VERSION)
+dnl AC_SUBST(TIX_MINOR_VERSION)
+dnl AC_SUBST(TIX_DEFS)
+
+dnl not used, don't export to save symbols
+dnl dnl AC_SUBST(TIX_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TIX_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_EXEC_PREFIX)
+
+dnl AC_SUBST(TIX_BUILD_INCLUDES)
+ AC_SUBST(TIX_BUILD_LIB_SPEC)
+dnl AC_SUBST(TIX_LIB_SPEC)
+])
diff --git a/contrib/gdb/gdb/aclocal.m4 b/contrib/gdb/gdb/aclocal.m4
index d23d084..4fd3658 100644
--- a/contrib/gdb/gdb/aclocal.m4
+++ b/contrib/gdb/gdb/aclocal.m4
@@ -1,14 +1,28 @@
-dnl This file is duplicated in four places:
-dnl * gdb/aclocal.m4
-dnl * gdb/testsuite/aclocal.m4
-dnl * expect/aclocal.m4
-dnl * dejagnu/aclocal.m4
-dnl Consider modifying all copies in parallel.
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
+dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
+
+dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
+sinclude(../bfd/acinclude.m4)
+
+dnl This gets the standard macros, like the TCL, TK, etc ones.
+sinclude(../config/acinclude.m4)
+
dnl CYGNUS LOCAL: This gets the right posix flag for gcc
AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
-AC_MSG_CHECKING([to see if this is LynxOS])
+AC_MSG_CHECKING([if running LynxOS])
AC_CACHE_VAL(ac_cv_os_lynx,
[AC_EGREP_CPP(yes,
[/*
@@ -40,28 +54,31 @@ if test "$ac_cv_os_lynx" = "yes" ; then
AC_MSG_RESULT(no)
fi
])
+
#
# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
# makes configure think it's cross compiling. If --target wasn't used, then
-# we can't configure, so something is wrong.
-AC_DEFUN(CY_AC_C_CROSS,
-[# If we cannot run a trivial program, we must be cross compiling.
-AC_MSG_CHECKING(whether cross-compiling)
-AC_CACHE_VAL(ac_cv_c_cross,[
-AC_TRY_RUN([
- main(){return(0);}],
- ac_cv_c_cross=no, ac_cv_c_cross=yes, ac_cv_c_cross=yes)
-])
-if test x"${target}" = x"${host}" -a x"${ac_cv_c_cross}" = x"yes"; then
- dnl this hack is cause the message is so long we don't call AC_MSG_ERROR
- echo "configure: error: You need to specify --target to cross compile," 1>&2;
- echo " or the native compiler is broken" 1>&2;
- exit 1;
-else
- cross_compiling=$ac_cv_c_cross
- AC_MSG_RESULT($ac_cv_c_cross)
+# we can't configure, so something is wrong. We don't use the cache
+# here cause if somebody fixes their compiler install, we want this to work.
+AC_DEFUN(CY_AC_C_WORKS,
+[# If we cannot compile and link a trivial program, we can't expect anything to work
+AC_MSG_CHECKING(whether the compiler ($CC) actually works)
+AC_TRY_COMPILE(, [/* don't need anything here */],
+ c_compiles=yes, c_compiles=no)
+
+AC_TRY_LINK(, [/* don't need anything here */],
+ c_links=yes, c_links=no)
+
+if test x"${c_compiles}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't compile.)
+fi
+
+if test x"${c_links}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't link.)
fi
+AC_MSG_RESULT(yes)
])
+
AC_DEFUN(CY_AC_PATH_TCLH, [
#
# Ok, lets find the tcl source trees so we can use the headers
@@ -70,36 +87,43 @@ AC_DEFUN(CY_AC_PATH_TCLH, [
# be careful that we don't match stuff like tclX by accident.
# the alternative search directory is involked by --with-tclinclude
#
+
no_tcl=true
-AC_MSG_CHECKING(for Tcl private headers)
-AC_ARG_WITH(tclinclude, [ --with-tclinclude directory where tcl private headers are], with_tclinclude=${withval})
+AC_MSG_CHECKING(for Tcl private headers. dir=${configdir})
+AC_ARG_WITH(tclinclude, [ --with-tclinclude=DIR Directory where tcl private headers are], with_tclinclude=${withval})
AC_CACHE_VAL(ac_cv_c_tclh,[
# first check to see if --with-tclinclude was specified
if test x"${with_tclinclude}" != x ; then
if test -f ${with_tclinclude}/tclInt.h ; then
ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
else
AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
fi
fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" = x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/..; pwd)`
+ fi
+fi
+
# next check in private source directory
#
# since ls returns lowest version numbers first, reverse its output
if test x"${ac_cv_c_tclh}" = x ; then
for i in \
${srcdir}/../tcl \
- `ls -dr ${srcdir}/../tcl[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` \
${srcdir}/../../tcl \
- `ls -dr ${srcdir}/../../tcl[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../../tcl[[7-9]]* 2>/dev/null` \
${srcdir}/../../../tcl \
- `ls -dr ${srcdir}/../../../tcl[[0-9]]* 2>/dev/null ` ; do
- if test -f $i/tclInt.h ; then
- ac_cv_c_tclh=`(cd $i; pwd)`
- break
- fi
- # Tcl 7.5 and greater puts headers in subdirectory.
+ `ls -dr ${srcdir}/../../../tcl[[7-9]]* 2>/dev/null ` ; do
if test -f $i/generic/tclInt.h ; then
- ac_cv_c_tclh=`(cd $i; pwd)`/generic
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
fi
done
fi
@@ -108,13 +132,13 @@ fi
# since ls returns lowest version numbers first, reverse its output
if test x"${ac_cv_c_tclh}" = x ; then
for i in \
- `ls -dr /usr/local/src/tcl[[0-9]]* 2>/dev/null` \
- `ls -dr /usr/local/lib/tcl[[0-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/src/tcl[[7-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[[7-9]]* 2>/dev/null` \
/usr/local/src/tcl \
/usr/local/lib/tcl \
${prefix}/include ; do
- if test -f $i/tclInt.h ; then
- ac_cv_c_tclh=`(cd $i; pwd)`
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
break
fi
done
@@ -130,7 +154,7 @@ if test x"${ac_cv_c_tclh}" = x ; then
fi
if test x"${ac_cv_c_tclh}" != x ; then
no_tcl=""
- if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
AC_MSG_RESULT([is installed])
TCLHDIR=""
else
@@ -140,176 +164,138 @@ if test x"${ac_cv_c_tclh}" != x ; then
fi
fi
-AC_MSG_CHECKING([Tcl version])
-rm -rf tclmajor tclminor
-orig_includes="$CPPFLAGS"
-
-if test x"${TCLHDIR}" != x ; then
- CPPFLAGS="$CPPFLAGS $TCLHDIR"
-fi
-
-AC_TRY_RUN([
-#include <stdio.h>
-#include "tcl.h"
-main() {
- FILE *maj = fopen("tclmajor","w");
- FILE *min = fopen("tclminor","w");
- fprintf(maj,"%d",TCL_MAJOR_VERSION);
- fprintf(min,"%d",TCL_MINOR_VERSION);
- fclose(maj);
- fclose(min);
- return 0;
-}],
- tclmajor=`cat tclmajor`
- tclminor=`cat tclminor`
- tclversion=$tclmajor.$tclminor
- AC_MSG_RESULT($tclversion)
- rm -f tclmajor tclminor
-,
- AC_MSG_RESULT([can't happen])
-,
- AC_MSG_ERROR([can't be cross compiled])
-)
-CPPFLAGS="${orig_includes}"
-
-AC_PROVIDE([$0])
AC_SUBST(TCLHDIR)
])
-AC_DEFUN(CY_AC_PATH_TCLLIB, [
+
+
+AC_DEFUN(CY_AC_PATH_TCLCONFIG, [
#
-# Ok, lets find the tcl library
+# Ok, lets find the tcl configuration
# First, look for one uninstalled.
-# the alternative search directory is invoked by --with-tcllib
+# the alternative search directory is invoked by --with-tclconfig
#
-if test $tclmajor -ge 7 -a $tclminor -ge 4 ; then
- installedtcllibroot=tcl$tclversion
-else
- installedtcllibroot=tcl
-fi
-
if test x"${no_tcl}" = x ; then
- # we reset no_tcl incase something fails here
+ # we reset no_tcl in case something fails here
no_tcl=true
- AC_ARG_WITH(tcllib, [ --with-tcllib directory where the tcl library is],
- with_tcllib=${withval})
- AC_MSG_CHECKING([for Tcl library])
- AC_CACHE_VAL(ac_cv_c_tcllib,[
- # First check to see if --with-tcllib was specified.
- # This requires checking for both the installed and uninstalled name-styles
- # since we have no idea if it's installed or not.
- if test x"${with_tcllib}" != x ; then
- if test -f "${with_tcllib}/lib$installedtcllibroot.so" ; then
- ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/lib$installedtcllibroot.so
- elif test -f "${with_tcllib}/libtcl.so" ; then
- ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/libtcl.so
- # then look for a freshly built statically linked library
- # if Makefile exists we assume its configured and libtcl will be built first.
- elif test -f "${with_tcllib}/lib$installedtcllibroot.a" ; then
- ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/lib$installedtcllibroot.a
- elif test -f "${with_tcllib}/libtcl.a" ; then
- ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/libtcl.a
+ AC_ARG_WITH(tclconfig, [ --with-tclconfig=DIR Directory containing tcl configuration (tclConfig.sh)],
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
else
- AC_MSG_ERROR([${with_tcllib} directory doesn't contain libraries])
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
fi
fi
- # then check for a private Tcl library
- # Since these are uninstalled, use the simple lib name root.
- if test x"${ac_cv_c_tcllib}" = x ; then
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
../tcl \
- `ls -dr ../tcl[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[7-9]]* 2>/dev/null` \
../../tcl \
- `ls -dr ../../tcl[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[7-9]]* 2>/dev/null` \
../../../tcl \
- `ls -dr ../../../tcl[[0-9]]* 2>/dev/null` ; do
- # Tcl 7.5 and greater puts library in subdir. Look there first.
- if test -f "$i/unix/libtcl.so" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.so
- break
- elif test -f "$i/unix/libtcl.a" -o -f "$i/unix/Makefile"; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.a
- break
- # look for a freshly built dynamically linked library
- elif test -f "$i/libtcl.so" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.so
- break
-
- # then look for a freshly built statically linked library
- # if Makefile exists we assume its configured and libtcl will be
- # built first.
- elif test -f "$i/libtcl.a" -o -f "$i/Makefile" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.a
+ `ls -dr ../../../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
break
fi
done
fi
# check in a few common install locations
- if test x"${ac_cv_c_tcllib}" = x ; then
+ if test x"${ac_cv_c_tclconfig}" = x ; then
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
- # first look for a freshly built dynamically linked library
- if test -f "$i/lib$installedtcllibroot.so" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/lib$installedtcllibroot.so
- break
- # then look for a freshly built statically linked library
- # if Makefile exists we assume its configured and libtcl will be built first.
- elif test -f "$i/lib$installedtcllibroot.a" -o -f "$i/Makefile" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/lib$installedtcllibroot.a
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
break
fi
done
fi
# check in a few other private locations
- if test x"${ac_cv_c_tcllib}" = x ; then
+ if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
${srcdir}/../tcl \
- `ls -dr ${srcdir}/../tcl[[0-9]]* 2>/dev/null` ; do
- # Tcl 7.5 and greater puts library in subdir. Look there first.
- if test -f "$i/unix/libtcl.so" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.so
- break
- elif test -f "$i/unix/libtcl.a" -o -f "$i/unix/Makefile"; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.a
- break
- # look for a freshly built dynamically linked library
- elif test -f "$i/libtcl.so" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.so
- break
-
- # then look for a freshly built statically linked library
- # if Makefile exists we assume its configured and libtcl will be
- # built first.
- elif test -f "$i/libtcl.a" -o -f "$i/Makefile" ; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.a
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
break
fi
done
fi
-
- # see if one is conveniently installed with the compiler
- if test x"${ac_cv_c_tcllib}" = x ; then
- orig_libs="$LIBS"
- LIBS="$LIBS -l$installedtcllibroot -lm"
- AC_TRY_RUN([
- Tcl_AppInit()
- { exit(0); }], ac_cv_c_tcllib="-l$installedtcllibroot", ac_cv_c_tcllib=""
- , ac_cv_c_tclib="-l$installedtcllibroot")
- LIBS="${orig_libs}"
- fi
])
- if test x"${ac_cv_c_tcllib}" = x ; then
- TCLLIB="# no Tcl library found"
- AC_MSG_WARN(Can't find Tcl library)
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ AC_MSG_WARN(Can't find Tcl configuration definitions)
else
- TCLLIB=${ac_cv_c_tcllib}
- AC_MSG_RESULT(found $TCLLIB)
no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ AC_MSG_RESULT(found $TCLCONFIG)
fi
fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [
+ . $TCLCONFIG
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_MAJOR_VERSION)
+ AC_SUBST(TCL_MINOR_VERSION)
+ AC_SUBST(TCL_CC)
+ AC_SUBST(TCL_DEFS)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_LIB_FILE)
+
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_EXEC_PREFIX)
+
+ AC_SUBST(TCL_SHLIB_CFLAGS)
+ AC_SUBST(TCL_SHLIB_LD)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+ AC_SUBST(TCL_SHLIB_SUFFIX)
+dnl not used, don't export to save symbols
+ AC_SUBST(TCL_DL_LIBS)
+ AC_SUBST(TCL_LD_FLAGS)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_LD_SEARCH_FLAGS)
+ AC_SUBST(TCL_COMPAT_OBJS)
+ AC_SUBST(TCL_RANLIB)
+ AC_SUBST(TCL_BUILD_LIB_SPEC)
+ AC_SUBST(TCL_LIB_SPEC)
+ AC_SUBST(TCL_LIB_VERSIONS_OK)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX)
-AC_PROVIDE([$0])
-AC_SUBST(TCLLIB)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
])
+
+# Warning: Tk definitions are very similar to Tcl definitions but
+# are not precisely the same. There are a couple of differences,
+# so don't do changes to Tcl thinking you can cut and paste it do
+# the Tk differences and later simply substitute "Tk" for "Tcl".
+# Known differences:
+# - Acceptable Tcl major version #s is 7-9 while Tk is 4-9
+# - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h
+# - Computing major/minor versions is different because Tk depends on
+# headers to Tcl, Tk, and X.
+# - Symbols in tkConfig.sh are different than tclConfig.sh
+# - Acceptable for Tk to be missing but not Tcl.
+
AC_DEFUN(CY_AC_PATH_TKH, [
#
# Ok, lets find the tk source trees so we can use the headers
@@ -322,63 +308,66 @@ AC_DEFUN(CY_AC_PATH_TKH, [
# recursive cache variables for the path will work right. We check all
# the possible paths in one loop rather than many seperate loops to speed
# things up.
-# the alternative search directory is invoked by --with-tkinclude
+# the alternative search directory is involked by --with-tkinclude
#
-AC_MSG_CHECKING(for Tk private headers)
-AC_ARG_WITH(tkinclude, [ --with-tkinclude directory where the tk private headers are],
- with_tkinclude=${withval})
no_tk=true
+AC_MSG_CHECKING(for Tk private headers)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude=DIR Directory where tk private headers are], with_tkinclude=${withval})
AC_CACHE_VAL(ac_cv_c_tkh,[
# first check to see if --with-tkinclude was specified
if test x"${with_tkinclude}" != x ; then
if test -f ${with_tkinclude}/tk.h ; then
ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
else
AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
fi
fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" = x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/..; pwd)`
+ fi
+fi
+
# next check in private source directory
#
-# since ls returns lowest version numbers first, reverse the entire list
-# and search for the worst fit, overwriting it with better fits as we find them
+# since ls returns lowest version numbers first, reverse its output
if test x"${ac_cv_c_tkh}" = x ; then
for i in \
${srcdir}/../tk \
- `ls -dr ${srcdir}/../tk[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` \
${srcdir}/../../tk \
- `ls -dr ${srcdir}/../../tk[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../../tk[[4-9]]* 2>/dev/null` \
${srcdir}/../../../tk \
- `ls -dr ${srcdir}/../../../tk[[0-9]]* 2>/dev/null ` ; do
- if test -f $i/tk.h ; then
- ac_cv_c_tkh=`(cd $i; pwd)`
+ `ls -dr ${srcdir}/../../../tk[[4-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
break
fi
- # Tk 4.1 and greater puts this in a subdir.
- if test -f $i/generic/tk.h; then
- ac_cv_c_tkh=`(cd $i; pwd)`/generic
- fi
done
fi
# finally check in a few common install locations
#
-# since ls returns lowest version numbers first, reverse the entire list
-# and search for the worst fit, overwriting it with better fits as we find them
+# since ls returns lowest version numbers first, reverse its output
if test x"${ac_cv_c_tkh}" = x ; then
for i in \
- `ls -dr /usr/local/src/tk[[0-9]]* 2>/dev/null` \
- `ls -dr /usr/local/lib/tk[[0-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/src/tk[[4-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[[4-9]]* 2>/dev/null` \
/usr/local/src/tk \
/usr/local/lib/tk \
${prefix}/include ; do
- if test -f $i/tk.h ; then
- ac_cv_c_tkh=`(cd $i; pwd)`
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
break
fi
done
fi
# see if one is installed
if test x"${ac_cv_c_tkh}" = x ; then
- AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed)
+ AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="")
fi
])
if test x"${ac_cv_c_tkh}" != x ; then
@@ -387,7 +376,7 @@ if test x"${ac_cv_c_tkh}" != x ; then
AC_MSG_RESULT([is installed])
TKHDIR=""
else
- AC_MSG_RESULT([found in $ac_cv_c_tkh])
+ AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
# this hack is cause the TKHDIR won't print if there is a "-I" in it.
TKHDIR="-I${ac_cv_c_tkh}"
fi
@@ -397,209 +386,922 @@ else
no_tk=true
fi
-# if Tk is installed, extract the major/minor version
-if test x"${no_tk}" = x ; then
-AC_MSG_CHECKING([Tk version])
-rm -rf tkmajor tkminor
-orig_includes="$CPPFLAGS"
-
-if test x"${TCLHDIR}" != x ; then
- CPPFLAGS="$CPPFLAGS $TCLHDIR"
-fi
-if test x"${TKHDIR}" != x ; then
- CPPFLAGS="$CPPFLAGS $TKHDIR"
-fi
-if test x"${x_includes}" != x -a x"${x_includes}" != xNONE ; then
- CPPFLAGS="$CPPFLAGS -I$x_includes"
-fi
-
-AC_TRY_RUN([
-#include <stdio.h>
-#include "tk.h"
- main() {
- FILE *maj = fopen("tkmajor","w");
- FILE *min = fopen("tkminor","w");
- fprintf(maj,"%d",TK_MAJOR_VERSION);
- fprintf(min,"%d",TK_MINOR_VERSION);
- fclose(maj);
- fclose(min);
- return 0;
-}],
- tkmajor=`cat tkmajor`
- tkminor=`cat tkminor`
- tkversion=$tkmajor.$tkminor
- AC_MSG_RESULT($tkversion)
- rm -f tkmajor tkminor
-,
- AC_MSG_ERROR([
-cannot compile a simple X program - suspect your xmkmf is
-misconfigured and is incorrectly reporting the location of your X
-include or libraries - report this to your system admin]) ,
- AC_MSG_ERROR([can't be cross compiled])
-)
-CPPFLAGS="${orig_includes}"
-fi
-
-AC_PROVIDE([$0])
AC_SUBST(TKHDIR)
])
-AC_DEFUN(CY_AC_PATH_TKLIB, [
-AC_REQUIRE([CY_AC_PATH_TCL])
+
+
+AC_DEFUN(CY_AC_PATH_TKCONFIG, [
#
-# Ok, lets find the tk library
-# First, look for the latest private (uninstalled) copy
-# Notice that the destinations in backwards priority since the tests have
-# no break.
-# Then we look for either .a, .so, or Makefile. A Makefile is acceptable
-# is it indicates the target has been configured and will (probably)
-# soon be built. This allows an entire tree of Tcl software to be
-# configured at once and then built.
-# the alternative search directory is invoked by --with-tklib
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
#
if test x"${no_tk}" = x ; then
- # reset no_tk incase something fails here
- no_tk="true"
-
- if test $tkmajor -ge 4 ; then
- installedtklibroot=tk$tkversion
- else
- installedtkllibroot=tk
- fi
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tkconfig, [ --with-tkconfig=DIR Directory containing tk configuration (tkConfig.sh)],
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
- AC_ARG_WITH(tklib, [ --with-tklib directory where the tk library is],
- with_tklib=${withval})
- AC_MSG_CHECKING([for Tk library])
- AC_CACHE_VAL(ac_cv_c_tklib,[
- # first check to see if --with-tklib was specified
- # This requires checking for both the installed and uninstalled name-styles
- # since we have no idea if it's installed or not.
- if test x"${with_tklib}" != x ; then
- if test -f "${with_tklib}/lib$installedtklibroot.so" ; then
- ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/lib$installedtklibroot.so
- no_tk=""
- elif test -f "${with_tklib}/libtk.so" ; then
- ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/libtk.so
- no_tk=""
- # then look for a freshly built statically linked library
- # if Makefile exists we assume its configured and libtk will be built
- elif test -f "${with_tklib}/lib$installedtklibroot.a" ; then
- ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/lib$installedtklibroot.a
- no_tk=""
- elif test -f "${with_tklib}/libtk.a" ; then
- ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/libtk.a
- no_tk=""
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
else
- AC_MSG_ERROR([${with_tklib} directory doesn't contain libraries])
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
fi
fi
+
# then check for a private Tk library
- # Since these are uninstalled, use the simple lib name root.
- if test x"${ac_cv_c_tklib}" = x ; then
+ if test x"${ac_cv_c_tkconfig}" = x ; then
for i in \
../tk \
- `ls -dr ../tk[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[4-9]]* 2>/dev/null` \
../../tk \
- `ls -dr ../../tk[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[4-9]]* 2>/dev/null` \
../../../tk \
- `ls -dr ../../../tk[[0-9]]* 2>/dev/null` ; do
- # Tk 4.1 and greater puts things in subdirs. Check these first.
- if test -f "$i/unix/libtk.so" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/unix/libtk.so
- no_tk=
- break
- elif test -f "$i/unix/libtk.a" -o -f "$i/unix/Makefile"; then
- ac_cv_c_tklib=`(cd $i; pwd)`/unix/libtk.a
- no_tk=
- break
- # look for a freshly built dynamically linked library
- elif test -f "$i/libtk.so" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/libtk.so
- no_tk=
+ `ls -dr ../../../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
break
- # then look for a freshly built statically linked library
- # if Makefile exists we assume its configured and libtk will be built
- elif test -f "$i/libtk.a" -o -f "$i/Makefile" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/libtk.a
- no_tk=""
- break
fi
done
fi
- # finally check in a few common install locations
- if test x"${ac_cv_c_tklib}" = x ; then
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
- # first look for a freshly built dynamically linked library
- if test -f "$i/lib$installedtklibroot.so" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/lib$installedtklibroot.so
- no_tk=""
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
break
- # then look for a freshly built statically linked library
- # if Makefile exists, we assume it's configured and libtcl will be built
- elif test -f "$i/lib$installedtklibroot.a" -o -f "$i/Makefile" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/lib$installedtklibroot.a
- no_tk=""
- break
fi
done
fi
# check in a few other private locations
- if test x"${ac_cv_c_tklib}" = x ; then
+ if test x"${ac_cv_c_tkconfig}" = x ; then
for i in \
${srcdir}/../tk \
- `ls -dr ${srcdir}/../tk[[0-9]]* 2>/dev/null` ; do
- # Tk 4.1 and greater puts things in subdirs. Check these first.
- if test -f "$i/unix/libtk.so" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/unix/libtk.so
- no_tk=
- break
- elif test -f "$i/unix/libtk.a" -o -f "$i/unix/Makefile"; then
- ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtk.a
- no_tk=
- break
- # look for a freshly built dynamically linked library
- elif test -f "$i/libtk.so" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/libtk.so
- no_tk=""
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
break
- # then look for a freshly built statically linked library
- # if Makefile exists, we assume it's configured and libtcl will be built
- elif test -f "$i/libtk.a" -o -f "$i/Makefile" ; then
- ac_cv_c_tklib=`(cd $i; pwd)`/libtk.a
- no_tk=""
- break
fi
done
fi
- # see if one is conveniently installed with the compiler
- if test x"${ac_cv_c_tklib}" = x ; then
- AC_REQUIRE([AC_PATH_X])
- orig_libs="$LIBS"
- LIBS="$LIBS -l$installedtklibroot $x_libraries $ac_cv_c_tcllib -lm"
- AC_TRY_RUN([
- Tcl_AppInit()
- { exit(0); }], ac_cv_c_tklib="-l$installedtklibroot", ac_cv_c_tklib=""
- , ac_cv_c_tklib="-l$installedtklibroot")
- LIBS="${orig_libs}"
- fi
])
- if test x"${ac_cv_c_tklib}" = x ; then
- TKLIB="# no Tk library found"
- AC_MSG_WARN(Can't find Tk library)
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ AC_MSG_WARN(Can't find Tk configuration definitions)
else
- TKLIB=$ac_cv_c_tklib
- AC_MSG_RESULT(found $TKLIB)
no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ AC_MSG_RESULT(found $TKCONFIG)
fi
fi
-AC_PROVIDE([$0])
-AC_SUBST(TKLIB)
+
])
-AC_DEFUN(CY_AC_PATH_TK, [
- CY_AC_PATH_TKH
- CY_AC_PATH_TKLIB
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TKCONFIG, [
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+ AC_SUBST(TK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TK_MAJOR_VERSION)
+dnl AC_SUBST(TK_MINOR_VERSION)
+ AC_SUBST(TK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(TK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_EXEC_PREFIX)
+
+ AC_SUBST(TK_BUILD_INCLUDES)
+ AC_SUBST(TK_XINCLUDES)
+ AC_SUBST(TK_XLIBSW)
+ AC_SUBST(TK_BUILD_LIB_SPEC)
+ AC_SUBST(TK_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLCONFIG, [
+#
+# Ok, lets find the itcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itclconfig
+#
+
+if test x"${no_itcl}" = x ; then
+ # we reset no_itcl in case something fails here
+ no_itcl=true
+ AC_ARG_WITH(itclconfig, [ --with-itclconfig directory containing itcl configuration (itclConfig.sh)],
+ with_itclconfig=${withval})
+ AC_MSG_CHECKING([for Itcl configuration])
+ AC_CACHE_VAL(ac_cv_c_itclconfig,[
+
+ # First check to see if --with-itclconfig was specified.
+ if test x"${with_itclconfig}" != x ; then
+ if test -f "${with_itclconfig}/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclconfig} directory doesn't contain itclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itcl library
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ../itcl/itcl \
+ `ls -dr ../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../itcl \
+ `ls -dr ../../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../../itcl \
+ `ls -dr ../../../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itcl \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ ITCLCONFIG="# no Itcl configs found"
+ AC_MSG_WARN(Can't find Itcl configuration definitions)
+ else
+ no_itcl=
+ ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
+ AC_MSG_RESULT(found $ITCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITCLCONFIG, [
+ if test -f "$ITCLCONFIG" ; then
+ . $ITCLCONFIG
+ fi
+
+ AC_SUBST(ITCL_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITCL_MAJOR_VERSION)
+dnl AC_SUBST(ITCL_MINOR_VERSION)
+ AC_SUBST(ITCL_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITCL_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_EXEC_PREFIX)
+
+ AC_SUBST(ITCL_BUILD_INCLUDES)
+ AC_SUBST(ITCL_BUILD_LIB_SPEC)
+ AC_SUBST(ITCL_LIB_SPEC)
])
-AC_DEFUN(CY_AC_PATH_TCL, [
- CY_AC_PATH_TCLH
- CY_AC_PATH_TCLLIB
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLH, [
+AC_MSG_CHECKING(for Itcl private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
+ if test -f $i/generic/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ AC_MSG_ERROR([Can't find Itcl private headers])
+fi
+if test x"${ac_cv_c_itclh}" != x ; then
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+fi
+# should always be here
+# ITCLLIB="../itcl/itcl/unix/libitcl.a"
+AC_SUBST(ITCLHDIR)
+#AC_SUBST(ITCLLIB)
])
+
+
+AC_DEFUN(CY_AC_PATH_ITKCONFIG, [
+#
+# Ok, lets find the itk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_itk}" = x ; then
+ # we reset no_itk in case something fails here
+ no_itk=true
+ AC_ARG_WITH(itkconfig, [ --with-itkconfig directory containing itk configuration (itkConfig.sh)],
+ with_itkconfig=${withval})
+ AC_MSG_CHECKING([for Itk configuration])
+ AC_CACHE_VAL(ac_cv_c_itkconfig,[
+
+ # First check to see if --with-itkconfig was specified.
+ if test x"${with_itkconfig}" != x ; then
+ if test -f "${with_itkconfig}/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itkconfig} directory doesn't contain itkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itk library
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ../itcl/itk \
+ `ls -dr ../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../itk \
+ `ls -dr ../../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../../itk \
+ `ls -dr ../../../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itk \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ ITKCONFIG="# no Itk configs found"
+ AC_MSG_WARN(Can't find Itk configuration definitions)
+ else
+ no_itk=
+ ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
+ AC_MSG_RESULT(found $ITKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITKCONFIG, [
+ if test -f "$ITKCONFIG" ; then
+ . $ITKCONFIG
+ fi
+
+ AC_SUBST(ITK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITK_MAJOR_VERSION)
+dnl AC_SUBST(ITK_MINOR_VERSION)
+ AC_SUBST(ITK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_EXEC_PREFIX)
+
+ AC_SUBST(ITK_BUILD_INCLUDES)
+ AC_SUBST(ITK_BUILD_LIB_SPEC)
+ AC_SUBST(ITK_LIB_SPEC)
+])
+
+AC_DEFUN(CY_AC_PATH_ITKH, [
+AC_MSG_CHECKING(for Itk private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itkh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
+ if test -f $i/generic/itk.h ; then
+ ac_cv_c_itkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itkh}" = x ; then
+ ITKHDIR="# no Itk private headers found"
+ AC_MSG_ERROR([Can't find Itk private headers])
+fi
+if test x"${ac_cv_c_itkh}" != x ; then
+ ITKHDIR="-I${ac_cv_c_itkh}"
+fi
+# should always be here
+# ITKLIB="../itcl/itk/unix/libitk.a"
+AC_SUBST(ITKHDIR)
+#AC_SUBST(ITKLIB)
+])
+
+# check for Tix headers.
+
+AC_DEFUN(CY_AC_PATH_TIXH, [
+AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_tixh}" = x ; then
+ for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
+ if test -f $i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_tixh}" = x ; then
+ TIXHDIR="# no Tix private headers found"
+ AC_MSG_ERROR([Can't find Tix private headers])
+fi
+if test x"${ac_cv_c_tixh}" != x ; then
+ TIXHDIR="-I${ac_cv_c_tixh}"
+fi
+AC_SUBST(TIXHDIR)
+])
+
+AC_DEFUN(CY_AC_PATH_TIXCONFIG, [
+#
+# Ok, lets find the tix configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_tix}" = x ; then
+ # we reset no_tix in case something fails here
+ no_tix=true
+ AC_ARG_WITH(tixconfig, [ --with-tixconfig directory containing tix configuration (tixConfig.sh)],
+ with_tixconfig=${withval})
+ AC_MSG_CHECKING([for Tix configuration])
+ AC_CACHE_VAL(ac_cv_c_tixconfig,[
+
+ # First check to see if --with-tixconfig was specified.
+ if test x"${with_tixconfig}" != x ; then
+ if test -f "${with_tixconfig}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tix library
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ../tix \
+ `ls -dr ../tix 2>/dev/null` \
+ ../../tix \
+ `ls -dr ../../tix 2>/dev/null` \
+ ../../../tix \
+ `ls -dr ../../../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ echo "**** Looking at $i"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ echo "**** Other private locations"
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tix \
+ `ls -dr ${srcdir}/../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/${configdir}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ TIXCONFIG="# no Tix configs found"
+ AC_MSG_WARN(Can't find Tix configuration definitions)
+ else
+ no_tix=
+ TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
+ AC_MSG_RESULT(found $TIXCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TIXCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [
+ if test -f "$TIXCONFIG" ; then
+ . $TIXCONFIG
+ fi
+
+ AC_SUBST(TIX_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TIX_MAJOR_VERSION)
+dnl AC_SUBST(TIX_MINOR_VERSION)
+dnl AC_SUBST(TIX_DEFS)
+
+dnl not used, don't export to save symbols
+dnl dnl AC_SUBST(TIX_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TIX_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_EXEC_PREFIX)
+
+dnl AC_SUBST(TIX_BUILD_INCLUDES)
+ AC_SUBST(TIX_BUILD_LIB_SPEC)
+dnl AC_SUBST(TIX_LIB_SPEC)
+])
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(AM_PROG_CC_STDC,
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
+dnl a magic option to avoid problems with ANSI preprocessor commands
+dnl like #elif.
+dnl FIXME: can't do this because then AC_AIX won't work due to a
+dnl circular dependency.
+dnl AC_BEFORE([$0], [AC_PROG_CPP])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+], [
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+ AC_MSG_RESULT([none needed])
+else
+ AC_MSG_RESULT($am_cv_prog_cc_stdc)
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
diff --git a/contrib/gdb/gdb/alpha-nat.c b/contrib/gdb/gdb/alpha-nat.c
index b027116..59bd0d8 100644
--- a/contrib/gdb/gdb/alpha-nat.c
+++ b/contrib/gdb/gdb/alpha-nat.c
@@ -1,5 +1,5 @@
/* Low level Alpha interface, for GDB when running native.
- Copyright 1993, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1993, 1995, 1996, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -22,9 +22,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#include "target.h"
#include <sys/ptrace.h>
-#include <machine/reg.h>
+#ifdef __linux__
+# include <asm/reg.h>
+# include <alpha/ptrace.h>
+#else
+# include <machine/reg.h>
+#endif
#include <sys/user.h>
+/* Prototypes for local functions. */
+
+static void fetch_osf_core_registers PARAMS ((char *,
+ unsigned, int, CORE_ADDR));
+static void fetch_elf_core_registers PARAMS ((char *,
+ unsigned, int, CORE_ADDR));
+
/* Size of elements in jmpbuf */
#define JB_ELEMENT_SIZE 8
@@ -74,11 +86,11 @@ get_longjmp_target (pc)
*/
static void
-fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
+fetch_osf_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned reg_addr;
+ CORE_ADDR reg_addr;
{
register int regno;
register int addr;
@@ -121,10 +133,42 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
}
if (bad_reg >= 0)
{
- error ("Register %s not found in core file.", reg_names[bad_reg]);
+ error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
}
}
+static void
+fetch_elf_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
+ char *core_reg_sect;
+ unsigned core_reg_size;
+ int which;
+ CORE_ADDR reg_addr;
+{
+ if (core_reg_size < 32*8)
+ {
+ error ("Core file register section too small (%u bytes).", core_reg_size);
+ return;
+ }
+
+ if (which == 2)
+ {
+ /* The FPU Registers. */
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 31*8);
+ memset (&registers[REGISTER_BYTE (FP0_REGNUM+31)], 0, 8);
+ memset (&register_valid[FP0_REGNUM], 1, 32);
+ }
+ else
+ {
+ /* The General Registers. */
+ memcpy (&registers[REGISTER_BYTE (V0_REGNUM)], core_reg_sect, 31*8);
+ memcpy (&registers[REGISTER_BYTE (PC_REGNUM)], core_reg_sect+31*8, 8);
+ memset (&registers[REGISTER_BYTE (ZERO_REGNUM)], 0, 8);
+ memset (&register_valid[V0_REGNUM], 1, 32);
+ register_valid[PC_REGNUM] = 1;
+ }
+}
+
+
/* Map gdb internal register number to a ptrace ``address''.
These ``addresses'' are defined in <sys/ptrace.h> */
@@ -136,10 +180,10 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
/* Return the ptrace ``address'' of register REGNO. */
-unsigned int
+CORE_ADDR
register_addr (regno, blockend)
int regno;
- int blockend;
+ CORE_ADDR blockend;
{
return REGISTER_PTRACE_ADDR (regno);
}
@@ -150,7 +194,7 @@ kernel_u_size ()
return (sizeof (struct user));
}
-#ifdef USE_PROC_FS
+#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
#include <sys/procfs.h>
/*
@@ -162,7 +206,7 @@ supply_gregset (gregsetp)
gregset_t *gregsetp;
{
register int regi;
- register long *regp = gregsetp->regs;
+ register long *regp = ALPHA_REGSET_BASE (gregsetp);
static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
for (regi = 0; regi < 31; regi++)
@@ -181,7 +225,7 @@ fill_gregset (gregsetp, regno)
int regno;
{
int regi;
- register long *regp = gregsetp->regs;
+ register long *regp = ALPHA_REGSET_BASE (gregsetp);
for (regi = 0; regi < 31; regi++)
if ((regno == -1) || (regno == regi))
@@ -201,7 +245,7 @@ supply_fpregset (fpregsetp)
fpregset_t *fpregsetp;
{
register int regi;
- register long *regp = fpregsetp->regs;
+ register long *regp = ALPHA_REGSET_BASE (fpregsetp);
for (regi = 0; regi < 32; regi++)
supply_register (regi + FP0_REGNUM, (char *)(regp + regi));
@@ -213,7 +257,7 @@ fill_fpregset (fpregsetp, regno)
int regno;
{
int regi;
- register long *regp = fpregsetp->regs;
+ register long *regp = ALPHA_REGSET_BASE (fpregsetp);
for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
{
@@ -229,15 +273,25 @@ fill_fpregset (fpregsetp, regno)
/* Register that we are able to handle alpha core file formats. */
-static struct core_fns alpha_core_fns =
+static struct core_fns alpha_osf_core_fns =
+{
+ /* This really is bfd_target_unknown_flavour. */
+
+ bfd_target_unknown_flavour,
+ fetch_osf_core_registers,
+ NULL
+};
+
+static struct core_fns alpha_elf_core_fns =
{
- bfd_target_aout_flavour,
- fetch_core_registers,
+ bfd_target_elf_flavour,
+ fetch_elf_core_registers,
NULL
};
void
_initialize_core_alpha ()
{
- add_core_fns (&alpha_core_fns);
+ add_core_fns (&alpha_osf_core_fns);
+ add_core_fns (&alpha_elf_core_fns);
}
diff --git a/contrib/gdb/gdb/alpha-tdep.c b/contrib/gdb/gdb/alpha-tdep.c
index 7fbf642..0201016 100644
--- a/contrib/gdb/gdb/alpha-tdep.c
+++ b/contrib/gdb/gdb/alpha-tdep.c
@@ -1,5 +1,5 @@
/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
- Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -31,11 +31,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* FIXME: Some of this code should perhaps be merged with mips-tdep.c. */
-/* FIXME: Put this declaration in frame.h. */
-extern struct obstack frame_cache_obstack;
-
+/* Prototypes for local functions. */
-/* Forward declarations. */
+static alpha_extra_func_info_t push_sigtramp_desc PARAMS ((CORE_ADDR low_addr));
static CORE_ADDR read_next_frame_reg PARAMS ((struct frame_info *, int));
@@ -132,6 +130,113 @@ struct linked_proc_info
} *linked_proc_desc_table = NULL;
+/* Under GNU/Linux, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal
+ handler. In particular, the return address of a signal handler
+ points to the following sequence (the first instruction is quadword
+ aligned):
+
+ bis $30,$30,$16
+ addq $31,0x67,$0
+ call_pal callsys
+
+ Each instruction has a unique encoding, so we simply attempt to
+ match the instruction the pc is pointing to with any of the above
+ instructions. If there is a hit, we know the offset to the start
+ of the designated sequence and can then check whether we really are
+ executing in a designated sequence. If not, -1 is returned,
+ otherwise the offset from the start of the desingated sequence is
+ returned.
+
+ There is a slight chance of false hits: code could jump into the
+ middle of the designated sequence, in which case there is no
+ guarantee that we are in the middle of a sigreturn syscall. Don't
+ think this will be a problem in praxis, though.
+*/
+
+long
+alpha_linux_sigtramp_offset (CORE_ADDR pc)
+{
+ unsigned int i[3], w;
+ long off;
+
+ if (read_memory_nobpt(pc, (char *) &w, 4) != 0)
+ return -1;
+
+ off = -1;
+ switch (w)
+ {
+ case 0x47de0410: off = 0; break; /* bis $30,$30,$16 */
+ case 0x43ecf400: off = 4; break; /* addq $31,0x67,$0 */
+ case 0x00000083: off = 8; break; /* call_pal callsys */
+ default: return -1;
+ }
+ pc -= off;
+ if (pc & 0x7)
+ {
+ /* designated sequence is not quadword aligned */
+ return -1;
+ }
+
+ if (read_memory_nobpt(pc, (char *) i, sizeof(i)) != 0)
+ return -1;
+
+ if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083)
+ return off;
+
+ return -1;
+}
+
+
+/* Under OSF/1, the __sigtramp routine is frameless and has a frame
+ size of zero, but we are able to backtrace through it. */
+CORE_ADDR
+alpha_osf_skip_sigtramp_frame (frame, pc)
+ struct frame_info *frame;
+ CORE_ADDR pc;
+{
+ char *name;
+ find_pc_partial_function (pc, &name, (CORE_ADDR *)NULL, (CORE_ADDR *)NULL);
+ if (IN_SIGTRAMP (pc, name))
+ return frame->frame;
+ else
+ return 0;
+}
+
+
+/* Dynamically create a signal-handler caller procedure descriptor for
+ the signal-handler return code starting at address LOW_ADDR. The
+ descriptor is added to the linked_proc_desc_table. */
+
+static alpha_extra_func_info_t
+push_sigtramp_desc (low_addr)
+ CORE_ADDR low_addr;
+{
+ struct linked_proc_info *link;
+ alpha_extra_func_info_t proc_desc;
+
+ link = (struct linked_proc_info *)
+ xmalloc (sizeof (struct linked_proc_info));
+ link->next = linked_proc_desc_table;
+ linked_proc_desc_table = link;
+
+ proc_desc = &link->info;
+
+ proc_desc->numargs = 0;
+ PROC_LOW_ADDR (proc_desc) = low_addr;
+ PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4;
+ PROC_DUMMY_FRAME (proc_desc) = 0;
+ PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */
+ PROC_FRAME_REG (proc_desc) = SP_REGNUM;
+ PROC_REG_MASK (proc_desc) = 0xffff;
+ PROC_FREG_MASK (proc_desc) = 0xffff;
+ PROC_PC_REG (proc_desc) = 26;
+ PROC_LOCALOFF (proc_desc) = 0;
+ SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc);
+ return (proc_desc);
+}
+
+
/* Guaranteed to set frame->saved_regs to some values (it never leaves it
NULL). */
@@ -145,9 +250,7 @@ alpha_find_saved_regs (frame)
alpha_extra_func_info_t proc_desc;
int returnreg;
- frame->saved_regs = (struct frame_saved_regs *)
- obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
- memset (frame->saved_regs, 0, sizeof (struct frame_saved_regs));
+ frame_saved_regs_zalloc (frame);
/* If it is the frame for __sigtramp, the saved registers are located
in a sigcontext structure somewhere on the stack. __sigtramp
@@ -161,25 +264,20 @@ alpha_find_saved_regs (frame)
#endif
if (frame->signal_handler_caller)
{
- CORE_ADDR sigcontext_pointer_addr;
CORE_ADDR sigcontext_addr;
- if (frame->next)
- sigcontext_pointer_addr = frame->next->frame;
- else
- sigcontext_pointer_addr = frame->frame;
- sigcontext_addr = read_memory_integer(sigcontext_pointer_addr, 8);
+ sigcontext_addr = SIGCONTEXT_ADDR (frame);
for (ireg = 0; ireg < 32; ireg++)
{
reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
- frame->saved_regs->regs[ireg] = reg_position;
+ frame->saved_regs[ireg] = reg_position;
}
for (ireg = 0; ireg < 32; ireg++)
{
reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8;
- frame->saved_regs->regs[FP0_REGNUM + ireg] = reg_position;
+ frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
}
- frame->saved_regs->regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
+ frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
return;
}
@@ -202,7 +300,7 @@ alpha_find_saved_regs (frame)
register number. */
if (mask & (1 << returnreg))
{
- frame->saved_regs->regs[returnreg] = reg_position;
+ frame->saved_regs[returnreg] = reg_position;
reg_position += 8;
mask &= ~(1 << returnreg); /* Clear bit for RA so we
don't save again later. */
@@ -211,7 +309,7 @@ alpha_find_saved_regs (frame)
for (ireg = 0; ireg <= 31 ; ++ireg)
if (mask & (1 << ireg))
{
- frame->saved_regs->regs[ireg] = reg_position;
+ frame->saved_regs[ireg] = reg_position;
reg_position += 8;
}
@@ -224,11 +322,11 @@ alpha_find_saved_regs (frame)
for (ireg = 0; ireg <= 31 ; ++ireg)
if (mask & (1 << ireg))
{
- frame->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
+ frame->saved_regs[FP0_REGNUM+ireg] = reg_position;
reg_position += 8;
}
- frame->saved_regs->regs[PC_REGNUM] = frame->saved_regs->regs[returnreg];
+ frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
}
static CORE_ADDR
@@ -246,8 +344,8 @@ read_next_frame_reg(fi, regno)
{
if (fi->saved_regs == NULL)
alpha_find_saved_regs (fi);
- if (fi->saved_regs->regs[regno])
- return read_memory_integer(fi->saved_regs->regs[regno], 8);
+ if (fi->saved_regs[regno])
+ return read_memory_integer(fi->saved_regs[regno], 8);
}
}
return read_register(regno);
@@ -285,13 +383,28 @@ alpha_saved_pc_after_call (frame)
proc_desc = find_proc_desc (pc, frame->next);
pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM;
- return read_register (pcreg);
+ if (frame->signal_handler_caller)
+ return alpha_frame_saved_pc (frame);
+ else
+ return read_register (pcreg);
}
static struct alpha_extra_func_info temp_proc_desc;
static struct frame_saved_regs temp_saved_regs;
+/* Nonzero if instruction at PC is a return instruction. "ret
+ $zero,($ra),1" on alpha. */
+
+static int
+alpha_about_to_return (pc)
+ CORE_ADDR pc;
+{
+ return read_memory_integer (pc, 4) == 0x6bfa8001;
+}
+
+
+
/* This fencepost looks highly suspicious to me. Removing it also
seems suspicious as it could affect remote debugging across serial
lines. */
@@ -342,8 +455,8 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\
return 0;
}
- else if (ABOUT_TO_RETURN(start_pc))
- break;
+ else if (alpha_about_to_return (start_pc))
+ break;
start_pc += 4; /* skip return */
return start_pc;
@@ -382,7 +495,15 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
word = extract_unsigned_integer (buf, 4);
if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
- frame_size += (-word) & 0xffff;
+ {
+ if (word & 0x8000)
+ frame_size += (-word) & 0xffff;
+ else
+ /* Exit loop if a positive stack adjustment is found, which
+ usually means that the stack cleanup code in the function
+ epilogue is reached. */
+ break;
+ }
else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
&& (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
{
@@ -404,14 +525,18 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
rearrange the register saves.
So we recognize only a few registers (t7, t9, ra) within
the procedure prologue as valid return address registers.
+ If we encounter a return instruction, we extract the
+ the return address register from it.
FIXME: Rewriting GDB to access the procedure descriptors,
e.g. via the minimal symbol table, might obviate this hack. */
if (pcreg == -1
- && cur_pc < (start_pc + 20)
+ && cur_pc < (start_pc + 80)
&& (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM))
pcreg = reg;
}
+ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
+ pcreg = (word >> 16) & 0x1f;
else if (word == 0x47de040f) /* bis sp,sp fp */
has_frame_reg = 1;
}
@@ -419,15 +544,13 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
{
/* If we haven't found a valid return address register yet,
keep searching in the procedure prologue. */
- while (cur_pc < (limit_pc + 20) && cur_pc < (start_pc + 20))
+ while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
{
char buf[4];
unsigned long word;
- int status;
- status = read_memory_nobpt (cur_pc, buf, 4);
- if (status)
- memory_error (status, cur_pc);
+ if (read_memory_nobpt (cur_pc, buf, 4))
+ break;
cur_pc += 4;
word = extract_unsigned_integer (buf, 4);
@@ -441,6 +564,11 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
break;
}
}
+ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
+ {
+ pcreg = (word >> 16) & 0x1f;
+ break;
+ }
}
}
@@ -471,6 +599,9 @@ after_prologue (pc, proc_desc)
if (proc_desc)
{
+ if (PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
+ return PROC_LOW_ADDR (proc_desc); /* "prologue" is in kernel */
+
/* If function is frameless, then we need to do it the hard way. I
strongly suspect that frameless always means prologueless... */
if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
@@ -493,7 +624,7 @@ after_prologue (pc, proc_desc)
}
/* Return non-zero if we *might* be in a function prologue. Return zero if we
- are definatly *not* in a function prologue. */
+ are definitively *not* in a function prologue. */
static int
alpha_in_prologue (pc, proc_desc)
@@ -599,6 +730,8 @@ find_proc_desc (pc, next_frame)
}
else
{
+ long offset;
+
/* Is linked_proc_desc_table really necessary? It only seems to be used
by procedure call dummys. However, the procedures being called ought
to have their own proc_descs, and even if they don't,
@@ -610,7 +743,19 @@ find_proc_desc (pc, next_frame)
&& PROC_HIGH_ADDR(&link->info) > pc)
return &link->info;
- if (startaddr == 0)
+ /* If PC is inside a dynamically generated sigtramp handler,
+ create and push a procedure descriptor for that code: */
+ offset = DYNAMIC_SIGTRAMP_OFFSET (pc);
+ if (offset >= 0)
+ return push_sigtramp_desc (pc - offset);
+
+ /* If heuristic_fence_post is non-zero, determine the procedure
+ start address by examining the instructions.
+ This allows us to find the start address of static functions which
+ have no symbolic information, as startaddr would have been set to
+ the preceding global function start address by the
+ find_pc_partial_function call above. */
+ if (startaddr == 0 || heuristic_fence_post != 0)
startaddr = heuristic_proc_start (pc);
proc_desc =
@@ -650,17 +795,7 @@ alpha_frame_chain(frame)
/* The previous frame from a sigtramp frame might be frameless
and have frame size zero. */
&& !frame->signal_handler_caller)
- {
- /* The alpha __sigtramp routine is frameless and has a frame size
- of zero, but we are able to backtrace through it. */
- char *name;
- find_pc_partial_function (saved_pc, &name,
- (CORE_ADDR *)NULL, (CORE_ADDR *)NULL);
- if (IN_SIGTRAMP (saved_pc, name))
- return frame->frame;
- else
- return 0;
- }
+ return FRAME_PAST_SIGTRAMP_FRAME (frame, saved_pc);
else
return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
+ PROC_FRAME_OFFSET(proc_desc);
@@ -696,7 +831,8 @@ init_extra_frame_info (frame)
/* This may not be quite right, if proc has a real frame register.
Get the value of the frame relative sp, procedure might have been
interrupted by a signal at it's very start. */
- else if (frame->pc == PROC_LOW_ADDR (proc_desc) && !PROC_DESC_IS_DUMMY (proc_desc))
+ else if (frame->pc == PROC_LOW_ADDR (proc_desc)
+ && !PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
else
frame->frame = read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
@@ -713,12 +849,11 @@ init_extra_frame_info (frame)
(CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
if (!IN_SIGTRAMP (frame->pc, name))
{
- frame->saved_regs = (struct frame_saved_regs*)
- obstack_alloc (&frame_cache_obstack,
- sizeof (struct frame_saved_regs));
- *frame->saved_regs = temp_saved_regs;
- frame->saved_regs->regs[PC_REGNUM]
- = frame->saved_regs->regs[RA_REGNUM];
+ frame->saved_regs = (CORE_ADDR*)
+ frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
+ memcpy (frame->saved_regs, temp_saved_regs.regs, SIZEOF_FRAME_SAVED_REGS);
+ frame->saved_regs[PC_REGNUM]
+ = frame->saved_regs[RA_REGNUM];
}
}
}
@@ -878,7 +1013,7 @@ alpha_push_dummy_frame()
*/
/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
-#define MASK(i,j) (((1L << ((j)+1)) - 1) ^ ((1L << (i)) - 1))
+#define MASK(i,j) ((((LONGEST)1 << ((j)+1)) - 1) ^ (((LONGEST)1 << (i)) - 1))
#define GEN_REG_SAVE_MASK (MASK(0,8) | MASK(16,29))
#define GEN_REG_SAVE_COUNT 24
#define FLOAT_REG_SAVE_MASK (MASK(0,1) | MASK(10,30))
@@ -974,17 +1109,18 @@ alpha_pop_frame()
for (regnum = 32; --regnum >= 0; )
if (PROC_REG_MASK(proc_desc) & (1 << regnum))
write_register (regnum,
- read_memory_integer (frame->saved_regs->regs[regnum],
+ read_memory_integer (frame->saved_regs[regnum],
8));
for (regnum = 32; --regnum >= 0; )
if (PROC_FREG_MASK(proc_desc) & (1 << regnum))
write_register (regnum + FP0_REGNUM,
- read_memory_integer (frame->saved_regs->regs[regnum + FP0_REGNUM], 8));
+ read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8));
}
write_register (SP_REGNUM, new_sp);
flush_cached_frames ();
- if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
+ if (proc_desc && (PROC_DESC_IS_DUMMY(proc_desc)
+ || PROC_DESC_IS_DYN_SIGTRAMP (proc_desc)))
{
struct linked_proc_info *pi_ptr, *prev_ptr;
@@ -1129,7 +1265,7 @@ alpha_register_convert_to_virtual (regnum, valtype, raw_buffer, virtual_buffer)
}
else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
{
- unsigned LONGEST l;
+ ULONGEST l;
l = extract_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum));
l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
@@ -1158,7 +1294,7 @@ alpha_register_convert_to_raw (valtype, regnum, virtual_buffer, raw_buffer)
}
else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
{
- unsigned LONGEST l;
+ ULONGEST l;
if (TYPE_UNSIGNED (valtype))
l = extract_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype));
else
diff --git a/contrib/gdb/gdb/annotate.c b/contrib/gdb/gdb/annotate.c
index 282e171..ec3e424 100644
--- a/contrib/gdb/gdb/annotate.c
+++ b/contrib/gdb/gdb/annotate.c
@@ -1,5 +1,5 @@
/* Annotation routines for GDB.
- Copyright 1986, 1989, 1990, 1991, 1992, 1995 Free Software Foundation, Inc.
+ Copyright 1986, 89, 90, 91, 92, 95, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -24,8 +24,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbtypes.h"
#include "breakpoint.h"
+
+/* Prototypes for local functions. */
+
static void print_value_flags PARAMS ((struct type *));
+static void breakpoint_changed PARAMS ((struct breakpoint *));
+
+void (*annotate_starting_hook) PARAMS ((void));
+void (*annotate_stopped_hook) PARAMS ((void));
+void (*annotate_signalled_hook) PARAMS ((void));
+void (*annotate_exited_hook) PARAMS ((void));
+
static void
print_value_flags (t)
struct type *t;
@@ -55,6 +65,14 @@ annotate_breakpoint (num)
}
void
+annotate_catchpoint (num)
+ int num;
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032catchpoint %d\n", num);
+}
+
+void
annotate_watchpoint (num)
int num;
{
@@ -65,30 +83,49 @@ annotate_watchpoint (num)
void
annotate_starting ()
{
- if (annotation_level > 1)
+
+ if (annotate_starting_hook)
+ annotate_starting_hook ();
+ else
{
- printf_filtered ("\n\032\032starting\n");
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032starting\n");
+ }
}
}
void
annotate_stopped ()
{
- if (annotation_level > 1)
- printf_filtered ("\n\032\032stopped\n");
+ if (annotate_stopped_hook)
+ annotate_stopped_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032stopped\n");
+ }
}
void
annotate_exited (exitstatus)
int exitstatus;
{
- if (annotation_level > 1)
- printf_filtered ("\n\032\032exited %d\n", exitstatus);
+ if (annotate_exited_hook)
+ annotate_exited_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032exited %d\n", exitstatus);
+ }
}
void
annotate_signalled ()
{
+ if (annotate_signalled_hook)
+ annotate_signalled_hook ();
+
if (annotation_level > 1)
printf_filtered ("\n\032\032signalled\n");
}
diff --git a/contrib/gdb/gdb/annotate.h b/contrib/gdb/gdb/annotate.h
index b91d140..59739db 100644
--- a/contrib/gdb/gdb/annotate.h
+++ b/contrib/gdb/gdb/annotate.h
@@ -17,9 +17,13 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#include "symtab.h"
+#include "gdbtypes.h"
+
extern void breakpoints_changed PARAMS ((void));
extern void annotate_breakpoint PARAMS ((int));
+extern void annotate_catchpoint PARAMS ((int));
extern void annotate_watchpoint PARAMS ((int));
extern void annotate_starting PARAMS ((void));
extern void annotate_stopped PARAMS ((void));
@@ -93,3 +97,8 @@ extern void annotate_elt_rep PARAMS ((unsigned int));
extern void annotate_elt_rep_end PARAMS ((void));
extern void annotate_elt PARAMS ((void));
extern void annotate_array_section_end PARAMS ((void));
+
+extern void (*annotate_starting_hook) PARAMS ((void));
+extern void (*annotate_stopped_hook) PARAMS ((void));
+extern void (*annotate_signalled_hook) PARAMS ((void));
+extern void (*annotate_exited_hook) PARAMS ((void));
diff --git a/contrib/gdb/gdb/arc-tdep.c b/contrib/gdb/gdb/arc-tdep.c
new file mode 100644
index 0000000..9295770
--- /dev/null
+++ b/contrib/gdb/gdb/arc-tdep.c
@@ -0,0 +1,733 @@
+/* ARC target-dependent stuff.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "floatformat.h"
+#include "symtab.h"
+#include "gdbcmd.h"
+
+/* Current CPU, set with the "set cpu" command. */
+static int arc_bfd_mach_type;
+char *arc_cpu_type;
+char *tmp_arc_cpu_type;
+
+/* Table of cpu names. */
+struct {
+ char *name;
+ int value;
+} arc_cpu_type_table[] = {
+ { "base", bfd_mach_arc_base },
+ { NULL, 0 }
+};
+
+/* Used by simulator. */
+int display_pipeline_p;
+int cpu_timer;
+/* This one must have the same type as used in the emulator.
+ It's currently an enum so this should be ok for now. */
+int debug_pipeline_p;
+
+#define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24)
+
+#define OPMASK 0xf8000000
+
+/* Instruction field accessor macros.
+ See the Programmer's Reference Manual. */
+#define X_OP(i) (((i) >> 27) & 0x1f)
+#define X_A(i) (((i) >> 21) & 0x3f)
+#define X_B(i) (((i) >> 15) & 0x3f)
+#define X_C(i) (((i) >> 9) & 0x3f)
+#define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100)
+#define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000)
+#define X_N(i) (((i) >> 5) & 3)
+#define X_Q(i) ((i) & 0x1f)
+
+/* Return non-zero if X is a short immediate data indicator. */
+#define SHIMM_P(x) ((x) == 61 || (x) == 63)
+
+/* Return non-zero if X is a "long" (32 bit) immediate data indicator. */
+#define LIMM_P(x) ((x) == 62)
+
+/* Build a simple instruction. */
+#define BUILD_INSN(op, a, b, c, d) \
+ ((((op) & 31) << 27) \
+ | (((a) & 63) << 21) \
+ | (((b) & 63) << 15) \
+ | (((c) & 63) << 9) \
+ | ((d) & 511))
+
+/* Codestream stuff. */
+static void codestream_read PARAMS ((unsigned int *, int));
+static void codestream_seek PARAMS ((CORE_ADDR));
+static unsigned int codestream_fill PARAMS ((int));
+
+#define CODESTREAM_BUFSIZ 16
+static CORE_ADDR codestream_next_addr;
+static CORE_ADDR codestream_addr;
+static unsigned int codestream_buf[CODESTREAM_BUFSIZ];
+static int codestream_off;
+static int codestream_cnt;
+
+#define codestream_tell() \
+ (codestream_addr + codestream_off * sizeof (codestream_buf[0]))
+#define codestream_peek() \
+ (codestream_cnt == 0 \
+ ? codestream_fill (1) \
+ : codestream_buf[codestream_off])
+#define codestream_get() \
+ (codestream_cnt-- == 0 \
+ ? codestream_fill (0) \
+ : codestream_buf[codestream_off++])
+
+static unsigned int
+codestream_fill (peek_flag)
+ int peek_flag;
+{
+ codestream_addr = codestream_next_addr;
+ codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
+ codestream_off = 0;
+ codestream_cnt = CODESTREAM_BUFSIZ;
+ read_memory (codestream_addr, (char *) codestream_buf,
+ CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
+ /* FIXME: check return code? */
+
+ /* Handle byte order differences. */
+ if (HOST_BYTE_ORDER != TARGET_BYTE_ORDER)
+ {
+ register unsigned int i, j, n = sizeof (codestream_buf[0]);
+ register char tmp, *p;
+ for (i = 0, p = (char *) codestream_buf; i < CODESTREAM_BUFSIZ;
+ ++i, p += n)
+ for (j = 0; j < n / 2; ++j)
+ tmp = p[j], p[j] = p[n - 1 - j], p[n - 1 - j] = tmp;
+ }
+
+ if (peek_flag)
+ return codestream_peek ();
+ else
+ return codestream_get ();
+}
+
+static void
+codestream_seek (place)
+ CORE_ADDR place;
+{
+ codestream_next_addr = place / CODESTREAM_BUFSIZ;
+ codestream_next_addr *= CODESTREAM_BUFSIZ;
+ codestream_cnt = 0;
+ codestream_fill (1);
+ while (codestream_tell () != place)
+ codestream_get ();
+}
+
+/* This function is currently unused but leave in for now. */
+
+static void
+codestream_read (buf, count)
+ unsigned int *buf;
+ int count;
+{
+ unsigned int *p;
+ int i;
+ p = buf;
+ for (i = 0; i < count; i++)
+ *p++ = codestream_get ();
+}
+
+/* Set up prologue scanning and return the first insn. */
+
+static unsigned int
+setup_prologue_scan (pc)
+ CORE_ADDR pc;
+{
+ unsigned int insn;
+
+ codestream_seek (pc);
+ insn = codestream_get ();
+
+ return insn;
+}
+
+/*
+ * Find & return amount a local space allocated, and advance codestream to
+ * first register push (if any).
+ * If entry sequence doesn't make sense, return -1, and leave
+ * codestream pointer random.
+ */
+
+static long
+arc_get_frame_setup (pc)
+ CORE_ADDR pc;
+{
+ unsigned int insn;
+ /* Size of frame or -1 if unrecognizable prologue. */
+ int frame_size = -1;
+ /* An initial "sub sp,sp,N" may or may not be for a stdarg fn. */
+ int maybe_stdarg_decr = -1;
+
+ insn = setup_prologue_scan (pc);
+
+ /* The authority for what appears here is the home-grown ABI.
+ The most recent version is 1.2. */
+
+ /* First insn may be "sub sp,sp,N" if stdarg fn. */
+ if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+ == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
+ {
+ maybe_stdarg_decr = X_D (insn);
+ insn = codestream_get ();
+ }
+
+ if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
+ == BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
+ {
+ insn = codestream_get ();
+ /* Frame may not be necessary, even though blink is saved.
+ At least this is something we recognize. */
+ frame_size = 0;
+ }
+
+ if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */
+ == BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0))
+ {
+ insn = codestream_get ();
+ if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+ != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
+ return -1;
+
+ /* Check for stack adjustment sub sp,sp,N. */
+ insn = codestream_peek ();
+ if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
+ == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
+ {
+ if (LIMM_P (X_C (insn)))
+ frame_size = codestream_get ();
+ else if (SHIMM_P (X_C (insn)))
+ frame_size = X_D (insn);
+ else
+ return -1;
+ if (frame_size < 0)
+ return -1;
+
+ codestream_get ();
+
+ /* This sequence is used to get the address of the return
+ buffer for a function that returns a structure. */
+ insn = codestream_peek ();
+ if (insn & OPMASK == 0x60000000)
+ codestream_get ();
+ }
+ /* Frameless fn. */
+ else
+ {
+ frame_size = 0;
+ }
+ }
+
+ /* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
+ stdarg fn. The stdarg decrement is not treated as part of the frame size,
+ so we have a dilemma: what do we return? For now, if we get a
+ "sub sp,sp,N" and nothing else assume this isn't a stdarg fn. One way
+ to fix this completely would be to add a bit to the function descriptor
+ that says the function is a stdarg function. */
+
+ if (frame_size < 0 && maybe_stdarg_decr > 0)
+ return maybe_stdarg_decr;
+ return frame_size;
+}
+
+/* Given a pc value, skip it forward past the function prologue by
+ disassembling instructions that appear to be a prologue.
+
+ If FRAMELESS_P is set, we are only testing to see if the function
+ is frameless. If it is a frameless function, return PC unchanged.
+ This allows a quicker answer. */
+
+CORE_ADDR
+skip_prologue (pc, frameless_p)
+ CORE_ADDR pc;
+ int frameless_p;
+{
+ unsigned int insn;
+ int i, frame_size;
+
+ if ((frame_size = arc_get_frame_setup (pc)) < 0)
+ return (pc);
+
+ if (frameless_p)
+ return frame_size == 0 ? pc : codestream_tell ();
+
+ /* Skip over register saves. */
+ for (i = 0; i < 8; i++)
+ {
+ insn = codestream_peek ();
+ if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
+ != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
+ break; /* not st insn */
+ if (! ARC_CALL_SAVED_REG (X_C (insn)))
+ break;
+ codestream_get ();
+ }
+
+ return codestream_tell ();
+}
+
+/* Return the return address for a frame.
+ This is used to implement FRAME_SAVED_PC.
+ This is taken from frameless_look_for_prologue. */
+
+CORE_ADDR
+arc_frame_saved_pc (frame)
+ struct frame_info *frame;
+{
+ CORE_ADDR func_start;
+ unsigned int insn;
+
+ func_start = get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET;
+ if (func_start == 0)
+ {
+ /* Best guess. */
+ return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
+ }
+
+ /* The authority for what appears here is the home-grown ABI.
+ The most recent version is 1.2. */
+
+ insn = setup_prologue_scan (func_start);
+
+ /* First insn may be "sub sp,sp,N" if stdarg fn. */
+ if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+ == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
+ insn = codestream_get ();
+
+ /* If the next insn is "st blink,[sp,4]" we can get blink from there.
+ Otherwise this is a leaf function and we can use blink. Note that
+ this still allows for the case where a leaf function saves/clobbers/
+ restores blink. */
+
+ if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
+ != BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
+ return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
+ else
+ return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
+}
+
+/*
+ * Parse the first few instructions of the function to see
+ * what registers were stored.
+ *
+ * The startup sequence can be at the start of the function.
+ * 'st blink,[sp+4], st fp,[sp], mov fp,sp'
+ *
+ * Local space is allocated just below by sub sp,sp,nnn.
+ * Next, the registers used by this function are stored (as offsets from sp).
+ */
+
+void
+frame_find_saved_regs (fip, fsrp)
+ struct frame_info *fip;
+ struct frame_saved_regs *fsrp;
+{
+ long locals;
+ unsigned int insn;
+ CORE_ADDR dummy_bottom;
+ CORE_ADDR adr;
+ int i, regnum, offset;
+
+ memset (fsrp, 0, sizeof *fsrp);
+
+ /* If frame is the end of a dummy, compute where the beginning would be. */
+ dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
+
+ /* Check if the PC is in the stack, in a dummy frame. */
+ if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
+ {
+ /* all regs were saved by push_call_dummy () */
+ adr = fip->frame;
+ for (i = 0; i < NUM_REGS; i++)
+ {
+ adr -= REGISTER_RAW_SIZE (i);
+ fsrp->regs[i] = adr;
+ }
+ return;
+ }
+
+ locals = arc_get_frame_setup (get_pc_function_start (fip->pc));
+
+ if (locals >= 0)
+ {
+ /* Set `adr' to the value of `sp'. */
+ adr = fip->frame - locals;
+ for (i = 0; i < 8; i++)
+ {
+ insn = codestream_get ();
+ if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
+ != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
+ break;
+ regnum = X_C (insn);
+ offset = X_D (insn);
+ fsrp->regs[regnum] = adr + offset;
+ }
+ }
+
+ fsrp->regs[PC_REGNUM] = fip->frame + 4;
+ fsrp->regs[FP_REGNUM] = fip->frame;
+}
+
+void
+push_dummy_frame ()
+{
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ int regnum;
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ read_register_gen (PC_REGNUM, regbuf);
+ write_memory (sp+4, regbuf, REGISTER_SIZE);
+ read_register_gen (FP_REGNUM, regbuf);
+ write_memory (sp, regbuf, REGISTER_SIZE);
+ write_register (FP_REGNUM, sp);
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ read_register_gen (regnum, regbuf);
+ sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
+ }
+ sp += (2*REGISTER_SIZE);
+ write_register (SP_REGNUM, sp);
+}
+
+void
+pop_frame ()
+{
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR fp;
+ int regnum;
+ struct frame_saved_regs fsr;
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ fp = FRAME_FP (frame);
+ get_frame_saved_regs (frame, &fsr);
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ CORE_ADDR adr;
+ adr = fsr.regs[regnum];
+ if (adr)
+ {
+ read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
+ write_register_bytes (REGISTER_BYTE (regnum), regbuf,
+ REGISTER_RAW_SIZE (regnum));
+ }
+ }
+ write_register (FP_REGNUM, read_memory_integer (fp, 4));
+ write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
+ write_register (SP_REGNUM, fp + 8);
+ flush_cached_frames ();
+}
+
+/* Simulate single-step. */
+
+typedef enum
+{
+ NORMAL4, /* a normal 4 byte insn */
+ NORMAL8, /* a normal 8 byte insn */
+ BRANCH4, /* a 4 byte branch insn, including ones without delay slots */
+ BRANCH8, /* an 8 byte branch insn, including ones with delay slots */
+} insn_type;
+
+/* Return the type of INSN and store in TARGET the destination address of a
+ branch if this is one. */
+/* ??? Need to verify all cases are properly handled. */
+
+static insn_type
+get_insn_type (insn, pc, target)
+ unsigned long insn;
+ CORE_ADDR pc, *target;
+{
+ unsigned long limm;
+
+ switch (insn >> 27)
+ {
+ case 0 : case 1 : case 2 : /* load/store insns */
+ if (LIMM_P (X_A (insn))
+ || LIMM_P (X_B (insn))
+ || LIMM_P (X_C (insn)))
+ return NORMAL8;
+ return NORMAL4;
+ case 4 : case 5 : case 6 : /* branch insns */
+ *target = pc + 4 + X_L (insn);
+ /* ??? It isn't clear that this is always the right answer.
+ The problem occurs when the next insn is an 8 byte insn. If the
+ branch is conditional there's no worry as there shouldn't be an 8
+ byte insn following. The programmer may be cheating if s/he knows
+ the branch will never be taken, but we don't deal with that.
+ Note that the programmer is also allowed to play games by putting
+ an insn with long immediate data in the delay slot and then duplicate
+ the long immediate data at the branch target. Ugh! */
+ if (X_N (insn) == 0)
+ return BRANCH4;
+ return BRANCH8;
+ case 7 : /* jump insns */
+ if (LIMM_P (X_B (insn)))
+ {
+ limm = read_memory_integer (pc + 4, 4);
+ *target = ARC_PC_TO_REAL_ADDRESS (limm);
+ return BRANCH8;
+ }
+ if (SHIMM_P (X_B (insn)))
+ *target = ARC_PC_TO_REAL_ADDRESS (X_D (insn));
+ else
+ *target = ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn)));
+ if (X_Q (insn) == 0 && X_N (insn) == 0)
+ return BRANCH4;
+ return BRANCH8;
+ default : /* arithmetic insns, etc. */
+ if (LIMM_P (X_A (insn))
+ || LIMM_P (X_B (insn))
+ || LIMM_P (X_C (insn)))
+ return NORMAL8;
+ return NORMAL4;
+ }
+}
+
+/* single_step() is called just before we want to resume the inferior, if we
+ want to single-step it but there is no hardware or kernel single-step
+ support. We find all the possible targets of the coming instruction and
+ breakpoint them.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+void
+arc_software_single_step (ignore, insert_breakpoints_p)
+ enum target_signal ignore; /* sig but we don't need it */
+ int insert_breakpoints_p;
+{
+ static CORE_ADDR next_pc, target;
+ static int brktrg_p;
+ typedef char binsn_quantum[BREAKPOINT_MAX];
+ static binsn_quantum break_mem[2];
+
+ if (insert_breakpoints_p)
+ {
+ insn_type type;
+ CORE_ADDR pc;
+ unsigned long insn;
+
+ pc = read_register (PC_REGNUM);
+ insn = read_memory_integer (pc, 4);
+ type = get_insn_type (insn, pc, &target);
+
+ /* Always set a breakpoint for the insn after the branch. */
+ next_pc = pc + ((type == NORMAL8 || type == BRANCH8) ? 8 : 4);
+ target_insert_breakpoint (next_pc, break_mem[0]);
+
+ brktrg_p = 0;
+
+ if ((type == BRANCH4 || type == BRANCH8)
+ /* Watch out for branches to the following location.
+ We just stored a breakpoint there and another call to
+ target_insert_breakpoint will think the real insn is the
+ breakpoint we just stored there. */
+ && target != next_pc)
+ {
+ brktrg_p = 1;
+ target_insert_breakpoint (target, break_mem[1]);
+ }
+
+ }
+ else
+ {
+ /* Remove breakpoints. */
+ target_remove_breakpoint (next_pc, break_mem[0]);
+
+ if (brktrg_p)
+ target_remove_breakpoint (target, break_mem[1]);
+
+ /* Fix the pc. */
+ stop_pc -= DECR_PC_AFTER_BREAK;
+ write_pc (stop_pc);
+ }
+}
+
+#ifdef GET_LONGJMP_TARGET
+/* 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 PC.
+ This routine returns true on success. */
+
+int
+get_longjmp_target(pc)
+ CORE_ADDR *pc;
+{
+ char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ CORE_ADDR sp, jb_addr;
+
+ sp = read_register (SP_REGNUM);
+
+ if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
+ buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+#endif /* GET_LONGJMP_TARGET */
+
+/* Disassemble one instruction. */
+
+static int
+arc_print_insn (vma, info)
+ bfd_vma vma;
+ disassemble_info *info;
+{
+ static int current_mach;
+ static int current_endian;
+ static disassembler_ftype current_disasm;
+
+ if (current_disasm == NULL
+ || arc_bfd_mach_type != current_mach
+ || TARGET_BYTE_ORDER != current_endian)
+ {
+ current_mach = arc_bfd_mach_type;
+ current_endian = TARGET_BYTE_ORDER;
+ current_disasm = arc_get_disassembler (current_mach,
+ current_endian == BIG_ENDIAN);
+ }
+
+ return (*current_disasm) (vma, info);
+}
+
+/* Command to set cpu type. */
+
+void
+arc_set_cpu_type_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int i;
+
+ if (tmp_arc_cpu_type == NULL || *tmp_arc_cpu_type == '\0')
+ {
+ printf_unfiltered ("The known ARC cpu types are as follows:\n");
+ for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
+ printf_unfiltered ("%s\n", arc_cpu_type_table[i].name);
+
+ /* Restore the value. */
+ tmp_arc_cpu_type = strsave (arc_cpu_type);
+
+ return;
+ }
+
+ if (!arc_set_cpu_type (tmp_arc_cpu_type))
+ {
+ error ("Unknown cpu type `%s'.", tmp_arc_cpu_type);
+ /* Restore its value. */
+ tmp_arc_cpu_type = strsave (arc_cpu_type);
+ }
+}
+
+static void
+arc_show_cpu_type_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+}
+
+/* Modify the actual cpu type.
+ Result is a boolean indicating success. */
+
+int
+arc_set_cpu_type (str)
+ char *str;
+{
+ int i, j;
+
+ if (str == NULL)
+ return 0;
+
+ for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
+ {
+ if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
+ {
+ arc_cpu_type = str;
+ arc_bfd_mach_type = arc_cpu_type_table[i].value;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void
+_initialize_arc_tdep ()
+{
+ struct cmd_list_element *c;
+
+ c = add_set_cmd ("cpu", class_support, var_string_noescape,
+ (char *) &tmp_arc_cpu_type,
+ "Set the type of ARC cpu in use.\n\
+This command has two purposes. In a multi-cpu system it lets one\n\
+change the cpu being debugged. It also gives one access to\n\
+cpu-type-specific registers and recognize cpu-type-specific instructions.\
+",
+ &setlist);
+ c->function.cfunc = arc_set_cpu_type_command;
+ c = add_show_from_set (c, &showlist);
+ c->function.cfunc = arc_show_cpu_type_command;
+
+ /* We have to use strsave here because the `set' command frees it before
+ setting a new value. */
+ tmp_arc_cpu_type = strsave (DEFAULT_ARC_CPU_TYPE);
+ arc_set_cpu_type (tmp_arc_cpu_type);
+
+ c = add_set_cmd ("displaypipeline", class_support, var_zinteger,
+ (char *) &display_pipeline_p,
+ "Set pipeline display (simulator only).\n\
+When enabled, the state of the pipeline after each cycle is displayed.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
+
+ c = add_set_cmd ("debugpipeline", class_support, var_zinteger,
+ (char *) &debug_pipeline_p,
+ "Set pipeline debug display (simulator only).\n\
+When enabled, debugging information about the pipeline is displayed.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
+
+ c = add_set_cmd ("cputimer", class_support, var_zinteger,
+ (char *) &cpu_timer,
+ "Set maximum cycle count (simulator only).\n\
+Control will return to gdb if the timer expires.\n\
+A negative value disables the timer.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
+
+ tm_print_insn = arc_print_insn;
+}
diff --git a/contrib/gdb/gdb/arm-tdep.c b/contrib/gdb/gdb/arm-tdep.c
index 884e9d8..607dc8f 100644
--- a/contrib/gdb/gdb/arm-tdep.c
+++ b/contrib/gdb/gdb/arm-tdep.c
@@ -1,5 +1,6 @@
/* Target-dependent code for the Acorn Risc Machine, for GDB, the GNU Debugger.
- Copyright 1988, 1989, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -20,539 +21,1099 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
-
-#if 0
+#include "gdbcmd.h"
#include "gdbcore.h"
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
+#include "symfile.h"
+#include "gdb_string.h"
+#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
+
+/*
+ The following macros are actually wrong. Neither arm nor thumb can
+ or should set the lsb on addr.
+ The thumb addresses are mod 2, so (addr & 2) would be a good heuristic
+ to use when checking for thumb (see arm_pc_is_thumb() below).
+ Unfortunately, something else depends on these (incorrect) macros, so
+ fixing them actually breaks gdb. I didn't have time to investigate. Z.R.
+*/
+/* Thumb function addresses are odd (bit 0 is set). Here are some
+ macros to test, set, or clear bit 0 of addresses. */
+#define IS_THUMB_ADDR(addr) ((addr) & 1)
+#define MAKE_THUMB_ADDR(addr) ((addr) | 1)
+#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
+
+/* Macros to round N up or down to the next A boundary; A must be
+ a power of two. */
+#define ROUND_DOWN(n,a) ((n) & ~((a) - 1))
+#define ROUND_UP(n,a) (((n) + (a) - 1) & ~((a) - 1))
+
+/* Should call_function allocate stack space for a struct return? */
+/* The system C compiler uses a similar structure return convention to gcc */
+int
+arm_use_struct_convention (gcc_p, type)
+ int gcc_p;
+ struct type *type;
+{
+ return (TYPE_LENGTH (type) > 4);
+}
-#define N_TXTADDR(hdr) 0x8000
-#define N_DATADDR(hdr) (hdr.a_text + 0x8000)
+int
+arm_frame_chain_valid (chain, thisframe)
+ CORE_ADDR chain;
+ struct frame_info *thisframe;
+{
+#define LOWEST_PC 0x20 /* the first 0x20 bytes are the trap vectors. */
+ return (chain != 0 && (FRAME_SAVED_PC (thisframe) >= LOWEST_PC));
+}
-#include <sys/user.h> /* After a.out.h */
-#include <sys/file.h>
-#include "gdb_stat.h"
+/* Set to true if the 32-bit mode is in use. */
-#include <errno.h>
-#endif
+int arm_apcs_32 = 1;
-
-#if 0
-/* Work with core dump and executable files, for GDB.
- This code would be in corefile.c if it weren't machine-dependent. */
+/* Flag set by arm_fix_call_dummy that tells whether the target function
+ is a Thumb function. This flag is checked by arm_push_arguments.
+ FIXME: Change the PUSH_ARGUMENTS macro (and its use in valops.c) to
+ pass the function address as an additional parameter. */
-/* Structure to describe the chain of shared libraries used
- by the execfile.
- e.g. prog shares Xt which shares X11 which shares c. */
+static int target_is_thumb;
-struct shared_library {
- struct exec_header header;
- char name[SHLIBLEN];
- CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file */
- long data_offset; /* offset of data section in file */
- int chan; /* file descriptor for the file */
- struct shared_library *shares; /* library this one shares */
-};
-static struct shared_library *shlib = 0;
+/* Flag set by arm_fix_call_dummy that tells whether the calling function
+ is a Thumb function. This flag is checked by arm_pc_is_thumb
+ and arm_call_dummy_breakpoint_offset. */
-/* Hook for `exec_file_command' command to call. */
+static int caller_is_thumb;
-extern void (*exec_file_display_hook) ();
-
-static CORE_ADDR unshared_text_start;
+/* Tell if the program counter value in MEMADDR is in a Thumb function. */
-/* extended header from exec file (for shared library info) */
+int
+arm_pc_is_thumb (memaddr)
+ bfd_vma memaddr;
+{
+ struct minimal_symbol * sym;
+ CORE_ADDR sp;
-static struct exec_header exec_header;
+ /* If bit 0 of the address is set, assume this is a Thumb address. */
+ if (IS_THUMB_ADDR (memaddr))
+ return 1;
-void
-exec_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
-
- /* Eliminate all traces of old exec file.
- Mark text segment as empty. */
-
- if (execfile)
- free (execfile);
- execfile = 0;
- data_start = 0;
- data_end -= exec_data_start;
- text_start = 0;
- unshared_text_start = 0;
- text_end = 0;
- exec_data_start = 0;
- exec_data_end = 0;
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
- if (shlib) {
- close_shared_library(shlib);
- shlib = 0;
- }
-
- /* Now open and digest the file the user requested, if any. */
-
- if (filename)
- {
- filename = tilde_expand (filename);
- make_cleanup (free, filename);
-
- execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
- &execfile);
- if (execchan < 0)
- perror_with_name (filename);
+ /* Thumb function have a "special" bit set in minimal symbols */
+ sym = lookup_minimal_symbol_by_pc (memaddr);
+ if (sym)
+ {
+ return (MSYMBOL_IS_SPECIAL(sym));
+ }
+ else
+ return 0;
+}
- {
- struct stat st_exec;
+/* Tell if the program counter value in MEMADDR is in a call dummy that
+ is being called from a Thumb function. */
-#ifdef HEADER_SEEK_FD
- HEADER_SEEK_FD (execchan);
-#endif
-
- val = myread (execchan, &exec_header, sizeof exec_header);
- exec_aouthdr = exec_header.a_exec;
+int
+arm_pc_is_thumb_dummy (memaddr)
+ bfd_vma memaddr;
+{
+ CORE_ADDR sp = read_sp();
+
+ if (PC_IN_CALL_DUMMY (memaddr, sp, sp+64))
+ return caller_is_thumb;
+ else
+ return 0;
+}
- if (val < 0)
- perror_with_name (filename);
+CORE_ADDR
+arm_addr_bits_remove (val)
+ CORE_ADDR val;
+{
+ if (arm_pc_is_thumb (val))
+ return (val & (arm_apcs_32 ? 0xfffffffe : 0x03fffffe));
+ else
+ return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc));
+}
- text_start = 0x8000;
+CORE_ADDR
+arm_saved_pc_after_call (frame)
+ struct frame_info *frame;
+{
+ return ADDR_BITS_REMOVE (read_register (LR_REGNUM));
+}
- /* Look for shared library if needed */
- if (exec_header.a_exec.a_magic & MF_USES_SL)
- shlib = open_shared_library(exec_header.a_shlibname, text_start);
+/* A typical Thumb prologue looks like this:
+ push {r7, lr}
+ add sp, sp, #-28
+ add r7, sp, #12
+ Sometimes the latter instruction may be replaced by:
+ mov r7, sp
+*/
- text_offset = N_TXTOFF (exec_aouthdr);
- exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
+static CORE_ADDR
+thumb_skip_prologue (pc)
+ CORE_ADDR pc;
+{
+ CORE_ADDR current_pc;
- if (shlib) {
- unshared_text_start = shared_text_end(shlib) & ~0x7fff;
- stack_start = shlib->header.a_exec.a_sldatabase;
- stack_end = STACK_END_ADDR;
- } else
- unshared_text_start = 0x8000;
- text_end = unshared_text_start + exec_aouthdr.a_text;
+ for (current_pc = pc; current_pc < pc + 20; current_pc += 2)
+ {
+ unsigned short insn = read_memory_unsigned_integer (current_pc, 2);
+
+ if ( (insn & 0xfe00) != 0xb400 /* push {..., r7, lr} */
+ && (insn & 0xff00) != 0xb000 /* add sp, #simm */
+ && (insn & 0xff00) != 0xaf00 /* add r7, sp, #imm */
+ && insn != 0x466f /* mov r7, sp */
+ && (insn & 0xffc0) != 0x4640) /* mov r0-r7, r8-r15 */
+ break;
+ }
- exec_data_start = unshared_text_start + exec_aouthdr.a_text;
- exec_data_end = exec_data_start + exec_aouthdr.a_data;
+ return current_pc;
+}
- data_start = exec_data_start;
- data_end += exec_data_start;
+/* APCS (ARM procedure call standard) defines the following prologue:
- fstat (execchan, &st_exec);
- exec_mtime = st_exec.st_mtime;
- }
+ mov ip, sp
+ [stmfd sp!, {a1,a2,a3,a4}]
+ stmfd sp!, {...,fp,ip,lr,pc}
+ [stfe f7, [sp, #-12]!]
+ [stfe f6, [sp, #-12]!]
+ [stfe f5, [sp, #-12]!]
+ [stfe f4, [sp, #-12]!]
+ sub fp, ip, #nn // nn == 20 or 4 depending on second ins
+*/
+
+CORE_ADDR
+arm_skip_prologue (pc)
+ CORE_ADDR pc;
+{
+ unsigned long inst;
+ CORE_ADDR skip_pc;
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
- validate_files ();
+ /* See what the symbol table says. */
+ if (find_pc_partial_function (pc, NULL, & func_addr, & func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.line != 0 && sal.end < func_end)
+ return sal.end;
}
- else if (from_tty)
- printf ("No exec file now.\n");
- /* Tell display code (if any) about the changed file name. */
- if (exec_file_display_hook)
- (*exec_file_display_hook) (filename);
-}
-#endif
+ /* Check if this is Thumb code. */
+ if (arm_pc_is_thumb (pc))
+ return thumb_skip_prologue (pc);
-#if 0
-/* Read from the program's memory (except for inferior processes).
- This function is misnamed, since it only reads, never writes; and
- since it will use the core file and/or executable file as necessary.
+ /* Can't find the prologue end in the symbol table, try it the hard way
+ by disassembling the instructions. */
+ skip_pc = pc;
+ inst = read_memory_integer (skip_pc, 4);
+ if (inst != 0xe1a0c00d) /* mov ip, sp */
+ return pc;
- It should be extended to write as well as read, FIXME, for patching files.
+ skip_pc += 4;
+ inst = read_memory_integer (skip_pc, 4);
+ if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */
+ {
+ skip_pc += 4;
+ inst = read_memory_integer (skip_pc, 4);
+ }
- Return 0 if address could be read, EIO if addresss out of bounds. */
+ if ((inst & 0xfffff800) != 0xe92dd800) /* stmfd sp!,{...,fp,ip,lr,pc} */
+ return pc;
-int
-xfer_core_file (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
+ skip_pc += 4;
+ inst = read_memory_integer (skip_pc, 4);
+
+ /* Any insns after this point may float into the code, if it makes
+ for better instruction scheduling, so we skip them only if
+ we find them, but still consdier the function to be frame-ful */
+
+ /* We may have either one sfmfd instruction here, or several stfe insns,
+ depending on the version of floating point code we support. */
+ if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, <cnt>, [sp]! */
+ {
+ skip_pc += 4;
+ inst = read_memory_integer (skip_pc, 4);
+ }
+ else
+ {
+ while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */
+ {
+ skip_pc += 4;
+ inst = read_memory_integer (skip_pc, 4);
+ }
+ }
+
+ if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */
+ skip_pc += 4;
+
+ return skip_pc;
+}
+
+
+
+/* Function: thumb_scan_prologue (helper function for arm_scan_prologue)
+ This function decodes a Thumb function prologue to determine:
+ 1) the size of the stack frame
+ 2) which registers are saved on it
+ 3) the offsets of saved regs
+ 4) the offset from the stack pointer to the frame pointer
+ This information is stored in the "extra" fields of the frame_info.
+
+ A typical Thumb function prologue might look like this:
+ push {r7, lr}
+ sub sp, #28,
+ add r7, sp, #12
+ Which would create this stack frame (offsets relative to FP)
+ old SP -> 24 stack parameters
+ 20 LR
+ 16 R7
+ R7 -> 0 local variables (16 bytes)
+ SP -> -12 additional stack space (12 bytes)
+ The frame size would thus be 36 bytes, and the frame offset would be
+ 12 bytes. The frame register is R7. */
+
+static void
+thumb_scan_prologue (fi)
+ struct frame_info * fi;
{
- register int i;
- register int val;
- int xferchan;
- char **xferfile;
- int fileptr;
- int returnval = 0;
+ CORE_ADDR prologue_start;
+ CORE_ADDR prologue_end;
+ CORE_ADDR current_pc;
+ int saved_reg[16]; /* which register has been copied to register n? */
+ int i;
- while (len > 0)
+ if (find_pc_partial_function (fi->pc, NULL, & prologue_start, & prologue_end))
{
- xferfile = 0;
- xferchan = 0;
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
- /* Determine which file the next bunch of addresses reside in,
- and where in the file. Set the file's read/write pointer
- to point at the proper place for the desired address
- and set xferfile and xferchan for the correct file.
+ if (sal.line == 0) /* no line info, use current PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+ prologue_end = prologue_start + 40; /* We're in the boondocks: allow for */
+ /* 16 pushes, an add, and "mv fp,sp" */
- If desired address is nonexistent, leave them zero.
+ prologue_end = min (prologue_end, fi->pc);
- i is set to the number of bytes that can be handled
- along with the next address.
+ /* Initialize the saved register map. When register H is copied to
+ register L, we will put H in saved_reg[L]. */
+ for (i = 0; i < 16; i++)
+ saved_reg[i] = i;
- We put the most likely tests first for efficiency. */
+ /* Search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers. */
- /* Note that if there is no core file
- data_start and data_end are equal. */
- if (memaddr >= data_start && memaddr < data_end)
- {
- i = min (len, data_end - memaddr);
- fileptr = memaddr - data_start + data_offset;
- xferfile = &corefile;
- xferchan = corechan;
- }
- /* Note that if there is no core file
- stack_start and stack_end define the shared library data. */
- else if (memaddr >= stack_start && memaddr < stack_end)
- {
- if (corechan < 0) {
- struct shared_library *lib;
- for (lib = shlib; lib; lib = lib->shares)
- if (memaddr >= lib->header.a_exec.a_sldatabase &&
- memaddr < lib->header.a_exec.a_sldatabase +
- lib->header.a_exec.a_data)
- break;
- if (lib) {
- i = min (len, lib->header.a_exec.a_sldatabase +
- lib->header.a_exec.a_data - memaddr);
- fileptr = lib->data_offset + memaddr -
- lib->header.a_exec.a_sldatabase;
- xferfile = execfile;
- xferchan = lib->chan;
- }
- } else {
- i = min (len, stack_end - memaddr);
- fileptr = memaddr - stack_start + stack_offset;
- xferfile = &corefile;
- xferchan = corechan;
- }
- }
- else if (corechan < 0
- && memaddr >= exec_data_start && memaddr < exec_data_end)
+ fi->framesize = 0;
+ for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2)
+ {
+ unsigned short insn;
+ int regno;
+ int offset;
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+
+ if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
{
- i = min (len, exec_data_end - memaddr);
- fileptr = memaddr - exec_data_start + exec_data_offset;
- xferfile = &execfile;
- xferchan = execchan;
+ /* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says
+ whether to save LR (R14). */
+ int mask = (insn & 0xff) | ((insn & 0x100) << 6);
+
+ /* Calculate offsets of saved R0-R7 and LR. */
+ for (regno = LR_REGNUM; regno >= 0; regno--)
+ if (mask & (1 << regno))
+ {
+ fi->framesize += 4;
+ fi->fsr.regs[saved_reg[regno]] = -(fi->framesize);
+ saved_reg[regno] = regno; /* reset saved register map */
+ }
}
- else if (memaddr >= text_start && memaddr < text_end)
+ else if ((insn & 0xff00) == 0xb000) /* add sp, #simm */
{
- struct shared_library *lib;
- for (lib = shlib; lib; lib = lib->shares)
- if (memaddr >= lib->text_start &&
- memaddr < lib->text_start + lib->header.a_exec.a_text)
- break;
- if (lib) {
- i = min (len, lib->header.a_exec.a_text +
- lib->text_start - memaddr);
- fileptr = memaddr - lib->text_start + text_offset;
- xferfile = &execfile;
- xferchan = lib->chan;
- } else {
- i = min (len, text_end - memaddr);
- fileptr = memaddr - unshared_text_start + text_offset;
- xferfile = &execfile;
- xferchan = execchan;
- }
+ offset = (insn & 0x7f) << 2; /* get scaled offset */
+ if (insn & 0x80) /* is it signed? */
+ offset = -offset;
+ fi->framesize -= offset;
}
- else if (memaddr < text_start)
+ else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */
{
- i = min (len, text_start - memaddr);
+ fi->framereg = THUMB_FP_REGNUM;
+ fi->frameoffset = (insn & 0xff) << 2; /* get scaled offset */
}
- else if (memaddr >= text_end
- && memaddr < (corechan >= 0? data_start : exec_data_start))
+ else if (insn == 0x466f) /* mov r7, sp */
{
- i = min (len, data_start - memaddr);
+ fi->framereg = THUMB_FP_REGNUM;
+ fi->frameoffset = 0;
+ saved_reg[THUMB_FP_REGNUM] = SP_REGNUM;
}
- else if (corechan >= 0
- && memaddr >= data_end && memaddr < stack_start)
+ else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */
{
- i = min (len, stack_start - memaddr);
+ int lo_reg = insn & 7; /* dest. register (r0-r7) */
+ int hi_reg = ((insn >> 3) & 7) + 8; /* source register (r8-15) */
+ saved_reg[lo_reg] = hi_reg; /* remember hi reg was saved */
}
- else if (corechan < 0 && memaddr >= exec_data_end)
+ else
+ break; /* anything else isn't prologue */
+ }
+}
+
+/* Function: check_prologue_cache
+ Check if prologue for this frame's PC has already been scanned.
+ If it has, copy the relevant information about that prologue and
+ return non-zero. Otherwise do not copy anything and return zero.
+
+ The information saved in the cache includes:
+ * the frame register number;
+ * the size of the stack frame;
+ * the offsets of saved regs (relative to the old SP); and
+ * the offset from the stack pointer to the frame pointer
+
+ The cache contains only one entry, since this is adequate
+ for the typical sequence of prologue scan requests we get.
+ When performing a backtrace, GDB will usually ask to scan
+ the same function twice in a row (once to get the frame chain,
+ and once to fill in the extra frame information).
+*/
+
+static struct frame_info prologue_cache;
+
+static int
+check_prologue_cache (fi)
+ struct frame_info * fi;
+{
+ int i;
+
+ if (fi->pc == prologue_cache.pc)
+ {
+ fi->framereg = prologue_cache.framereg;
+ fi->framesize = prologue_cache.framesize;
+ fi->frameoffset = prologue_cache.frameoffset;
+ for (i = 0; i <= NUM_REGS; i++)
+ fi->fsr.regs[i] = prologue_cache.fsr.regs[i];
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/* Function: save_prologue_cache
+ Copy the prologue information from fi to the prologue cache.
+*/
+
+static void
+save_prologue_cache (fi)
+ struct frame_info * fi;
+{
+ int i;
+
+ prologue_cache.pc = fi->pc;
+ prologue_cache.framereg = fi->framereg;
+ prologue_cache.framesize = fi->framesize;
+ prologue_cache.frameoffset = fi->frameoffset;
+
+ for (i = 0; i <= NUM_REGS; i++)
+ prologue_cache.fsr.regs[i] = fi->fsr.regs[i];
+}
+
+
+/* Function: arm_scan_prologue
+ This function decodes an ARM function prologue to determine:
+ 1) the size of the stack frame
+ 2) which registers are saved on it
+ 3) the offsets of saved regs
+ 4) the offset from the stack pointer to the frame pointer
+ This information is stored in the "extra" fields of the frame_info.
+
+ A typical Arm function prologue might look like this:
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #16
+ Which would create this stack frame (offsets relative to FP):
+ IP -> 4 (caller's stack)
+ FP -> 0 PC (points to address of stmfd instruction + 12 in callee)
+ -4 LR (return address in caller)
+ -8 IP (copy of caller's SP)
+ -12 FP (caller's FP)
+ SP -> -28 Local variables
+ The frame size would thus be 32 bytes, and the frame offset would be
+ 28 bytes. */
+
+static void
+arm_scan_prologue (fi)
+ struct frame_info * fi;
+{
+ int regno, sp_offset, fp_offset;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+
+ /* Check if this function is already in the cache of frame information. */
+ if (check_prologue_cache (fi))
+ return;
+
+ /* Assume there is no frame until proven otherwise. */
+ fi->framereg = SP_REGNUM;
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+
+ /* Check for Thumb prologue. */
+ if (arm_pc_is_thumb (fi->pc))
+ {
+ thumb_scan_prologue (fi);
+ save_prologue_cache (fi);
+ return;
+ }
+
+ /* Find the function prologue. If we can't find the function in
+ the symbol table, peek in the stack frame to find the PC. */
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ /* Assume the prologue is everything between the first instruction
+ in the function and the first source line. */
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+ {
+ /* Get address of the stmfd in the prologue of the callee; the saved
+ PC is the address of the stmfd + 12. */
+ prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12;
+ prologue_end = prologue_start + 40; /* FIXME: should be big enough */
+ }
+
+ /* Now search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers. */
+
+ sp_offset = fp_offset = 0;
+ for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 4)
+ {
+ unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
+
+ if ((insn & 0xffff0000) == 0xe92d0000) /* stmfd sp!, {..., r7, lr} */
{
- i = min (len, - memaddr);
+ int mask = insn & 0xffff;
+
+ /* Calculate offsets of saved registers. */
+ for (regno = PC_REGNUM; regno >= 0; regno--)
+ if (mask & (1 << regno))
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[regno] = sp_offset;
+ }
}
- else if (memaddr >= stack_end && stack_end != 0)
+ else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */
{
- i = min (len, - memaddr);
+ unsigned imm = insn & 0xff; /* immediate value */
+ unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ imm = (imm >> rot) | (imm << (32-rot));
+ fp_offset = -imm;
+ fi->framereg = FP_REGNUM;
}
- else
+ else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */
{
- /* Address did not classify into one of the known ranges.
- This shouldn't happen; we catch the endpoints. */
- fatal ("Internal: Bad case logic in xfer_core_file.");
+ unsigned imm = insn & 0xff; /* immediate value */
+ unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ imm = (imm >> rot) | (imm << (32-rot));
+ sp_offset -= imm;
}
-
- /* Now we know which file to use.
- Set up its pointer and transfer the data. */
- if (xferfile)
+ else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */
{
- if (*xferfile == 0)
- if (xferfile == &execfile)
- error ("No program file to examine.");
- else
- error ("No core dump file or running program to examine.");
- val = lseek (xferchan, fileptr, 0);
- if (val < 0)
- perror_with_name (*xferfile);
- val = myread (xferchan, myaddr, i);
- if (val < 0)
- perror_with_name (*xferfile);
+ sp_offset -= 12;
+ regno = F0_REGNUM + ((insn >> 12) & 0x07);
+ fi->fsr.regs[regno] = sp_offset;
}
- /* If this address is for nonexistent memory,
- read zeros if reading, or do nothing if writing.
- Actually, we never right. */
+ else if (insn == 0xe1a0c00d) /* mov ip, sp */
+ continue;
else
- {
- memset (myaddr, '\0', i);
- returnval = EIO;
- }
-
- memaddr += i;
- myaddr += i;
- len -= i;
+ break; /* not a recognized prologue instruction */
}
- return returnval;
+
+ /* The frame size is just the negative of the offset (from the original SP)
+ of the last thing thing we pushed on the stack. The frame offset is
+ [new FP] - [new SP]. */
+ fi->framesize = -sp_offset;
+ fi->frameoffset = fp_offset - sp_offset;
+
+ save_prologue_cache (fi);
}
+
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register. One thing
+ we might want to do here is to check REGNUM against the clobber mask, and
+ somehow flag it as invalid if it isn't saved on the stack somewhere. This
+ would provide a graceful failure mode when trying to get the value of
+ caller-saves registers for an inner frame. */
+
+static CORE_ADDR
+arm_find_callers_reg (fi, regnum)
+ struct frame_info * fi;
+ int regnum;
+{
+ for (; fi; fi = fi->next)
+
+#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else
#endif
-
-/* APCS (ARM procedure call standard) defines the following prologue:
+ if (fi->fsr.regs[regnum] != 0)
+ return read_memory_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum));
+ return read_register (regnum);
+}
- mov ip, sp
- [stmfd sp!, {a1,a2,a3,a4}]
- stmfd sp!, {...,fp,ip,lr,pc}
- [stfe f7, [sp, #-12]!]
- [stfe f6, [sp, #-12]!]
- [stfe f5, [sp, #-12]!]
- [stfe f4, [sp, #-12]!]
- sub fp, ip, #nn // nn == 20 or 4 depending on second ins
+
+/* Function: frame_chain
+ Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+ For ARM, we save the frame size when we initialize the frame_info.
+
+ The original definition of this function was a macro in tm-arm.h:
+ { In the case of the ARM, the frame's nominal address is the FP value,
+ and 12 bytes before comes the saved previous FP value as a 4-byte word. }
+
+ #define FRAME_CHAIN(thisframe) \
+ ((thisframe)->pc >= LOWEST_PC ? \
+ read_memory_integer ((thisframe)->frame - 12, 4) :\
+ 0)
*/
CORE_ADDR
-skip_prologue(pc)
-CORE_ADDR pc;
-{
- CORE_ADDR skip_pc = pc;
-#if 0
- union insn_fmt op;
-
- op.ins = read_memory_integer(skip_pc, 4);
- /* look for the "mov ip,sp" */
- if (op.generic.type != TYPE_ARITHMETIC ||
- op.arith.opcode != OPCODE_MOV ||
- op.arith.dest != SPTEMP ||
- op.arith.operand2 != SP) return pc;
- skip_pc += 4;
- /* skip the "stmfd sp!,{a1,a2,a3,a4}" if its there */
- op.ins = read_memory_integer(skip_pc, 4);
- if (op.generic.type == TYPE_BLOCK_BRANCH &&
- op.generic.subtype == SUBTYPE_BLOCK &&
- op.block.mask == 0xf &&
- op.block.base == SP &&
- op.block.is_load == 0 &&
- op.block.writeback == 1 &&
- op.block.increment == 0 &&
- op.block.before == 1) skip_pc += 4;
- /* skip the "stmfd sp!,{...,fp,ip,lr,pc} */
- op.ins = read_memory_integer(skip_pc, 4);
- if (op.generic.type != TYPE_BLOCK_BRANCH ||
- op.generic.subtype != SUBTYPE_BLOCK ||
- /* the mask should look like 110110xxxxxx0000 */
- (op.block.mask & 0xd800) != 0xd800 ||
- op.block.base != SP ||
- op.block.is_load != 0 ||
- op.block.writeback != 1 ||
- op.block.increment != 0 ||
- op.block.before != 1) return pc;
- skip_pc += 4;
- /* check for "sub fp,ip,#nn" */
- op.ins = read_memory_integer(skip_pc, 4);
- if (op.generic.type != TYPE_ARITHMETIC ||
- op.arith.opcode != OPCODE_SUB ||
- op.arith.dest != FP ||
- op.arith.operand1 != SPTEMP) return pc;
+arm_frame_chain (fi)
+ struct frame_info * fi;
+{
+#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
+ CORE_ADDR fn_start, callers_pc, fp;
+
+ /* is this a dummy frame? */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return fi->frame; /* dummy frame same as caller's frame */
+
+ /* is caller-of-this a dummy frame? */
+ callers_pc = FRAME_SAVED_PC(fi); /* find out who called us: */
+ fp = arm_find_callers_reg (fi, FP_REGNUM);
+ if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
+ return fp; /* dummy frame's frame may bear no relation to ours */
+
+ if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0; /* in _start fn, don't chain further */
#endif
- return skip_pc + 4;
+ CORE_ADDR caller_pc, fn_start;
+ struct frame_info caller_fi;
+ int framereg = fi->framereg;
+
+ if (fi->pc < LOWEST_PC)
+ return 0;
+
+ /* If the caller is the startup code, we're at the end of the chain. */
+ caller_pc = FRAME_SAVED_PC (fi);
+ if (find_pc_partial_function (caller_pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0;
+
+ /* If the caller is Thumb and the caller is ARM, or vice versa,
+ the frame register of the caller is different from ours.
+ So we must scan the prologue of the caller to determine its
+ frame register number. */
+ if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (fi->pc))
+ {
+ memset (& caller_fi, 0, sizeof (caller_fi));
+ caller_fi.pc = caller_pc;
+ arm_scan_prologue (& caller_fi);
+ framereg = caller_fi.framereg;
+ }
+
+ /* If the caller used a frame register, return its value.
+ Otherwise, return the caller's stack pointer. */
+ if (framereg == FP_REGNUM || framereg == THUMB_FP_REGNUM)
+ return arm_find_callers_reg (fi, framereg);
+ else
+ return fi->frame + fi->framesize;
}
+/* Function: init_extra_frame_info
+ This function actually figures out the frame address for a given pc and
+ sp. This is tricky because we sometimes don't use an explicit
+ frame pointer, and the previous stack pointer isn't necessarily recorded
+ on the stack. The only reliable way to get this info is to
+ examine the prologue. */
+
void
-arm_frame_find_saved_regs (frame_info, saved_regs_addr)
- struct frame_info *frame_info;
- struct frame_saved_regs *saved_regs_addr;
-{
- register int regnum;
- register int frame;
- register int next_addr;
- register int return_data_save;
- register int saved_register_mask;
-
- memset (saved_regs_addr, '\0', sizeof (*saved_regs_addr));
- frame = frame_info->frame;
- return_data_save = read_memory_integer (frame, 4) & 0x03fffffc - 12;
- saved_register_mask = read_memory_integer (return_data_save, 4);
- next_addr = frame - 12;
- for (regnum = 4; regnum < 10; regnum++)
- if (saved_register_mask & (1 << regnum))
- {
- next_addr -= 4;
- saved_regs_addr->regs[regnum] = next_addr;
- }
- if (read_memory_integer (return_data_save + 4, 4) == 0xed6d7103)
+arm_init_extra_frame_info (fi)
+ struct frame_info * fi;
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+
+#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
{
- next_addr -= 12;
- saved_regs_addr->regs[F0_REGNUM + 7] = next_addr;
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+ return;
}
- if (read_memory_integer (return_data_save + 8, 4) == 0xed6d6103)
+ else
+#endif
{
- next_addr -= 12;
- saved_regs_addr->regs[F0_REGNUM + 6] = next_addr;
+ arm_scan_prologue (fi);
+
+ if (!fi->next) /* this is the innermost frame? */
+ fi->frame = read_register (fi->framereg);
+ else /* not the innermost frame */
+ /* If we have an FP, the callee saved it. */
+ if (fi->framereg == FP_REGNUM || fi->framereg == THUMB_FP_REGNUM)
+ if (fi->next->fsr.regs[fi->framereg] != 0)
+ fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg],
+ 4);
+
+ /* Calculate actual addresses of saved registers using offsets determined
+ by arm_scan_prologue. */
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->fsr.regs[reg] != 0)
+ fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset;
}
- if (read_memory_integer (return_data_save + 12, 4) == 0xed6d5103)
+}
+
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if LR_REGNUM is saved
+ in the stack anywhere, otherwise we get it from the registers.
+
+ The old definition of this function was a macro:
+ #define FRAME_SAVED_PC(FRAME) \
+ ADDR_BITS_REMOVE (read_memory_integer ((FRAME)->frame - 4, 4))
+*/
+
+CORE_ADDR
+arm_frame_saved_pc (fi)
+ struct frame_info * fi;
+{
+#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ else
+#endif
{
- next_addr -= 12;
- saved_regs_addr->regs[F0_REGNUM + 5] = next_addr;
+ CORE_ADDR pc = arm_find_callers_reg (fi, LR_REGNUM);
+ return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
}
- if (read_memory_integer(return_data_save + 16, 4) == 0xed6d4103)
+}
+
+
+/* Return the frame address. On ARM, it is R11; on Thumb it is R7.
+ Examine the Program Status Register to decide which state we're in. */
+
+CORE_ADDR
+arm_target_read_fp ()
+{
+ if (read_register (PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
+ return read_register (THUMB_FP_REGNUM); /* R7 if Thumb */
+ else
+ return read_register (FP_REGNUM); /* R11 if ARM */
+}
+
+
+/* Calculate the frame offsets of the saved registers (ARM version). */
+void
+arm_frame_find_saved_regs (fi, regaddr)
+ struct frame_info *fi;
+ struct frame_saved_regs *regaddr;
+{
+ memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs));
+}
+
+
+void
+arm_push_dummy_frame ()
+{
+ CORE_ADDR old_sp = read_register (SP_REGNUM);
+ CORE_ADDR sp = old_sp;
+ CORE_ADDR fp, prologue_start;
+ int regnum;
+
+ /* Push the two dummy prologue instructions in reverse order,
+ so that they'll be in the correct low-to-high order in memory. */
+ /* sub fp, ip, #4 */
+ sp = push_word (sp, 0xe24cb004);
+ /* stmdb sp!, {r0-r10, fp, ip, lr, pc} */
+ prologue_start = sp = push_word (sp, 0xe92ddfff);
+
+ /* push a pointer to the dummy prologue + 12, because when
+ stm instruction stores the PC, it stores the address of the stm
+ instruction itself plus 12. */
+ fp = sp = push_word (sp, prologue_start + 12);
+ sp = push_word (sp, read_register (PC_REGNUM)); /* FIXME: was PS_REGNUM */
+ sp = push_word (sp, old_sp);
+ sp = push_word (sp, read_register (FP_REGNUM));
+
+ for (regnum = 10; regnum >= 0; regnum --)
+ sp = push_word (sp, read_register (regnum));
+
+ write_register (FP_REGNUM, fp);
+ write_register (THUMB_FP_REGNUM, fp);
+ write_register (SP_REGNUM, sp);
+}
+
+/* Fix up the call dummy, based on whether the processor is currently
+ in Thumb or ARM mode, and whether the target function is Thumb
+ or ARM. There are three different situations requiring three
+ different dummies:
+
+ * ARM calling ARM: uses the call dummy in tm-arm.h, which has already
+ been copied into the dummy parameter to this function.
+ * ARM calling Thumb: uses the call dummy in tm-arm.h, but with the
+ "mov pc,r4" instruction patched to be a "bx r4" instead.
+ * Thumb calling anything: uses the Thumb dummy defined below, which
+ works for calling both ARM and Thumb functions.
+
+ All three call dummies expect to receive the target function address
+ in R4, with the low bit set if it's a Thumb function.
+*/
+
+void
+arm_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
+ char * dummy;
+ CORE_ADDR pc;
+ CORE_ADDR fun;
+ int nargs;
+ value_ptr * args;
+ struct type * type;
+ int gcc_p;
+{
+ static short thumb_dummy[4] =
+ {
+ 0xf000, 0xf801, /* bl label */
+ 0xdf18, /* swi 24 */
+ 0x4720, /* label: bx r4 */
+ };
+ static unsigned long arm_bx_r4 = 0xe12fff14; /* bx r4 instruction */
+
+ /* Set flag indicating whether the current PC is in a Thumb function. */
+ caller_is_thumb = arm_pc_is_thumb (read_pc());
+
+ /* If the target function is Thumb, set the low bit of the function address.
+ And if the CPU is currently in ARM mode, patch the second instruction
+ of call dummy to use a BX instruction to switch to Thumb mode. */
+ target_is_thumb = arm_pc_is_thumb (fun);
+ if (target_is_thumb)
{
- next_addr -= 12;
- saved_regs_addr->regs[F0_REGNUM + 4] = next_addr;
+ fun |= 1;
+ if (!caller_is_thumb)
+ store_unsigned_integer (dummy + 4, sizeof (arm_bx_r4), arm_bx_r4);
+ }
+
+ /* If the CPU is currently in Thumb mode, use the Thumb call dummy
+ instead of the ARM one that's already been copied. This will
+ work for both Thumb and ARM target functions. */
+ if (caller_is_thumb)
+ {
+ int i;
+ char *p = dummy;
+ int len = sizeof (thumb_dummy) / sizeof (thumb_dummy[0]);
+
+ for (i = 0; i < len; i++)
+ {
+ store_unsigned_integer (p, sizeof (thumb_dummy[0]), thumb_dummy[i]);
+ p += sizeof (thumb_dummy[0]);
+ }
}
- saved_regs_addr->regs[SP_REGNUM] = next_addr;
- saved_regs_addr->regs[PC_REGNUM] = frame - 4;
- saved_regs_addr->regs[PS_REGNUM] = frame - 4;
- saved_regs_addr->regs[FP_REGNUM] = frame - 12;
+
+ /* Put the target address in r4; the call dummy will copy this to the PC. */
+ write_register (4, fun);
+}
+
+
+/* Return the offset in the call dummy of the instruction that needs
+ to have a breakpoint placed on it. This is the offset of the 'swi 24'
+ instruction, which is no longer actually used, but simply acts
+ as a place-holder now.
+
+ This implements the CALL_DUMMY_BREAK_OFFSET macro.
+*/
+
+int
+arm_call_dummy_breakpoint_offset ()
+{
+ if (caller_is_thumb)
+ return 4;
+ else
+ return 8;
+}
+
+
+CORE_ADDR
+arm_push_arguments(nargs, args, sp, struct_return, struct_addr)
+ int nargs;
+ value_ptr * args;
+ CORE_ADDR sp;
+ int struct_return;
+ CORE_ADDR struct_addr;
+{
+ int argreg;
+ int float_argreg;
+ int argnum;
+ int stack_offset;
+ struct stack_arg {
+ char *val;
+ int len;
+ int offset;
+ };
+ struct stack_arg *stack_args =
+ (struct stack_arg*)alloca (nargs * sizeof (struct stack_arg));
+ int nstack_args = 0;
+
+
+ /* Initialize the integer and float register pointers. */
+ argreg = A1_REGNUM;
+ float_argreg = F0_REGNUM;
+
+ /* the struct_return pointer occupies the first parameter-passing reg */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* The offset onto the stack at which we will start copying parameters
+ (after the registers are used up) begins at 16 in the old ABI.
+ This leaves room for the "home" area for register parameters. */
+ stack_offset = REGISTER_SIZE * 4;
+
+ /* Process args from left to right. Store as many as allowed in
+ registers, save the rest to be pushed on the stack */
+ for(argnum = 0; argnum < nargs; argnum++)
+ {
+ char * val;
+ value_ptr arg = args[argnum];
+ struct type * arg_type = check_typedef (VALUE_TYPE (arg));
+ struct type * target_type = TYPE_TARGET_TYPE (arg_type);
+ int len = TYPE_LENGTH (arg_type);
+ enum type_code typecode = TYPE_CODE (arg_type);
+ CORE_ADDR regval;
+ int newarg;
+
+ val = (char *) VALUE_CONTENTS (arg);
+
+ /* If the argument is a pointer to a function, and it's a Thumb
+ function, set the low bit of the pointer. */
+ if (typecode == TYPE_CODE_PTR
+ && target_type != NULL
+ && TYPE_CODE (target_type) == TYPE_CODE_FUNC)
+ {
+ regval = extract_address (val, len);
+ if (arm_pc_is_thumb (regval))
+ store_address (val, len, MAKE_THUMB_ADDR (regval));
+ }
+
+#define MAPCS_FLOAT 0 /* --mapcs-float not implemented by the compiler yet */
+#if MAPCS_FLOAT
+ /* Up to four floating point arguments can be passed in floating
+ point registers on ARM (not on Thumb). */
+ if (typecode == TYPE_CODE_FLT
+ && float_argreg <= ARM_LAST_FP_ARG_REGNUM
+ && !target_is_thumb)
+ {
+ /* This is a floating point value that fits entirely
+ in a single register. */
+ regval = extract_address (val, len);
+ write_register (float_argreg++, regval);
+ }
+ else
+#endif
+ {
+ /* Copy the argument to general registers or the stack in
+ register-sized pieces. Large arguments are split between
+ registers and stack. */
+ while (len > 0)
+ {
+ if (argreg <= ARM_LAST_ARG_REGNUM)
+ {
+ int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
+ regval = extract_address (val, partial_len);
+
+ /* It's a simple argument being passed in a general
+ register. */
+ write_register (argreg, regval);
+ argreg++;
+ len -= partial_len;
+ val += partial_len;
+ }
+ else
+ {
+ /* keep for later pushing */
+ stack_args[nstack_args].val = val;
+ stack_args[nstack_args++].len = len;
+ break;
+ }
+ }
+ }
+ }
+ /* now do the real stack pushing, process args right to left */
+ while(nstack_args--)
+ {
+ sp -= stack_args[nstack_args].len;
+ write_memory(sp, stack_args[nstack_args].val,
+ stack_args[nstack_args].len);
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+void
+arm_pop_frame ()
+{
+ struct frame_info *frame = get_current_frame();
+ int regnum;
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_integer (frame->fsr.regs[regnum], 4));
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (SP_REGNUM, read_register (frame->framereg));
+
+ flush_cached_frames ();
}
static void
-print_fpu_flags(flags)
-int flags;
+print_fpu_flags (flags)
+ int flags;
{
- if (flags & (1 << 0)) fputs("IVO ", stdout);
- if (flags & (1 << 1)) fputs("DVZ ", stdout);
- if (flags & (1 << 2)) fputs("OFL ", stdout);
- if (flags & (1 << 3)) fputs("UFL ", stdout);
- if (flags & (1 << 4)) fputs("INX ", stdout);
- putchar('\n');
+ if (flags & (1 << 0)) fputs ("IVO ", stdout);
+ if (flags & (1 << 1)) fputs ("DVZ ", stdout);
+ if (flags & (1 << 2)) fputs ("OFL ", stdout);
+ if (flags & (1 << 3)) fputs ("UFL ", stdout);
+ if (flags & (1 << 4)) fputs ("INX ", stdout);
+ putchar ('\n');
}
void
-arm_float_info()
+arm_float_info ()
{
- register unsigned long status = read_register(FPS_REGNUM);
+ register unsigned long status = read_register (FPS_REGNUM);
int type;
type = (status >> 24) & 127;
- printf("%s FPU type %d\n",
- (status & (1<<31)) ? "Hardware" : "Software",
- type);
- fputs("mask: ", stdout);
- print_fpu_flags(status >> 16);
- fputs("flags: ", stdout);
- print_fpu_flags(status);
+ printf ("%s FPU type %d\n",
+ (status & (1<<31)) ? "Hardware" : "Software",
+ type);
+ fputs ("mask: ", stdout);
+ print_fpu_flags (status >> 16);
+ fputs ("flags: ", stdout);
+ print_fpu_flags (status);
}
+static char *original_register_names[] =
+{ "a1", "a2", "a3", "a4", /* 0 1 2 3 */
+ "v1", "v2", "v3", "v4", /* 4 5 6 7 */
+ "v5", "v6", "sl", "fp", /* 8 9 10 11 */
+ "ip", "sp", "lr", "pc", /* 12 13 14 15 */
+ "f0", "f1", "f2", "f3", /* 16 17 18 19 */
+ "f4", "f5", "f6", "f7", /* 20 21 22 23 */
+ "fps","ps" } /* 24 25 */;
+
+/* These names are the ones which gcc emits, and
+ I find them less confusing. Toggle between them
+ using the `othernames' command. */
+static char *additional_register_names[] =
+{ "r0", "r1", "r2", "r3", /* 0 1 2 3 */
+ "r4", "r5", "r6", "r7", /* 4 5 6 7 */
+ "r8", "r9", "sl", "fp", /* 8 9 10 11 */
+ "ip", "sp", "lr", "pc", /* 12 13 14 15 */
+ "f0", "f1", "f2", "f3", /* 16 17 18 19 */
+ "f4", "f5", "f6", "f7", /* 20 21 22 23 */
+ "fps","ps" } /* 24 25 */;
+
+char **arm_register_names = original_register_names;
-static void arm_othernames()
+
+static void
+arm_othernames ()
{
static int toggle;
- static char *original[] = ORIGINAL_REGISTER_NAMES;
- static char *extra_crispy[] = ADDITIONAL_REGISTER_NAMES;
-
- memcpy (reg_names, toggle ? extra_crispy : original, sizeof(original));
+ arm_register_names = (toggle
+ ? additional_register_names
+ : original_register_names);
toggle = !toggle;
}
-void
-_initialize_arm_tdep ()
-{
- tm_print_insn = print_insn_little_arm;
- add_com ("othernames", class_obscure, arm_othernames);
-}
/* FIXME: Fill in with the 'right thing', see asm
template in arm-convert.s */
void
convert_from_extended (ptr, dbl)
-void *ptr;
-double *dbl;
+ void * ptr;
+ double * dbl;
{
*dbl = *(double*)ptr;
}
-
void
convert_to_extended (dbl, ptr)
-void *ptr;
-double *dbl;
+ void * ptr;
+ double * dbl;
{
*(double*)ptr = *dbl;
}
-
-int
-arm_nullified_insn (inst)
- unsigned long inst;
+static int
+condition_true (cond, status_reg)
+ unsigned long cond;
+ unsigned long status_reg;
{
- unsigned long cond = inst & 0xf0000000;
- unsigned long status_reg;
-
if (cond == INST_AL || cond == INST_NV)
- return 0;
-
- status_reg = read_register (PS_REGNUM);
+ return 1;
switch (cond)
{
case INST_EQ:
- return ((status_reg & FLAG_Z) == 0);
- case INST_NE:
return ((status_reg & FLAG_Z) != 0);
+ case INST_NE:
+ return ((status_reg & FLAG_Z) == 0);
case INST_CS:
- return ((status_reg & FLAG_C) == 0);
- case INST_CC:
return ((status_reg & FLAG_C) != 0);
+ case INST_CC:
+ return ((status_reg & FLAG_C) == 0);
case INST_MI:
- return ((status_reg & FLAG_N) == 0);
- case INST_PL:
return ((status_reg & FLAG_N) != 0);
+ case INST_PL:
+ return ((status_reg & FLAG_N) == 0);
case INST_VS:
- return ((status_reg & FLAG_V) == 0);
- case INST_VC:
return ((status_reg & FLAG_V) != 0);
+ case INST_VC:
+ return ((status_reg & FLAG_V) == 0);
case INST_HI:
- return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
+ return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
case INST_LS:
- return (((status_reg & (FLAG_C | FLAG_Z)) ^ FLAG_C) == 0);
+ return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
case INST_GE:
- return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
- case INST_LT:
return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
+ case INST_LT:
+ return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
case INST_GT:
- return (((status_reg & FLAG_Z) != 0) ||
- (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)));
- case INST_LE:
return (((status_reg & FLAG_Z) == 0) &&
(((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)));
+ case INST_LE:
+ return (((status_reg & FLAG_Z) != 0) ||
+ (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)));
}
- return 0;
+ return 1;
}
-
-
-/* taken from remote-arm.c .. */
-
#define submask(x) ((1L << ((x) + 1)) - 1)
-#define bit(obj,st) (((obj) & (1L << (st))) >> st)
-#define bits(obj,st,fn) \
- (((obj) & submask (fn) & ~ submask ((st) - 1)) >> (st))
+#define bit(obj,st) (((obj) >> (st)) & 1)
+#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
#define sbits(obj,st,fn) \
((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
#define BranchDest(addr,instr) \
@@ -560,10 +1121,11 @@ arm_nullified_insn (inst)
#define ARM_PC_32 1
static unsigned long
-shifted_reg_val (inst, carry, pc_val)
+shifted_reg_val (inst, carry, pc_val, status_reg)
unsigned long inst;
int carry;
unsigned long pc_val;
+ unsigned long status_reg;
{
unsigned long res, shift;
int rm = bits (inst, 0, 3);
@@ -578,7 +1140,7 @@ shifted_reg_val (inst, carry, pc_val)
shift = bits (inst, 7, 11);
res = (rm == 15
- ? ((pc_val | (ARM_PC_32 ? 0 : read_register (PS_REGNUM)))
+ ? ((pc_val | (ARM_PC_32 ? 0 : status_reg))
+ (bit (inst, 4) ? 12 : 8))
: read_register (rm));
@@ -611,18 +1173,83 @@ shifted_reg_val (inst, carry, pc_val)
}
+/* Return number of 1-bits in VAL. */
+
+static int
+bitcount (val)
+ unsigned long val;
+{
+ int nbits;
+ for (nbits = 0; val != 0; nbits++)
+ val &= val - 1; /* delete rightmost 1-bit in val */
+ return nbits;
+}
+
+
+static CORE_ADDR
+thumb_get_next_pc (pc)
+ CORE_ADDR pc;
+{
+ unsigned long pc_val = ((unsigned long)pc) + 4; /* PC after prefetch */
+ unsigned short inst1 = read_memory_integer (pc, 2);
+ CORE_ADDR nextpc = pc + 2; /* default is next instruction */
+ unsigned long offset;
+
+ if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
+ {
+ CORE_ADDR sp;
+
+ /* Fetch the saved PC from the stack. It's stored above
+ all of the other registers. */
+ offset = bitcount (bits (inst1, 0, 7)) * REGISTER_SIZE;
+ sp = read_register (SP_REGNUM);
+ nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4);
+ nextpc = ADDR_BITS_REMOVE (nextpc);
+ if (nextpc == pc)
+ error ("Infinite loop detected");
+ }
+ else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
+ {
+ unsigned long status = read_register (PS_REGNUM);
+ unsigned long cond = bits (inst1, 8, 11);
+ if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */
+ nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
+ }
+ else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */
+ {
+ nextpc = pc_val + (sbits (inst1, 0, 10) << 1);
+ }
+ else if ((inst1 & 0xf800) == 0xf000) /* long branch with link */
+ {
+ unsigned short inst2 = read_memory_integer (pc + 2, 2);
+ offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
+ nextpc = pc_val + offset;
+ }
+
+ return nextpc;
+}
+
+
CORE_ADDR
arm_get_next_pc (pc)
CORE_ADDR pc;
{
- unsigned long pc_val = (unsigned long) pc;
- unsigned long this_instr = read_memory_integer (pc, 4);
- unsigned long status = read_register (PS_REGNUM);
- CORE_ADDR nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
+ unsigned long pc_val;
+ unsigned long this_instr;
+ unsigned long status;
+ CORE_ADDR nextpc;
+
+ if (arm_pc_is_thumb (pc))
+ return thumb_get_next_pc (pc);
+
+ pc_val = (unsigned long) pc;
+ this_instr = read_memory_integer (pc, 4);
+ status = read_register (PS_REGNUM);
+ nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
- if (! arm_nullified_insn (this_instr))
+ if (condition_true (bits (this_instr, 28, 31), status))
{
- switch (bits(this_instr, 24, 27))
+ switch (bits (this_instr, 24, 27))
{
case 0x0: case 0x1: /* data processing */
case 0x2: case 0x3:
@@ -631,7 +1258,7 @@ arm_get_next_pc (pc)
unsigned long rn;
int c;
- if (bits(this_instr, 12, 15) != 15)
+ if (bits (this_instr, 12, 15) != 15)
break;
if (bits (this_instr, 22, 25) == 0
@@ -647,11 +1274,11 @@ arm_get_next_pc (pc)
{
unsigned long immval = bits (this_instr, 0, 7);
unsigned long rotate = 2 * bits (this_instr, 8, 11);
- operand2 = ((immval >> rotate) | (immval << (32-rotate))
- & 0xffffffff);
+ operand2 = ((immval >> rotate) | (immval << (32-rotate)))
+ & 0xffffffff;
}
else /* operand 2 is a shifted register */
- operand2 = shifted_reg_val (this_instr, c, pc_val);
+ operand2 = shifted_reg_val (this_instr, c, pc_val, status);
switch (bits (this_instr, 21, 24))
{
@@ -770,14 +1397,7 @@ arm_get_next_pc (pc)
{
/* up */
unsigned long reglist = bits (this_instr, 0, 14);
- unsigned long regbit;
-
- for (; reglist != 0; reglist &= ~regbit)
- {
- regbit = reglist & (-reglist);
- offset += 4;
- }
-
+ offset = bitcount (reglist) * 4;
if (bit (this_instr, 24)) /* pre */
offset += 4;
}
@@ -824,3 +1444,183 @@ arm_get_next_pc (pc)
return nextpc;
}
+#include "bfd-in2.h"
+#include "libcoff.h"
+
+static int
+gdb_print_insn_arm (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info * info;
+{
+ if (arm_pc_is_thumb (memaddr))
+ {
+ static asymbol * asym;
+ static combined_entry_type ce;
+ static struct coff_symbol_struct csym;
+ static struct _bfd fake_bfd;
+ static bfd_target fake_target;
+
+ if (csym.native == NULL)
+ {
+ /* Create a fake symbol vector containing a Thumb symbol. This is
+ solely so that the code in print_insn_little_arm() and
+ print_insn_big_arm() in opcodes/arm-dis.c will detect the presence
+ of a Thumb symbol and switch to decoding Thumb instructions. */
+
+ fake_target.flavour = bfd_target_coff_flavour;
+ fake_bfd.xvec = & fake_target;
+ ce.u.syment.n_sclass = C_THUMBEXTFUNC;
+ csym.native = & ce;
+ csym.symbol.the_bfd = & fake_bfd;
+ csym.symbol.name = "fake";
+ asym = (asymbol *) & csym;
+ }
+
+ memaddr = UNMAKE_THUMB_ADDR (memaddr);
+ info->symbols = & asym;
+ }
+ else
+ info->symbols = NULL;
+
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ return print_insn_big_arm (memaddr, info);
+ else
+ return print_insn_little_arm (memaddr, info);
+}
+
+/* Sequence of bytes for breakpoint instruction. */
+#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} /* Recognized illegal opcodes */
+#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
+#define THUMB_LE_BREAKPOINT {0xfe,0xdf}
+#define THUMB_BE_BREAKPOINT {0xdf,0xfe}
+
+/* The following has been superseded by BREAKPOINT_FOR_PC, but
+ is defined merely to keep mem-break.c happy. */
+#define LITTLE_BREAKPOINT ARM_LE_BREAKPOINT
+#define BIG_BREAKPOINT ARM_BE_BREAKPOINT
+
+/* This function implements the BREAKPOINT_FROM_PC macro. It uses the program
+ counter value to determine whether a 16- or 32-bit breakpoint should be
+ used. It returns a pointer to a string of bytes that encode a breakpoint
+ instruction, stores the length of the string to *lenptr, and adjusts pc
+ (if necessary) to point to the actual memory location where the
+ breakpoint should be inserted. */
+
+unsigned char *
+arm_breakpoint_from_pc (pcptr, lenptr)
+ CORE_ADDR * pcptr;
+ int * lenptr;
+{
+ if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr))
+ {
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ {
+ static char thumb_breakpoint[] = THUMB_BE_BREAKPOINT;
+ *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
+ *lenptr = sizeof (thumb_breakpoint);
+ return thumb_breakpoint;
+ }
+ else
+ {
+ static char thumb_breakpoint[] = THUMB_LE_BREAKPOINT;
+ *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
+ *lenptr = sizeof (thumb_breakpoint);
+ return thumb_breakpoint;
+ }
+ }
+ else
+ {
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ {
+ static char arm_breakpoint[] = ARM_BE_BREAKPOINT;
+ *lenptr = sizeof (arm_breakpoint);
+ return arm_breakpoint;
+ }
+ else
+ {
+ static char arm_breakpoint[] = ARM_LE_BREAKPOINT;
+ *lenptr = sizeof (arm_breakpoint);
+ return arm_breakpoint;
+ }
+ }
+}
+/* Return non-zero if the PC is inside a call thunk (aka stub or trampoline).
+ This implements the IN_SOLIB_CALL_TRAMPOLINE macro. */
+
+int
+arm_in_call_stub (pc, name)
+ CORE_ADDR pc;
+ char * name;
+{
+ CORE_ADDR start_addr;
+
+ /* Find the starting address of the function containing the PC. If the
+ caller didn't give us a name, look it up at the same time. */
+ if (find_pc_partial_function (pc, name ? NULL : &name, &start_addr, NULL) == 0)
+ return 0;
+
+ return strncmp (name, "_call_via_r", 11) == 0;
+}
+
+
+/* If PC is in a Thumb call or return stub, return the address of the target
+ PC, which is in a register. The thunk functions are called _called_via_xx,
+ where x is the register name. The possible names are r0-r9, sl, fp, ip,
+ sp, and lr. */
+
+CORE_ADDR
+arm_skip_stub (pc)
+ CORE_ADDR pc;
+{
+ char * name;
+ CORE_ADDR start_addr;
+
+ /* Find the starting address and name of the function containing the PC. */
+ if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
+ return 0;
+
+ /* Call thunks always start with "_call_via_". */
+ if (strncmp (name, "_call_via_", 10) == 0)
+ {
+ /* Use the name suffix to determine which register contains
+ the target PC. */
+ static char *table[15] =
+ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "sl", "fp", "ip", "sp", "lr"
+ };
+ int regno;
+
+ for (regno = 0; regno <= 14; regno++)
+ if (strcmp (&name[10], table[regno]) == 0)
+ return read_register (regno);
+ }
+ return 0; /* not a stub */
+}
+
+
+void
+_initialize_arm_tdep ()
+{
+ tm_print_insn = gdb_print_insn_arm;
+
+ add_com ("othernames", class_obscure, arm_othernames,
+ "Switch to the other set of register names.");
+
+ /* ??? Maybe this should be a boolean. */
+ add_show_from_set (add_set_cmd ("apcs32", no_class,
+ var_zinteger, (char *)&arm_apcs_32,
+ "Set usage of ARM 32-bit mode.\n", &setlist),
+ & showlist);
+
+}
+
+/* Test whether the coff symbol specific value corresponds to a Thumb function */
+int
+coff_sym_is_thumb(int val)
+{
+ return (val == C_THUMBEXT ||
+ val == C_THUMBSTAT ||
+ val == C_THUMBEXTFUNC ||
+ val == C_THUMBSTATFUNC ||
+ val == C_THUMBLABEL);
+}
diff --git a/contrib/gdb/gdb/arm-xdep.c b/contrib/gdb/gdb/arm-xdep.c
index b855ac8..f0d806e 100644
--- a/contrib/gdb/gdb/arm-xdep.c
+++ b/contrib/gdb/gdb/arm-xdep.c
@@ -246,10 +246,10 @@ core_file_command (filename, from_tty)
if (val < 0
|| (val = myread (corechan, buf, sizeof buf)) < 0)
{
- char * buffer = (char *) alloca (strlen (reg_names[regno])
+ char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno))
+ 30);
strcpy (buffer, "Reading register ");
- strcat (buffer, reg_names[regno]);
+ strcat (buffer, REGISTER_NAME (regno));
perror_with_name (buffer);
}
@@ -274,3 +274,286 @@ core_file_command (filename, from_tty)
else if (from_tty)
printf ("No core file now.\n");
}
+
+#if 0
+/* Work with core dump and executable files, for GDB.
+ This code would be in corefile.c if it weren't machine-dependent. */
+
+/* Structure to describe the chain of shared libraries used
+ by the execfile.
+ e.g. prog shares Xt which shares X11 which shares c. */
+
+struct shared_library {
+ struct exec_header header;
+ char name[SHLIBLEN];
+ CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file */
+ long data_offset; /* offset of data section in file */
+ int chan; /* file descriptor for the file */
+ struct shared_library *shares; /* library this one shares */
+};
+static struct shared_library *shlib = 0;
+
+/* Hook for `exec_file_command' command to call. */
+
+extern void (*exec_file_display_hook) ();
+
+static CORE_ADDR unshared_text_start;
+
+/* extended header from exec file (for shared library info) */
+
+static struct exec_header exec_header;
+
+void
+exec_file_command (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ int val;
+
+ /* Eliminate all traces of old exec file.
+ Mark text segment as empty. */
+
+ if (execfile)
+ free (execfile);
+ execfile = 0;
+ data_start = 0;
+ data_end -= exec_data_start;
+ text_start = 0;
+ unshared_text_start = 0;
+ text_end = 0;
+ exec_data_start = 0;
+ exec_data_end = 0;
+ if (execchan >= 0)
+ close (execchan);
+ execchan = -1;
+ if (shlib) {
+ close_shared_library(shlib);
+ shlib = 0;
+ }
+
+ /* Now open and digest the file the user requested, if any. */
+
+ if (filename)
+ {
+ filename = tilde_expand (filename);
+ make_cleanup (free, filename);
+
+ execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+ &execfile);
+ if (execchan < 0)
+ perror_with_name (filename);
+
+ {
+ struct stat st_exec;
+
+#ifdef HEADER_SEEK_FD
+ HEADER_SEEK_FD (execchan);
+#endif
+
+ val = myread (execchan, &exec_header, sizeof exec_header);
+ exec_aouthdr = exec_header.a_exec;
+
+ if (val < 0)
+ perror_with_name (filename);
+
+ text_start = 0x8000;
+
+ /* Look for shared library if needed */
+ if (exec_header.a_exec.a_magic & MF_USES_SL)
+ shlib = open_shared_library(exec_header.a_shlibname, text_start);
+
+ text_offset = N_TXTOFF (exec_aouthdr);
+ exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
+
+ if (shlib) {
+ unshared_text_start = shared_text_end(shlib) & ~0x7fff;
+ stack_start = shlib->header.a_exec.a_sldatabase;
+ stack_end = STACK_END_ADDR;
+ } else
+ unshared_text_start = 0x8000;
+ text_end = unshared_text_start + exec_aouthdr.a_text;
+
+ exec_data_start = unshared_text_start + exec_aouthdr.a_text;
+ exec_data_end = exec_data_start + exec_aouthdr.a_data;
+
+ data_start = exec_data_start;
+ data_end += exec_data_start;
+
+ fstat (execchan, &st_exec);
+ exec_mtime = st_exec.st_mtime;
+ }
+
+ validate_files ();
+ }
+ else if (from_tty)
+ printf ("No executable file now.\n");
+
+ /* Tell display code (if any) about the changed file name. */
+ if (exec_file_display_hook)
+ (*exec_file_display_hook) (filename);
+}
+#endif
+
+#if 0
+/* Read from the program's memory (except for inferior processes).
+ This function is misnamed, since it only reads, never writes; and
+ since it will use the core file and/or executable file as necessary.
+
+ It should be extended to write as well as read, FIXME, for patching files.
+
+ Return 0 if address could be read, EIO if addresss out of bounds. */
+
+int
+xfer_core_file (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ register int i;
+ register int val;
+ int xferchan;
+ char **xferfile;
+ int fileptr;
+ int returnval = 0;
+
+ while (len > 0)
+ {
+ xferfile = 0;
+ xferchan = 0;
+
+ /* Determine which file the next bunch of addresses reside in,
+ and where in the file. Set the file's read/write pointer
+ to point at the proper place for the desired address
+ and set xferfile and xferchan for the correct file.
+
+ If desired address is nonexistent, leave them zero.
+
+ i is set to the number of bytes that can be handled
+ along with the next address.
+
+ We put the most likely tests first for efficiency. */
+
+ /* Note that if there is no core file
+ data_start and data_end are equal. */
+ if (memaddr >= data_start && memaddr < data_end)
+ {
+ i = min (len, data_end - memaddr);
+ fileptr = memaddr - data_start + data_offset;
+ xferfile = &corefile;
+ xferchan = corechan;
+ }
+ /* Note that if there is no core file
+ stack_start and stack_end define the shared library data. */
+ else if (memaddr >= stack_start && memaddr < stack_end)
+ {
+ if (corechan < 0) {
+ struct shared_library *lib;
+ for (lib = shlib; lib; lib = lib->shares)
+ if (memaddr >= lib->header.a_exec.a_sldatabase &&
+ memaddr < lib->header.a_exec.a_sldatabase +
+ lib->header.a_exec.a_data)
+ break;
+ if (lib) {
+ i = min (len, lib->header.a_exec.a_sldatabase +
+ lib->header.a_exec.a_data - memaddr);
+ fileptr = lib->data_offset + memaddr -
+ lib->header.a_exec.a_sldatabase;
+ xferfile = execfile;
+ xferchan = lib->chan;
+ }
+ } else {
+ i = min (len, stack_end - memaddr);
+ fileptr = memaddr - stack_start + stack_offset;
+ xferfile = &corefile;
+ xferchan = corechan;
+ }
+ }
+ else if (corechan < 0
+ && memaddr >= exec_data_start && memaddr < exec_data_end)
+ {
+ i = min (len, exec_data_end - memaddr);
+ fileptr = memaddr - exec_data_start + exec_data_offset;
+ xferfile = &execfile;
+ xferchan = execchan;
+ }
+ else if (memaddr >= text_start && memaddr < text_end)
+ {
+ struct shared_library *lib;
+ for (lib = shlib; lib; lib = lib->shares)
+ if (memaddr >= lib->text_start &&
+ memaddr < lib->text_start + lib->header.a_exec.a_text)
+ break;
+ if (lib) {
+ i = min (len, lib->header.a_exec.a_text +
+ lib->text_start - memaddr);
+ fileptr = memaddr - lib->text_start + text_offset;
+ xferfile = &execfile;
+ xferchan = lib->chan;
+ } else {
+ i = min (len, text_end - memaddr);
+ fileptr = memaddr - unshared_text_start + text_offset;
+ xferfile = &execfile;
+ xferchan = execchan;
+ }
+ }
+ else if (memaddr < text_start)
+ {
+ i = min (len, text_start - memaddr);
+ }
+ else if (memaddr >= text_end
+ && memaddr < (corechan >= 0? data_start : exec_data_start))
+ {
+ i = min (len, data_start - memaddr);
+ }
+ else if (corechan >= 0
+ && memaddr >= data_end && memaddr < stack_start)
+ {
+ i = min (len, stack_start - memaddr);
+ }
+ else if (corechan < 0 && memaddr >= exec_data_end)
+ {
+ i = min (len, - memaddr);
+ }
+ else if (memaddr >= stack_end && stack_end != 0)
+ {
+ i = min (len, - memaddr);
+ }
+ else
+ {
+ /* Address did not classify into one of the known ranges.
+ This shouldn't happen; we catch the endpoints. */
+ fatal ("Internal: Bad case logic in xfer_core_file.");
+ }
+
+ /* Now we know which file to use.
+ Set up its pointer and transfer the data. */
+ if (xferfile)
+ {
+ if (*xferfile == 0)
+ if (xferfile == &execfile)
+ error ("No program file to examine.");
+ else
+ error ("No core dump file or running program to examine.");
+ val = lseek (xferchan, fileptr, 0);
+ if (val < 0)
+ perror_with_name (*xferfile);
+ val = myread (xferchan, myaddr, i);
+ if (val < 0)
+ perror_with_name (*xferfile);
+ }
+ /* If this address is for nonexistent memory,
+ read zeros if reading, or do nothing if writing.
+ Actually, we never right. */
+ else
+ {
+ memset (myaddr, '\0', i);
+ returnval = EIO;
+ }
+
+ memaddr += i;
+ myaddr += i;
+ len -= i;
+ }
+ return returnval;
+}
+#endif
diff --git a/contrib/gdb/gdb/ax-gdb.c b/contrib/gdb/gdb/ax-gdb.c
new file mode 100644
index 0000000..55cc856
--- /dev/null
+++ b/contrib/gdb/gdb/ax-gdb.c
@@ -0,0 +1,1942 @@
+/* GDB-specific functions for operating on agent expressions
+ Copyright 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* $Id: ax-gdb.c,v 1.8 1998/12/03 05:34:24 cagney Exp $ */
+
+#include "defs.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "expression.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "frame.h"
+#include "target.h"
+#include "ax.h"
+#include "ax-gdb.h"
+
+/* Probably the best way to read this file is to start with the types
+ and enums in ax-gdb.h, and then look at gen_expr, towards the
+ bottom; that's the main function that looks at the GDB expressions
+ and calls everything else to generate code.
+
+ I'm beginning to wonder whether it wouldn't be nicer to internally
+ generate trees, with types, and then spit out the bytecode in
+ linear form afterwards; we could generate fewer `swap', `ext', and
+ `zero_ext' bytecodes that way; it would make good constant folding
+ easier, too. But at the moment, I think we should be willing to
+ pay for the simplicity of this code with less-than-optimal bytecode
+ strings.
+
+ Remember, "GBD" stands for "Great Britain, Dammit!" So be careful. */
+
+
+
+/* Prototypes for local functions. */
+
+/* There's a standard order to the arguments of these functions:
+ union exp_element ** --- pointer into expression
+ struct agent_expr * --- agent expression buffer to generate code into
+ struct axs_value * --- describes value left on top of stack */
+
+static struct value *const_var_ref PARAMS ((struct symbol *var));
+static struct value *const_expr PARAMS ((union exp_element **pc));
+static struct value *maybe_const_expr PARAMS ((union exp_element **pc));
+
+static void gen_traced_pop PARAMS ((struct agent_expr *, struct axs_value *));
+
+static void gen_sign_extend PARAMS ((struct agent_expr *, struct type *));
+static void gen_extend PARAMS ((struct agent_expr *, struct type *));
+static void gen_fetch PARAMS ((struct agent_expr *, struct type *));
+static void gen_left_shift PARAMS ((struct agent_expr *, int));
+
+
+static void gen_frame_args_address PARAMS ((struct agent_expr *));
+static void gen_frame_locals_address PARAMS ((struct agent_expr *));
+static void gen_offset PARAMS ((struct agent_expr *ax, int offset));
+static void gen_sym_offset PARAMS ((struct agent_expr *, struct symbol *));
+static void gen_var_ref PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ struct symbol *var));
+
+
+static void gen_int_literal PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ LONGEST k, struct type *type));
+
+
+static void require_rvalue PARAMS ((struct agent_expr *ax,
+ struct axs_value *value));
+static void gen_usual_unary PARAMS ((struct agent_expr *ax,
+ struct axs_value *value));
+static int type_wider_than PARAMS ((struct type *type1,
+ struct type *type2));
+static struct type *max_type PARAMS ((struct type *type1,
+ struct type *type2));
+static void gen_conversion PARAMS ((struct agent_expr *ax,
+ struct type *from,
+ struct type *to));
+static int is_nontrivial_conversion PARAMS ((struct type *from,
+ struct type *to));
+static void gen_usual_arithmetic PARAMS ((struct agent_expr *ax,
+ struct axs_value *value1,
+ struct axs_value *value2));
+static void gen_integral_promotions PARAMS ((struct agent_expr *ax,
+ struct axs_value *value));
+static void gen_cast PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ struct type *type));
+static void gen_scale PARAMS ((struct agent_expr *ax,
+ enum agent_op op,
+ struct type *type));
+static void gen_add PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ struct axs_value *value1,
+ struct axs_value *value2,
+ char *name));
+static void gen_sub PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ struct axs_value *value1,
+ struct axs_value *value2));
+static void gen_binop PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ struct axs_value *value1,
+ struct axs_value *value2,
+ enum agent_op op,
+ enum agent_op op_unsigned,
+ int may_carry,
+ char *name));
+static void gen_logical_not PARAMS ((struct agent_expr *ax,
+ struct axs_value *value));
+static void gen_complement PARAMS ((struct agent_expr *ax,
+ struct axs_value *value));
+static void gen_deref PARAMS ((struct agent_expr *, struct axs_value *));
+static void gen_address_of PARAMS ((struct agent_expr *, struct axs_value *));
+static int find_field PARAMS ((struct type *type, char *name));
+static void gen_bitfield_ref PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ struct type *type,
+ int start, int end));
+static void gen_struct_ref PARAMS ((struct agent_expr *ax,
+ struct axs_value *value,
+ char *field,
+ char *operator_name,
+ char *operand_name));
+static void gen_repeat PARAMS ((union exp_element **pc,
+ struct agent_expr *ax,
+ struct axs_value *value));
+static void gen_sizeof PARAMS ((union exp_element **pc,
+ struct agent_expr *ax,
+ struct axs_value *value));
+static void gen_expr PARAMS ((union exp_element **pc,
+ struct agent_expr *ax,
+ struct axs_value *value));
+
+static void print_axs_value PARAMS ((GDB_FILE *f, struct axs_value *value));
+static void agent_command PARAMS ((char *exp, int from_tty));
+
+
+/* Detecting constant expressions. */
+
+/* If the variable reference at *PC is a constant, return its value.
+ Otherwise, return zero.
+
+ Hey, Wally! How can a variable reference be a constant?
+
+ Well, Beav, this function really handles the OP_VAR_VALUE operator,
+ not specifically variable references. GDB uses OP_VAR_VALUE to
+ refer to any kind of symbolic reference: function names, enum
+ elements, and goto labels are all handled through the OP_VAR_VALUE
+ operator, even though they're constants. It makes sense given the
+ situation.
+
+ Gee, Wally, don'cha wonder sometimes if data representations that
+ subvert commonly accepted definitions of terms in favor of heavily
+ context-specific interpretations are really just a tool of the
+ programming hegemony to preserve their power and exclude the
+ proletariat? */
+
+static struct value *
+const_var_ref (var)
+ struct symbol *var;
+{
+ struct type *type = SYMBOL_TYPE (var);
+
+ switch (SYMBOL_CLASS (var))
+ {
+ case LOC_CONST:
+ return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var));
+
+ case LOC_LABEL:
+ return value_from_longest (type, (LONGEST) SYMBOL_VALUE_ADDRESS (var));
+
+ default:
+ return 0;
+ }
+}
+
+
+/* If the expression starting at *PC has a constant value, return it.
+ Otherwise, return zero. If we return a value, then *PC will be
+ advanced to the end of it. If we return zero, *PC could be
+ anywhere. */
+static struct value *
+const_expr (pc)
+ union exp_element **pc;
+{
+ enum exp_opcode op = (*pc)->opcode;
+ struct value *v1;
+
+ switch (op)
+ {
+ case OP_LONG:
+ {
+ struct type *type = (*pc)[1].type;
+ LONGEST k = (*pc)[2].longconst;
+ (*pc) += 4;
+ return value_from_longest (type, k);
+ }
+
+ case OP_VAR_VALUE:
+ {
+ struct value *v = const_var_ref ((*pc)[2].symbol);
+ (*pc) += 4;
+ return v;
+ }
+
+ /* We could add more operators in here. */
+
+ case UNOP_NEG:
+ (*pc)++;
+ v1 = const_expr (pc);
+ if (v1)
+ return value_neg (v1);
+ else
+ return 0;
+
+ default:
+ return 0;
+ }
+}
+
+
+/* Like const_expr, but guarantee also that *PC is undisturbed if the
+ expression is not constant. */
+static struct value *
+maybe_const_expr (pc)
+ union exp_element **pc;
+{
+ union exp_element *tentative_pc = *pc;
+ struct value *v = const_expr (&tentative_pc);
+
+ /* If we got a value, then update the real PC. */
+ if (v)
+ *pc = tentative_pc;
+
+ return v;
+}
+
+
+/* Generating bytecode from GDB expressions: general assumptions */
+
+/* Here are a few general assumptions made throughout the code; if you
+ want to make a change that contradicts one of these, then you'd
+ better scan things pretty thoroughly.
+
+ - We assume that all values occupy one stack element. For example,
+ sometimes we'll swap to get at the left argument to a binary
+ operator. If we decide that void values should occupy no stack
+ elements, or that synthetic arrays (whose size is determined at
+ run time, created by the `@' operator) should occupy two stack
+ elements (address and length), then this will cause trouble.
+
+ - We assume the stack elements are infinitely wide, and that we
+ don't have to worry what happens if the user requests an
+ operation that is wider than the actual interpreter's stack.
+ That is, it's up to the interpreter to handle directly all the
+ integer widths the user has access to. (Woe betide the language
+ with bignums!)
+
+ - We don't support side effects. Thus, we don't have to worry about
+ GCC's generalized lvalues, function calls, etc.
+
+ - We don't support floating point. Many places where we switch on
+ some type don't bother to include cases for floating point; there
+ may be even more subtle ways this assumption exists. For
+ example, the arguments to % must be integers.
+
+ - We assume all subexpressions have a static, unchanging type. If
+ we tried to support convenience variables, this would be a
+ problem.
+
+ - All values on the stack should always be fully zero- or
+ sign-extended.
+
+ (I wasn't sure whether to choose this or its opposite --- that
+ only addresses are assumed extended --- but it turns out that
+ neither convention completely eliminates spurious extend
+ operations (if everything is always extended, then you have to
+ extend after add, because it could overflow; if nothing is
+ extended, then you end up producing extends whenever you change
+ sizes), and this is simpler.) */
+
+
+/* Generating bytecode from GDB expressions: the `trace' kludge */
+
+/* The compiler in this file is a general-purpose mechanism for
+ translating GDB expressions into bytecode. One ought to be able to
+ find a million and one uses for it.
+
+ However, at the moment it is HOPELESSLY BRAIN-DAMAGED for the sake
+ of expediency. Let he who is without sin cast the first stone.
+
+ For the data tracing facility, we need to insert `trace' bytecodes
+ before each data fetch; this records all the memory that the
+ expression touches in the course of evaluation, so that memory will
+ be available when the user later tries to evaluate the expression
+ in GDB.
+
+ This should be done (I think) in a post-processing pass, that walks
+ an arbitrary agent expression and inserts `trace' operations at the
+ appropriate points. But it's much faster to just hack them
+ directly into the code. And since we're in a crunch, that's what
+ I've done.
+
+ Setting the flag trace_kludge to non-zero enables the code that
+ emits the trace bytecodes at the appropriate points. */
+static int trace_kludge;
+
+/* Trace the lvalue on the stack, if it needs it. In either case, pop
+ the value. Useful on the left side of a comma, and at the end of
+ an expression being used for tracing. */
+static void
+gen_traced_pop (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ if (trace_kludge)
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ /* We don't trace rvalues, just the lvalues necessary to
+ produce them. So just dispose of this value. */
+ ax_simple (ax, aop_pop);
+ break;
+
+ case axs_lvalue_memory:
+ {
+ int length = TYPE_LENGTH (value->type);
+
+ /* There's no point in trying to use a trace_quick bytecode
+ here, since "trace_quick SIZE pop" is three bytes, whereas
+ "const8 SIZE trace" is also three bytes, does the same
+ thing, and the simplest code which generates that will also
+ work correctly for objects with large sizes. */
+ ax_const_l (ax, length);
+ ax_simple (ax, aop_trace);
+ }
+ break;
+
+ case axs_lvalue_register:
+ /* We need to mention the register somewhere in the bytecode,
+ so ax_reqs will pick it up and add it to the mask of
+ registers used. */
+ ax_reg (ax, value->u.reg);
+ ax_simple (ax, aop_pop);
+ break;
+ }
+ else
+ /* If we're not tracing, just pop the value. */
+ ax_simple (ax, aop_pop);
+}
+
+
+
+/* Generating bytecode from GDB expressions: helper functions */
+
+/* Assume that the lower bits of the top of the stack is a value of
+ type TYPE, and the upper bits are zero. Sign-extend if necessary. */
+static void
+gen_sign_extend (ax, type)
+ struct agent_expr *ax;
+ struct type *type;
+{
+ /* Do we need to sign-extend this? */
+ if (! TYPE_UNSIGNED (type))
+ ax_ext (ax, type->length * TARGET_CHAR_BIT);
+}
+
+
+/* Assume the lower bits of the top of the stack hold a value of type
+ TYPE, and the upper bits are garbage. Sign-extend or truncate as
+ needed. */
+static void
+gen_extend (ax, type)
+ struct agent_expr *ax;
+ struct type *type;
+{
+ int bits = type->length * TARGET_CHAR_BIT;
+ /* I just had to. */
+ ((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, bits));
+}
+
+
+/* Assume that the top of the stack contains a value of type "pointer
+ to TYPE"; generate code to fetch its value. Note that TYPE is the
+ target type, not the pointer type. */
+static void
+gen_fetch (ax, type)
+ struct agent_expr *ax;
+ struct type *type;
+{
+ if (trace_kludge)
+ {
+ /* Record the area of memory we're about to fetch. */
+ ax_trace_quick (ax, TYPE_LENGTH (type));
+ }
+
+ switch (type->code)
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ /* It's a scalar value, so we know how to dereference it. How
+ many bytes long is it? */
+ switch (type->length)
+ {
+ case 8 / TARGET_CHAR_BIT: ax_simple (ax, aop_ref8 ); break;
+ case 16 / TARGET_CHAR_BIT: ax_simple (ax, aop_ref16); break;
+ case 32 / TARGET_CHAR_BIT: ax_simple (ax, aop_ref32); break;
+ case 64 / TARGET_CHAR_BIT: ax_simple (ax, aop_ref64); break;
+
+ /* Either our caller shouldn't have asked us to dereference
+ that pointer (other code's fault), or we're not
+ implementing something we should be (this code's fault).
+ In any case, it's a bug the user shouldn't see. */
+ default:
+ error ("GDB bug: ax-gdb.c (gen_fetch): strange size");
+ }
+
+ gen_sign_extend (ax, type);
+ break;
+
+ default:
+ /* Either our caller shouldn't have asked us to dereference that
+ pointer (other code's fault), or we're not implementing
+ something we should be (this code's fault). In any case,
+ it's a bug the user shouldn't see. */
+ error ("GDB bug: ax-gdb.c (gen_fetch): bad type code");
+ }
+}
+
+
+/* Generate code to left shift the top of the stack by DISTANCE bits, or
+ right shift it by -DISTANCE bits if DISTANCE < 0. This generates
+ unsigned (logical) right shifts. */
+static void
+gen_left_shift (ax, distance)
+ struct agent_expr *ax;
+ int distance;
+{
+ if (distance > 0)
+ {
+ ax_const_l (ax, distance);
+ ax_simple (ax, aop_lsh);
+ }
+ else if (distance < 0)
+ {
+ ax_const_l (ax, -distance);
+ ax_simple (ax, aop_rsh_unsigned);
+ }
+}
+
+
+
+/* Generating bytecode from GDB expressions: symbol references */
+
+/* Generate code to push the base address of the argument portion of
+ the top stack frame. */
+static void
+gen_frame_args_address (ax)
+ struct agent_expr *ax;
+{
+ long frame_reg, frame_offset;
+
+ TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+ ax_reg (ax, frame_reg);
+ gen_offset (ax, frame_offset);
+}
+
+
+/* Generate code to push the base address of the locals portion of the
+ top stack frame. */
+static void
+gen_frame_locals_address (ax)
+ struct agent_expr *ax;
+{
+ long frame_reg, frame_offset;
+
+ TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+ ax_reg (ax, frame_reg);
+ gen_offset (ax, frame_offset);
+}
+
+
+/* Generate code to add OFFSET to the top of the stack. Try to
+ generate short and readable code. We use this for getting to
+ variables on the stack, and structure members. If we were
+ programming in ML, it would be clearer why these are the same
+ thing. */
+static void
+gen_offset (ax, offset)
+ struct agent_expr *ax;
+ int offset;
+{
+ /* It would suffice to simply push the offset and add it, but this
+ makes it easier to read positive and negative offsets in the
+ bytecode. */
+ if (offset > 0)
+ {
+ ax_const_l (ax, offset);
+ ax_simple (ax, aop_add);
+ }
+ else if (offset < 0)
+ {
+ ax_const_l (ax, -offset);
+ ax_simple (ax, aop_sub);
+ }
+}
+
+
+/* In many cases, a symbol's value is the offset from some other
+ address (stack frame, base register, etc.) Generate code to add
+ VAR's value to the top of the stack. */
+static void
+gen_sym_offset (ax, var)
+ struct agent_expr *ax;
+ struct symbol *var;
+{
+ gen_offset (ax, SYMBOL_VALUE (var));
+}
+
+
+/* Generate code for a variable reference to AX. The variable is the
+ symbol VAR. Set VALUE to describe the result. */
+
+static void
+gen_var_ref (ax, value, var)
+ struct agent_expr *ax;
+ struct axs_value *value;
+ struct symbol *var;
+{
+ /* Dereference any typedefs. */
+ value->type = check_typedef (SYMBOL_TYPE (var));
+
+ /* I'm imitating the code in read_var_value. */
+ switch (SYMBOL_CLASS (var))
+ {
+ case LOC_CONST: /* A constant, like an enum value. */
+ ax_const_l (ax, (LONGEST) SYMBOL_VALUE (var));
+ value->kind = axs_rvalue;
+ break;
+
+ case LOC_LABEL: /* A goto label, being used as a value. */
+ ax_const_l (ax, (LONGEST) SYMBOL_VALUE_ADDRESS (var));
+ value->kind = axs_rvalue;
+ break;
+
+ case LOC_CONST_BYTES:
+ error ("GDB bug: ax-gdb.c (gen_var_ref): LOC_CONST_BYTES symbols are not supported");
+
+ /* Variable at a fixed location in memory. Easy. */
+ case LOC_STATIC:
+ /* Push the address of the variable. */
+ ax_const_l (ax, SYMBOL_VALUE_ADDRESS (var));
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_ARG: /* var lives in argument area of frame */
+ gen_frame_args_address (ax);
+ gen_sym_offset (ax, var);
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_REF_ARG: /* As above, but the frame slot really
+ holds the address of the variable. */
+ gen_frame_args_address (ax);
+ gen_sym_offset (ax, var);
+ /* Don't assume any particular pointer size. */
+ gen_fetch (ax, lookup_pointer_type (builtin_type_void));
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_LOCAL: /* var lives in locals area of frame */
+ case LOC_LOCAL_ARG:
+ gen_frame_locals_address (ax);
+ gen_sym_offset (ax, var);
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_BASEREG: /* relative to some base register */
+ case LOC_BASEREG_ARG:
+ ax_reg (ax, SYMBOL_BASEREG (var));
+ gen_sym_offset (ax, var);
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_TYPEDEF:
+ error ("Cannot compute value of typedef `%s'.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+
+ case LOC_BLOCK:
+ ax_const_l (ax, BLOCK_START (SYMBOL_BLOCK_VALUE (var)));
+ value->kind = axs_rvalue;
+ break;
+
+ case LOC_REGISTER:
+ case LOC_REGPARM:
+ /* Don't generate any code at all; in the process of treating
+ this as an lvalue or rvalue, the caller will generate the
+ right code. */
+ value->kind = axs_lvalue_register;
+ value->u.reg = SYMBOL_VALUE (var);
+ break;
+
+ /* A lot like LOC_REF_ARG, but the pointer lives directly in a
+ register, not on the stack. Simpler than LOC_REGISTER and
+ LOC_REGPARM, because it's just like any other case where the
+ thing has a real address. */
+ case LOC_REGPARM_ADDR:
+ ax_reg (ax, SYMBOL_VALUE (var));
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_UNRESOLVED:
+ {
+ struct minimal_symbol *msym
+ = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+ if (! msym)
+ error ("Couldn't resolve symbol `%s'.", SYMBOL_SOURCE_NAME (var));
+
+ /* Push the address of the variable. */
+ ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym));
+ value->kind = axs_lvalue_memory;
+ }
+ break;
+
+ case LOC_OPTIMIZED_OUT:
+ error ("The variable `%s' has been optimized out.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+
+ default:
+ error ("Cannot find value of botched symbol `%s'.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+ }
+}
+
+
+
+/* Generating bytecode from GDB expressions: literals */
+
+static void
+gen_int_literal (ax, value, k, type)
+ struct agent_expr *ax;
+ struct axs_value *value;
+ LONGEST k;
+ struct type *type;
+{
+ ax_const_l (ax, k);
+ value->kind = axs_rvalue;
+ value->type = type;
+}
+
+
+
+/* Generating bytecode from GDB expressions: unary conversions, casts */
+
+/* Take what's on the top of the stack (as described by VALUE), and
+ try to make an rvalue out of it. Signal an error if we can't do
+ that. */
+static void
+require_rvalue (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ /* It's already an rvalue. */
+ break;
+
+ case axs_lvalue_memory:
+ /* The top of stack is the address of the object. Dereference. */
+ gen_fetch (ax, value->type);
+ break;
+
+ case axs_lvalue_register:
+ /* There's nothing on the stack, but value->u.reg is the
+ register number containing the value.
+
+ When we add floating-point support, this is going to have to
+ change. What about SPARC register pairs, for example? */
+ ax_reg (ax, value->u.reg);
+ gen_extend (ax, value->type);
+ break;
+ }
+
+ value->kind = axs_rvalue;
+}
+
+
+/* Assume the top of the stack is described by VALUE, and perform the
+ usual unary conversions. This is motivated by ANSI 6.2.2, but of
+ course GDB expressions are not ANSI; they're the mishmash union of
+ a bunch of languages. Rah.
+
+ NOTE! This function promises to produce an rvalue only when the
+ incoming value is of an appropriate type. In other words, the
+ consumer of the value this function produces may assume the value
+ is an rvalue only after checking its type.
+
+ The immediate issue is that if the user tries to use a structure or
+ union as an operand of, say, the `+' operator, we don't want to try
+ to convert that structure to an rvalue; require_rvalue will bomb on
+ structs and unions. Rather, we want to simply pass the struct
+ lvalue through unchanged, and let `+' raise an error. */
+
+static void
+gen_usual_unary (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ /* We don't have to generate any code for the usual integral
+ conversions, since values are always represented as full-width on
+ the stack. Should we tweak the type? */
+
+ /* Some types require special handling. */
+ switch (value->type->code)
+ {
+ /* Functions get converted to a pointer to the function. */
+ case TYPE_CODE_FUNC:
+ value->type = lookup_pointer_type (value->type);
+ value->kind = axs_rvalue; /* Should always be true, but just in case. */
+ break;
+
+ /* Arrays get converted to a pointer to their first element, and
+ are no longer an lvalue. */
+ case TYPE_CODE_ARRAY:
+ {
+ struct type *elements = TYPE_TARGET_TYPE (value->type);
+ value->type = lookup_pointer_type (elements);
+ value->kind = axs_rvalue;
+ /* We don't need to generate any code; the address of the array
+ is also the address of its first element. */
+ }
+ break;
+
+ /* Don't try to convert structures and unions to rvalues. Let the
+ consumer signal an error. */
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ return;
+
+ /* If the value is an enum, call it an integer. */
+ case TYPE_CODE_ENUM:
+ value->type = builtin_type_int;
+ break;
+ }
+
+ /* If the value is an lvalue, dereference it. */
+ require_rvalue (ax, value);
+}
+
+
+/* Return non-zero iff the type TYPE1 is considered "wider" than the
+ type TYPE2, according to the rules described in gen_usual_arithmetic. */
+static int
+type_wider_than (type1, type2)
+ struct type *type1, *type2;
+{
+ return (TYPE_LENGTH (type1) > TYPE_LENGTH (type2)
+ || (TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
+ && TYPE_UNSIGNED (type1)
+ && ! TYPE_UNSIGNED (type2)));
+}
+
+
+/* Return the "wider" of the two types TYPE1 and TYPE2. */
+static struct type *
+max_type (type1, type2)
+ struct type *type1, *type2;
+{
+ return type_wider_than (type1, type2) ? type1 : type2;
+}
+
+
+/* Generate code to convert a scalar value of type FROM to type TO. */
+static void
+gen_conversion (ax, from, to)
+ struct agent_expr *ax;
+ struct type *from, *to;
+{
+ /* Perhaps there is a more graceful way to state these rules. */
+
+ /* If we're converting to a narrower type, then we need to clear out
+ the upper bits. */
+ if (TYPE_LENGTH (to) < TYPE_LENGTH (from))
+ gen_extend (ax, from);
+
+ /* If the two values have equal width, but different signednesses,
+ then we need to extend. */
+ else if (TYPE_LENGTH (to) == TYPE_LENGTH (from))
+ {
+ if (TYPE_UNSIGNED (from) != TYPE_UNSIGNED (to))
+ gen_extend (ax, to);
+ }
+
+ /* If we're converting to a wider type, and becoming unsigned, then
+ we need to zero out any possible sign bits. */
+ else if (TYPE_LENGTH (to) > TYPE_LENGTH (from))
+ {
+ if (TYPE_UNSIGNED (to))
+ gen_extend (ax, to);
+ }
+}
+
+
+/* Return non-zero iff the type FROM will require any bytecodes to be
+ emitted to be converted to the type TO. */
+static int
+is_nontrivial_conversion (from, to)
+ struct type *from, *to;
+{
+ struct agent_expr *ax = new_agent_expr (0);
+ int nontrivial;
+
+ /* Actually generate the code, and see if anything came out. At the
+ moment, it would be trivial to replicate the code in
+ gen_conversion here, but in the future, when we're supporting
+ floating point and the like, it may not be. Doing things this
+ way allows this function to be independent of the logic in
+ gen_conversion. */
+ gen_conversion (ax, from, to);
+ nontrivial = ax->len > 0;
+ free_agent_expr (ax);
+ return nontrivial;
+}
+
+
+/* Generate code to perform the "usual arithmetic conversions" (ANSI C
+ 6.2.1.5) for the two operands of an arithmetic operator. This
+ effectively finds a "least upper bound" type for the two arguments,
+ and promotes each argument to that type. *VALUE1 and *VALUE2
+ describe the values as they are passed in, and as they are left. */
+static void
+gen_usual_arithmetic (ax, value1, value2)
+ struct agent_expr *ax;
+ struct axs_value *value1, *value2;
+{
+ /* Do the usual binary conversions. */
+ if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ {
+ /* The ANSI integral promotions seem to work this way: Order the
+ integer types by size, and then by signedness: an n-bit
+ unsigned type is considered "wider" than an n-bit signed
+ type. Promote to the "wider" of the two types, and always
+ promote at least to int. */
+ struct type *target = max_type (builtin_type_int,
+ max_type (value1->type, value2->type));
+
+ /* Deal with value2, on the top of the stack. */
+ gen_conversion (ax, value2->type, target);
+
+ /* Deal with value1, not on the top of the stack. Don't
+ generate the `swap' instructions if we're not actually going
+ to do anything. */
+ if (is_nontrivial_conversion (value1->type, target))
+ {
+ ax_simple (ax, aop_swap);
+ gen_conversion (ax, value1->type, target);
+ ax_simple (ax, aop_swap);
+ }
+
+ value1->type = value2->type = target;
+ }
+}
+
+
+/* Generate code to perform the integral promotions (ANSI 6.2.1.1) on
+ the value on the top of the stack, as described by VALUE. Assume
+ the value has integral type. */
+static void
+gen_integral_promotions (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ if (! type_wider_than (value->type, builtin_type_int))
+ {
+ gen_conversion (ax, value->type, builtin_type_int);
+ value->type = builtin_type_int;
+ }
+ else if (! type_wider_than (value->type, builtin_type_unsigned_int))
+ {
+ gen_conversion (ax, value->type, builtin_type_unsigned_int);
+ value->type = builtin_type_unsigned_int;
+ }
+}
+
+
+/* Generate code for a cast to TYPE. */
+static void
+gen_cast (ax, value, type)
+ struct agent_expr *ax;
+ struct axs_value *value;
+ struct type *type;
+{
+ /* GCC does allow casts to yield lvalues, so this should be fixed
+ before merging these changes into the trunk. */
+ require_rvalue (ax, value);
+ /* Dereference typedefs. */
+ type = check_typedef (type);
+
+ switch (type->code)
+ {
+ case TYPE_CODE_PTR:
+ /* It's implementation-defined, and I'll bet this is what GCC
+ does. */
+ break;
+
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FUNC:
+ error ("Illegal type cast: intended type must be scalar.");
+
+ case TYPE_CODE_ENUM:
+ /* We don't have to worry about the size of the value, because
+ all our integral values are fully sign-extended, and when
+ casting pointers we can do anything we like. Is there any
+ way for us to actually know what GCC actually does with a
+ cast like this? */
+ value->type = type;
+ break;
+
+ case TYPE_CODE_INT:
+ gen_conversion (ax, value->type, type);
+ break;
+
+ case TYPE_CODE_VOID:
+ /* We could pop the value, and rely on everyone else to check
+ the type and notice that this value doesn't occupy a stack
+ slot. But for now, leave the value on the stack, and
+ preserve the "value == stack element" assumption. */
+ break;
+
+ default:
+ error ("Casts to requested type are not yet implemented.");
+ }
+
+ value->type = type;
+}
+
+
+
+/* Generating bytecode from GDB expressions: arithmetic */
+
+/* Scale the integer on the top of the stack by the size of the target
+ of the pointer type TYPE. */
+static void
+gen_scale (ax, op, type)
+ struct agent_expr *ax;
+ enum agent_op op;
+ struct type *type;
+{
+ struct type *element = TYPE_TARGET_TYPE (type);
+
+ if (element->length != 1)
+ {
+ ax_const_l (ax, element->length);
+ ax_simple (ax, op);
+ }
+}
+
+
+/* Generate code for an addition; non-trivial because we deal with
+ pointer arithmetic. We set VALUE to describe the result value; we
+ assume VALUE1 and VALUE2 describe the two operands, and that
+ they've undergone the usual binary conversions. Used by both
+ BINOP_ADD and BINOP_SUBSCRIPT. NAME is used in error messages. */
+static void
+gen_add (ax, value, value1, value2, name)
+ struct agent_expr *ax;
+ struct axs_value *value, *value1, *value2;
+ char *name;
+{
+ /* Is it INT+PTR? */
+ if (value1->type->code == TYPE_CODE_INT
+ && value2->type->code == TYPE_CODE_PTR)
+ {
+ /* Swap the values and proceed normally. */
+ ax_simple (ax, aop_swap);
+ gen_scale (ax, aop_mul, value2->type);
+ ax_simple (ax, aop_add);
+ gen_extend (ax, value2->type); /* Catch overflow. */
+ value->type = value2->type;
+ }
+
+ /* Is it PTR+INT? */
+ else if (value1->type->code == TYPE_CODE_PTR
+ && value2->type->code == TYPE_CODE_INT)
+ {
+ gen_scale (ax, aop_mul, value1->type);
+ ax_simple (ax, aop_add);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ /* Must be number + number; the usual binary conversions will have
+ brought them both to the same width. */
+ else if (value1->type->code == TYPE_CODE_INT
+ && value2->type->code == TYPE_CODE_INT)
+ {
+ ax_simple (ax, aop_add);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ else
+ error ("Illegal combination of types in %s.", name);
+
+ value->kind = axs_rvalue;
+}
+
+
+/* Generate code for an addition; non-trivial because we have to deal
+ with pointer arithmetic. We set VALUE to describe the result
+ value; we assume VALUE1 and VALUE2 describe the two operands, and
+ that they've undergone the usual binary conversions. */
+static void
+gen_sub (ax, value, value1, value2)
+ struct agent_expr *ax;
+ struct axs_value *value, *value1, *value2;
+{
+ struct type *element;
+
+ if (value1->type->code == TYPE_CODE_PTR)
+ {
+ /* Is it PTR - INT? */
+ if (value2->type->code == TYPE_CODE_INT)
+ {
+ gen_scale (ax, aop_mul, value1->type);
+ ax_simple (ax, aop_sub);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ /* Is it PTR - PTR? Strictly speaking, the types ought to
+ match, but this is what the normal GDB expression evaluator
+ tests for. */
+ else if (value2->type->code == TYPE_CODE_PTR
+ && (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type))
+ == TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type))))
+ {
+ ax_simple (ax, aop_sub);
+ gen_scale (ax, aop_div_unsigned, value1->type);
+ value->type = builtin_type_long; /* FIXME --- should be ptrdiff_t */
+ }
+ else
+ error ("\
+First argument of `-' is a pointer, but second argument is neither\n\
+an integer nor a pointer of the same type.");
+ }
+
+ /* Must be number + number. */
+ else if (value1->type->code == TYPE_CODE_INT
+ && value2->type->code == TYPE_CODE_INT)
+ {
+ ax_simple (ax, aop_sub);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ else
+ error ("Illegal combination of types in subtraction.");
+
+ value->kind = axs_rvalue;
+}
+
+/* Generate code for a binary operator that doesn't do pointer magic.
+ We set VALUE to describe the result value; we assume VALUE1 and
+ VALUE2 describe the two operands, and that they've undergone the
+ usual binary conversions. MAY_CARRY should be non-zero iff the
+ result needs to be extended. NAME is the English name of the
+ operator, used in error messages */
+static void
+gen_binop (ax, value, value1, value2, op, op_unsigned, may_carry, name)
+ struct agent_expr *ax;
+ struct axs_value *value, *value1, *value2;
+ enum agent_op op, op_unsigned;
+ int may_carry;
+ char *name;
+{
+ /* We only handle INT op INT. */
+ if ((value1->type->code != TYPE_CODE_INT)
+ || (value2->type->code != TYPE_CODE_INT))
+ error ("Illegal combination of types in %s.", name);
+
+ ax_simple (ax,
+ TYPE_UNSIGNED (value1->type) ? op_unsigned : op);
+ if (may_carry)
+ gen_extend (ax, value1->type); /* catch overflow */
+ value->type = value1->type;
+ value->kind = axs_rvalue;
+}
+
+
+static void
+gen_logical_not (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ if (TYPE_CODE (value->type) != TYPE_CODE_INT
+ && TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ error ("Illegal type of operand to `!'.");
+
+ gen_usual_unary (ax, value);
+ ax_simple (ax, aop_log_not);
+ value->type = builtin_type_int;
+}
+
+
+static void
+gen_complement (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ if (TYPE_CODE (value->type) != TYPE_CODE_INT)
+ error ("Illegal type of operand to `~'.");
+
+ gen_usual_unary (ax, value);
+ gen_integral_promotions (ax, value);
+ ax_simple (ax, aop_bit_not);
+ gen_extend (ax, value->type);
+}
+
+
+
+/* Generating bytecode from GDB expressions: * & . -> @ sizeof */
+
+/* Dereference the value on the top of the stack. */
+static void
+gen_deref (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ /* The caller should check the type, because several operators use
+ this, and we don't know what error message to generate. */
+ if (value->type->code != TYPE_CODE_PTR)
+ error ("GDB bug: ax-gdb.c (gen_deref): expected a pointer");
+
+ /* We've got an rvalue now, which is a pointer. We want to yield an
+ lvalue, whose address is exactly that pointer. So we don't
+ actually emit any code; we just change the type from "Pointer to
+ T" to "T", and mark the value as an lvalue in memory. Leave it
+ to the consumer to actually dereference it. */
+ value->type = check_typedef (TYPE_TARGET_TYPE (value->type));
+ value->kind = ((value->type->code == TYPE_CODE_FUNC)
+ ? axs_rvalue : axs_lvalue_memory);
+}
+
+
+/* Produce the address of the lvalue on the top of the stack. */
+static void
+gen_address_of (ax, value)
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ /* Special case for taking the address of a function. The ANSI
+ standard describes this as a special case, too, so this
+ arrangement is not without motivation. */
+ if (value->type->code == TYPE_CODE_FUNC)
+ /* The value's already an rvalue on the stack, so we just need to
+ change the type. */
+ value->type = lookup_pointer_type (value->type);
+ else
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ error ("Operand of `&' is an rvalue, which has no address.");
+
+ case axs_lvalue_register:
+ error ("Operand of `&' is in a register, and has no address.");
+
+ case axs_lvalue_memory:
+ value->kind = axs_rvalue;
+ value->type = lookup_pointer_type (value->type);
+ break;
+ }
+}
+
+
+/* A lot of this stuff will have to change to support C++. But we're
+ not going to deal with that at the moment. */
+
+/* Find the field in the structure type TYPE named NAME, and return
+ its index in TYPE's field array. */
+static int
+find_field (type, name)
+ struct type *type;
+ char *name;
+{
+ int i;
+
+ CHECK_TYPEDEF (type);
+
+ /* Make sure this isn't C++. */
+ if (TYPE_N_BASECLASSES (type) != 0)
+ error ("GDB bug: ax-gdb.c (find_field): derived classes supported");
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ char *this_name = TYPE_FIELD_NAME (type, i);
+
+ if (this_name && STREQ (name, this_name))
+ return i;
+
+ if (this_name[0] == '\0')
+ error ("GDB bug: ax-gdb.c (find_field): anonymous unions not supported");
+ }
+
+ error ("Couldn't find member named `%s' in struct/union `%s'",
+ name, type->tag_name);
+
+ return 0;
+}
+
+
+/* Generate code to push the value of a bitfield of a structure whose
+ address is on the top of the stack. START and END give the
+ starting and one-past-ending *bit* numbers of the field within the
+ structure. */
+static void
+gen_bitfield_ref (ax, value, type, start, end)
+ struct agent_expr *ax;
+ struct axs_value *value;
+ struct type *type;
+ int start, end;
+{
+ /* Note that ops[i] fetches 8 << i bits. */
+ static enum agent_op ops[]
+ = { aop_ref8, aop_ref16, aop_ref32, aop_ref64 };
+ static int num_ops = (sizeof (ops) / sizeof (ops[0]));
+
+ /* We don't want to touch any byte that the bitfield doesn't
+ actually occupy; we shouldn't make any accesses we're not
+ explicitly permitted to. We rely here on the fact that the
+ bytecode `ref' operators work on unaligned addresses.
+
+ It takes some fancy footwork to get the stack to work the way
+ we'd like. Say we're retrieving a bitfield that requires three
+ fetches. Initially, the stack just contains the address:
+ addr
+ For the first fetch, we duplicate the address
+ addr addr
+ then add the byte offset, do the fetch, and shift and mask as
+ needed, yielding a fragment of the value, properly aligned for
+ the final bitwise or:
+ addr frag1
+ then we swap, and repeat the process:
+ frag1 addr --- address on top
+ frag1 addr addr --- duplicate it
+ frag1 addr frag2 --- get second fragment
+ frag1 frag2 addr --- swap again
+ frag1 frag2 frag3 --- get third fragment
+ Notice that, since the third fragment is the last one, we don't
+ bother duplicating the address this time. Now we have all the
+ fragments on the stack, and we can simply `or' them together,
+ yielding the final value of the bitfield. */
+
+ /* The first and one-after-last bits in the field, but rounded down
+ and up to byte boundaries. */
+ int bound_start = (start / TARGET_CHAR_BIT) * TARGET_CHAR_BIT;
+ int bound_end = (((end + TARGET_CHAR_BIT - 1)
+ / TARGET_CHAR_BIT)
+ * TARGET_CHAR_BIT);
+
+ /* current bit offset within the structure */
+ int offset;
+
+ /* The index in ops of the opcode we're considering. */
+ int op;
+
+ /* The number of fragments we generated in the process. Probably
+ equal to the number of `one' bits in bytesize, but who cares? */
+ int fragment_count;
+
+ /* Dereference any typedefs. */
+ type = check_typedef (type);
+
+ /* Can we fetch the number of bits requested at all? */
+ if ((end - start) > ((1 << num_ops) * 8))
+ error ("GDB bug: ax-gdb.c (gen_bitfield_ref): bitfield too wide");
+
+ /* Note that we know here that we only need to try each opcode once.
+ That may not be true on machines with weird byte sizes. */
+ offset = bound_start;
+ fragment_count = 0;
+ for (op = num_ops - 1; op >= 0; op--)
+ {
+ /* number of bits that ops[op] would fetch */
+ int op_size = 8 << op;
+
+ /* The stack at this point, from bottom to top, contains zero or
+ more fragments, then the address. */
+
+ /* Does this fetch fit within the bitfield? */
+ if (offset + op_size <= bound_end)
+ {
+ /* Is this the last fragment? */
+ int last_frag = (offset + op_size == bound_end);
+
+ if (! last_frag)
+ ax_simple (ax, aop_dup); /* keep a copy of the address */
+
+ /* Add the offset. */
+ gen_offset (ax, offset / TARGET_CHAR_BIT);
+
+ if (trace_kludge)
+ {
+ /* Record the area of memory we're about to fetch. */
+ ax_trace_quick (ax, op_size / TARGET_CHAR_BIT);
+ }
+
+ /* Perform the fetch. */
+ ax_simple (ax, ops[op]);
+
+ /* Shift the bits we have to their proper position.
+ gen_left_shift will generate right shifts when the operand
+ is negative.
+
+ A big-endian field diagram to ponder:
+ byte 0 byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 byte 7
+ +------++------++------++------++------++------++------++------+
+ xxxxAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCxxxxxxxxxxx
+ ^ ^ ^ ^
+ bit number 16 32 48 53
+ These are bit numbers as supplied by GDB. Note that the
+ bit numbers run from right to left once you've fetched the
+ value!
+
+ A little-endian field diagram to ponder:
+ byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
+ +------++------++------++------++------++------++------++------+
+ xxxxxxxxxxxAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCxxxx
+ ^ ^ ^ ^ ^
+ bit number 48 32 16 4 0
+
+ In both cases, the most significant end is on the left
+ (i.e. normal numeric writing order), which means that you
+ don't go crazy thinking about `left' and `right' shifts.
+
+ We don't have to worry about masking yet:
+ - If they contain garbage off the least significant end, then we
+ must be looking at the low end of the field, and the right
+ shift will wipe them out.
+ - If they contain garbage off the most significant end, then we
+ must be looking at the most significant end of the word, and
+ the sign/zero extension will wipe them out.
+ - If we're in the interior of the word, then there is no garbage
+ on either end, because the ref operators zero-extend. */
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ gen_left_shift (ax, end - (offset + op_size));
+ else
+ gen_left_shift (ax, offset - start);
+
+ if (! last_frag)
+ /* Bring the copy of the address up to the top. */
+ ax_simple (ax, aop_swap);
+
+ offset += op_size;
+ fragment_count++;
+ }
+ }
+
+ /* Generate enough bitwise `or' operations to combine all the
+ fragments we left on the stack. */
+ while (fragment_count-- > 1)
+ ax_simple (ax, aop_bit_or);
+
+ /* Sign- or zero-extend the value as appropriate. */
+ ((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, end - start));
+
+ /* This is *not* an lvalue. Ugh. */
+ value->kind = axs_rvalue;
+ value->type = type;
+}
+
+
+/* Generate code to reference the member named FIELD of a structure or
+ union. The top of the stack, as described by VALUE, should have
+ type (pointer to a)* struct/union. OPERATOR_NAME is the name of
+ the operator being compiled, and OPERAND_NAME is the kind of thing
+ it operates on; we use them in error messages. */
+static void
+gen_struct_ref (ax, value, field, operator_name, operand_name)
+ struct agent_expr *ax;
+ struct axs_value *value;
+ char *field;
+ char *operator_name;
+ char *operand_name;
+{
+ struct type *type;
+ int i;
+
+ /* Follow pointers until we reach a non-pointer. These aren't the C
+ semantics, but they're what the normal GDB evaluator does, so we
+ should at least be consistent. */
+ while (value->type->code == TYPE_CODE_PTR)
+ {
+ gen_usual_unary (ax, value);
+ gen_deref (ax, value);
+ }
+ type = value->type;
+
+ /* This must yield a structure or a union. */
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ error ("The left operand of `%s' is not a %s.",
+ operator_name, operand_name);
+
+ /* And it must be in memory; we don't deal with structure rvalues,
+ or structures living in registers. */
+ if (value->kind != axs_lvalue_memory)
+ error ("Structure does not live in memory.");
+
+ i = find_field (type, field);
+
+ /* Is this a bitfield? */
+ if (TYPE_FIELD_PACKED (type, i))
+ gen_bitfield_ref (ax, value, TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_BITPOS (type, i),
+ (TYPE_FIELD_BITPOS (type, i)
+ + TYPE_FIELD_BITSIZE (type, i)));
+ else
+ {
+ gen_offset (ax, TYPE_FIELD_BITPOS (type, i) / TARGET_CHAR_BIT);
+ value->kind = axs_lvalue_memory;
+ value->type = TYPE_FIELD_TYPE (type, i);
+ }
+}
+
+
+/* Generate code for GDB's magical `repeat' operator.
+ LVALUE @ INT creates an array INT elements long, and whose elements
+ have the same type as LVALUE, located in memory so that LVALUE is
+ its first element. For example, argv[0]@argc gives you the array
+ of command-line arguments.
+
+ Unfortunately, because we have to know the types before we actually
+ have a value for the expression, we can't implement this perfectly
+ without changing the type system, having values that occupy two
+ stack slots, doing weird things with sizeof, etc. So we require
+ the right operand to be a constant expression. */
+static void
+gen_repeat (pc, ax, value)
+ union exp_element **pc;
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ struct axs_value value1;
+ /* We don't want to turn this into an rvalue, so no conversions
+ here. */
+ gen_expr (pc, ax, &value1);
+ if (value1.kind != axs_lvalue_memory)
+ error ("Left operand of `@' must be an object in memory.");
+
+ /* Evaluate the length; it had better be a constant. */
+ {
+ struct value *v = const_expr (pc);
+ int length;
+
+ if (! v)
+ error ("Right operand of `@' must be a constant, in agent expressions.");
+ if (v->type->code != TYPE_CODE_INT)
+ error ("Right operand of `@' must be an integer.");
+ length = value_as_long (v);
+ if (length <= 0)
+ error ("Right operand of `@' must be positive.");
+
+ /* The top of the stack is already the address of the object, so
+ all we need to do is frob the type of the lvalue. */
+ {
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ struct type *range
+ = create_range_type (0, builtin_type_int, 0, length - 1);
+ struct type *array = create_array_type (0, value1.type, range);
+
+ value->kind = axs_lvalue_memory;
+ value->type = array;
+ }
+ }
+}
+
+
+/* Emit code for the `sizeof' operator.
+ *PC should point at the start of the operand expression; we advance it
+ to the first instruction after the operand. */
+static void
+gen_sizeof (pc, ax, value)
+ union exp_element **pc;
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ /* We don't care about the value of the operand expression; we only
+ care about its type. However, in the current arrangement, the
+ only way to find an expression's type is to generate code for it.
+ So we generate code for the operand, and then throw it away,
+ replacing it with code that simply pushes its size. */
+ int start = ax->len;
+ gen_expr (pc, ax, value);
+
+ /* Throw away the code we just generated. */
+ ax->len = start;
+
+ ax_const_l (ax, TYPE_LENGTH (value->type));
+ value->kind = axs_rvalue;
+ value->type = builtin_type_int;
+}
+
+
+/* Generating bytecode from GDB expressions: general recursive thingy */
+
+/* A gen_expr function written by a Gen-X'er guy.
+ Append code for the subexpression of EXPR starting at *POS_P to AX. */
+static void
+gen_expr (pc, ax, value)
+ union exp_element **pc;
+ struct agent_expr *ax;
+ struct axs_value *value;
+{
+ /* Used to hold the descriptions of operand expressions. */
+ struct axs_value value1, value2;
+ enum exp_opcode op = (*pc)[0].opcode;
+
+ /* If we're looking at a constant expression, just push its value. */
+ {
+ struct value *v = maybe_const_expr (pc);
+
+ if (v)
+ {
+ ax_const_l (ax, value_as_long (v));
+ value->kind = axs_rvalue;
+ value->type = check_typedef (VALUE_TYPE (v));
+ return;
+ }
+ }
+
+ /* Otherwise, go ahead and generate code for it. */
+ switch (op)
+ {
+ /* Binary arithmetic operators. */
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_SUBSCRIPT:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ (*pc)++;
+ gen_expr (pc, ax, &value1);
+ gen_usual_unary (ax, &value1);
+ gen_expr (pc, ax, &value2);
+ gen_usual_unary (ax, &value2);
+ gen_usual_arithmetic (ax, &value1, &value2);
+ switch (op)
+ {
+ case BINOP_ADD:
+ gen_add (ax, value, &value1, &value2, "addition");
+ break;
+ case BINOP_SUB:
+ gen_sub (ax, value, &value1, &value2);
+ break;
+ case BINOP_MUL:
+ gen_binop (ax, value, &value1, &value2,
+ aop_mul, aop_mul, 1, "multiplication");
+ break;
+ case BINOP_DIV:
+ gen_binop (ax, value, &value1, &value2,
+ aop_div_signed, aop_div_unsigned, 1, "division");
+ break;
+ case BINOP_REM:
+ gen_binop (ax, value, &value1, &value2,
+ aop_rem_signed, aop_rem_unsigned, 1, "remainder");
+ break;
+ case BINOP_SUBSCRIPT:
+ gen_add (ax, value, &value1, &value2, "array subscripting");
+ if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ error ("Illegal combination of types in array subscripting.");
+ gen_deref (ax, value);
+ break;
+ case BINOP_BITWISE_AND:
+ gen_binop (ax, value, &value1, &value2,
+ aop_bit_and, aop_bit_and, 0, "bitwise and");
+ break;
+
+ case BINOP_BITWISE_IOR:
+ gen_binop (ax, value, &value1, &value2,
+ aop_bit_or, aop_bit_or, 0, "bitwise or");
+ break;
+
+ case BINOP_BITWISE_XOR:
+ gen_binop (ax, value, &value1, &value2,
+ aop_bit_xor, aop_bit_xor, 0, "bitwise exclusive-or");
+ break;
+
+ default:
+ /* We should only list operators in the outer case statement
+ that we actually handle in the inner case statement. */
+ error ("GDB bug: ax-gdb.c (gen_expr): op case sets don't match");
+ }
+ break;
+
+ /* Note that we need to be a little subtle about generating code
+ for comma. In C, we can do some optimizations here because
+ we know the left operand is only being evaluated for effect.
+ However, if the tracing kludge is in effect, then we always
+ need to evaluate the left hand side fully, so that all the
+ variables it mentions get traced. */
+ case BINOP_COMMA:
+ (*pc)++;
+ gen_expr (pc, ax, &value1);
+ /* Don't just dispose of the left operand. We might be tracing,
+ in which case we want to emit code to trace it if it's an
+ lvalue. */
+ gen_traced_pop (ax, &value1);
+ gen_expr (pc, ax, value);
+ /* It's the consumer's responsibility to trace the right operand. */
+ break;
+
+ case OP_LONG: /* some integer constant */
+ {
+ struct type *type = (*pc)[1].type;
+ LONGEST k = (*pc)[2].longconst;
+ (*pc) += 4;
+ gen_int_literal (ax, value, k, type);
+ }
+ break;
+
+ case OP_VAR_VALUE:
+ gen_var_ref (ax, value, (*pc)[2].symbol);
+ (*pc) += 4;
+ break;
+
+ case OP_REGISTER:
+ {
+ int reg = (int) (*pc)[1].longconst;
+ (*pc) += 3;
+ value->kind = axs_lvalue_register;
+ value->u.reg = reg;
+ value->type = REGISTER_VIRTUAL_TYPE (reg);
+ }
+ break;
+
+ case OP_INTERNALVAR:
+ error ("GDB agent expressions cannot use convenience variables.");
+
+ /* Weirdo operator: see comments for gen_repeat for details. */
+ case BINOP_REPEAT:
+ /* Note that gen_repeat handles its own argument evaluation. */
+ (*pc)++;
+ gen_repeat (pc, ax, value);
+ break;
+
+ case UNOP_CAST:
+ {
+ struct type *type = (*pc)[1].type;
+ (*pc) += 3;
+ gen_expr (pc, ax, value);
+ gen_cast (ax, value, type);
+ }
+ break;
+
+ case UNOP_MEMVAL:
+ {
+ struct type *type = check_typedef ((*pc)[1].type);
+ (*pc) += 3;
+ gen_expr (pc, ax, value);
+ /* I'm not sure I understand UNOP_MEMVAL entirely. I think
+ it's just a hack for dealing with minsyms; you take some
+ integer constant, pretend it's the address of an lvalue of
+ the given type, and dereference it. */
+ if (value->kind != axs_rvalue)
+ /* This would be weird. */
+ error ("GDB bug: ax-gdb.c (gen_expr): OP_MEMVAL operand isn't an rvalue???");
+ value->type = type;
+ value->kind = axs_lvalue_memory;
+ }
+ break;
+
+ case UNOP_NEG:
+ (*pc)++;
+ /* -FOO is equivalent to 0 - FOO. */
+ gen_int_literal (ax, &value1, (LONGEST) 0, builtin_type_int);
+ gen_usual_unary (ax, &value1); /* shouldn't do much */
+ gen_expr (pc, ax, &value2);
+ gen_usual_unary (ax, &value2);
+ gen_usual_arithmetic (ax, &value1, &value2);
+ gen_sub (ax, value, &value1, &value2);
+ break;
+
+ case UNOP_LOGICAL_NOT:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_logical_not (ax, value);
+ break;
+
+ case UNOP_COMPLEMENT:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_complement (ax, value);
+ break;
+
+ case UNOP_IND:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_usual_unary (ax, value);
+ if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ error ("Argument of unary `*' is not a pointer.");
+ gen_deref (ax, value);
+ break;
+
+ case UNOP_ADDR:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_address_of (ax, value);
+ break;
+
+ case UNOP_SIZEOF:
+ (*pc)++;
+ /* Notice that gen_sizeof handles its own operand, unlike most
+ of the other unary operator functions. This is because we
+ have to throw away the code we generate. */
+ gen_sizeof (pc, ax, value);
+ break;
+
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ {
+ int length = (*pc)[1].longconst;
+ char *name = &(*pc)[2].string;
+
+ (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1);
+ gen_expr (pc, ax, value);
+ if (op == STRUCTOP_STRUCT)
+ gen_struct_ref (ax, value, name, ".", "structure or union");
+ else if (op == STRUCTOP_PTR)
+ gen_struct_ref (ax, value, name, "->",
+ "pointer to a structure or union");
+ else
+ /* If this `if' chain doesn't handle it, then the case list
+ shouldn't mention it, and we shouldn't be here. */
+ error ("GDB bug: ax-gdb.c (gen_expr): unhandled struct case");
+ }
+ break;
+
+ case OP_TYPE:
+ error ("Attempt to use a type name as an expression.");
+
+ default:
+ error ("Unsupported operator in expression.");
+ }
+}
+
+
+
+#if 0 /* not used */
+/* Generating bytecode from GDB expressions: driver */
+
+/* Given a GDB expression EXPR, produce a string of agent bytecode
+ which computes its value. Return the agent expression, and set
+ *VALUE to describe its type, and whether it's an lvalue or rvalue. */
+struct agent_expr *
+expr_to_agent (expr, value)
+ struct expression *expr;
+ struct axs_value *value;
+{
+ struct cleanup *old_chain = 0;
+ struct agent_expr *ax = new_agent_expr ();
+ union exp_element *pc;
+
+ old_chain = make_cleanup ((make_cleanup_func) free_agent_expr, ax);
+
+ pc = expr->elts;
+ trace_kludge = 0;
+ gen_expr (&pc, ax, value);
+
+ /* We have successfully built the agent expr, so cancel the cleanup
+ request. If we add more cleanups that we always want done, this
+ will have to get more complicated. */
+ discard_cleanups (old_chain);
+ return ax;
+}
+
+
+/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
+ string of agent bytecode which will leave its address and size on
+ the top of stack. Return the agent expression.
+
+ Not sure this function is useful at all. */
+struct agent_expr *
+expr_to_address_and_size (expr)
+ struct expression *expr;
+{
+ struct axs_value value;
+ struct agent_expr *ax = expr_to_agent (expr, &value);
+
+ /* Complain if the result is not a memory lvalue. */
+ if (value.kind != axs_lvalue_memory)
+ {
+ free_agent_expr (ax);
+ error ("Expression does not denote an object in memory.");
+ }
+
+ /* Push the object's size on the stack. */
+ ax_const_l (ax, TYPE_LENGTH (value.type));
+
+ return ax;
+}
+#endif /* 0 */
+
+/* Given a GDB expression EXPR, return bytecode to trace its value.
+ The result will use the `trace' and `trace_quick' bytecodes to
+ record the value of all memory touched by the expression. The
+ caller can then use the ax_reqs function to discover which
+ registers it relies upon. */
+struct agent_expr *
+gen_trace_for_expr (scope, expr)
+ CORE_ADDR scope;
+ struct expression *expr;
+{
+ struct cleanup *old_chain = 0;
+ struct agent_expr *ax = new_agent_expr (scope);
+ union exp_element *pc;
+ struct axs_value value;
+
+ old_chain = make_cleanup ((make_cleanup_func) free_agent_expr, ax);
+
+ pc = expr->elts;
+ trace_kludge = 1;
+ gen_expr (&pc, ax, &value);
+
+ /* Make sure we record the final object, and get rid of it. */
+ gen_traced_pop (ax, &value);
+
+ /* Oh, and terminate. */
+ ax_simple (ax, aop_end);
+
+ /* We have successfully built the agent expr, so cancel the cleanup
+ request. If we add more cleanups that we always want done, this
+ will have to get more complicated. */
+ discard_cleanups (old_chain);
+ return ax;
+}
+
+
+
+/* The "agent" command, for testing: compile and disassemble an expression. */
+
+static void
+print_axs_value (f, value)
+ GDB_FILE *f;
+ struct axs_value *value;
+{
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ fputs_filtered ("rvalue", f);
+ break;
+
+ case axs_lvalue_memory:
+ fputs_filtered ("memory lvalue", f);
+ break;
+
+ case axs_lvalue_register:
+ fprintf_filtered (f, "register %d lvalue", value->u.reg);
+ break;
+ }
+
+ fputs_filtered (" : ", f);
+ type_print (value->type, "", f, -1);
+}
+
+
+static void
+agent_command (exp, from_tty)
+ char *exp;
+ int from_tty;
+{
+ struct cleanup *old_chain = 0;
+ struct expression *expr;
+ struct agent_expr *agent;
+ struct agent_reqs reqs;
+ struct frame_info *fi = get_current_frame (); /* need current scope */
+
+ /* We don't deal with overlay debugging at the moment. We need to
+ think more carefully about this. If you copy this code into
+ another command, change the error message; the user shouldn't
+ have to know anything about agent expressions. */
+ if (overlay_debugging)
+ error ("GDB can't do agent expression translation with overlays.");
+
+ if (exp == 0)
+ error_no_arg ("expression to translate");
+
+ expr = parse_expression (exp);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ agent = gen_trace_for_expr (fi->pc, expr);
+ make_cleanup ((make_cleanup_func) free_agent_expr, agent);
+ ax_print (gdb_stdout, agent);
+ ax_reqs (agent, &reqs);
+
+ do_cleanups (old_chain);
+ dont_repeat ();
+}
+
+
+/* Initialization code. */
+
+void _initialize_ax_gdb PARAMS ((void));
+void
+_initialize_ax_gdb ()
+{
+ struct cmd_list_element *c;
+
+ add_cmd ("agent", class_maintenance, agent_command,
+ "Translate an expression into remote agent bytecode.",
+ &maintenancelist);
+}
diff --git a/contrib/gdb/gdb/ax-gdb.h b/contrib/gdb/gdb/ax-gdb.h
new file mode 100644
index 0000000..575b4bf
--- /dev/null
+++ b/contrib/gdb/gdb/ax-gdb.h
@@ -0,0 +1,111 @@
+/* GDB-specific functions for operating on agent expressions
+ Copyright 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* $Id: ax-gdb.h,v 1.3.20.1 1999/04/01 17:33:04 jimb Exp $ */
+
+#ifndef AX_GDB_H
+#define AX_GDB_H
+
+
+/* Types and enums */
+
+/* GDB stores expressions in the form of a flattened tree (struct
+ expression), so we just walk that tree and generate agent bytecodes
+ as we go along.
+
+ GDB's normal evaluation uses struct value, which contains the
+ expression's value as well as its address or the register it came
+ from. The `+' operator uses the value, whereas the unary `&'
+ operator will use the address portion. The `=' operator will use
+ the address or register number of its left hand side.
+
+ The issues are different when generating agent bytecode. Given a
+ variable reference expression, we should not necessarily generate
+ code to fetch its value, because the next operator may be `=' or
+ unary `&'. Instead, when we recurse on a subexpression, we
+ indicate whether we want that expression to produce an lvalue or an
+ rvalue. If we requested an lvalue, then the recursive call tells
+ us whether it generated code to compute an address on the stack, or
+ whether the lvalue lives in a register.
+
+ The `axs' prefix here means `agent expression, static', because
+ this is all static analysis of the expression, i.e. analysis which
+ doesn't depend on the contents of memory and registers. */
+
+
+/* Different kinds of agent expression static values. */
+enum axs_lvalue_kind {
+ /* We generated code to compute the subexpression's value.
+ Constants and arithmetic operators yield this. */
+ axs_rvalue,
+
+ /* We generated code to yield the subexpression's value's address on
+ the top of the stack. If the caller needs an rvalue, it should
+ call require_rvalue to produce the rvalue from this address. */
+ axs_lvalue_memory,
+
+ /* We didn't generate any code, and the stack is undisturbed,
+ because the subexpression's value lives in a register; u.reg is
+ the register number. If the caller needs an rvalue, it should
+ call require_rvalue to produce the rvalue from this register
+ number. */
+ axs_lvalue_register
+};
+
+/* Structure describing what we got from a subexpression. Think of
+ this as parallel to value.h's enum lval_type, except that we're
+ describing a value which will exist when the expression is
+ evaluated in the future, not a value we have in our hand. */
+struct axs_value {
+ enum axs_lvalue_kind kind; /* see above */
+
+ /* The type of the subexpression. Even if lvalue == axs_lvalue_memory,
+ this is the type of the value itself; the value on the stack is a
+ "pointer to" an object of this type. */
+ struct type *type;
+
+ union {
+ /* if kind == axs_lvalue_register, this is the register number */
+ int reg;
+ } u;
+};
+
+
+/* Translating GDB expressions into agent expressions. */
+
+/* Given a GDB expression EXPR, translate it into the agent bytecode,
+ and return it. FLAGS are from enum expr_to_agent_flags. */
+extern struct agent_expr *expr_to_agent PARAMS ((struct expression *EXPR,
+ struct axs_value *VALUE));
+
+/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
+ string of agent bytecode which will leave its address and size on
+ the top of stack. Return the agent expression. */
+extern struct agent_expr *expr_to_address_and_size
+ PARAMS ((struct expression *EXPR));
+
+/* Given a GDB expression EXPR, return bytecode to trace its value.
+ The result will use the `trace' and `trace_quick' bytecodes to
+ record the value of all memory touched by the expression, and leave
+ no values on the stack. The caller can then use the ax_reqs
+ function to discover which registers the expression uses. */
+extern struct agent_expr *gen_trace_for_expr PARAMS ((CORE_ADDR,
+ struct expression *));
+
+#endif /* AX_GDB_H */
diff --git a/contrib/gdb/gdb/ax-general.c b/contrib/gdb/gdb/ax-general.c
new file mode 100644
index 0000000..6f399a8
--- /dev/null
+++ b/contrib/gdb/gdb/ax-general.c
@@ -0,0 +1,552 @@
+/* Functions for manipulating expressions designed to be executed on the agent
+ Copyright 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* $Id: ax-general.c,v 1.3 1998/12/02 23:22:58 msnyder Exp $ */
+
+/* Despite what the above comment says about this file being part of
+ GDB, we would like to keep these functions free of GDB
+ dependencies, since we want to be able to use them in contexts
+ outside of GDB (test suites, the stub, etc.) */
+
+#include "defs.h"
+#include "ax.h"
+
+
+/* Functions for building expressions. */
+
+/* Allocate a new, empty agent expression. */
+struct agent_expr *
+new_agent_expr (scope)
+ CORE_ADDR scope;
+{
+ struct agent_expr *x = xmalloc (sizeof (*x));
+ x->len = 0;
+ x->size = 1; /* Change this to a larger value once
+ reallocation code is tested. */
+ x->buf = xmalloc (x->size);
+ x->scope = scope;
+
+ return x;
+}
+
+/* Free a agent expression. */
+void
+free_agent_expr (x)
+ struct agent_expr *x;
+{
+ free (x->buf);
+ free (x);
+}
+
+
+/* Make sure that X has room for at least N more bytes. This doesn't
+ affect the length, just the allocated size. */
+static void
+grow_expr (x, n)
+ struct agent_expr *x;
+ int n;
+{
+ if (x->len + n > x->size)
+ {
+ x->size *= 2;
+ if (x->size < x->len + n)
+ x->size = x->len + n + 10;
+ x->buf = xrealloc (x->buf, x->size);
+ }
+}
+
+
+/* Append the low N bytes of VAL as an N-byte integer to the
+ expression X, in big-endian order. */
+static void
+append_const (x, val, n)
+ struct agent_expr *x;
+ LONGEST val;
+ int n;
+{
+ int i;
+
+ grow_expr (x, n);
+ for (i = n - 1; i >= 0; i--)
+ {
+ x->buf[x->len + i] = val & 0xff;
+ val >>= 8;
+ }
+ x->len += n;
+}
+
+
+/* Extract an N-byte big-endian unsigned integer from expression X at
+ offset O. */
+static LONGEST
+read_const (x, o, n)
+ struct agent_expr *x;
+ int o, n;
+{
+ int i;
+ LONGEST accum = 0;
+
+ /* Make sure we're not reading off the end of the expression. */
+ if (o + n > x->len)
+ error ("GDB bug: ax-general.c (read_const): incomplete constant");
+
+ for (i = 0; i < n; i++)
+ accum = (accum << 8) | x->buf[o + i];
+
+ return accum;
+}
+
+
+/* Append a simple operator OP to EXPR. */
+void
+ax_simple (x, op)
+ struct agent_expr *x;
+ enum agent_op op;
+{
+ grow_expr (x, 1);
+ x->buf[x->len++] = op;
+}
+
+
+/* Append a sign-extension or zero-extension instruction to EXPR, to
+ extend an N-bit value. */
+static void
+generic_ext (x, op, n)
+ struct agent_expr *x;
+ enum agent_op op;
+ int n;
+{
+ /* N must fit in a byte. */
+ if (n < 0 || n > 255)
+ error ("GDB bug: ax-general.c (generic_ext): bit count out of range");
+ /* That had better be enough range. */
+ if (sizeof (LONGEST) * 8 > 255)
+ error ("GDB bug: ax-general.c (generic_ext): opcode has inadequate range");
+
+ grow_expr (x, 2);
+ x->buf[x->len++] = op;
+ x->buf[x->len++] = n;
+}
+
+
+/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
+void
+ax_ext (x, n)
+ struct agent_expr *x;
+ int n;
+{
+ generic_ext (x, aop_ext, n);
+}
+
+
+/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
+void
+ax_zero_ext (x, n)
+ struct agent_expr *x;
+ int n;
+{
+ generic_ext (x, aop_zero_ext, n);
+}
+
+
+/* Append a trace_quick instruction to EXPR, to record N bytes. */
+void
+ax_trace_quick (x, n)
+ struct agent_expr *x;
+ int n;
+{
+ /* N must fit in a byte. */
+ if (n < 0 || n > 255)
+ error ("GDB bug: ax-general.c (ax_trace_quick): size out of range for trace_quick");
+
+ grow_expr (x, 2);
+ x->buf[x->len++] = aop_trace_quick;
+ x->buf[x->len++] = n;
+}
+
+
+/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
+ aop_if_goto). We assume we don't know the target offset yet,
+ because it's probably a forward branch, so we leave space in EXPR
+ for the target, and return the offset in EXPR of that space, so we
+ can backpatch it once we do know the target offset. Use ax_label
+ to do the backpatching. */
+int ax_goto (x, op)
+ struct agent_expr *x;
+ enum agent_op op;
+{
+ grow_expr (x, 3);
+ x->buf[x->len + 0] = op;
+ x->buf[x->len + 1] = 0xff;
+ x->buf[x->len + 2] = 0xff;
+ x->len += 3;
+ return x->len - 2;
+}
+
+/* Suppose a given call to ax_goto returns some value PATCH. When you
+ know the offset TARGET that goto should jump to, call
+ ax_label (EXPR, PATCH, TARGET)
+ to patch TARGET into the ax_goto instruction. */
+void
+ax_label (x, patch, target)
+ struct agent_expr *x;
+ int patch;
+ int target;
+{
+ /* Make sure the value is in range. Don't accept 0xffff as an
+ offset; that's our magic sentinel value for unpatched branches. */
+ if (target < 0 || target >= 0xffff)
+ error ("GDB bug: ax-general.c (ax_label): label target out of range");
+
+ x->buf[patch] = (target >> 8) & 0xff;
+ x->buf[patch + 1] = target & 0xff;
+}
+
+
+/* Assemble code to push a constant on the stack. */
+void
+ax_const_l (x, l)
+ struct agent_expr *x;
+ LONGEST l;
+{
+ static enum agent_op ops[]
+ = { aop_const8, aop_const16, aop_const32, aop_const64 };
+ int size;
+ int op;
+
+ /* How big is the number? 'op' keeps track of which opcode to use.
+ Notice that we don't really care whether the original number was
+ signed or unsigned; we always reproduce the value exactly, and
+ use the shortest representation. */
+ for (op = 0, size = 8; size < 64; size *= 2, op++)
+ if (-((LONGEST) 1 << size) <= l && l < ((LONGEST) 1 << size))
+ break;
+
+ /* Emit the right opcode... */
+ ax_simple (x, ops[op]);
+
+ /* Emit the low SIZE bytes as an unsigned number. We know that
+ sign-extending this will yield l. */
+ append_const (x, l, size / 8);
+
+ /* Now, if it was negative, and not full-sized, sign-extend it. */
+ if (l < 0 && size < 64)
+ ax_ext (x, size);
+}
+
+
+void
+ax_const_d (x, d)
+ struct agent_expr *x;
+ LONGEST d;
+{
+ /* FIXME: floating-point support not present yet. */
+ error ("GDB bug: ax-general.c (ax_const_d): floating point not supported yet");
+}
+
+
+/* Assemble code to push the value of register number REG on the
+ stack. */
+void ax_reg (x, reg)
+ struct agent_expr *x;
+ int reg;
+{
+ /* Make sure the register number is in range. */
+ if (reg < 0 || reg > 0xffff)
+ error ("GDB bug: ax-general.c (ax_reg): register number out of range");
+ grow_expr (x, 3);
+ x->buf[x->len ] = aop_reg;
+ x->buf[x->len + 1] = (reg >> 8) & 0xff;
+ x->buf[x->len + 2] = (reg ) & 0xff;
+ x->len += 3;
+}
+
+
+
+/* Functions for disassembling agent expressions, and otherwise
+ debugging the expression compiler. */
+
+struct aop_map aop_map[] = {
+ { 0, 0, 0, 0, 0 },
+ { "float", 0, 0, 0, 0 }, /* 0x01 */
+ { "add", 0, 0, 2, 1 }, /* 0x02 */
+ { "sub", 0, 0, 2, 1 }, /* 0x03 */
+ { "mul", 0, 0, 2, 1 }, /* 0x04 */
+ { "div_signed", 0, 0, 2, 1 }, /* 0x05 */
+ { "div_unsigned", 0, 0, 2, 1 }, /* 0x06 */
+ { "rem_signed", 0, 0, 2, 1 }, /* 0x07 */
+ { "rem_unsigned", 0, 0, 2, 1 }, /* 0x08 */
+ { "lsh", 0, 0, 2, 1 }, /* 0x09 */
+ { "rsh_signed", 0, 0, 2, 1 }, /* 0x0a */
+ { "rsh_unsigned", 0, 0, 2, 1 }, /* 0x0b */
+ { "trace", 0, 0, 2, 0 }, /* 0x0c */
+ { "trace_quick", 1, 0, 1, 1 }, /* 0x0d */
+ { "log_not", 0, 0, 1, 1 }, /* 0x0e */
+ { "bit_and", 0, 0, 2, 1 }, /* 0x0f */
+ { "bit_or", 0, 0, 2, 1 }, /* 0x10 */
+ { "bit_xor", 0, 0, 2, 1 }, /* 0x11 */
+ { "bit_not", 0, 0, 1, 1 }, /* 0x12 */
+ { "equal", 0, 0, 2, 1 }, /* 0x13 */
+ { "less_signed", 0, 0, 2, 1 }, /* 0x14 */
+ { "less_unsigned", 0, 0, 2, 1 }, /* 0x15 */
+ { "ext", 1, 0, 1, 1 }, /* 0x16 */
+ { "ref8", 0, 8, 1, 1 }, /* 0x17 */
+ { "ref16", 0, 16, 1, 1 }, /* 0x18 */
+ { "ref32", 0, 32, 1, 1 }, /* 0x19 */
+ { "ref64", 0, 64, 1, 1 }, /* 0x1a */
+ { "ref_float", 0, 0, 1, 1 }, /* 0x1b */
+ { "ref_double", 0, 0, 1, 1 }, /* 0x1c */
+ { "ref_long_double", 0, 0, 1, 1 }, /* 0x1d */
+ { "l_to_d", 0, 0, 1, 1 }, /* 0x1e */
+ { "d_to_l", 0, 0, 1, 1 }, /* 0x1f */
+ { "if_goto", 2, 0, 1, 0 }, /* 0x20 */
+ { "goto", 2, 0, 0, 0 }, /* 0x21 */
+ { "const8", 1, 8, 0, 1 }, /* 0x22 */
+ { "const16", 2, 16, 0, 1 }, /* 0x23 */
+ { "const32", 4, 32, 0, 1 }, /* 0x24 */
+ { "const64", 8, 64, 0, 1 }, /* 0x25 */
+ { "reg", 2, 0, 0, 1 }, /* 0x26 */
+ { "end", 0, 0, 0, 0 }, /* 0x27 */
+ { "dup", 0, 0, 1, 2 }, /* 0x28 */
+ { "pop", 0, 0, 1, 0 }, /* 0x29 */
+ { "zero_ext", 1, 0, 1, 1 }, /* 0x2a */
+ { "swap", 0, 0, 2, 2 }, /* 0x2b */
+ { 0, 0, 0, 0, 0 }, /* 0x2c */
+ { 0, 0, 0, 0, 0 }, /* 0x2d */
+ { 0, 0, 0, 0, 0 }, /* 0x2e */
+ { 0, 0, 0, 0, 0 }, /* 0x2f */
+ { "trace16", 2, 0, 1, 1 }, /* 0x30 */
+};
+
+
+/* Disassemble the expression EXPR, writing to F. */
+void
+ax_print (f, x)
+ GDB_FILE *f;
+ struct agent_expr *x;
+{
+ int i;
+ int is_float = 0;
+
+ /* Check the size of the name array against the number of entries in
+ the enum, to catch additions that people didn't sync. */
+ if ((sizeof (aop_map) / sizeof (aop_map[0]))
+ != aop_last)
+ error ("GDB bug: ax-general.c (ax_print): opcode map out of sync");
+
+ for (i = 0; i < x->len; )
+ {
+ enum agent_op op = x->buf[i];
+
+ if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
+ || ! aop_map[op].name)
+ {
+ fprintf_filtered (f, "%3d <bad opcode %02x>\n", i, op);
+ i++;
+ continue;
+ }
+ if (i + 1 + aop_map[op].op_size > x->len)
+ {
+ fprintf_filtered (f, "%3d <incomplete opcode %s>\n",
+ i, aop_map[op].name);
+ break;
+ }
+
+ fprintf_filtered (f, "%3d %s", i, aop_map[op].name);
+ if (aop_map[op].op_size > 0)
+ {
+ fputs_filtered (" ", f);
+
+ print_longest (f, 'd', 0,
+ read_const (x, i + 1, aop_map[op].op_size));
+ }
+ fprintf_filtered (f, "\n");
+ i += 1 + aop_map[op].op_size;
+
+ is_float = (op == aop_float);
+ }
+}
+
+
+/* Given an agent expression AX, fill in an agent_reqs structure REQS
+ describing it. */
+void
+ax_reqs (ax, reqs)
+ struct agent_expr *ax;
+ struct agent_reqs *reqs;
+{
+ int i;
+ int height;
+
+ /* Bit vector for registers used. */
+ int reg_mask_len = 1;
+ unsigned char *reg_mask = xmalloc (reg_mask_len * sizeof (reg_mask[0]));
+
+ /* Jump target table. targets[i] is non-zero iff there is a jump to
+ offset i. */
+ char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
+
+ /* Instruction boundary table. boundary[i] is non-zero iff an
+ instruction starts at offset i. */
+ char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
+
+ /* Stack height record. iff either targets[i] or boundary[i] is
+ non-zero, heights[i] is the height the stack should have before
+ executing the bytecode at that point. */
+ int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
+
+ /* Pointer to a description of the present op. */
+ struct aop_map *op;
+
+ memset (reg_mask, 0, reg_mask_len * sizeof (reg_mask[0]));
+ memset (targets, 0, ax->len * sizeof (targets[0]));
+ memset (boundary, 0, ax->len * sizeof (boundary[0]));
+
+ reqs->max_height = reqs->min_height = height = 0;
+ reqs->flaw = agent_flaw_none;
+ reqs->max_data_size = 0;
+
+ for (i = 0; i < ax->len; i += 1 + op->op_size)
+ {
+ if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
+ {
+ reqs->flaw = agent_flaw_bad_instruction;
+ free (reg_mask);
+ return;
+ }
+
+ op = &aop_map[ax->buf[i]];
+
+ if (! op->name)
+ {
+ reqs->flaw = agent_flaw_bad_instruction;
+ free (reg_mask);
+ return;
+ }
+
+ if (i + 1 + op->op_size > ax->len)
+ {
+ reqs->flaw = agent_flaw_incomplete_instruction;
+ free (reg_mask);
+ return;
+ }
+
+ /* If this instruction is a jump target, does the current stack
+ height match the stack height at the jump source? */
+ if (targets[i] && (heights[i] != height))
+ {
+ reqs->flaw = agent_flaw_height_mismatch;
+ free (reg_mask);
+ return;
+ }
+
+ boundary[i] = 1;
+ heights[i] = height;
+
+ height -= op->consumed;
+ if (height < reqs->min_height)
+ reqs->min_height = height;
+ height += op->produced;
+ if (height > reqs->max_height)
+ reqs->max_height = height;
+
+ if (op->data_size > reqs->max_data_size)
+ reqs->max_data_size = op->data_size;
+
+ /* For jump instructions, check that the target is a valid
+ offset. If it is, record the fact that that location is a
+ jump target, and record the height we expect there. */
+ if (aop_goto == op - aop_map
+ || aop_if_goto == op - aop_map)
+ {
+ int target = read_const (ax, i + 1, 2);
+ if (target < 0 || target >= ax->len)
+ {
+ reqs->flaw = agent_flaw_bad_jump;
+ free (reg_mask);
+ return;
+ }
+ /* Have we already found other jumps to the same location? */
+ else if (targets[target])
+ {
+ if (heights[i] != height)
+ {
+ reqs->flaw = agent_flaw_height_mismatch;
+ free (reg_mask);
+ return;
+ }
+ }
+ else
+ {
+ targets[target] = 1;
+ heights[target] = height;
+ }
+ }
+
+ /* For unconditional jumps with a successor, check that the
+ successor is a target, and pick up its stack height. */
+ if (aop_goto == op - aop_map
+ && i + 3 < ax->len)
+ {
+ if (! targets[i + 3])
+ {
+ reqs->flaw = agent_flaw_hole;
+ free (reg_mask);
+ return;
+ }
+
+ height = heights[i + 3];
+ }
+
+ /* For reg instructions, record the register in the bit mask. */
+ if (aop_reg == op - aop_map)
+ {
+ int reg = read_const (ax, i + 1, 2);
+ int byte = reg / 8;
+
+ /* Grow the bit mask if necessary. */
+ if (byte >= reg_mask_len)
+ {
+ /* It's not appropriate to double here. This isn't a
+ string buffer. */
+ int new_len = byte + 1;
+ reg_mask = xrealloc (reg_mask,
+ new_len * sizeof (reg_mask[0]));
+ memset (reg_mask + reg_mask_len, 0,
+ (new_len - reg_mask_len) * sizeof (reg_mask[0]));
+ reg_mask_len = new_len;
+ }
+
+ reg_mask[byte] |= 1 << (reg % 8);
+ }
+ }
+
+ /* Check that all the targets are on boundaries. */
+ for (i = 0; i < ax->len; i++)
+ if (targets[i] && !boundary[i])
+ {
+ reqs->flaw = agent_flaw_bad_jump;
+ free (reg_mask);
+ return;
+ }
+
+ reqs->final_height = height;
+ reqs->reg_mask_len = reg_mask_len;
+ reqs->reg_mask = reg_mask;
+}
diff --git a/contrib/gdb/gdb/ax.h b/contrib/gdb/gdb/ax.h
new file mode 100644
index 0000000..fe23a31
--- /dev/null
+++ b/contrib/gdb/gdb/ax.h
@@ -0,0 +1,285 @@
+/* Definitions for expressions designed to be executed on the agent
+ Copyright 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* $Id: ax.h,v 1.3.20.1 1999/04/01 17:33:04 jimb Exp $ */
+
+#ifndef AGENTEXPR_H
+#define AGENTEXPR_H
+
+/* It's sometimes useful to be able to debug programs that you can't
+ really stop for more than a fraction of a second. To this end, the
+ user can specify a tracepoint (like a breakpoint, but you don't
+ stop at it), and specify a bunch of expressions to record the
+ values of when that tracepoint is reached. As the program runs,
+ GDB collects the values. At any point (possibly while values are
+ still being collected), the user can display the collected values.
+
+ This is used with remote debugging; we don't really support it on
+ native configurations.
+
+ This means that expressions are being evaluated by the remote agent,
+ which doesn't have any access to the symbol table information, and
+ needs to be small and simple.
+
+ The agent_expr routines and datatypes are a bytecode language
+ designed to be executed by the agent. Agent expressions work in
+ terms of fixed-width values, operators, memory references, and
+ register references. You can evaluate a agent expression just given
+ a bunch of memory and register values to sniff at; you don't need
+ any symbolic information like variable names, types, etc.
+
+ GDB translates source expressions, whose meaning depends on
+ symbolic information, into agent bytecode expressions, whose meaning
+ is independent of symbolic information. This means the agent can
+ evaluate them on the fly without reference to data only available
+ to the host GDB. */
+
+
+/* Agent expression data structures. */
+
+/* The type of an element of the agent expression stack.
+ The bytecode operation indicates which element we should access;
+ the value itself has no typing information. GDB generates all
+ bytecode streams, so we don't have to worry about type errors. */
+
+union agent_val {
+ LONGEST l;
+ DOUBLEST d;
+};
+
+/* A buffer containing a agent expression. */
+struct agent_expr {
+ unsigned char *buf;
+ int len; /* number of characters used */
+ int size; /* allocated size */
+ CORE_ADDR scope;
+};
+
+
+
+
+/* The actual values of the various bytecode operations.
+
+ Other independent implementations of the agent bytecode engine will
+ rely on the exact values of these enums, and may not be recompiled
+ when we change this table. The numeric values should remain fixed
+ whenever possible. Thus, we assign them values explicitly here (to
+ allow gaps to form safely), and the disassembly table in
+ agentexpr.h behaves like an opcode map. If you want to see them
+ grouped logically, see doc/agentexpr.texi. */
+
+enum agent_op {
+ aop_float = 0x01,
+ aop_add = 0x02,
+ aop_sub = 0x03,
+ aop_mul = 0x04,
+ aop_div_signed = 0x05,
+ aop_div_unsigned = 0x06,
+ aop_rem_signed = 0x07,
+ aop_rem_unsigned = 0x08,
+ aop_lsh = 0x09,
+ aop_rsh_signed = 0x0a,
+ aop_rsh_unsigned = 0x0b,
+ aop_trace = 0x0c,
+ aop_trace_quick = 0x0d,
+ aop_log_not = 0x0e,
+ aop_bit_and = 0x0f,
+ aop_bit_or = 0x10,
+ aop_bit_xor = 0x11,
+ aop_bit_not = 0x12,
+ aop_equal = 0x13,
+ aop_less_signed = 0x14,
+ aop_less_unsigned = 0x15,
+ aop_ext = 0x16,
+ aop_ref8 = 0x17,
+ aop_ref16 = 0x18,
+ aop_ref32 = 0x19,
+ aop_ref64 = 0x1a,
+ aop_ref_float = 0x1b,
+ aop_ref_double = 0x1c,
+ aop_ref_long_double = 0x1d,
+ aop_l_to_d = 0x1e,
+ aop_d_to_l = 0x1f,
+ aop_if_goto = 0x20,
+ aop_goto = 0x21,
+ aop_const8 = 0x22,
+ aop_const16 = 0x23,
+ aop_const32 = 0x24,
+ aop_const64 = 0x25,
+ aop_reg = 0x26,
+ aop_end = 0x27,
+ aop_dup = 0x28,
+ aop_pop = 0x29,
+ aop_zero_ext = 0x2a,
+ aop_swap = 0x2b,
+ aop_trace16 = 0x30,
+ aop_last
+};
+
+
+
+/* Functions for building expressions. */
+
+/* Allocate a new, empty agent expression. */
+extern struct agent_expr *new_agent_expr PARAMS ((CORE_ADDR));
+
+/* Free a agent expression. */
+extern void free_agent_expr PARAMS ((struct agent_expr *));
+
+/* Append a simple operator OP to EXPR. */
+extern void ax_simple PARAMS ((struct agent_expr *EXPR, enum agent_op OP));
+
+/* Append the floating-point prefix, for the next bytecode. */
+#define ax_float(EXPR) (ax_simple ((EXPR), aop_float))
+
+/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
+extern void ax_ext PARAMS ((struct agent_expr *EXPR, int N));
+
+/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
+extern void ax_zero_ext PARAMS ((struct agent_expr *EXPR, int N));
+
+/* Append a trace_quick instruction to EXPR, to record N bytes. */
+extern void ax_trace_quick PARAMS ((struct agent_expr *EXPR, int N));
+
+/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
+ aop_if_goto). We assume we don't know the target offset yet,
+ because it's probably a forward branch, so we leave space in EXPR
+ for the target, and return the offset in EXPR of that space, so we
+ can backpatch it once we do know the target offset. Use ax_label
+ to do the backpatching. */
+extern int ax_goto PARAMS ((struct agent_expr *EXPR, enum agent_op OP));
+
+/* Suppose a given call to ax_goto returns some value PATCH. When you
+ know the offset TARGET that goto should jump to, call
+ ax_label (EXPR, PATCH, TARGET)
+ to patch TARGET into the ax_goto instruction. */
+extern void ax_label PARAMS ((struct agent_expr *EXPR, int patch, int target));
+
+/* Assemble code to push a constant on the stack. */
+extern void ax_const_l PARAMS ((struct agent_expr *EXPR, LONGEST l));
+extern void ax_const_d PARAMS ((struct agent_expr *EXPR, LONGEST d));
+
+/* Assemble code to push the value of register number REG on the
+ stack. */
+extern void ax_reg PARAMS ((struct agent_expr *EXPR, int REG));
+
+
+/* Functions for printing out expressions, and otherwise debugging
+ things. */
+
+/* Disassemble the expression EXPR, writing to F. */
+extern void ax_print PARAMS ((GDB_FILE *f, struct agent_expr *EXPR));
+
+/* An entry in the opcode map. */
+struct aop_map {
+
+ /* The name of the opcode. Null means that this entry is not a
+ valid opcode --- a hole in the opcode space. */
+ char *name;
+
+ /* All opcodes take no operands from the bytecode stream, or take
+ unsigned integers of various sizes. If this is a positive number
+ n, then the opcode is followed by an n-byte operand, which should
+ be printed as an unsigned integer. If this is zero, then the
+ opcode takes no operands from the bytecode stream.
+
+ If we get more complicated opcodes in the future, don't add other
+ magic values of this; that's a crock. Add an `enum encoding'
+ field to this, or something like that. */
+ int op_size;
+
+ /* The size of the data operated upon, in bits, for bytecodes that
+ care about that (ref and const). Zero for all others. */
+ int data_size;
+
+ /* Number of stack elements consumed, and number produced. */
+ int consumed, produced;
+};
+
+/* Map of the bytecodes, indexed by bytecode number. */
+extern struct aop_map aop_map[];
+
+/* Different kinds of flaws an agent expression might have, as
+ detected by agent_reqs. */
+enum agent_flaws {
+ agent_flaw_none = 0, /* code is good */
+
+ /* There is an invalid instruction in the stream. */
+ agent_flaw_bad_instruction,
+
+ /* There is an incomplete instruction at the end of the expression. */
+ agent_flaw_incomplete_instruction,
+
+ /* agent_reqs was unable to prove that every jump target is to a
+ valid offset. Valid offsets are within the bounds of the
+ expression, and to a valid instruction boundary. */
+ agent_flaw_bad_jump,
+
+ /* agent_reqs was unable to prove to its satisfaction that, for each
+ jump target location, the stack will have the same height whether
+ that location is reached via a jump or by straight execution. */
+ agent_flaw_height_mismatch,
+
+ /* agent_reqs was unable to prove that every instruction following
+ an unconditional jump was the target of some other jump. */
+ agent_flaw_hole
+};
+
+/* Structure describing the requirements of a bytecode expression. */
+struct agent_reqs {
+
+ /* If the following is not equal to agent_flaw_none, the rest of the
+ information in this structure is suspect. */
+ enum agent_flaws flaw;
+
+ /* Number of elements left on stack at end; may be negative if expr
+ only consumes elements. */
+ int final_height;
+
+ /* Maximum and minimum stack height, relative to initial height. */
+ int max_height, min_height;
+
+ /* Largest `ref' or `const' opcode used, in bits. Zero means the
+ expression has no such instructions. */
+ int max_data_size;
+
+ /* Bit vector of registers used. Register R is used iff
+
+ reg_mask[R / 8] & (1 << (R % 8))
+
+ is non-zero. Note! You may not assume that this bitmask is long
+ enough to hold bits for all the registers of the machine; the
+ agent expression code has no idea how many registers the machine
+ has. However, the bitmask is reg_mask_len bytes long, so the
+ valid register numbers run from 0 to reg_mask_len * 8 - 1.
+
+ We're assuming eight-bit bytes. So sue me.
+
+ The caller should free reg_list when done. */
+ int reg_mask_len;
+ unsigned char *reg_mask;
+};
+
+
+/* Given an agent expression AX, fill in an agent_reqs structure REQS
+ describing it. */
+extern void ax_reqs PARAMS ((struct agent_expr *ax,
+ struct agent_reqs *reqs));
+
+#endif /* AGENTEXPR_H */
diff --git a/contrib/gdb/gdb/bcache.c b/contrib/gdb/gdb/bcache.c
index ae73c11..d28515b 100644
--- a/contrib/gdb/gdb/bcache.c
+++ b/contrib/gdb/gdb/bcache.c
@@ -1,6 +1,6 @@
/* Implement a cached obstack.
Written by Fred Fish (fnf@cygnus.com)
- Copyright 1995 Free Software Foundation, Inc.
+ Copyright 1995, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -23,6 +23,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bcache.h"
#include "gdb_string.h" /* For memcpy declaration */
+/* Prototypes for local functions. */
+
+static unsigned int hash PARAMS ((void *, int));
+
+static void *lookup_cache PARAMS ((void *, int, int, struct bcache *));
+
/* FIXME: Incredibly simplistic hash generator. Probably way too expensive
(consider long strings) and unlikely to have good distribution across hash
values for typical input. */
@@ -173,16 +179,40 @@ print_bcache_statistics (bcachep, id)
printf_filtered (" Cached '%s' statistics:\n", id);
printf_filtered (" Cache hits: %d\n", bcachep -> cache_hits);
printf_filtered (" Cache misses: %d\n", bcachep -> cache_misses);
- printf_filtered (" Cache hit ratio: %d%%\n", ((bcachep -> cache_hits) * 100) / (bcachep -> cache_hits + bcachep -> cache_misses));
+ printf_filtered (" Cache hit ratio: ");
+ if (bcachep -> cache_hits + bcachep -> cache_misses > 0)
+ {
+ printf_filtered ("%d%%\n", ((bcachep -> cache_hits) * 100) /
+ (bcachep -> cache_hits + bcachep -> cache_misses));
+ }
+ else
+ {
+ printf_filtered ("(not applicable)\n");
+ }
printf_filtered (" Space used for caching: %d\n", bcachep -> cache_bytes);
printf_filtered (" Space saved by cache hits: %d\n", bcachep -> cache_savings);
printf_filtered (" Number of bcache overflows: %d\n", bcachep -> bcache_overflows);
printf_filtered (" Number of index buckets used: %d\n", tcount);
printf_filtered (" Number of hash table buckets used: %d\n", hcount);
printf_filtered (" Number of chained items: %d\n", lcount);
- printf_filtered (" Average hash table population: %d%%\n",
- (hcount * 100) / (tcount * BCACHE_HASHSIZE));
- printf_filtered (" Average chain length %d\n", lcount / hcount);
+ printf_filtered (" Average hash table population: ");
+ if (tcount > 0)
+ {
+ printf_filtered ("%d%%\n", (hcount * 100) / (tcount * BCACHE_HASHSIZE));
+ }
+ else
+ {
+ printf_filtered ("(not applicable)\n");
+ }
+ printf_filtered (" Average chain length ");
+ if (hcount > 0)
+ {
+ printf_filtered ("%d\n", lcount / hcount);
+ }
+ else
+ {
+ printf_filtered ("(not applicable)\n");
+ }
printf_filtered (" Maximum chain length %d at %d:%d\n", lmax, lmaxt, lmaxh);
}
diff --git a/contrib/gdb/gdb/bcache.h b/contrib/gdb/gdb/bcache.h
index 48b71e2..cf0c62e 100644
--- a/contrib/gdb/gdb/bcache.h
+++ b/contrib/gdb/gdb/bcache.h
@@ -47,7 +47,7 @@ struct hashlink {
a hashlink struct to hold the next pointer and the data. */
#define BCACHE_DATA_ALIGNMENT \
- (((char *) &BCACHE_DATA((struct hashlink*) 0) - (char *) 0))
+ (((char *) BCACHE_DATA((struct hashlink*) 0) - (char *) 0))
struct bcache {
struct obstack cache;
diff --git a/contrib/gdb/gdb/blockframe.c b/contrib/gdb/gdb/blockframe.c
index d98f6a4..9366ca6 100644
--- a/contrib/gdb/gdb/blockframe.c
+++ b/contrib/gdb/gdb/blockframe.c
@@ -1,6 +1,6 @@
/* Get info from stack frames;
convert between frames, blocks, functions and pc values.
- Copyright 1986, 1987, 1988, 1989, 1991, 1994, 1995
+ Copyright 1986, 87, 88, 89, 91, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -31,6 +31,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "inferior.h" /* for read_pc */
#include "annotate.h"
+/* Prototypes for exported functions. */
+
+void _initialize_blockframe PARAMS ((void));
+
+/* A default FRAME_CHAIN_VALID, in the form that is suitable for most
+ targets. If FRAME_CHAIN_VALID returns zero it means that the given
+ frame is the outermost one and has no caller. */
+
+int
+default_frame_chain_valid (chain, thisframe)
+ CORE_ADDR chain;
+ struct frame_info *thisframe;
+{
+ return ((chain) != 0
+ && !inside_main_func ((thisframe) -> pc)
+ && !inside_entry_func ((thisframe) -> pc));
+}
+
+/* Use the alternate method of avoiding running up off the end of the
+ frame chain or following frames back into the startup code. See
+ the comments in objfiles.h. */
+
+int
+alternate_frame_chain_valid (chain, thisframe)
+ CORE_ADDR chain;
+ struct frame_info *thisframe;
+{
+ return ((chain) != 0
+ && !inside_entry_file (FRAME_SAVED_PC (thisframe)));
+}
+
+/* A very simple method of determining a valid frame */
+
+int
+nonnull_frame_chain_valid (chain, thisframe)
+ CORE_ADDR chain;
+ struct frame_info *thisframe;
+{
+ return ((chain) != 0);
+}
+
/* Is ADDR inside the startup file? Note that if your machine
has a way to detect the bottom of the stack, there is no need
to call this function from FRAME_CHAIN_VALID; the reason for
@@ -50,7 +91,8 @@ inside_entry_file (addr)
#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT
/* Do not stop backtracing if the pc is in the call dummy
at the entry point. */
- if (PC_IN_CALL_DUMMY (addr, 0, 0))
+/* FIXME: Won't always work with zeros for the last two arguments */
+ if (PC_IN_CALL_DUMMY (addr, 0, 0))
return 0;
#endif
return (addr >= symfile_objfile -> ei.entry_file_lowpc &&
@@ -69,7 +111,6 @@ int
inside_main_func (pc)
CORE_ADDR pc;
{
-struct symbol *mainsym;
if (pc == 0)
return 1;
if (symfile_objfile == 0)
@@ -82,13 +123,16 @@ struct symbol *mainsym;
if (symfile_objfile -> ei.main_func_lowpc == INVALID_ENTRY_LOWPC &&
symfile_objfile -> ei.main_func_highpc == INVALID_ENTRY_HIGHPC)
{
+ struct symbol *mainsym;
+
mainsym = lookup_symbol ("main", NULL, VAR_NAMESPACE, NULL, NULL);
if (mainsym && SYMBOL_CLASS(mainsym) == LOC_BLOCK)
{
- symfile_objfile->ei.main_func_lowpc = BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym));
- symfile_objfile->ei.main_func_highpc = BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym));
+ symfile_objfile->ei.main_func_lowpc =
+ BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym));
+ symfile_objfile->ei.main_func_highpc =
+ BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym));
}
-
}
return (symfile_objfile -> ei.main_func_lowpc <= pc &&
symfile_objfile -> ei.main_func_highpc > pc);
@@ -113,6 +157,7 @@ CORE_ADDR pc;
#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT
/* Do not stop backtracing if the pc is in the call dummy
at the entry point. */
+/* FIXME: Won't always work with zeros for the last two arguments */
if (PC_IN_CALL_DUMMY (pc, 0, 0))
return 0;
#endif
@@ -128,7 +173,24 @@ static struct frame_info *current_frame;
inferior is stopped. Control variables for the frame cache should
be local to this module. */
-struct obstack frame_cache_obstack;
+static struct obstack frame_cache_obstack;
+
+void *
+frame_obstack_alloc (size)
+ unsigned long size;
+{
+ return obstack_alloc (&frame_cache_obstack, size);
+}
+
+void
+frame_saved_regs_zalloc (fi)
+ struct frame_info *fi;
+{
+ fi->saved_regs = (CORE_ADDR*)
+ frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
+ memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+}
+
/* Return the innermost (currently executing) stack frame. */
@@ -168,6 +230,7 @@ create_new_frame (addr, pc)
sizeof (struct frame_info));
/* Arbitrary frame */
+ fi->saved_regs = NULL;
fi->next = NULL;
fi->prev = NULL;
fi->frame = addr;
@@ -244,9 +307,10 @@ frameless_look_for_prologue (frame)
struct frame_info *frame;
{
CORE_ADDR func_start, after_prologue;
- func_start = (get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET);
+ func_start = get_pc_function_start (frame->pc);
if (func_start)
{
+ func_start += FUNCTION_START_OFFSET;
after_prologue = func_start;
#ifdef SKIP_PROLOGUE_FRAMELESS_P
/* This is faster, since only care whether there *is* a prologue,
@@ -257,6 +321,12 @@ frameless_look_for_prologue (frame)
#endif
return after_prologue == func_start;
}
+ else if (frame->pc == 0)
+ /* A frame with a zero PC is usually created by dereferencing a NULL
+ function pointer, normally causing an immediate core dump of the
+ inferior. Mark function as frameless, as the inferior has no chance
+ of setting up a stack frame. */
+ return 1;
else
/* If we can't find the start of the function, we don't really
know whether the function is frameless, but we should be able
@@ -358,6 +428,7 @@ get_prev_frame_info (next_frame)
obstack_alloc (&frame_cache_obstack,
sizeof (struct frame_info));
+ prev->saved_regs = NULL;
if (next_frame)
next_frame->prev = prev;
prev->next = next_frame;
@@ -449,7 +520,10 @@ get_frame_pc (frame)
return frame->pc;
}
-#if defined (FRAME_FIND_SAVED_REGS)
+
+#ifdef FRAME_FIND_SAVED_REGS
+/* XXX - deprecated. This is a compatibility function for targets
+ that do not yet implement FRAME_INIT_SAVED_REGS. */
/* Find the addresses in which registers are saved in FRAME. */
void
@@ -457,7 +531,22 @@ get_frame_saved_regs (frame, saved_regs_addr)
struct frame_info *frame;
struct frame_saved_regs *saved_regs_addr;
{
- FRAME_FIND_SAVED_REGS (frame, *saved_regs_addr);
+ if (frame->saved_regs == NULL)
+ {
+ frame->saved_regs = (CORE_ADDR*)
+ frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
+ }
+ if (saved_regs_addr == NULL)
+ {
+ struct frame_saved_regs saved_regs;
+ FRAME_FIND_SAVED_REGS (frame, saved_regs);
+ memcpy (frame->saved_regs, &saved_regs, SIZEOF_FRAME_SAVED_REGS);
+ }
+ else
+ {
+ FRAME_FIND_SAVED_REGS (frame, *saved_regs_addr);
+ memcpy (frame->saved_regs, saved_regs_addr, SIZEOF_FRAME_SAVED_REGS);
+ }
}
#endif
@@ -526,27 +615,32 @@ get_frame_function (frame)
return block_function (bl);
}
+
/* Return the blockvector immediately containing the innermost lexical block
- containing the specified pc value, or 0 if there is none.
+ containing the specified pc value and section, or 0 if there is none.
PINDEX is a pointer to the index value of the block. If PINDEX
is NULL, we don't pass this information back to the caller. */
struct blockvector *
-blockvector_for_pc (pc, pindex)
+blockvector_for_pc_sect (pc, section, pindex, symtab)
register CORE_ADDR pc;
+ struct sec *section;
int *pindex;
+ struct symtab *symtab;
+
{
register struct block *b;
register int bot, top, half;
- register struct symtab *s;
struct blockvector *bl;
- /* First search all symtabs for one whose file contains our pc */
- s = find_pc_symtab (pc);
- if (s == 0)
- return 0;
+ if (symtab == 0) /* if no symtab specified by caller */
+ {
+ /* First search all symtabs for one whose file contains our pc */
+ if ((symtab = find_pc_sect_symtab (pc, section)) == 0)
+ return 0;
+ }
- bl = BLOCKVECTOR (s);
+ bl = BLOCKVECTOR (symtab);
b = BLOCKVECTOR_BLOCK (bl, 0);
/* Then search that symtab for the smallest block that wins. */
@@ -570,7 +664,7 @@ blockvector_for_pc (pc, pindex)
while (bot >= 0)
{
b = BLOCKVECTOR_BLOCK (bl, bot);
- if (BLOCK_END (b) > pc)
+ if (BLOCK_END (b) >= pc)
{
if (pindex)
*pindex = bot;
@@ -578,45 +672,80 @@ blockvector_for_pc (pc, pindex)
}
bot--;
}
-
return 0;
}
-/* Return the innermost lexical block containing the specified pc value,
- or 0 if there is none. */
+/* Return the blockvector immediately containing the innermost lexical block
+ containing the specified pc value, or 0 if there is none.
+ Backward compatibility, no section. */
+
+struct blockvector *
+blockvector_for_pc (pc, pindex)
+ register CORE_ADDR pc;
+ int *pindex;
+{
+ return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
+ pindex, NULL);
+}
+
+/* Return the innermost lexical block containing the specified pc value
+ in the specified section, or 0 if there is none. */
struct block *
-block_for_pc (pc)
+block_for_pc_sect (pc, section)
register CORE_ADDR pc;
+ struct sec *section;
{
register struct blockvector *bl;
int index;
- bl = blockvector_for_pc (pc, &index);
+ bl = blockvector_for_pc_sect (pc, section, &index, NULL);
if (bl)
return BLOCKVECTOR_BLOCK (bl, index);
return 0;
}
-/* Return the function containing pc value PC.
+/* Return the innermost lexical block containing the specified pc value,
+ or 0 if there is none. Backward compatibility, no section. */
+
+struct block *
+block_for_pc (pc)
+ register CORE_ADDR pc;
+{
+ return block_for_pc_sect (pc, find_pc_mapped_section (pc));
+}
+
+/* Return the function containing pc value PC in section SECTION.
Returns 0 if function is not known. */
struct symbol *
-find_pc_function (pc)
+find_pc_sect_function (pc, section)
CORE_ADDR pc;
+ struct sec *section;
{
- register struct block *b = block_for_pc (pc);
+ register struct block *b = block_for_pc_sect (pc, section);
if (b == 0)
return 0;
return block_function (b);
}
+/* Return the function containing pc value PC.
+ Returns 0 if function is not known. Backward compatibility, no section */
+
+struct symbol *
+find_pc_function (pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_function (pc, find_pc_mapped_section (pc));
+}
+
/* These variables are used to cache the most recent result
* of find_pc_partial_function. */
-static CORE_ADDR cache_pc_function_low = 0;
-static CORE_ADDR cache_pc_function_high = 0;
-static char *cache_pc_function_name = 0;
+static CORE_ADDR cache_pc_function_low = 0;
+static CORE_ADDR cache_pc_function_high = 0;
+static char *cache_pc_function_name = 0;
+static struct sec *cache_pc_function_section = NULL;
/* Clear cache, e.g. when symbol table is discarded. */
@@ -626,50 +755,58 @@ clear_pc_function_cache()
cache_pc_function_low = 0;
cache_pc_function_high = 0;
cache_pc_function_name = (char *)0;
+ cache_pc_function_section = NULL;
}
/* Finds the "function" (text symbol) that is smaller than PC but
- greatest of all of the potential text symbols. Sets *NAME and/or
- *ADDRESS conditionally if that pointer is non-null. If ENDADDR is
- non-null, then set *ENDADDR to be the end of the function
- (exclusive), but passing ENDADDR as non-null means that the
- function might cause symbols to be read. This function either
+ greatest of all of the potential text symbols in SECTION. Sets
+ *NAME and/or *ADDRESS conditionally if that pointer is non-null.
+ If ENDADDR is non-null, then set *ENDADDR to be the end of the
+ function (exclusive), but passing ENDADDR as non-null means that
+ the function might cause symbols to be read. This function either
succeeds or fails (not halfway succeeds). If it succeeds, it sets
*NAME, *ADDRESS, and *ENDADDR to real information and returns 1.
- If it fails, it sets *NAME, *ADDRESS, and *ENDADDR to zero
- and returns 0. */
+ If it fails, it sets *NAME, *ADDRESS, and *ENDADDR to zero and
+ returns 0. */
int
-find_pc_partial_function (pc, name, address, endaddr)
- CORE_ADDR pc;
- char **name;
+find_pc_sect_partial_function (pc, section, name, address, endaddr)
+ CORE_ADDR pc;
+ asection *section;
+ char **name;
CORE_ADDR *address;
CORE_ADDR *endaddr;
{
struct partial_symtab *pst;
- struct symbol *f;
+ struct symbol *f;
struct minimal_symbol *msymbol;
struct partial_symbol *psb;
- struct obj_section *sec;
+ struct obj_section *osect;
+ int i;
+ CORE_ADDR mapped_pc;
+
+ mapped_pc = overlay_mapped_address (pc, section);
- if (pc >= cache_pc_function_low && pc < cache_pc_function_high)
+ if (mapped_pc >= cache_pc_function_low &&
+ mapped_pc < cache_pc_function_high &&
+ section == cache_pc_function_section)
goto return_cached_value;
/* If sigtramp is in the u area, it counts as a function (especially
important for step_1). */
#if defined SIGTRAMP_START
- if (IN_SIGTRAMP (pc, (char *)NULL))
+ if (IN_SIGTRAMP (mapped_pc, (char *)NULL))
{
- cache_pc_function_low = SIGTRAMP_START;
- cache_pc_function_high = SIGTRAMP_END;
- cache_pc_function_name = "<sigtramp>";
-
+ cache_pc_function_low = SIGTRAMP_START (mapped_pc);
+ cache_pc_function_high = SIGTRAMP_END (mapped_pc);
+ cache_pc_function_name = "<sigtramp>";
+ cache_pc_function_section = section;
goto return_cached_value;
}
#endif
- msymbol = lookup_minimal_symbol_by_pc (pc);
- pst = find_pc_psymtab (pc);
+ msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
+ pst = find_pc_sect_psymtab (mapped_pc, section);
if (pst)
{
/* Need to read the symbols to get a good value for the end address. */
@@ -685,15 +822,16 @@ find_pc_partial_function (pc, name, address, endaddr)
{
/* Checking whether the msymbol has a larger value is for the
"pathological" case mentioned in print_frame_info. */
- f = find_pc_function (pc);
+ f = find_pc_sect_function (mapped_pc, section);
if (f != NULL
&& (msymbol == NULL
|| (BLOCK_START (SYMBOL_BLOCK_VALUE (f))
>= SYMBOL_VALUE_ADDRESS (msymbol))))
{
- cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
- cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
- cache_pc_function_name = SYMBOL_NAME (f);
+ cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
+ cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
+ cache_pc_function_name = SYMBOL_NAME (f);
+ cache_pc_function_section = section;
goto return_cached_value;
}
}
@@ -702,7 +840,7 @@ find_pc_partial_function (pc, name, address, endaddr)
/* Now that static symbols go in the minimal symbol table, perhaps
we could just ignore the partial symbols. But at least for now
we use the partial or minimal symbol, whichever is larger. */
- psb = find_pc_psymbol (pst, pc);
+ psb = find_pc_sect_psymbol (pst, mapped_pc, section);
if (psb
&& (msymbol == NULL ||
@@ -725,9 +863,9 @@ find_pc_partial_function (pc, name, address, endaddr)
of the text seg doesn't appear to be part of the last function in the
text segment. */
- sec = find_pc_section (pc);
+ osect = find_pc_sect_section (mapped_pc, section);
- if (!sec)
+ if (!osect)
msymbol = NULL;
/* Must be in the minimal symbol table. */
@@ -743,30 +881,79 @@ find_pc_partial_function (pc, name, address, endaddr)
return 0;
}
- cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
- cache_pc_function_name = SYMBOL_NAME (msymbol);
+ cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
+ cache_pc_function_name = SYMBOL_NAME (msymbol);
+ cache_pc_function_section = section;
+
+ /* Use the lesser of the next minimal symbol in the same section, or
+ the end of the section, as the end of the function. */
+
+ /* Step over other symbols at this same address, and symbols in
+ other sections, to find the next symbol in this section with
+ a different address. */
- /* Use the lesser of the next minimal symbol, or the end of the section, as
- the end of the function. */
+ for (i=1; SYMBOL_NAME (msymbol+i) != NULL; i++)
+ {
+ if (SYMBOL_VALUE_ADDRESS (msymbol+i) != SYMBOL_VALUE_ADDRESS (msymbol)
+ && SYMBOL_BFD_SECTION (msymbol+i) == SYMBOL_BFD_SECTION (msymbol))
+ break;
+ }
- if (SYMBOL_NAME (msymbol + 1) != NULL
- && SYMBOL_VALUE_ADDRESS (msymbol + 1) < sec->endaddr)
- cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + 1);
+ if (SYMBOL_NAME (msymbol + i) != NULL
+ && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
+ cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
else
/* We got the start address from the last msymbol in the objfile.
So the end address is the end of the section. */
- cache_pc_function_high = sec->endaddr;
+ cache_pc_function_high = osect->endaddr;
return_cached_value:
+
if (address)
- *address = cache_pc_function_low;
+ {
+ if (pc_in_unmapped_range (pc, section))
+ *address = overlay_unmapped_address (cache_pc_function_low, section);
+ else
+ *address = cache_pc_function_low;
+ }
+
if (name)
*name = cache_pc_function_name;
+
if (endaddr)
- *endaddr = cache_pc_function_high;
+ {
+ if (pc_in_unmapped_range (pc, section))
+ {
+ /* Because the high address is actually beyond the end of
+ the function (and therefore possibly beyond the end of
+ the overlay), we must actually convert (high - 1)
+ and then add one to that. */
+
+ *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
+ section);
+ }
+ else
+ *endaddr = cache_pc_function_high;
+ }
+
return 1;
}
+/* Backward compatibility, no section argument */
+
+int
+find_pc_partial_function (pc, name, address, endaddr)
+ CORE_ADDR pc;
+ char **name;
+ CORE_ADDR *address;
+ CORE_ADDR *endaddr;
+{
+ asection *section;
+
+ section = find_pc_overlay (pc);
+ return find_pc_sect_partial_function (pc, section, name, address, endaddr);
+}
+
/* Return the innermost stack frame executing inside of BLOCK,
or NULL if there is no such frame. If BLOCK is NULL, just return NULL. */
@@ -847,6 +1034,266 @@ sigtramp_saved_pc (frame)
}
#endif /* SIGCONTEXT_PC_OFFSET */
+#ifdef USE_GENERIC_DUMMY_FRAMES
+
+/*
+ * GENERIC DUMMY FRAMES
+ *
+ * The following code serves to maintain the dummy stack frames for
+ * inferior function calls (ie. when gdb calls into the inferior via
+ * call_function_by_hand). This code saves the machine state before
+ * the call in host memory, so we must maintain an independant stack
+ * and keep it consistant etc. I am attempting to make this code
+ * generic enough to be used by many targets.
+ *
+ * The cheapest and most generic way to do CALL_DUMMY on a new target
+ * is probably to define CALL_DUMMY to be empty, CALL_DUMMY_LENGTH to
+ * zero, and CALL_DUMMY_LOCATION to AT_ENTRY. Then you must remember
+ * to define PUSH_RETURN_ADDRESS, because no call instruction will be
+ * being executed by the target. Also FRAME_CHAIN_VALID as
+ * generic_frame_chain_valid. */
+
+static struct dummy_frame *dummy_frame_stack = NULL;
+
+/* Function: find_dummy_frame(pc, fp, sp)
+ Search the stack of dummy frames for one matching the given PC, FP and SP.
+ This is the work-horse for pc_in_call_dummy and read_register_dummy */
+
+char *
+generic_find_dummy_frame (pc, fp)
+ CORE_ADDR pc;
+ CORE_ADDR fp;
+{
+ struct dummy_frame * dummyframe;
+
+ if (pc != entry_point_address ())
+ return 0;
+
+ for (dummyframe = dummy_frame_stack; dummyframe != NULL;
+ dummyframe = dummyframe->next)
+ if (fp == dummyframe->fp || fp == dummyframe->sp)
+ /* The frame in question lies between the saved fp and sp, inclusive */
+ return dummyframe->regs;
+
+ return 0;
+}
+
+/* Function: pc_in_call_dummy (pc, fp)
+ Return true if this is a dummy frame created by gdb for an inferior call */
+
+int
+generic_pc_in_call_dummy (pc, fp)
+ CORE_ADDR pc;
+ CORE_ADDR fp;
+{
+ /* if find_dummy_frame succeeds, then PC is in a call dummy */
+ return (generic_find_dummy_frame (pc, fp) != 0);
+}
+
+/* Function: read_register_dummy
+ Find a saved register from before GDB calls a function in the inferior */
+
+CORE_ADDR
+generic_read_register_dummy (pc, fp, regno)
+ CORE_ADDR pc;
+ CORE_ADDR fp;
+ int regno;
+{
+ char *dummy_regs = generic_find_dummy_frame (pc, fp);
+
+ if (dummy_regs)
+ return extract_address (&dummy_regs[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE(regno));
+ else
+ return 0;
+}
+
+/* Save all the registers on the dummy frame stack. Most ports save the
+ registers on the target stack. This results in lots of unnecessary memory
+ references, which are slow when debugging via a serial line. Instead, we
+ save all the registers internally, and never write them to the stack. The
+ registers get restored when the called function returns to the entry point,
+ where a breakpoint is laying in wait. */
+
+void
+generic_push_dummy_frame ()
+{
+ struct dummy_frame *dummy_frame;
+ CORE_ADDR fp = (get_current_frame ())->frame;
+
+ /* check to see if there are stale dummy frames,
+ perhaps left over from when a longjump took us out of a
+ function that was called by the debugger */
+
+ dummy_frame = dummy_frame_stack;
+ while (dummy_frame)
+ if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */
+ {
+ dummy_frame_stack = dummy_frame->next;
+ free (dummy_frame);
+ dummy_frame = dummy_frame_stack;
+ }
+ else
+ dummy_frame = dummy_frame->next;
+
+ dummy_frame = xmalloc (sizeof (struct dummy_frame));
+ dummy_frame->pc = read_register (PC_REGNUM);
+ dummy_frame->sp = read_register (SP_REGNUM);
+ dummy_frame->fp = fp;
+ read_register_bytes (0, dummy_frame->regs, REGISTER_BYTES);
+ dummy_frame->next = dummy_frame_stack;
+ dummy_frame_stack = dummy_frame;
+}
+
+/* Function: pop_frame
+ Restore the machine state from either the saved dummy stack or a
+ real stack frame. */
+
+void
+generic_pop_current_frame (pop)
+ void (*pop) PARAMS ((struct frame_info *frame));
+{
+ struct frame_info *frame = get_current_frame ();
+ if (PC_IN_CALL_DUMMY(frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ pop (frame);
+}
+
+/* Function: pop_dummy_frame
+ Restore the machine state from a saved dummy stack frame. */
+
+void
+generic_pop_dummy_frame ()
+{
+ struct dummy_frame *dummy_frame = dummy_frame_stack;
+
+ /* FIXME: what if the first frame isn't the right one, eg..
+ because one call-by-hand function has done a longjmp into another one? */
+
+ if (!dummy_frame)
+ error ("Can't pop dummy frame!");
+ dummy_frame_stack = dummy_frame->next;
+ write_register_bytes (0, dummy_frame->regs, REGISTER_BYTES);
+ flush_cached_frames ();
+ free (dummy_frame);
+}
+
+/* Function: frame_chain_valid
+ Returns true for a user frame or a call_function_by_hand dummy frame,
+ and false for the CRT0 start-up frame. Purpose is to terminate backtrace */
+
+int
+generic_frame_chain_valid (fp, fi)
+ CORE_ADDR fp;
+ struct frame_info *fi;
+{
+ if (PC_IN_CALL_DUMMY(FRAME_SAVED_PC(fi), fp, fp))
+ return 1; /* don't prune CALL_DUMMY frames */
+ else /* fall back to default algorithm (see frame.h) */
+ return (fp != 0
+ && (INNER_THAN (fi->frame, fp) || fi->frame == fp)
+ && !inside_entry_file (FRAME_SAVED_PC(fi)));
+}
+
+/* Function: get_saved_register
+ Find register number REGNUM relative to FRAME and put its (raw,
+ target format) contents in *RAW_BUFFER.
+
+ Set *OPTIMIZED if the variable was optimized out (and thus can't be
+ fetched). Note that this is never set to anything other than zero
+ in this implementation.
+
+ Set *LVAL to lval_memory, lval_register, or not_lval, depending on
+ whether the value was fetched from memory, from a register, or in a
+ strange and non-modifiable way (e.g. a frame pointer which was
+ calculated rather than fetched). We will use not_lval for values
+ fetched from generic dummy frames.
+
+ Set *ADDRP to the address, either in memory on as a REGISTER_BYTE
+ offset into the registers array. If the value is stored in a dummy
+ frame, set *ADDRP to zero.
+
+ To use this implementation, define a function called
+ "get_saved_register" in your target code, which simply passes all
+ of its arguments to this function.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+
+void
+generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+ char *raw_buffer;
+ int *optimized;
+ CORE_ADDR *addrp;
+ struct frame_info *frame;
+ int regnum;
+ enum lval_type *lval;
+{
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+
+ if (addrp) /* default assumption: not found in memory */
+ *addrp = 0;
+
+ /* Note: since the current frame's registers could only have been
+ saved by frames INTERIOR TO the current frame, we skip examining
+ the current frame itself: otherwise, we would be getting the
+ previous frame's registers which were saved by the current frame. */
+
+ while (frame && ((frame = frame->next) != NULL))
+ {
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ if (lval) /* found it in a CALL_DUMMY frame */
+ *lval = not_lval;
+ if (raw_buffer)
+ memcpy (raw_buffer,
+ generic_find_dummy_frame (frame->pc, frame->frame) +
+ REGISTER_BYTE (regnum),
+ REGISTER_RAW_SIZE (regnum));
+ return;
+ }
+
+ FRAME_INIT_SAVED_REGS (frame);
+ if (frame->saved_regs != NULL
+ && frame->saved_regs[regnum] != 0)
+ {
+ if (lval) /* found it saved on the stack */
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer) /* SP register treated specially */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ frame->saved_regs[regnum]);
+ }
+ else
+ {
+ if (addrp) /* any other register */
+ *addrp = frame->saved_regs[regnum];
+ if (raw_buffer)
+ read_memory (frame->saved_regs[regnum], raw_buffer,
+ REGISTER_RAW_SIZE (regnum));
+ }
+ return;
+ }
+ }
+
+ /* If we get thru the loop to this point, it means the register was
+ not saved in any frame. Return the actual live-register value. */
+
+ if (lval) /* found it in a live register */
+ *lval = lval_register;
+ if (addrp)
+ *addrp = REGISTER_BYTE (regnum);
+ if (raw_buffer)
+ read_register_gen (regnum, raw_buffer);
+}
+#endif /* USE_GENERIC_DUMMY_FRAMES */
+
void
_initialize_blockframe ()
{
diff --git a/contrib/gdb/gdb/breakpoint.c b/contrib/gdb/gdb/breakpoint.c
index 3930e7a..4b05949 100644
--- a/contrib/gdb/gdb/breakpoint.c
+++ b/contrib/gdb/gdb/breakpoint.c
@@ -1,5 +1,5 @@
/* Everything about breakpoints, for GDB.
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,14 +30,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "value.h"
#include "command.h"
#include "inferior.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "target.h"
#include "language.h"
#include "gdb_string.h"
#include "demangle.h"
#include "annotate.h"
+#include "symfile.h"
+#include "objfiles.h"
-/* local function prototypes */
+/* Prototypes for local functions. */
static void
catch_command_1 PARAMS ((char *, int, int));
@@ -66,11 +68,7 @@ map_breakpoint_numbers PARAMS ((char *, void (*)(struct breakpoint *)));
static void
ignore_command PARAMS ((char *, int));
-static int
-breakpoint_re_set_one PARAMS ((char *));
-
-static void
-delete_command PARAMS ((char *, int));
+static int breakpoint_re_set_one PARAMS ((PTR));
static void
clear_command PARAMS ((char *, int));
@@ -78,6 +76,9 @@ clear_command PARAMS ((char *, int));
static void
catch_command PARAMS ((char *, int));
+static void
+handle_gnu_4_16_catch_command PARAMS ((char *, int, int));
+
static struct symtabs_and_lines
get_catch_sals PARAMS ((int));
@@ -87,7 +88,7 @@ watch_command PARAMS ((char *, int));
static int
can_use_hardware_watchpoint PARAMS ((struct value *));
-static void
+void
tbreak_command PARAMS ((char *, int));
static void
@@ -96,14 +97,14 @@ break_command_1 PARAMS ((char *, int, int));
static void
mention PARAMS ((struct breakpoint *));
-static struct breakpoint *
+struct breakpoint *
set_raw_breakpoint PARAMS ((struct symtab_and_line));
static void
-check_duplicates PARAMS ((CORE_ADDR));
+check_duplicates PARAMS ((CORE_ADDR, asection *));
static void
-describe_other_breakpoints PARAMS ((CORE_ADDR));
+describe_other_breakpoints PARAMS ((CORE_ADDR, asection *));
static void
breakpoints_info PARAMS ((char *, int));
@@ -114,11 +115,10 @@ breakpoint_1 PARAMS ((int, int));
static bpstat
bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
-static int
-breakpoint_cond_eval PARAMS ((char *));
+static int breakpoint_cond_eval PARAMS ((PTR));
static void
-cleanup_executing_breakpoints PARAMS ((int));
+cleanup_executing_breakpoints PARAMS ((PTR));
static void
commands_command PARAMS ((char *, int));
@@ -129,14 +129,83 @@ condition_command PARAMS ((char *, int));
static int
get_number PARAMS ((char **));
-static void
+void
set_breakpoint_count PARAMS ((int));
+#if 0
+static struct breakpoint *
+create_temp_exception_breakpoint PARAMS ((CORE_ADDR));
+#endif
+
+typedef enum {
+ mark_inserted,
+ mark_uninserted
+} insertion_state_t;
+
static int
-remove_breakpoint PARAMS ((struct breakpoint *));
+remove_breakpoint PARAMS ((struct breakpoint *, insertion_state_t));
+
+static int print_it_normal PARAMS ((bpstat));
+
+typedef struct {
+ enum exception_event_kind kind;
+ int enable;
+} args_for_catchpoint_enable;
+
+static int watchpoint_check PARAMS ((PTR));
+
+static int cover_target_enable_exception_callback PARAMS ((PTR));
+
+static int print_it_done PARAMS ((bpstat));
+
+static int print_it_noop PARAMS ((bpstat));
+
+static void maintenance_info_breakpoints PARAMS ((char *, int));
+
+#ifdef GET_LONGJMP_TARGET
+static void create_longjmp_breakpoint PARAMS ((char *));
+#endif
+
+static int hw_breakpoint_used_count PARAMS ((void));
+
+static int hw_watchpoint_used_count PARAMS ((enum bptype, int *));
+
+static void hbreak_command PARAMS ((char *, int));
+
+static void thbreak_command PARAMS ((char *, int));
+
+static void watch_command_1 PARAMS ((char *, int, int));
+
+static void rwatch_command PARAMS ((char *, int));
+
+static void awatch_command PARAMS ((char *, int));
+
+static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
+
+/* Prototypes for exported functions. */
+
+static void
+awatch_command PARAMS ((char *, int));
+
+static void
+do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
+
+/* If FALSE, gdb will not use hardware support for watchpoints, even
+ if such is available. */
+static int can_use_hw_watchpoints;
+
+void delete_command PARAMS ((char *, int));
+
+void _initialize_breakpoint PARAMS ((void));
+
+void set_breakpoint_count PARAMS ((int));
extern int addressprint; /* Print machine addresses? */
+#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD)
+static int internal_breakpoint_number = -1;
+#endif
+
/* Are we executing breakpoint commands? */
static int executing_breakpoint_commands;
@@ -151,6 +220,16 @@ static int executing_breakpoint_commands;
b? (tmp=b->next, 1): 0; \
b = tmp)
+/* True if SHIFT_INST_REGS defined, false otherwise. */
+
+int must_shift_inst_regs =
+#if defined(SHIFT_INST_REGS)
+1
+#else
+0
+#endif
+;
+
/* True if breakpoint hit counts should be displayed in breakpoint info. */
int show_breakpoint_hit_counts = 1;
@@ -161,11 +240,75 @@ struct breakpoint *breakpoint_chain;
/* Number of last breakpoint made. */
-static int breakpoint_count;
+int breakpoint_count;
+
+/* Pointer to current exception event record */
+static struct exception_event_record * current_exception_event;
+
+/* Indicator of whether exception catchpoints should be nuked
+ between runs of a program */
+int exception_catchpoints_are_fragile = 0;
+
+/* Indicator of when exception catchpoints set-up should be
+ reinitialized -- e.g. when program is re-run */
+int exception_support_initialized = 0;
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been
+ loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the
+ inferior has stopped in the dynamic linker hook, and becomes
+ invalid as soon as the inferior is continued. Clients should make
+ a copy of this string if they wish to continue the inferior and
+ then access the string. */
+
+#ifndef SOLIB_LOADED_LIBRARY_PATHNAME
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) ""
+#endif
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been
+ unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is
+ TRUE, or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the
+ inferior has stopped in the dynamic linker hook, and becomes
+ invalid as soon as the inferior is continued. Clients should make
+ a copy of this string if they wish to continue the inferior and
+ then access the string. */
+
+#ifndef SOLIB_UNLOADED_LIBRARY_PATHNAME
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) ""
+#endif
+
+/* This function is called by the "catch load" command. It allows the
+ debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded. */
+
+#ifndef SOLIB_CREATE_CATCH_LOAD_HOOK
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error ("catch of library loads not yet implemented on this platform")
+#endif
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is
+ unloaded. */
+
+#ifndef SOLIB_CREATE_CATCH_UNLOAD_HOOK
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error ("catch of library unloads not yet implemented on this platform")
+#endif
/* Set breakpoint count to NUM. */
-static void
+void
set_breakpoint_count (num)
int num;
{
@@ -330,10 +473,9 @@ commands_command (arg, from_tty)
ALL_BREAKPOINTS (b)
if (b->number == bnum)
{
- if (from_tty && input_from_terminal_p ())
- printf_filtered ("Type commands for when breakpoint %d is hit, one per line.\n\
-End with a line saying just \"end\".\n", bnum);
- l = read_command_lines ();
+ char tmpbuf[128];
+ sprintf (tmpbuf, "Type commands for when breakpoint %d is hit, one per line.", bnum);
+ l = read_command_lines (tmpbuf, from_tty);
free_command_lines (&b->commands);
b->commands = l;
breakpoints_changed ();
@@ -342,8 +484,6 @@ End with a line saying just \"end\".\n", bnum);
error ("No breakpoint number %d.", bnum);
}
-extern int memory_breakpoint_size; /* from mem-break.c */
-
/* Like target_read_memory() but if breakpoints are inserted, return
the shadow contents instead of the breakpoints themselves.
@@ -360,84 +500,96 @@ read_memory_nobpt (memaddr, myaddr, len)
{
int status;
struct breakpoint *b;
+ CORE_ADDR bp_addr = 0;
+ int bp_size = 0;
- if (memory_breakpoint_size < 0)
- /* No breakpoints on this machine. FIXME: This should be
- dependent on the debugging target. Probably want
- target_insert_breakpoint to return a size, saying how many
- bytes of the shadow contents are used, or perhaps have
- something like target_xfer_shadow. */
+ if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
+ /* No breakpoints on this machine. */
return target_read_memory (memaddr, myaddr, len);
ALL_BREAKPOINTS (b)
{
+ if (b->type == bp_none)
+ warning ("attempted to read through apparently deleted breakpoint #%d?\n", b->number);
+
+ /* memory breakpoint? */
if (b->type == bp_watchpoint
|| b->type == bp_hardware_watchpoint
|| b->type == bp_read_watchpoint
- || b->type == bp_access_watchpoint
- || !b->inserted)
+ || b->type == bp_access_watchpoint)
+ continue;
+ /* bp in memory? */
+ if (!b->inserted)
continue;
- else if (b->address + memory_breakpoint_size <= memaddr)
- /* The breakpoint is entirely before the chunk of memory
- we are reading. */
+ /* Addresses and length of the part of the breakpoint that
+ we need to copy. */
+ /* XXXX The m68k, sh and h8300 have different local and remote
+ breakpoint values. BREAKPOINT_FROM_PC still manages to
+ correctly determine the breakpoints memory address and size
+ for these targets. */
+ bp_addr = b->address;
+ bp_size = 0;
+ if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
continue;
- else if (b->address >= memaddr + len)
- /* The breakpoint is entirely after the chunk of memory we
+ if (bp_size == 0)
+ /* bp isn't valid */
+ continue;
+ if (bp_addr + bp_size <= memaddr)
+ /* The breakpoint is entirely before the chunk of memory we
are reading. */
continue;
- else
- {
- /* Copy the breakpoint from the shadow contents, and recurse
- for the things before and after. */
-
- /* Addresses and length of the part of the breakpoint that
- we need to copy. */
- CORE_ADDR membpt = b->address;
- unsigned int bptlen = memory_breakpoint_size;
- /* Offset within shadow_contents. */
- int bptoffset = 0;
+ if (bp_addr >= memaddr + len)
+ /* The breakpoint is entirely after the chunk of memory we are
+ reading. */
+ continue;
+ /* Copy the breakpoint from the shadow contents, and recurse for
+ the things before and after. */
+ {
+ /* Offset within shadow_contents. */
+ int bptoffset = 0;
- if (membpt < memaddr)
- {
- /* Only copy the second part of the breakpoint. */
- bptlen -= memaddr - membpt;
- bptoffset = memaddr - membpt;
- membpt = memaddr;
- }
-
- if (membpt + bptlen > memaddr + len)
- {
- /* Only copy the first part of the breakpoint. */
- bptlen -= (membpt + bptlen) - (memaddr + len);
- }
-
- memcpy (myaddr + membpt - memaddr,
- b->shadow_contents + bptoffset, bptlen);
-
- if (membpt > memaddr)
- {
- /* Copy the section of memory before the breakpoint. */
- status = read_memory_nobpt (memaddr, myaddr, membpt - memaddr);
- if (status != 0)
- return status;
- }
-
- if (membpt + bptlen < memaddr + len)
- {
- /* Copy the section of memory after the breakpoint. */
- status = read_memory_nobpt
- (membpt + bptlen,
- myaddr + membpt + bptlen - memaddr,
- memaddr + len - (membpt + bptlen));
- if (status != 0)
- return status;
- }
- return 0;
- }
+ if (bp_addr < memaddr)
+ {
+ /* Only copy the second part of the breakpoint. */
+ bp_size -= memaddr - bp_addr;
+ bptoffset = memaddr - bp_addr;
+ bp_addr = memaddr;
+ }
+
+ if (bp_addr + bp_size > memaddr + len)
+ {
+ /* Only copy the first part of the breakpoint. */
+ bp_size -= (bp_addr + bp_size) - (memaddr + len);
+ }
+
+ memcpy (myaddr + bp_addr - memaddr,
+ b->shadow_contents + bptoffset, bp_size);
+
+ if (bp_addr > memaddr)
+ {
+ /* Copy the section of memory before the breakpoint. */
+ status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+ if (status != 0)
+ return status;
+ }
+
+ if (bp_addr + bp_size < memaddr + len)
+ {
+ /* Copy the section of memory after the breakpoint. */
+ status = read_memory_nobpt
+ (bp_addr + bp_size,
+ myaddr + bp_addr + bp_size - memaddr,
+ memaddr + len - (bp_addr + bp_size));
+ if (status != 0)
+ return status;
+ }
+ return 0;
+ }
}
/* Nothing overlaps. Just call read_memory_noerr. */
return target_read_memory (memaddr, myaddr, len);
}
+
/* insert_breakpoints is used when starting or continuing the program.
remove_breakpoints is used when the program stops.
@@ -451,138 +603,258 @@ insert_breakpoints ()
int val = 0;
int disabled_breaks = 0;
+ static char message1[] = "Error inserting catchpoint %d:\n";
+ static char message[sizeof (message1) + 30];
+
+
ALL_BREAKPOINTS_SAFE (b, temp)
- if (b->type != bp_watchpoint
- && b->type != bp_hardware_watchpoint
- && b->type != bp_read_watchpoint
- && b->type != bp_access_watchpoint
- && b->enable != disabled
- && b->enable != shlib_disabled
- && ! b->inserted
- && ! b->duplicate)
- {
- if (b->type == bp_hardware_breakpoint)
- val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
- else
- val = target_insert_breakpoint(b->address, b->shadow_contents);
- if (val)
- {
- /* Can't set the breakpoint. */
+ {
+ if (b->type != bp_watchpoint
+ && b->type != bp_hardware_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_throw
+ && b->type != bp_catch_catch
+ && b->enable != disabled
+ && b->enable != shlib_disabled
+ && b->enable != call_disabled
+ && ! b->inserted
+ && ! b->duplicate)
+ {
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
+ else
+ {
+ /* Check to see if breakpoint is in an overlay section;
+ if so, we should set the breakpoint at the LMA address.
+ Only if the section is currently mapped should we ALSO
+ set a break at the VMA address. */
+ if (overlay_debugging && b->section &&
+ section_is_overlay (b->section))
+ {
+ CORE_ADDR addr;
+
+ addr = overlay_unmapped_address (b->address, b->section);
+ val = target_insert_breakpoint (addr, b->shadow_contents);
+ /* This would be the time to check val, to see if the
+ breakpoint write to the load address succeeded.
+ However, this might be an ordinary occurrance, eg. if
+ the unmapped overlay is in ROM. */
+ val = 0; /* in case unmapped address failed */
+ if (section_is_mapped (b->section))
+ val = target_insert_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else /* ordinary (non-overlay) address */
+ val = target_insert_breakpoint(b->address, b->shadow_contents);
+ }
+ if (val)
+ {
+ /* Can't set the breakpoint. */
#if defined (DISABLE_UNSETTABLE_BREAK)
- if (DISABLE_UNSETTABLE_BREAK (b->address))
+ if (DISABLE_UNSETTABLE_BREAK (b->address))
+ {
+ /* See also: disable_breakpoints_in_shlibs. */
+ val = 0;
+ b->enable = shlib_disabled;
+ if (!disabled_breaks)
+ {
+ target_terminal_ours_for_output ();
+ fprintf_unfiltered (gdb_stderr,
+ "Cannot insert breakpoint %d:\n", b->number);
+ printf_filtered ("Temporarily disabling shared library breakpoints:\n");
+ }
+ disabled_breaks = 1;
+ printf_filtered ("%d ", b->number);
+ }
+ else
+#endif
+ {
+ target_terminal_ours_for_output ();
+ fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number);
+#ifdef ONE_PROCESS_WRITETEXT
+ fprintf_unfiltered (gdb_stderr,
+ "The same program may be running in another process.\n");
+#endif
+ memory_error (val, b->address); /* which bombs us out */
+ }
+ }
+ else
+ b->inserted = 1;
+ }
+ else if (ep_is_exception_catchpoint (b)
+ && b->enable != disabled
+ && b->enable != shlib_disabled
+ && b->enable != call_disabled
+ && ! b->inserted
+ && ! b->duplicate)
+
+ {
+ /* If we get here, we must have a callback mechanism for exception
+ events -- with g++ style embedded label support, we insert
+ ordinary breakpoints and not catchpoints. */
+ sprintf (message, message1, b->number); /* Format possible error message */
+
+ val = target_insert_breakpoint(b->address, b->shadow_contents);
+ if (val)
+ {
+ /* Couldn't set breakpoint for some reason */
+ target_terminal_ours_for_output ();
+ fprintf_unfiltered (gdb_stderr,
+ "Cannot insert catchpoint %d; disabling it\n", b->number);
+ b->enable = disabled;
+ }
+ else
+ {
+ /* Bp set, now make sure callbacks are enabled */
+ int val;
+ args_for_catchpoint_enable args;
+ args.kind = b->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW;
+ args.enable = 1;
+ val = catch_errors (cover_target_enable_exception_callback,
+ &args,
+ message, RETURN_MASK_ALL);
+ if (val != 0 && val != -1)
{
- val = 0;
- b->enable = shlib_disabled;
- if (!disabled_breaks)
- {
- target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr,
- "Cannot insert breakpoint %d:\n", b->number);
- printf_filtered ("Temporarily disabling shared library breakpoints:\n");
- }
- disabled_breaks = 1;
- printf_filtered ("%d ", b->number);
+ b->inserted = 1;
}
- else
-#endif
+ /* Check if something went wrong; val == 0 can be ignored */
+ if (val == -1)
{
+ /* something went wrong */
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number);
-#ifdef ONE_PROCESS_WRITETEXT
- fprintf_unfiltered (gdb_stderr,
- "The same program may be running in another process.\n");
-#endif
- memory_error (val, b->address); /* which bombs us out */
+ fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d; disabling it\n", b->number);
+ b->enable = disabled;
}
- }
- else
- b->inserted = 1;
+ }
}
- else if ((b->type == bp_hardware_watchpoint ||
- b->type == bp_read_watchpoint ||
- b->type == bp_access_watchpoint)
- && b->enable == enabled
- && ! b->inserted
- && ! b->duplicate)
- {
- struct frame_info *saved_frame;
- int saved_level, within_current_scope;
- value_ptr mark = value_mark ();
- value_ptr v;
-
- /* Save the current frame and level so we can restore it after
- evaluating the watchpoint expression on its own frame. */
- saved_frame = selected_frame;
- saved_level = selected_frame_level;
-
- /* Determine if the watchpoint is within scope. */
- if (b->exp_valid_block == NULL)
- within_current_scope = 1;
- else
- {
- struct frame_info *fi =
- find_frame_addr_in_frame_chain (b->watchpoint_frame);
- within_current_scope = (fi != NULL);
- if (within_current_scope)
- select_frame (fi, -1);
- }
+
+ else if ((b->type == bp_hardware_watchpoint ||
+ b->type == bp_read_watchpoint ||
+ b->type == bp_access_watchpoint)
+ && b->enable == enabled
+ && ! b->inserted
+ && ! b->duplicate)
+ {
+ struct frame_info *saved_frame;
+ int saved_level, within_current_scope;
+ value_ptr mark = value_mark ();
+ value_ptr v;
+
+ /* Save the current frame and level so we can restore it after
+ evaluating the watchpoint expression on its own frame. */
+ saved_frame = selected_frame;
+ saved_level = selected_frame_level;
+
+ /* Determine if the watchpoint is within scope. */
+ if (b->exp_valid_block == NULL)
+ within_current_scope = 1;
+ else
+ {
+ struct frame_info *fi;
+
+ /* There might be no current frame at this moment if we are
+ resuming from a step over a breakpoint.
+ Set up current frame before trying to find the watchpoint
+ frame. */
+ get_current_frame ();
+ fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
+ within_current_scope = (fi != NULL);
+ if (within_current_scope)
+ select_frame (fi, -1);
+ }
- if (within_current_scope)
- {
- /* Evaluate the expression and cut the chain of values
- produced off from the value chain. */
- v = evaluate_expression (b->exp);
- value_release_to_mark (mark);
+ if (within_current_scope)
+ {
+ /* Evaluate the expression and cut the chain of values
+ produced off from the value chain. */
+ v = evaluate_expression (b->exp);
+ value_release_to_mark (mark);
- b->val_chain = v;
- b->inserted = 1;
+ b->val_chain = v;
+ b->inserted = 1;
- /* Look at each value on the value chain. */
- for ( ; v; v=v->next)
- {
- /* If it's a memory location, then we must watch it. */
- if (v->lval == lval_memory)
- {
- int addr, len, type;
+ /* Look at each value on the value chain. */
+ for ( ; v; v=v->next)
+ {
+ /* If it's a memory location, then we must watch it. */
+ if (v->lval == lval_memory)
+ {
+ int addr, len, type;
- addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- len = TYPE_LENGTH (VALUE_TYPE (v));
- type = 0;
- if (b->type == bp_read_watchpoint)
- type = 1;
- else if (b->type == bp_access_watchpoint)
- type = 2;
-
- val = target_insert_watchpoint (addr, len, type);
- if (val == -1)
- {
- b->inserted = 0;
- break;
- }
- val = 0;
- }
- }
- /* Failure to insert a watchpoint on any memory value in the
- value chain brings us here. */
- if (!b->inserted)
- warning ("Hardware watchpoint %d: Could not insert watchpoint\n",
- b->number);
- }
- else
- {
- printf_filtered ("\
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = 0;
+ if (b->type == bp_read_watchpoint)
+ type = 1;
+ else if (b->type == bp_access_watchpoint)
+ type = 2;
+
+ val = target_insert_watchpoint (addr, len, type);
+ if (val == -1)
+ {
+ b->inserted = 0;
+ break;
+ }
+ val = 0;
+ }
+ }
+ /* Failure to insert a watchpoint on any memory value in the
+ value chain brings us here. */
+ if (!b->inserted)
+ warning ("Hardware watchpoint %d: Could not insert watchpoint\n",
+ b->number);
+ }
+ else
+ {
+ printf_filtered ("\
Hardware watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", b->number);
- if (b->related_breakpoint)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
- }
+ if (b->related_breakpoint)
+ b->related_breakpoint->disposition = del_at_next_stop;
+ b->disposition = del_at_next_stop;
+ }
- /* Restore the frame and level. */
- select_frame (saved_frame, saved_level);
- }
+ /* Restore the frame and level. */
+ if ((saved_frame != selected_frame) ||
+ (saved_level != selected_frame_level))
+ select_and_print_frame (saved_frame, saved_level);
+ }
+ else if ((b->type == bp_catch_fork
+ || b->type == bp_catch_vfork
+ || b->type == bp_catch_exec)
+ && b->enable == enabled
+ && ! b->inserted
+ && ! b->duplicate)
+ {
+ val = -1;
+ switch (b->type)
+ {
+ case bp_catch_fork :
+ val = target_insert_fork_catchpoint (inferior_pid);
+ break;
+ case bp_catch_vfork :
+ val = target_insert_vfork_catchpoint (inferior_pid);
+ break;
+ case bp_catch_exec :
+ val = target_insert_exec_catchpoint (inferior_pid);
+ break;
+ }
+ if (val < 0)
+ {
+ target_terminal_ours_for_output ();
+ fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d:\n", b->number);
+ }
+ else
+ b->inserted = 1;
+ }
+ }
if (disabled_breaks)
printf_filtered ("\n");
+
return val;
}
@@ -597,7 +869,7 @@ remove_breakpoints ()
{
if (b->inserted)
{
- val = remove_breakpoint (b);
+ val = remove_breakpoint (b, mark_uninserted);
if (val != 0)
return val;
}
@@ -605,25 +877,220 @@ remove_breakpoints ()
return 0;
}
+int
+reattach_breakpoints (pid)
+ int pid;
+{
+ register struct breakpoint *b;
+ int val;
+ int saved_inferior_pid = inferior_pid;
+
+ inferior_pid = pid; /* Because remove_breakpoint will use this global. */
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted)
+ {
+ remove_breakpoint (b, mark_inserted);
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
+ else
+ val = target_insert_breakpoint(b->address, b->shadow_contents);
+ if (val != 0)
+ {
+ inferior_pid = saved_inferior_pid;
+ return val;
+ }
+ }
+ }
+ inferior_pid = saved_inferior_pid;
+ return 0;
+}
+
+void
+update_breakpoints_after_exec ()
+{
+ struct breakpoint * b;
+ struct breakpoint * temp;
+
+ /* Doing this first prevents the badness of having delete_breakpoint()
+ write a breakpoint's current "shadow contents" to lift the bp. That
+ shadow is NOT valid after an exec()! */
+ mark_breakpoints_out ();
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ /* Solib breakpoints must be explicitly reset after an exec(). */
+ if (b->type == bp_shlib_event)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Step-resume breakpoints are meaningless after an exec(). */
+ if (b->type == bp_step_resume)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Ditto the sigtramp handler breakpoints. */
+ if (b->type == bp_through_sigtramp)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Ditto the exception-handling catchpoints. */
+ if ((b->type == bp_catch_catch) || (b->type == bp_catch_throw))
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Don't delete an exec catchpoint, because else the inferior
+ won't stop when it ought!
+
+ Similarly, we probably ought to keep vfork catchpoints, 'cause
+ on this target, we may not be able to stop when the vfork is seen,
+ but only when the subsequent exec is seen. (And because deleting
+ fork catchpoints here but not vfork catchpoints will seem mysterious
+ to users, keep those too.)
+
+ ??rehrauer: Let's hope that merely clearing out this catchpoint's
+ target address field, if any, is sufficient to have it be reset
+ automagically. Certainly on HP-UX that's true. */
+ if ((b->type == bp_catch_exec) ||
+ (b->type == bp_catch_vfork) ||
+ (b->type == bp_catch_fork))
+ {
+ b->address = (CORE_ADDR) NULL;
+ continue;
+ }
+
+ /* bp_finish is a special case. The only way we ought to be able
+ to see one of these when an exec() has happened, is if the user
+ caught a vfork, and then said "finish". Ordinarily a finish just
+ carries them to the call-site of the current callee, by setting
+ a temporary bp there and resuming. But in this case, the finish
+ will carry them entirely through the vfork & exec.
+
+ We don't want to allow a bp_finish to remain inserted now. But
+ we can't safely delete it, 'cause finish_command has a handle to
+ the bp on a bpstat, and will later want to delete it. There's a
+ chance (and I've seen it happen) that if we delete the bp_finish
+ here, that its storage will get reused by the time finish_command
+ gets 'round to deleting the "use to be a bp_finish" breakpoint.
+ We really must allow finish_command to delete a bp_finish.
+
+ In the absense of a general solution for the "how do we know it's
+ safe to delete something others may have handles to?" problem, what
+ we'll do here is just uninsert the bp_finish, and let finish_command
+ delete it.
+
+ (We know the bp_finish is "doomed" in the sense that it's momentary,
+ and will be deleted as soon as finish_command sees the inferior stopped.
+ So it doesn't matter that the bp's address is probably bogus in the
+ new a.out, unlike e.g., the solib breakpoints.) */
+ if (b->type == bp_finish)
+ {
+ continue;
+ }
+
+ /* Without a symbolic address, we have little hope of the
+ pre-exec() address meaning the same thing in the post-exec()
+ a.out. */
+ if (b->addr_string == NULL)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* If this breakpoint has survived the above battery of checks, then
+ it must have a symbolic address. Be sure that it gets reevaluated
+ to a target address, rather than reusing the old evaluation. */
+ b->address = (CORE_ADDR) NULL;
+ }
+}
+
+int
+detach_breakpoints (pid)
+ int pid;
+{
+ register struct breakpoint *b;
+ int val;
+ int saved_inferior_pid = inferior_pid;
+
+ if (pid == inferior_pid)
+ error ("Cannot detach breakpoints of inferior_pid");
+
+ inferior_pid = pid; /* Because remove_breakpoint will use this global. */
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted)
+ {
+ val = remove_breakpoint (b, mark_inserted);
+ if (val != 0)
+ {
+ inferior_pid = saved_inferior_pid;
+ return val;
+ }
+ }
+ }
+ inferior_pid = saved_inferior_pid;
+ return 0;
+}
static int
-remove_breakpoint (b)
+remove_breakpoint (b, is)
struct breakpoint *b;
+ insertion_state_t is;
{
int val;
+ if (b->type == bp_none)
+ warning ("attempted to remove apparently deleted breakpoint #%d?\n", b->number);
+
if (b->type != bp_watchpoint
&& b->type != bp_hardware_watchpoint
&& b->type != bp_read_watchpoint
- && b->type != bp_access_watchpoint)
+ && b->type != bp_access_watchpoint
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_catch
+ && b->type != bp_catch_throw)
+
{
if (b->type == bp_hardware_breakpoint)
val = target_remove_hw_breakpoint(b->address, b->shadow_contents);
else
- val = target_remove_breakpoint(b->address, b->shadow_contents);
+ {
+ /* Check to see if breakpoint is in an overlay section;
+ if so, we should remove the breakpoint at the LMA address.
+ If that is not equal to the raw address, then we should
+ presumable remove the breakpoint there as well. */
+ if (overlay_debugging && b->section &&
+ section_is_overlay (b->section))
+ {
+ CORE_ADDR addr;
+
+ addr = overlay_unmapped_address (b->address, b->section);
+ val = target_remove_breakpoint (addr, b->shadow_contents);
+ /* This would be the time to check val, to see if the
+ shadow breakpoint write to the load address succeeded.
+ However, this might be an ordinary occurrance, eg. if
+ the unmapped overlay is in ROM. */
+ val = 0; /* in case unmapped address failed */
+ if (section_is_mapped (b->section))
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else /* ordinary (non-overlay) address */
+ val = target_remove_breakpoint(b->address, b->shadow_contents);
+ }
if (val)
return val;
- b->inserted = 0;
+ b->inserted = (is == mark_inserted);
}
else if ((b->type == bp_hardware_watchpoint ||
b->type == bp_read_watchpoint ||
@@ -633,7 +1100,7 @@ remove_breakpoint (b)
{
value_ptr v, n;
- b->inserted = 0;
+ b->inserted = (is == mark_inserted);
/* Walk down the saved value chain. */
for (v = b->val_chain; v; v = v->next)
{
@@ -641,18 +1108,24 @@ remove_breakpoint (b)
at that address. */
if (v->lval == lval_memory)
{
- int addr, len;
+ int addr, len, type;
addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
len = TYPE_LENGTH (VALUE_TYPE (v));
- val = target_remove_watchpoint (addr, len, b->type);
+ type = 0;
+ if (b->type == bp_read_watchpoint)
+ type = 1;
+ else if (b->type == bp_access_watchpoint)
+ type = 2;
+
+ val = target_remove_watchpoint (addr, len, type);
if (val == -1)
b->inserted = 1;
val = 0;
}
}
/* Failure to remove any of the hardware watchpoints comes here. */
- if (b->inserted)
+ if ((is == mark_uninserted) && (b->inserted))
warning ("Hardware watchpoint %d: Could not remove watchpoint\n",
b->number);
@@ -665,6 +1138,53 @@ remove_breakpoint (b)
}
b->val_chain = NULL;
}
+ else if ((b->type == bp_catch_fork ||
+ b->type == bp_catch_vfork ||
+ b->type == bp_catch_exec)
+ && b->enable == enabled
+ && ! b->duplicate)
+ {
+ val = -1;
+ switch (b->type)
+ {
+ case bp_catch_fork:
+ val = target_remove_fork_catchpoint (inferior_pid);
+ break;
+ case bp_catch_vfork :
+ val = target_remove_vfork_catchpoint (inferior_pid);
+ break;
+ case bp_catch_exec :
+ val = target_remove_exec_catchpoint (inferior_pid);
+ break;
+ }
+ if (val)
+ return val;
+ b->inserted = (is == mark_inserted);
+ }
+ else if ((b->type == bp_catch_catch ||
+ b->type == bp_catch_throw)
+ && b->enable == enabled
+ && ! b->duplicate)
+ {
+
+ val = target_remove_breakpoint(b->address, b->shadow_contents);
+ if (val)
+ return val;
+ b->inserted = (is == mark_inserted);
+ }
+ else if (ep_is_exception_catchpoint (b)
+ && b->inserted /* sometimes previous insert doesn't happen */
+ && b->enable == enabled
+ && ! b->duplicate)
+ {
+
+ val = target_remove_breakpoint(b->address, b->shadow_contents);
+ if (val)
+ return val;
+
+ b->inserted = (is == mark_inserted);
+ }
+
return 0;
}
@@ -680,33 +1200,71 @@ mark_breakpoints_out ()
}
/* Clear the "inserted" flag in all breakpoints and delete any breakpoints
- which should go away between runs of the program. */
+ which should go away between runs of the program.
+
+ Plus other such housekeeping that has to be done for breakpoints
+ between runs.
+
+ Note: this function gets called at the end of a run (by generic_mourn_inferior)
+ and when a run begins (by init_wait_for_inferior). */
+
+
void
-breakpoint_init_inferior ()
+breakpoint_init_inferior (context)
+ enum inf_context context;
{
register struct breakpoint *b, *temp;
+ static int warning_needed = 0;
ALL_BREAKPOINTS_SAFE (b, temp)
{
b->inserted = 0;
- /* If the call dummy breakpoint is at the entry point it will
- cause problems when the inferior is rerun, so we better
- get rid of it. */
- if (b->type == bp_call_dummy)
- delete_breakpoint (b);
+ switch (b->type)
+ {
+ case bp_call_dummy:
+ case bp_watchpoint_scope:
- /* Likewise for scope breakpoints. */
- if (b->type == bp_watchpoint_scope)
- delete_breakpoint (b);
+ /* If the call dummy breakpoint is at the entry point it will
+ cause problems when the inferior is rerun, so we better
+ get rid of it.
- /* Likewise for watchpoints on local expressions. */
- if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint ||
- b->type == bp_read_watchpoint || b->type == bp_access_watchpoint)
- && b->exp_valid_block != NULL)
- delete_breakpoint (b);
+ Also get rid of scope breakpoints. */
+ delete_breakpoint (b);
+ break;
+
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+
+ /* Likewise for watchpoints on local expressions. */
+ if (b->exp_valid_block != NULL)
+ delete_breakpoint (b);
+ break;
+ default:
+ /* Likewise for exception catchpoints in dynamic-linked
+ executables where required */
+ if (ep_is_exception_catchpoint (b) &&
+ exception_catchpoints_are_fragile)
+ {
+ warning_needed = 1;
+ delete_breakpoint (b);
+ }
+ break;
+ }
}
+
+ if (exception_catchpoints_are_fragile)
+ exception_support_initialized = 0;
+
+ /* Don't issue the warning unless it's really needed... */
+ if (warning_needed && (context != inf_exited))
+ {
+ warning ("Exception catchpoints from last run were deleted, you must reinsert them explicitly");
+ warning_needed = 0;
+ }
}
/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC.
@@ -720,10 +1278,42 @@ breakpoint_here_p (pc)
register struct breakpoint *b;
ALL_BREAKPOINTS (b)
- if (b->enable != disabled
+ if (b->enable == enabled
&& b->enable != shlib_disabled
- && b->address == pc)
- return 1;
+ && b->enable != call_disabled
+ && b->address == pc) /* bp is enabled and matches pc */
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(), but it
+ only returns true if there is actually a breakpoint inserted at PC. */
+
+int
+breakpoint_inserted_here_p (pc)
+ CORE_ADDR pc;
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->inserted
+ && b->address == pc) /* bp is inserted and matches pc */
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
return 0;
}
@@ -737,12 +1327,15 @@ int
frame_in_dummy (frame)
struct frame_info *frame;
{
+#ifdef CALL_DUMMY
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ return generic_pc_in_call_dummy (frame->pc, frame->frame);
+#else
struct breakpoint *b;
-#ifdef CALL_DUMMY
ALL_BREAKPOINTS (b)
{
- static unsigned LONGEST dummy[] = CALL_DUMMY;
+ static ULONGEST dummy[] = CALL_DUMMY;
if (b->type == bp_call_dummy
&& b->frame == frame->frame
@@ -755,6 +1348,7 @@ frame_in_dummy (frame)
&& frame->pc <= b->address)
return 1;
}
+#endif /* GENERIC_DUMMY_FRAMES */
#endif /* CALL_DUMMY */
return 0;
}
@@ -775,9 +1369,17 @@ breakpoint_thread_match (pc, pid)
ALL_BREAKPOINTS (b)
if (b->enable != disabled
&& b->enable != shlib_disabled
+ && b->enable != call_disabled
&& b->address == pc
&& (b->thread == -1 || b->thread == thread))
- return 1;
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
return 0;
}
@@ -786,6 +1388,44 @@ breakpoint_thread_match (pc, pid)
/* bpstat stuff. External routines' interfaces are documented
in breakpoint.h. */
+int
+ep_is_catchpoint (ep)
+ struct breakpoint * ep;
+{
+ return
+ (ep->type == bp_catch_load)
+ || (ep->type == bp_catch_unload)
+ || (ep->type == bp_catch_fork)
+ || (ep->type == bp_catch_vfork)
+ || (ep->type == bp_catch_exec)
+ || (ep->type == bp_catch_catch)
+ || (ep->type == bp_catch_throw)
+
+
+ /* ??rehrauer: Add more kinds here, as are implemented... */
+ ;
+}
+
+int
+ep_is_shlib_catchpoint (ep)
+ struct breakpoint * ep;
+{
+ return
+ (ep->type == bp_catch_load)
+ || (ep->type == bp_catch_unload)
+ ;
+}
+
+int
+ep_is_exception_catchpoint (ep)
+ struct breakpoint * ep;
+{
+ return
+ (ep->type == bp_catch_catch)
+ || (ep->type == bp_catch_throw)
+ ;
+}
+
/* Clear a bpstat so that it says we are not at any breakpoint.
Also free any storage that is part of a bpstat. */
@@ -854,6 +1494,32 @@ bpstat_find_breakpoint(bsp, breakpoint)
return NULL;
}
+/* Find a step_resume breakpoint associated with this bpstat.
+ (If there are multiple step_resume bp's on the list, this function
+ will arbitrarily pick one.)
+
+ It is an error to use this function if BPSTAT doesn't contain a
+ step_resume breakpoint.
+
+ See wait_for_inferior's use of this function. */
+struct breakpoint *
+bpstat_find_step_resume_breakpoint (bsp)
+ bpstat bsp;
+{
+ if (bsp == NULL)
+ error ("Internal error (bpstat_find_step_resume_breakpoint)");
+
+ for (; bsp != NULL; bsp = bsp->next)
+ {
+ if ((bsp->breakpoint_at != NULL) &&
+ (bsp->breakpoint_at->type == bp_step_resume))
+ return bsp->breakpoint_at;
+ }
+
+ error ("Internal error (no step_resume breakpoint found)");
+}
+
+
/* Return the breakpoint number of the first breakpoint we are stopped
at. *BSP upon return is a bpstat which points to the remaining
breakpoints stopped at (but which is not guaranteed to be good for
@@ -900,7 +1566,7 @@ bpstat_clear_actions (bs)
/* ARGSUSED */
static void
cleanup_executing_breakpoints (ignore)
- int ignore;
+ PTR ignore;
{
executing_breakpoint_commands = 0;
}
@@ -918,10 +1584,24 @@ bpstat_do_actions (bsp)
struct cleanup *old_chain;
struct command_line *cmd;
+ /* Avoid endless recursion if a `source' command is contained
+ in bs->commands. */
+ if (executing_breakpoint_commands)
+ return;
+
executing_breakpoint_commands = 1;
old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
top:
+ /* Note that (as of this writing), our callers all appear to
+ be passing us the address of global stop_bpstat. And, if
+ our calls to execute_control_command cause the inferior to
+ proceed, that global (and hence, *bsp) will change.
+
+ We must be careful to not touch *bsp unless the inferior
+ has not proceeded. */
+
+ /* This pointer will iterate over the list of bpstat's. */
bs = *bsp;
breakpoint_proceeded = 0;
@@ -931,7 +1611,11 @@ top:
while (cmd != NULL)
{
execute_control_command (cmd);
- cmd = cmd->next;
+
+ if (breakpoint_proceeded)
+ break;
+ else
+ cmd = cmd->next;
}
if (breakpoint_proceeded)
/* The inferior is proceeded by the command; bomb out now.
@@ -949,7 +1633,21 @@ top:
/* This is the normal print_it function for a bpstat. In the future,
much of this logic could (should?) be moved to bpstat_stop_status,
- by having it set different print_it functions. */
+ by having it set different print_it functions.
+
+ Current scheme: When we stop, bpstat_print() is called.
+ It loops through the bpstat list of things causing this stop,
+ calling the print_it function for each one. The default
+ print_it function, used for breakpoints, is print_it_normal().
+ (Also see print_it_noop() and print_it_done()).
+
+ Return values from this routine (used by bpstat_print() to
+ decide what to do):
+ 1: Means we printed something, and we do *not* desire that
+ something to be followed by a location.
+ 0: Means we printed something, and we *do* desire that
+ something to be followed by a location.
+ -1: Means we printed nothing. */
static int
print_it_normal (bs)
@@ -959,14 +1657,113 @@ print_it_normal (bs)
which has since been deleted. */
if (bs->breakpoint_at == NULL
|| (bs->breakpoint_at->type != bp_breakpoint
+ && bs->breakpoint_at->type != bp_catch_load
+ && bs->breakpoint_at->type != bp_catch_unload
+ && bs->breakpoint_at->type != bp_catch_fork
+ && bs->breakpoint_at->type != bp_catch_vfork
+ && bs->breakpoint_at->type != bp_catch_exec
+ && bs->breakpoint_at->type != bp_catch_catch
+ && bs->breakpoint_at->type != bp_catch_throw
&& bs->breakpoint_at->type != bp_hardware_breakpoint
&& bs->breakpoint_at->type != bp_watchpoint
&& bs->breakpoint_at->type != bp_read_watchpoint
&& bs->breakpoint_at->type != bp_access_watchpoint
&& bs->breakpoint_at->type != bp_hardware_watchpoint))
- return 0;
+ return -1;
- if (bs->breakpoint_at->type == bp_breakpoint ||
+ if (ep_is_shlib_catchpoint (bs->breakpoint_at))
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+ if (bs->breakpoint_at->type == bp_catch_load)
+ printf_filtered ("loaded");
+ else if (bs->breakpoint_at->type == bp_catch_unload)
+ printf_filtered ("unloaded");
+ printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
+ return 0;
+ }
+ else if (bs->breakpoint_at->type == bp_catch_fork ||
+ bs->breakpoint_at->type == bp_catch_vfork)
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+ if (bs->breakpoint_at->type == bp_catch_fork)
+ printf_filtered ("forked");
+ else if (bs->breakpoint_at->type == bp_catch_vfork)
+ printf_filtered ("vforked");
+ printf_filtered (" process %d), ", bs->breakpoint_at->forked_inferior_pid);
+ return 0;
+ }
+ else if (bs->breakpoint_at->type == bp_catch_exec)
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exec'd %s), ",
+ bs->breakpoint_at->number,
+ bs->breakpoint_at->exec_pathname);
+ return 0;
+ }
+ else if (bs->breakpoint_at->type == bp_catch_catch)
+ {
+ if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exception caught), ", bs->breakpoint_at->number);
+ printf_filtered ("throw location ");
+ if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_THROW_FILE,
+ CURRENT_EXCEPTION_THROW_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered (", catch location ");
+ if (CURRENT_EXCEPTION_CATCH_PC && CURRENT_EXCEPTION_CATCH_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_CATCH_FILE,
+ CURRENT_EXCEPTION_CATCH_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered ("\n");
+ return 1; /* don't bother to print location frame info */
+ }
+ else
+ {
+ return -1; /* really throw, some other bpstat will handle it */
+ }
+ }
+ else if (bs->breakpoint_at->type == bp_catch_throw)
+ {
+ if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exception thrown), ", bs->breakpoint_at->number);
+ printf_filtered ("throw location ");
+ if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_THROW_FILE,
+ CURRENT_EXCEPTION_THROW_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered (", catch location ");
+ if (CURRENT_EXCEPTION_CATCH_PC && CURRENT_EXCEPTION_CATCH_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_CATCH_FILE,
+ CURRENT_EXCEPTION_CATCH_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered ("\n");
+ return 1; /* don't bother to print location frame info */
+ }
+ else
+ {
+ return -1; /* really catch, some other bpstat willhandle it */
+ }
+ }
+
+ else if (bs->breakpoint_at->type == bp_breakpoint ||
bs->breakpoint_at->type == bp_hardware_breakpoint)
{
/* I think the user probably only wants to see one breakpoint
@@ -1007,10 +1804,25 @@ print_it_normal (bs)
return -1;
}
-/* Print a message indicating what happened. Returns nonzero to
- say that only the source line should be printed after this (zero
- return means print the frame as well as the source line). */
-/* Currently we always return zero. */
+/* Print a message indicating what happened.
+ This is called from normal_stop().
+ The input to this routine is the head of the bpstat list - a list
+ of the eventpoints that caused this stop.
+ This routine calls the "print_it" routine(s) associated
+ with these eventpoints. This will print (for example)
+ the "Breakpoint n," part of the output.
+ The return value of this routine is one of:
+
+ -1: Means we printed nothing
+ 0: Means we printed something, and expect subsequent
+ code to print the location. An example is
+ "Breakpoint 1, " which should be followed by
+ the location.
+ 1 : Means we printed something, but there is no need
+ to also print the location part of the message.
+ An example is the catch/throw messages, which
+ don't require a location appended to the end. */
+
int
bpstat_print (bs)
bpstat bs;
@@ -1018,7 +1830,7 @@ bpstat_print (bs)
int val;
if (bs == NULL)
- return 0;
+ return -1;
val = (*bs->print_it) (bs);
if (val >= 0)
@@ -1032,7 +1844,7 @@ bpstat_print (bs)
return bpstat_print (bs->next);
/* We reached the end of the chain without printing anything. */
- return 0;
+ return -1;
}
/* Evaluate the expression EXP and return 1 if value is zero.
@@ -1042,7 +1854,7 @@ bpstat_print (bs)
static int
breakpoint_cond_eval (exp)
- char *exp;
+ PTR exp;
{
value_ptr mark = value_mark ();
int i = !value_true (evaluate_expression ((struct expression *)exp));
@@ -1085,7 +1897,7 @@ bpstat_alloc (b, cbs)
static int
watchpoint_check (p)
- char *p;
+ PTR p;
{
bpstat bs = (bpstat) p;
struct breakpoint *b;
@@ -1151,8 +1963,8 @@ watchpoint_check (p)
Watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", bs->breakpoint_at->number);
if (b->related_breakpoint)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ b->related_breakpoint->disposition = del_at_next_stop;
+ b->disposition = del_at_next_stop;
return WP_DELETED;
}
@@ -1160,6 +1972,15 @@ which its expression is valid.\n", bs->breakpoint_at->number);
/* This is used when everything which needs to be printed has
already been printed. But we still want to print the frame. */
+
+/* Background: When we stop, bpstat_print() is called.
+ It loops through the bpstat list of things causing this stop,
+ calling the print_it function for each one. The default
+ print_it function, used for breakpoints, is print_it_normal().
+ Also see print_it_noop() and print_it_done() are the other
+ two possibilities. See comments in bpstat_print() and
+ in header of print_it_normal() for more detail. */
+
static int
print_it_done (bs)
bpstat bs;
@@ -1168,6 +1989,13 @@ print_it_done (bs)
}
/* This is used when nothing should be printed for this bpstat entry. */
+/* Background: When we stop, bpstat_print() is called.
+ It loops through the bpstat list of things causing this stop,
+ calling the print_it function for each one. The default
+ print_it function, used for breakpoints, is print_it_normal().
+ Also see print_it_noop() and print_it_done() are the other
+ two possibilities. See comments in bpstat_print() and
+ in header of print_it_normal() for more detail. */
static int
print_it_noop (bs)
@@ -1194,9 +2022,7 @@ print_it_noop (bs)
several reasons concurrently.)
Each element of the chain has valid next, breakpoint_at,
- commands, FIXME??? fields.
-
- */
+ commands, FIXME??? fields. */
bpstat
bpstat_stop_status (pc, not_a_breakpoint)
@@ -1205,10 +2031,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
{
register struct breakpoint *b, *temp;
CORE_ADDR bp_addr;
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
/* True if we've hit a breakpoint (as opposed to a watchpoint). */
int real_breakpoint = 0;
-#endif
/* Root of the chain of bpstat's */
struct bpstats root_bs[1];
/* Pointer to the last thing in the chain currently. */
@@ -1223,7 +2047,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
ALL_BREAKPOINTS_SAFE (b, temp)
{
if (b->enable == disabled
- || b->enable == shlib_disabled)
+ || b->enable == shlib_disabled
+ || b->enable == call_disabled)
continue;
if (b->type != bp_watchpoint
@@ -1231,11 +2056,19 @@ bpstat_stop_status (pc, not_a_breakpoint)
&& b->type != bp_read_watchpoint
&& b->type != bp_access_watchpoint
&& b->type != bp_hardware_breakpoint
- && b->address != bp_addr)
- continue;
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_catch
+ && b->type != bp_catch_throw) /* a non-watchpoint bp */
+ if (b->address != bp_addr || /* address doesn't match or */
+ (overlay_debugging && /* overlay doesn't match */
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section)))
+ continue;
if (b->type == bp_hardware_breakpoint
- && b->address != (bp_addr - DECR_PC_AFTER_HW_BREAK))
+ && b->address != (*pc - DECR_PC_AFTER_HW_BREAK))
continue;
if (b->type != bp_watchpoint
@@ -1245,20 +2078,55 @@ bpstat_stop_status (pc, not_a_breakpoint)
&& not_a_breakpoint)
continue;
- /* Come here if it's a watchpoint, or if the break address matches */
+ /* Is this a catchpoint of a load or unload? If so, did we
+ get a load or unload of the specified library? If not,
+ ignore it. */
+ if ((b->type == bp_catch_load)
+#if defined(SOLIB_HAVE_LOAD_EVENT)
+ && (!SOLIB_HAVE_LOAD_EVENT(inferior_pid)
+ || ((b->dll_pathname != NULL)
+ && (strcmp (b->dll_pathname, SOLIB_LOADED_LIBRARY_PATHNAME(inferior_pid)) != 0)))
+#endif
+ )
+ continue;
+
+ if ((b->type == bp_catch_unload)
+#if defined(SOLIB_HAVE_UNLOAD_EVENT)
+ && (!SOLIB_HAVE_UNLOAD_EVENT(inferior_pid)
+ || ((b->dll_pathname != NULL)
+ && (strcmp (b->dll_pathname, SOLIB_UNLOADED_LIBRARY_PATHNAME(inferior_pid)) != 0)))
+#endif
+ )
+ continue;
+
+ if ((b->type == bp_catch_fork)
+ && ! target_has_forked (inferior_pid, &b->forked_inferior_pid))
+ continue;
+
+ if ((b->type == bp_catch_vfork)
+ && ! target_has_vforked (inferior_pid, &b->forked_inferior_pid))
+ continue;
+
+ if ((b->type == bp_catch_exec)
+ && ! target_has_execd (inferior_pid, &b->exec_pathname))
+ continue;
+
+ if (ep_is_exception_catchpoint (b) &&
+ !(current_exception_event = target_get_current_exception_event ()))
+ continue;
- ++(b->hit_count);
+ /* Come here if it's a watchpoint, or if the break address matches */
bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */
+ /* Watchpoints may change this, if not found to have triggered. */
bs->stop = 1;
bs->print = 1;
sprintf (message, message1, b->number);
if (b->type == bp_watchpoint || b->type == bp_hardware_watchpoint)
{
- switch (catch_errors (watchpoint_check, (char *) bs, message,
- RETURN_MASK_ALL))
+ switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL))
{
case WP_DELETED:
/* We've already printed what needs to be printed. */
@@ -1267,11 +2135,14 @@ bpstat_stop_status (pc, not_a_breakpoint)
break;
case WP_VALUE_CHANGED:
/* Stop. */
+ ++(b->hit_count);
break;
case WP_VALUE_NOT_CHANGED:
/* Don't stop. */
bs->print_it = print_it_noop;
bs->stop = 0;
+ /* Don't consider this a hit. */
+ --(b->hit_count);
continue;
default:
/* Can't happen. */
@@ -1280,8 +2151,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
if (b->related_breakpoint)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ b->related_breakpoint->disposition = del_at_next_stop;
+ b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
@@ -1309,8 +2180,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
}
}
if (found)
- switch (catch_errors (watchpoint_check, (char *) bs, message,
- RETURN_MASK_ALL))
+ switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL))
{
case WP_DELETED:
/* We've already printed what needs to be printed. */
@@ -1320,26 +2190,33 @@ bpstat_stop_status (pc, not_a_breakpoint)
case WP_VALUE_CHANGED:
case WP_VALUE_NOT_CHANGED:
/* Stop. */
+ ++(b->hit_count);
break;
default:
/* Can't happen. */
case 0:
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
- if (b->related_breakpoint)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ if (b->related_breakpoint)
+ b->related_breakpoint->disposition = del_at_next_stop;
+ b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
break;
}
}
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- else
- real_breakpoint = 1;
-#endif
+ else
+ {
+ /* By definition, an encountered breakpoint is a triggered
+ breakpoint. */
+ ++(b->hit_count);
+
+ real_breakpoint = 1;
+ }
- if (b->frame && b->frame != (get_current_frame ())->frame)
+ if (b->frame && b->frame != (get_current_frame ())->frame &&
+ (b->type == bp_step_resume &&
+ (INNER_THAN (get_current_frame ()->frame, b->frame))))
bs->stop = 0;
else
{
@@ -1351,7 +2228,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
so that the conditions will have the right context. */
select_frame (get_current_frame (), 0);
value_is_zero
- = catch_errors (breakpoint_cond_eval, (char *)(b->cond),
+ = catch_errors (breakpoint_cond_eval, (b->cond),
"Error in testing breakpoint condition:\n",
RETURN_MASK_ALL);
/* FIXME-someday, should give breakpoint # */
@@ -1360,6 +2237,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
if (b->cond && value_is_zero)
{
bs->stop = 0;
+ /* Don't consider this a hit. */
+ --(b->hit_count);
}
else if (b->ignore_count > 0)
{
@@ -1374,7 +2253,9 @@ bpstat_stop_status (pc, not_a_breakpoint)
bs->commands = b->commands;
if (b->silent)
bs->print = 0;
- if (bs->commands && STREQ ("silent", bs->commands->line))
+ if (bs->commands &&
+ (STREQ ("silent", bs->commands->line) ||
+ (xdb_commands && STREQ ("Q", bs->commands->line))))
{
bs->commands = bs->commands->next;
bs->print = 0;
@@ -1388,20 +2269,30 @@ bpstat_stop_status (pc, not_a_breakpoint)
bs->next = NULL; /* Terminate the chain */
bs = root_bs->next; /* Re-grab the head of the chain */
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- if (bs)
+
+ if (real_breakpoint && bs)
{
- if (real_breakpoint)
+ if (bs->breakpoint_at->type == bp_hardware_breakpoint)
+ {
+ if (DECR_PC_AFTER_HW_BREAK != 0)
+ {
+ *pc = *pc - DECR_PC_AFTER_HW_BREAK;
+ write_pc (*pc);
+ }
+ }
+ else
{
- *pc = bp_addr;
+ if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
+ {
+ *pc = bp_addr;
#if defined (SHIFT_INST_REGS)
- SHIFT_INST_REGS();
+ SHIFT_INST_REGS();
#else /* No SHIFT_INST_REGS. */
- write_pc (bp_addr);
+ write_pc (bp_addr);
#endif /* No SHIFT_INST_REGS. */
+ }
}
}
-#endif /* DECR_PC_AFTER_BREAK != 0. */
/* The value of a hardware watchpoint hasn't changed, but the
intermediate memory locations we are watching may have. */
@@ -1456,6 +2347,9 @@ bpstat_what (bs)
/* We hit the shared library event breakpoint. */
shlib_event,
+ /* We caught a shared library event. */
+ catch_shlib_event,
+
/* This is just used to count how many enums there are. */
class_last
};
@@ -1473,6 +2367,7 @@ bpstat_what (bs)
#define sr BPSTAT_WHAT_STEP_RESUME
#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP
#define shl BPSTAT_WHAT_CHECK_SHLIBS
+#define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
/* "Can't happen." Might want to print an error message.
abort() is not out of the question, but chances are GDB is just
@@ -1497,20 +2392,22 @@ bpstat_what (bs)
table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
{
/* old action */
- /* kc ss sn sgl slr clr clrs sr ts shl
- */
-/*no_effect*/ {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl},
-/*wp_silent*/ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl},
-/*wp_noisy*/ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl},
-/*bp_nostop*/ {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl},
-/*bp_silent*/ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl},
-/*bp_noisy*/ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl},
-/*long_jump*/ {slr, ss, sn, slr, err, err, err, sr, ts, shl},
-/*long_resume*/ {clr, ss, sn, clrs, err, err, err, sr, ts, shl},
-/*step_resume*/ {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl},
-/*through_sig*/ {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl},
-/*shlib*/ {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl}
- };
+ /* kc ss sn sgl slr clr clrs sr ts shl shlr
+ */
+/*no_effect*/ {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl, shlr},
+/*wp_silent*/ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+/*wp_noisy*/ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+/*bp_nostop*/ {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl, shlr},
+/*bp_silent*/ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+/*bp_noisy*/ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+/*long_jump*/ {slr, ss, sn, slr, err, err, err, sr, ts, shl, shlr},
+/*long_resume*/ {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
+/*step_resume*/ {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl, shlr},
+/*through_sig*/ {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl, shlr},
+/*shlib*/ {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl, shlr},
+/*catch_shlib*/ {shlr, shlr, shlr, shlr, shlr, shlr, shlr, shlr, ts, shlr, shlr}
+ };
+
#undef kc
#undef ss
#undef sn
@@ -1522,6 +2419,7 @@ bpstat_what (bs)
#undef sr
#undef ts
#undef shl
+#undef shlr
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
struct bpstat_what retval;
@@ -1535,6 +2433,9 @@ bpstat_what (bs)
continue;
switch (bs->breakpoint_at->type)
{
+ case bp_none:
+ continue;
+
case bp_breakpoint:
case bp_hardware_breakpoint:
case bp_until:
@@ -1589,6 +2490,43 @@ bpstat_what (bs)
case bp_shlib_event:
bs_class = shlib_event;
break;
+ case bp_catch_load:
+ case bp_catch_unload:
+ /* Only if this catchpoint triggered should we cause the
+ step-out-of-dld behaviour. Otherwise, we ignore this
+ catchpoint. */
+ if (bs->stop)
+ bs_class = catch_shlib_event;
+ else
+ bs_class = no_effect;
+ break;
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ if (bs->stop)
+ {
+ if (bs->print)
+ bs_class = bp_noisy;
+ else
+ bs_class = bp_silent;
+ }
+ else
+ /* There was a catchpoint, but we're not stopping. This requires
+ no further action. */
+ bs_class = no_effect;
+ break;
+ case bp_catch_catch:
+ if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_CATCH)
+ bs_class = bp_nostop;
+ else if (bs->stop)
+ bs_class = bs->print ? bp_noisy : bp_silent;
+ break;
+ case bp_catch_throw:
+ if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_THROW)
+ bs_class = bp_nostop;
+ else if (bs->stop)
+ bs_class = bs->print ? bp_noisy : bp_silent;
+ break;
case bp_call_dummy:
/* Make sure the action is stop (silent or noisy), so infrun.c
pops the dummy frame. */
@@ -1615,11 +2553,93 @@ bpstat_should_step ()
return 1;
return 0;
}
+
+/* Nonzero if there are enabled hardware watchpoints. */
+int
+bpstat_have_active_hw_watchpoints ()
+{
+ struct breakpoint *b;
+ ALL_BREAKPOINTS (b)
+ if ((b->enable == enabled) &&
+ (b->inserted) &&
+ ((b->type == bp_hardware_watchpoint) ||
+ (b->type == bp_read_watchpoint) ||
+ (b->type == bp_access_watchpoint)))
+ return 1;
+ return 0;
+}
+
+/* Given a bpstat that records zero or more triggered eventpoints, this
+ function returns another bpstat which contains only the catchpoints
+ on that first list, if any. */
+void
+bpstat_get_triggered_catchpoints (ep_list, cp_list)
+ bpstat ep_list;
+ bpstat * cp_list;
+{
+ struct bpstats root_bs[1];
+ bpstat bs = root_bs;
+ struct breakpoint * ep;
+ char * dll_pathname;
+
+ bpstat_clear (cp_list);
+ root_bs->next = NULL;
+
+ for (; ep_list != NULL; ep_list = ep_list->next )
+ {
+ /* Is this eventpoint a catchpoint? If not, ignore it. */
+ ep = ep_list->breakpoint_at;
+ if (ep == NULL)
+ break;
+ if ((ep->type != bp_catch_load) &&
+ (ep->type != bp_catch_unload) &&
+ (ep->type != bp_catch_catch) &&
+ (ep->type != bp_catch_throw)) /* pai: (temp) ADD fork/vfork here!! */
+ continue;
+
+ /* Yes; add it to the list. */
+ bs = bpstat_alloc (ep, bs);
+ *bs = *ep_list;
+ bs->next = NULL;
+ bs = root_bs->next;
+
+#if defined(SOLIB_ADD)
+ /* Also, for each triggered catchpoint, tag it with the name of
+ the library that caused this trigger. (We copy the name now,
+ because it's only guaranteed to be available NOW, when the
+ catchpoint triggers. Clients who may wish to know the name
+ later must get it from the catchpoint itself.) */
+ if (ep->triggered_dll_pathname != NULL)
+ free (ep->triggered_dll_pathname);
+ if (ep->type == bp_catch_load)
+ dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid);
+ else
+ dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid);
+#else
+ dll_pathname = NULL;
+#endif
+ if (dll_pathname)
+ {
+ ep->triggered_dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1);
+ strcpy (ep->triggered_dll_pathname, dll_pathname);
+ }
+ else
+ ep->triggered_dll_pathname = NULL;
+ }
+
+ *cp_list = bs;
+}
+
/* Print information on breakpoint number BNUM, or -1 if all.
If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
is nonzero, process only watchpoints. */
+typedef struct {
+ enum bptype type;
+ char * description;
+} ep_type_description_t;
+
static void
breakpoint_1 (bnum, allflag)
int bnum;
@@ -1630,16 +2650,35 @@ breakpoint_1 (bnum, allflag)
register struct symbol *sym;
CORE_ADDR last_addr = (CORE_ADDR)-1;
int found_a_breakpoint = 0;
- static char *bptypes[] = {"breakpoint", "hw breakpoint",
- "until", "finish", "watchpoint",
- "hw watchpoint", "read watchpoint",
- "acc watchpoint", "longjmp",
- "longjmp resume", "step resume",
- "sigtramp",
- "watchpoint scope", "call dummy",
- "shlib events" };
- static char *bpdisps[] = {"del", "dis", "keep"};
- static char bpenables[] = "ny";
+ static ep_type_description_t bptypes[] =
+ {
+ {bp_none, "?deleted?"},
+ {bp_breakpoint, "breakpoint"},
+ {bp_hardware_breakpoint, "hw breakpoint"},
+ {bp_until, "until"},
+ {bp_finish, "finish"},
+ {bp_watchpoint, "watchpoint"},
+ {bp_hardware_watchpoint, "hw watchpoint"},
+ {bp_read_watchpoint, "read watchpoint"},
+ {bp_access_watchpoint, "acc watchpoint"},
+ {bp_longjmp, "longjmp"},
+ {bp_longjmp_resume, "longjmp resume"},
+ {bp_step_resume, "step resume"},
+ {bp_through_sigtramp, "sigtramp"},
+ {bp_watchpoint_scope, "watchpoint scope"},
+ {bp_call_dummy, "call dummy"},
+ {bp_shlib_event, "shlib events"},
+ {bp_catch_load, "catch load"},
+ {bp_catch_unload, "catch unload"},
+ {bp_catch_fork, "catch fork"},
+ {bp_catch_vfork, "catch vfork"},
+ {bp_catch_exec, "catch exec"},
+ {bp_catch_catch, "catch catch"},
+ {bp_catch_throw, "catch throw"}
+ };
+
+ static char *bpdisps[] = {"del", "dstp", "dis", "keep"};
+ static char bpenables[] = "nyn";
char wrap_indent[80];
ALL_BREAKPOINTS (b)
@@ -1649,6 +2688,13 @@ breakpoint_1 (bnum, allflag)
/* We only print out user settable breakpoints unless the allflag is set. */
if (!allflag
&& b->type != bp_breakpoint
+ && b->type != bp_catch_load
+ && b->type != bp_catch_unload
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_catch
+ && b->type != bp_catch_throw
&& b->type != bp_hardware_breakpoint
&& b->type != bp_watchpoint
&& b->type != bp_read_watchpoint
@@ -1683,7 +2729,11 @@ breakpoint_1 (bnum, allflag)
annotate_field (0);
printf_filtered ("%-3d ", b->number);
annotate_field (1);
- printf_filtered ("%-14s ", bptypes[(int)b->type]);
+ if ((int)b->type > (sizeof(bptypes)/sizeof(bptypes[0])))
+ error ("bptypes table does not describe type #%d.", (int)b->type);
+ if ((int)b->type != bptypes[(int)b->type].type)
+ error ("bptypes table does not describe type #%d?", (int)b->type);
+ printf_filtered ("%-14s ", bptypes[(int)b->type].description);
annotate_field (2);
printf_filtered ("%-4s ", bpdisps[(int)b->disposition]);
annotate_field (3);
@@ -1704,6 +2754,51 @@ breakpoint_1 (bnum, allflag)
annotate_field (5);
print_expression (b->exp, gdb_stdout);
break;
+
+ case bp_catch_load:
+ case bp_catch_unload:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ annotate_field (5);
+ if (b->dll_pathname == NULL)
+ printf_filtered ("<any library> ");
+ else
+ printf_filtered ("library \"%s\" ", b->dll_pathname);
+ break;
+
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ annotate_field (5);
+ if (b->forked_inferior_pid != 0)
+ printf_filtered ("process %d ", b->forked_inferior_pid);
+ break;
+
+ case bp_catch_exec:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ annotate_field (5);
+ if (b->exec_pathname != NULL)
+ printf_filtered ("program \"%s\" ", b->exec_pathname);
+ break;
+ case bp_catch_catch:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ annotate_field (5);
+ printf_filtered ("exception catch ");
+ break;
+ case bp_catch_throw:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ annotate_field (5);
+ printf_filtered ("exception throw ");
+ break;
case bp_breakpoint:
case bp_hardware_breakpoint:
@@ -1732,7 +2827,7 @@ breakpoint_1 (bnum, allflag)
last_addr = b->address;
if (b->source_file)
{
- sym = find_pc_function (b->address);
+ sym = find_pc_sect_function (b->address, b->section);
if (sym)
{
fputs_filtered ("in ", gdb_stdout);
@@ -1748,6 +2843,9 @@ breakpoint_1 (bnum, allflag)
break;
}
+ if (b->thread != -1)
+ printf_filtered (" thread %d", b->thread );
+
printf_filtered ("\n");
if (b->frame)
@@ -1768,12 +2866,21 @@ breakpoint_1 (bnum, allflag)
printf_filtered ("\n");
}
- if (show_breakpoint_hit_counts && b->hit_count)
+ if (b->thread != -1)
{
/* FIXME should make an annotation for this */
+ printf_filtered ("\tstop only in thread %d\n", b->thread);
+ }
- printf_filtered ("\tbreakpoint already hit %d time%s\n",
- b->hit_count, (b->hit_count == 1 ? "" : "s"));
+ if (show_breakpoint_hit_counts && b->hit_count)
+ {
+ /* FIXME should make an annotation for this */
+ if (ep_is_catchpoint (b))
+ printf_filtered ("\tcatchpoint");
+ else
+ printf_filtered ("\tbreakpoint");
+ printf_filtered (" already hit %d time%s\n",
+ b->hit_count, (b->hit_count == 1 ? "" : "s"));
}
if (b->ignore_count)
@@ -1828,7 +2935,7 @@ breakpoints_info (bnum_exp, from_tty)
#if MAINTENANCE_CMDS
/* ARGSUSED */
-static void
+void
maintenance_info_breakpoints (bnum_exp, from_tty)
char *bnum_exp;
int from_tty;
@@ -1846,29 +2953,34 @@ maintenance_info_breakpoints (bnum_exp, from_tty)
/* Print a message describing any breakpoints set at PC. */
static void
-describe_other_breakpoints (pc)
- register CORE_ADDR pc;
+describe_other_breakpoints (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register int others = 0;
register struct breakpoint *b;
ALL_BREAKPOINTS (b)
if (b->address == pc)
- others++;
+ if (overlay_debugging == 0 ||
+ b->section == section)
+ others++;
if (others > 0)
{
printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
ALL_BREAKPOINTS (b)
if (b->address == pc)
- {
- others--;
- printf_filtered
- ("%d%s%s ",
- b->number,
- ((b->enable == disabled || b->enable == shlib_disabled)
- ? " (disabled)" : ""),
- (others > 1) ? "," : ((others == 1) ? " and" : ""));
- }
+ if (overlay_debugging == 0 ||
+ b->section == section)
+ {
+ others--;
+ printf_filtered
+ ("%d%s%s ",
+ b->number,
+ ((b->enable == disabled || b->enable == shlib_disabled || b->enable == call_disabled)
+ ? " (disabled)" : ""),
+ (others > 1) ? "," : ((others == 1) ? " and" : ""));
+ }
printf_filtered ("also set at pc ");
print_address_numeric (pc, 1, gdb_stdout);
printf_filtered (".\n");
@@ -1896,8 +3008,9 @@ set_default_breakpoint (valid, addr, symtab, line)
This is so that the bpt instruction is only inserted once. */
static void
-check_duplicates (address)
+check_duplicates (address, section)
CORE_ADDR address;
+ asection *section;
{
register struct breakpoint *b;
register int count = 0;
@@ -1908,7 +3021,9 @@ check_duplicates (address)
ALL_BREAKPOINTS (b)
if (b->enable != disabled
&& b->enable != shlib_disabled
- && b->address == address)
+ && b->enable != call_disabled
+ && b->address == address
+ && (overlay_debugging == 0 || b->section == section))
{
count++;
b->duplicate = count > 1;
@@ -1925,7 +3040,7 @@ check_duplicates (address)
error(); otherwise it leaves a bogus breakpoint on the chain. Validate
your arguments BEFORE calling this routine! */
-static struct breakpoint *
+struct breakpoint *
set_raw_breakpoint (sal)
struct symtab_and_line sal;
{
@@ -1939,6 +3054,7 @@ set_raw_breakpoint (sal)
else
b->source_file = savestring (sal.symtab->filename,
strlen (sal.symtab->filename));
+ b->section = sal.section;
b->language = current_language->la_language;
b->input_radix = input_radix;
b->thread = -1;
@@ -1949,6 +3065,10 @@ set_raw_breakpoint (sal)
b->ignore_count = 0;
b->commands = NULL;
b->frame = 0;
+ b->dll_pathname = NULL;
+ b->triggered_dll_pathname = NULL;
+ b->forked_inferior_pid = 0;
+ b->exec_pathname = NULL;
/* Add this breakpoint to the end of the chain
so that a list of breakpoints will come out in order
@@ -1964,14 +3084,12 @@ set_raw_breakpoint (sal)
b1->next = b;
}
- check_duplicates (sal.pc);
+ check_duplicates (sal.pc, sal.section);
breakpoints_changed ();
return b;
}
-static int internal_breakpoint_number = -1;
-
#ifdef GET_LONGJMP_TARGET
static void
@@ -1981,6 +3099,7 @@ create_longjmp_breakpoint (func_name)
struct symtab_and_line sal;
struct breakpoint *b;
+ INIT_SAL (&sal); /* initialize to zeroes */
if (func_name != NULL)
{
struct minimal_symbol *m;
@@ -1991,12 +3110,7 @@ create_longjmp_breakpoint (func_name)
else
return;
}
- else
- sal.pc = 0;
-
- sal.symtab = NULL;
- sal.line = 0;
-
+ sal.section = find_pc_overlay (sal.pc);
b = set_raw_breakpoint (sal);
if (!b) return;
@@ -2024,7 +3138,7 @@ enable_longjmp_breakpoint()
if (b->type == bp_longjmp)
{
b->enable = enabled;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
}
}
@@ -2038,7 +3152,7 @@ disable_longjmp_breakpoint()
|| b->type == bp_longjmp_resume)
{
b->enable = disabled;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
}
}
@@ -2060,15 +3174,51 @@ create_solib_event_breakpoint (address)
struct breakpoint *b;
struct symtab_and_line sal;
+ INIT_SAL (&sal); /* initialize to zeroes */
sal.pc = address;
- sal.symtab = NULL;
- sal.line = 0;
+ sal.section = find_pc_overlay (sal.pc);
b = set_raw_breakpoint (sal);
b->number = internal_breakpoint_number--;
b->disposition = donttouch;
b->type = bp_shlib_event;
}
+void
+disable_breakpoints_in_shlibs (silent)
+ int silent;
+{
+ struct breakpoint * b;
+ int disabled_shlib_breaks = 0;
+
+ /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
+ ALL_BREAKPOINTS (b)
+ {
+#if defined (PC_SOLIB)
+ if (((b->type == bp_breakpoint) ||
+ (b->type == bp_hardware_breakpoint)) &&
+ (b->enable != shlib_disabled) &&
+ (b->enable != call_disabled) &&
+ ! b->duplicate &&
+ PC_SOLIB (b->address))
+ {
+ b->enable = shlib_disabled;
+ if (!silent)
+ {
+ if (!disabled_shlib_breaks)
+ {
+ target_terminal_ours_for_output ();
+ printf_filtered ("Temporarily disabling shared library breakpoints:\n");
+ }
+ disabled_shlib_breaks = 1;
+ printf_filtered ("%d ", b->number);
+ }
+ }
+#endif
+ }
+ if (disabled_shlib_breaks && !silent)
+ printf_filtered ("\n");
+}
+
/* Try to reenable any breakpoints in shared libraries. */
void
re_enable_breakpoints_in_shlibs ()
@@ -2089,7 +3239,193 @@ re_enable_breakpoints_in_shlibs ()
#endif
-int
+static void
+create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string, bp_kind)
+ char * hookname;
+ int tempflag;
+ char * dll_pathname;
+ char * cond_string;
+ enum bptype bp_kind;
+{
+ struct breakpoint * b;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct cleanup * old_chain;
+ struct cleanup * canonical_strings_chain = NULL;
+ int i;
+ char * addr_start = hookname;
+ char * addr_end = NULL;
+ char ** canonical = (char **) NULL;
+ int thread = -1; /* All threads. */
+
+ /* Set a breakpoint on the specified hook. */
+ sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical);
+ addr_end = hookname;
+
+ if (sals.nelts == 0)
+ {
+ warning ("Unable to set a breakpoint on dynamic linker callback.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ return;
+ }
+ if (sals.nelts != 1)
+ {
+ warning ("Unable to set a unique breakpoint on dynamic linker callback.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ return;
+ }
+
+ /* Make sure that all storage allocated in decode_line_1 gets freed in case
+ the following errors out. */
+ old_chain = make_cleanup (free, sals.sals);
+ if (canonical != (char **)NULL)
+ {
+ make_cleanup (free, canonical);
+ canonical_strings_chain = make_cleanup (null_cleanup, 0);
+ if (canonical[0] != NULL)
+ make_cleanup (free, canonical[0]);
+ }
+
+ resolve_sal_pc (&sals.sals[0]);
+
+ /* Remove the canonical strings from the cleanup, they are needed below. */
+ if (canonical != (char **)NULL)
+ discard_cleanups (canonical_strings_chain);
+
+ b = set_raw_breakpoint (sals.sals[0]);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+
+ if (canonical != (char **)NULL && canonical[0] != NULL)
+ b->addr_string = canonical[0];
+ else if (addr_start)
+ b->addr_string = savestring (addr_start, addr_end - addr_start);
+
+ b->enable = enabled;
+ b->disposition = tempflag ? del : donttouch;
+
+ if (dll_pathname == NULL)
+ b->dll_pathname = NULL;
+ else
+ {
+ b->dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1);
+ strcpy (b->dll_pathname, dll_pathname);
+ }
+ b->type = bp_kind;
+
+ mention (b);
+ do_cleanups (old_chain);
+}
+
+void
+create_solib_load_event_breakpoint (hookname, tempflag, dll_pathname, cond_string)
+ char * hookname;
+ int tempflag;
+ char * dll_pathname;
+ char * cond_string;
+{
+ create_solib_load_unload_event_breakpoint (hookname,
+ tempflag,
+ dll_pathname,
+ cond_string,
+ bp_catch_load);
+}
+
+void
+create_solib_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string)
+ char * hookname;
+ int tempflag;
+ char * dll_pathname;
+ char * cond_string;
+{
+ create_solib_load_unload_event_breakpoint (hookname,
+ tempflag,
+ dll_pathname,
+ cond_string,
+ bp_catch_unload);
+}
+
+static void
+create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_kind)
+ int tempflag;
+ char * cond_string;
+ enum bptype bp_kind;
+{
+ struct symtab_and_line sal;
+ struct breakpoint * b;
+ int thread = -1; /* All threads. */
+
+ INIT_SAL(&sal);
+ sal.pc = 0;
+ sal.symtab = NULL;
+ sal.line = 0;
+
+ b = set_raw_breakpoint (sal);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+ b->addr_string = NULL;
+ b->enable = enabled;
+ b->disposition = tempflag ? del : donttouch;
+ b->forked_inferior_pid = 0;
+
+ b->type = bp_kind;
+
+ mention (b);
+}
+
+void
+create_fork_event_catchpoint (tempflag, cond_string)
+ int tempflag;
+ char * cond_string;
+{
+ create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork);
+}
+
+void
+create_vfork_event_catchpoint (tempflag, cond_string)
+ int tempflag;
+ char * cond_string;
+{
+ create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
+}
+
+void
+create_exec_event_catchpoint (tempflag, cond_string)
+ int tempflag;
+ char * cond_string;
+{
+ struct symtab_and_line sal;
+ struct breakpoint * b;
+ int thread = -1; /* All threads. */
+
+ INIT_SAL(&sal);
+ sal.pc = 0;
+ sal.symtab = NULL;
+ sal.line = 0;
+
+ b = set_raw_breakpoint (sal);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+ b->addr_string = NULL;
+ b->enable = enabled;
+ b->disposition = tempflag ? del : donttouch;
+
+ b->type = bp_catch_exec;
+
+ mention (b);
+}
+
+static int
hw_breakpoint_used_count()
{
register struct breakpoint *b;
@@ -2104,7 +3440,7 @@ hw_breakpoint_used_count()
return i;
}
-int
+static int
hw_watchpoint_used_count(type, other_type_used)
enum bptype type;
int *other_type_used;
@@ -2132,8 +3468,7 @@ hw_watchpoint_used_count(type, other_type_used)
breakpoint at the target of the jmp_buf.
FIXME - This ought to be done by setting a temporary breakpoint that gets
- deleted automatically...
-*/
+ deleted automatically... */
void
set_longjmp_resume_breakpoint(pc, frame)
@@ -2151,11 +3486,52 @@ set_longjmp_resume_breakpoint(pc, frame)
b->frame = frame->frame;
else
b->frame = 0;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
return;
}
}
+void
+disable_watchpoints_before_interactive_call_start ()
+{
+ struct breakpoint * b;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (((b->type == bp_watchpoint)
+ || (b->type == bp_hardware_watchpoint)
+ || (b->type == bp_read_watchpoint)
+ || (b->type == bp_access_watchpoint)
+ || ep_is_exception_catchpoint (b))
+ && (b->enable == enabled))
+ {
+ b->enable = call_disabled;
+ check_duplicates (b->address, b->section);
+ }
+ }
+}
+
+void
+enable_watchpoints_after_interactive_call_stop ()
+{
+ struct breakpoint * b;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (((b->type == bp_watchpoint)
+ || (b->type == bp_hardware_watchpoint)
+ || (b->type == bp_read_watchpoint)
+ || (b->type == bp_access_watchpoint)
+ || ep_is_exception_catchpoint (b))
+ && (b->enable == call_disabled))
+ {
+ b->enable = enabled;
+ check_duplicates (b->address, b->section);
+ }
+ }
+}
+
+
/* Set a breakpoint that will evaporate an end of command
at address specified by SAL.
Restrict it to frame FRAME if FRAME is nonzero. */
@@ -2182,19 +3558,6 @@ set_momentary_breakpoint (sal, frame, type)
return b;
}
-#if 0
-void
-clear_momentary_breakpoints ()
-{
- register struct breakpoint *b, *temp;
- ALL_BREAKPOINTS_SAFE (b, temp)
- if (b->disposition == delete)
- {
- delete_breakpoint (b);
- break;
- }
-}
-#endif
/* Tell the user we have just set a breakpoint B. */
@@ -2214,6 +3577,9 @@ mention (b)
switch (b->type)
{
+ case bp_none:
+ printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number);
+ break;
case bp_watchpoint:
printf_filtered ("Watchpoint %d: ", b->number);
print_expression (b->exp, gdb_stdout);
@@ -2227,7 +3593,7 @@ mention (b)
print_expression (b->exp, gdb_stdout);
break;
case bp_access_watchpoint:
- printf_filtered ("Hardware access(read/write) watchpoint %d: ",b->number);
+ printf_filtered ("Hardware access (read/write) watchpoint %d: ",b->number);
print_expression (b->exp, gdb_stdout);
break;
case bp_breakpoint:
@@ -2238,6 +3604,30 @@ mention (b)
printf_filtered ("Hardware assisted breakpoint %d", b->number);
say_where = 1;
break;
+ case bp_catch_load:
+ case bp_catch_unload:
+ printf_filtered ("Catchpoint %d (%s %s)",
+ b->number,
+ (b->type == bp_catch_load) ? "load" : "unload",
+ (b->dll_pathname != NULL) ? b->dll_pathname : "<any library>");
+ break;
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ printf_filtered ("Catchpoint %d (%s)",
+ b->number,
+ (b->type == bp_catch_fork) ? "fork" : "vfork");
+ break;
+ case bp_catch_exec:
+ printf_filtered ("Catchpoint %d (exec)",
+ b->number);
+ break;
+ case bp_catch_catch:
+ case bp_catch_throw:
+ printf_filtered ("Catchpoint %d (%s)",
+ b->number,
+ (b->type == bp_catch_catch) ? "catch" : "throw");
+ break;
+
case bp_until:
case bp_finish:
case bp_longjmp:
@@ -2259,47 +3649,12 @@ mention (b)
if (b->source_file)
printf_filtered (": file %s, line %d.",
b->source_file, b->line_number);
+ TUIDO(((TuiOpaqueFuncPtr)tui_vAllSetHasBreakAt, b, 1));
+ TUIDO(((TuiOpaqueFuncPtr)tuiUpdateAllExecInfos));
}
printf_filtered ("\n");
}
-#if 0
-/* Nobody calls this currently. */
-/* Set a breakpoint from a symtab and line.
- If TEMPFLAG is nonzero, it is a temporary breakpoint.
- ADDR_STRING is a malloc'd string holding the name of where we are
- setting the breakpoint. This is used later to re-set it after the
- program is relinked and symbols are reloaded.
- Print the same confirmation messages that the breakpoint command prints. */
-
-void
-set_breakpoint (s, line, tempflag, addr_string)
- struct symtab *s;
- int line;
- int tempflag;
- char *addr_string;
-{
- register struct breakpoint *b;
- struct symtab_and_line sal;
-
- sal.symtab = s;
- sal.line = line;
- sal.pc = 0;
- resolve_sal_pc (&sal); /* Might error out */
- describe_other_breakpoints (sal.pc);
-
- b = set_raw_breakpoint (sal);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->type = bp_breakpoint;
- b->cond = 0;
- b->addr_string = addr_string;
- b->enable = enabled;
- b->disposition = tempflag ? delete : donttouch;
-
- mention (b);
-}
-#endif /* 0 */
/* Set a breakpoint according to ARG (function, linenum or *address)
flag: first bit : 0 non-temporary, 1 temporary.
@@ -2335,8 +3690,7 @@ break_command_1 (arg, flag, from_tty)
sals.sals = NULL;
sals.nelts = 0;
- sal.line = sal.pc = sal.end = 0;
- sal.symtab = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', use the default breakpoint. */
@@ -2350,6 +3704,7 @@ break_command_1 (arg, flag, from_tty)
sal.pc = default_breakpoint_address;
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
+ sal.section = find_pc_overlay (sal.pc);
sals.sals[0] = sal;
sals.nelts = 1;
}
@@ -2402,6 +3757,24 @@ break_command_1 (arg, flag, from_tty)
int toklen;
resolve_sal_pc (&sals.sals[i]);
+
+ /* It's possible for the PC to be nonzero, but still an illegal
+ value on some targets.
+
+ For example, on HP-UX if you start gdb, and before running the
+ inferior you try to set a breakpoint on a shared library function
+ "foo" where the inferior doesn't call "foo" directly but does
+ pass its address to another function call, then we do find a
+ minimal symbol for the "foo", but it's address is invalid.
+ (Appears to be an index into a table that the loader sets up
+ when the inferior is run.)
+
+ Give the target a chance to bless sals.sals[i].pc before we
+ try to make a breakpoint for it. */
+ if (PC_REQUIRES_RUN_BEFORE_USE(sals.sals[i].pc))
+ {
+ error ("Cannot break on %s without a running program.", addr_start);
+ }
tok = arg;
@@ -2462,7 +3835,7 @@ break_command_1 (arg, flag, from_tty)
sal = sals.sals[i];
if (from_tty)
- describe_other_breakpoints (sal.pc);
+ describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
@@ -2482,7 +3855,6 @@ break_command_1 (arg, flag, from_tty)
b->enable = enabled;
b->disposition = tempflag ? del : donttouch;
-
mention (b);
}
@@ -2494,6 +3866,174 @@ break_command_1 (arg, flag, from_tty)
do_cleanups (old_chain);
}
+static void
+break_at_finish_at_depth_command_1 (arg, flag, from_tty)
+ char *arg;
+ int flag;
+ int from_tty;
+{
+ struct frame_info *frame;
+ CORE_ADDR low, high, selected_pc = 0;
+ char *extra_args, *level_arg, *addr_string;
+ int extra_args_len = 0, if_arg = 0;
+
+ if (!arg ||
+ (arg[0] == 'i' && arg[1] == 'f' && (arg[2] == ' ' || arg[2] == '\t')))
+ {
+
+ if (default_breakpoint_valid)
+ {
+ if (selected_frame)
+ {
+ selected_pc = selected_frame->pc;
+ if (arg)
+ if_arg = 1;
+ }
+ else
+ error ("No selected frame.");
+ }
+ else
+ error ("No default breakpoint address now.");
+ }
+ else
+ {
+ extra_args = strchr (arg, ' ');
+ if (extra_args)
+ {
+ extra_args++;
+ extra_args_len = strlen (extra_args);
+ level_arg = (char *) xmalloc (extra_args - arg);
+ strncpy (level_arg, arg, extra_args - arg - 1);
+ level_arg[extra_args - arg - 1] = '\0';
+ }
+ else
+ {
+ level_arg = (char *) xmalloc (strlen (arg) + 1);
+ strcpy (level_arg, arg);
+ }
+
+ frame = parse_frame_specification (level_arg);
+ if (frame)
+ selected_pc = frame->pc;
+ else
+ selected_pc = 0;
+ }
+ if (if_arg)
+ {
+ extra_args = arg;
+ extra_args_len = strlen (arg);
+ }
+
+ if (selected_pc)
+ {
+ if (find_pc_partial_function(selected_pc, (char **)NULL, &low, &high))
+ {
+ addr_string = (char *) xmalloc (26 + extra_args_len);
+ if (extra_args_len)
+ sprintf (addr_string, "*0x%x %s", high, extra_args);
+ else
+ sprintf (addr_string, "*0x%x", high);
+ break_command_1 (addr_string, flag, from_tty);
+ free (addr_string);
+ }
+ else
+ error ("No function contains the specified address");
+ }
+ else
+ error ("Unable to set breakpoint at procedure exit");
+}
+
+
+static void
+break_at_finish_command_1 (arg, flag, from_tty)
+ char *arg;
+ int flag;
+ int from_tty;
+{
+ char *addr_string, *break_string, *beg_addr_string;
+ CORE_ADDR low, high;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct cleanup *old_chain;
+ char *extra_args;
+ int extra_args_len = 0;
+ int i, if_arg = 0;
+
+ if (!arg ||
+ (arg[0] == 'i' && arg[1] == 'f' && (arg[2] == ' ' || arg[2] == '\t')))
+ {
+ if (default_breakpoint_valid)
+ {
+ if (selected_frame)
+ {
+ addr_string = (char *) xmalloc (15);
+ sprintf (addr_string, "*0x%x", selected_frame->pc);
+ if (arg)
+ if_arg = 1;
+ }
+ else
+ error ("No selected frame.");
+ }
+ else
+ error ("No default breakpoint address now.");
+ }
+ else
+ {
+ addr_string = (char *) xmalloc (strlen (arg) + 1);
+ strcpy (addr_string, arg);
+ }
+
+ if (if_arg)
+ {
+ extra_args = arg;
+ extra_args_len = strlen (arg);
+ }
+ else
+ if (arg)
+ {
+ /* get the stuff after the function name or address */
+ extra_args = strchr (arg, ' ');
+ if (extra_args)
+ {
+ extra_args++;
+ extra_args_len = strlen (extra_args);
+ }
+ }
+
+ sals.sals = NULL;
+ sals.nelts = 0;
+
+ beg_addr_string = addr_string;
+ sals = decode_line_1 (&addr_string, 1, (struct symtab *)NULL, 0,
+ (char ***)NULL);
+
+ free (beg_addr_string);
+ old_chain = make_cleanup (free, sals.sals);
+ for (i = 0; (i < sals.nelts); i++)
+ {
+ sal = sals.sals[i];
+ if (find_pc_partial_function (sal.pc, (char **)NULL, &low, &high))
+ {
+ break_string = (char *) xmalloc (extra_args_len + 26);
+ if (extra_args_len)
+ sprintf (break_string, "*0x%x %s", high, extra_args);
+ else
+ sprintf (break_string, "*0x%x", high);
+ break_command_1 (break_string, flag, from_tty);
+ free(break_string);
+ }
+ else
+ error ("No function contains the specified address");
+ }
+ if (sals.nelts > 1)
+ {
+ printf_filtered ("Multiple breakpoints were set.\n");
+ printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+ }
+ do_cleanups(old_chain);
+}
+
+
/* Helper function for break_command_1 and disassemble_command. */
void
@@ -2502,14 +4042,46 @@ resolve_sal_pc (sal)
{
CORE_ADDR pc;
- if (sal->pc == 0 && sal->symtab != 0)
+ if (sal->pc == 0 && sal->symtab != NULL)
{
- pc = find_line_pc (sal->symtab, sal->line);
- if (pc == 0)
+ if (!find_line_pc (sal->symtab, sal->line, &pc))
error ("No line %d in file \"%s\".",
sal->line, sal->symtab->filename);
sal->pc = pc;
}
+
+ if (sal->section == 0 && sal->symtab != NULL)
+ {
+ struct blockvector *bv;
+ struct block *b;
+ struct symbol *sym;
+ int index;
+
+ bv = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
+ if (bv != NULL)
+ {
+ b = BLOCKVECTOR_BLOCK (bv, index);
+ sym = block_function (b);
+ if (sym != NULL)
+ {
+ fixup_symbol_section (sym, sal->symtab->objfile);
+ sal->section = SYMBOL_BFD_SECTION (sym);
+ }
+ else
+ {
+ /* It really is worthwhile to have the section, so we'll just
+ have to look harder. This case can be executed if we have
+ line numbers but no functions (as can happen in assembly
+ source). */
+
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol_by_pc (sal->pc);
+ if (msym)
+ sal->section = SYMBOL_BFD_SECTION (msym);
+ }
+ }
+ }
}
void
@@ -2520,7 +4092,23 @@ break_command (arg, from_tty)
break_command_1 (arg, 0, from_tty);
}
-static void
+void
+break_at_finish_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ break_at_finish_command_1 (arg, 0, from_tty);
+}
+
+void
+break_at_finish_at_depth_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ break_at_finish_at_depth_command_1 (arg, 0, from_tty);
+}
+
+void
tbreak_command (arg, from_tty)
char *arg;
int from_tty;
@@ -2528,6 +4116,14 @@ tbreak_command (arg, from_tty)
break_command_1 (arg, BP_TEMPFLAG, from_tty);
}
+void
+tbreak_at_finish_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ break_at_finish_command_1 (arg, BP_TEMPFLAG, from_tty);
+}
+
static void
hbreak_command (arg, from_tty)
char *arg;
@@ -2544,9 +4140,87 @@ thbreak_command (arg, from_tty)
break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
}
+static void
+stop_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ printf_filtered ("Specify the type of breakpoint to set.\n\
+Usage: stop in <function | address>\n\
+ stop at <line>\n");
+}
+
+static void
+stopin_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ int badInput = 0;
+
+ if (arg == (char *)NULL)
+ badInput = 1;
+ else if (*arg != '*')
+ {
+ char *argptr = arg;
+ int hasColon = 0;
+
+ /* look for a ':'. If this is a line number specification, then say
+ it is bad, otherwise, it should be an address or function/method
+ name */
+ while (*argptr && !hasColon)
+ {
+ hasColon = (*argptr == ':');
+ argptr++;
+ }
+
+ if (hasColon)
+ badInput = (*argptr != ':'); /* Not a class::method */
+ else
+ badInput = isdigit(*arg); /* a simple line number */
+ }
+
+ if (badInput)
+ printf_filtered("Usage: stop in <function | address>\n");
+ else
+ break_command_1 (arg, 0, from_tty);
+}
+
+static void
+stopat_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ int badInput = 0;
+
+ if (arg == (char *)NULL || *arg == '*') /* no line number */
+ badInput = 1;
+ else
+ {
+ char *argptr = arg;
+ int hasColon = 0;
+
+ /* look for a ':'. If there is a '::' then get out, otherwise
+ it is probably a line number. */
+ while (*argptr && !hasColon)
+ {
+ hasColon = (*argptr == ':');
+ argptr++;
+ }
+
+ if (hasColon)
+ badInput = (*argptr == ':'); /* we have class::method */
+ else
+ badInput = !isdigit(*arg); /* not a line number */
+ }
+
+ if (badInput)
+ printf_filtered("Usage: stop at <line>\n");
+ else
+ break_command_1 (arg, 0, from_tty);
+}
+
/* ARGSUSED */
-/* accessflag: 0: watch write, 1: watch read, 2: watch access(read or write)
-*/
+/* accessflag: 0: watch write, 1: watch read, 2: watch access(read or write) */
static void
watch_command_1 (arg, accessflag, from_tty)
char *arg;
@@ -2558,7 +4232,8 @@ watch_command_1 (arg, accessflag, from_tty)
struct expression *exp;
struct block *exp_valid_block;
struct value *val, *mark;
- struct frame_info *frame, *prev_frame;
+ struct frame_info *frame;
+ struct frame_info *prev_frame = NULL;
char *exp_start = NULL;
char *exp_end = NULL;
char *tok, *end_tok;
@@ -2566,13 +4241,11 @@ watch_command_1 (arg, accessflag, from_tty)
char *cond_start = NULL;
char *cond_end = NULL;
struct expression *cond = NULL;
- int i, other_type_used, target_resources_ok;
+ int i, other_type_used, target_resources_ok = 0;
enum bptype bp_type;
int mem_cnt = 0;
- sal.pc = 0;
- sal.symtab = NULL;
- sal.line = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* Parse arguments. */
innermost_block = NULL;
@@ -2620,6 +4293,28 @@ watch_command_1 (arg, accessflag, from_tty)
if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint)
error ("Target resources have been allocated for other types of watchpoints.");
}
+
+#if defined(HPUXHPPA)
+ /* On HP-UX if you set a h/w
+ watchpoint before the "run" command, the inferior dies with a e.g.,
+ SIGILL once you start it. I initially believed this was due to a
+ bad interaction between page protection traps and the initial
+ startup sequence by the dynamic linker.
+
+ However, I tried avoiding that by having HP-UX's implementation of
+ TARGET_CAN_USE_HW_WATCHPOINT return FALSE if there was no inferior_pid
+ yet, which forced slow watches before a "run" or "attach", and it
+ still fails somewhere in the startup code.
+
+ Until I figure out what's happening, I'm disallowing watches altogether
+ before the "run" or "attach" command. We'll tell the user they must
+ set watches after getting the program started. */
+ if (! target_has_execution)
+ {
+ warning ("can't do that without a running program; try \"break main\", \"run\" first");
+ return;
+ }
+#endif /* HPUXHPPA */
/* Now set up the breakpoint. */
b = set_raw_breakpoint (sal);
@@ -2655,15 +4350,15 @@ watch_command_1 (arg, accessflag, from_tty)
expression. */
if (innermost_block)
{
- struct breakpoint *scope_breakpoint;
- struct symtab_and_line scope_sal;
-
if (prev_frame)
{
- scope_sal.pc = get_frame_pc (prev_frame);
- scope_sal.symtab = NULL;
- scope_sal.line = 0;
-
+ struct breakpoint *scope_breakpoint;
+ struct symtab_and_line scope_sal;
+
+ INIT_SAL (&scope_sal); /* initialize to zeroes */
+ scope_sal.pc = get_frame_pc (prev_frame);
+ scope_sal.section = find_pc_overlay (scope_sal.pc);
+
scope_breakpoint = set_raw_breakpoint (scope_sal);
set_breakpoint_count (breakpoint_count + 1);
scope_breakpoint->number = breakpoint_count;
@@ -2693,11 +4388,20 @@ watch_command_1 (arg, accessflag, from_tty)
in hardware. If the watchpoint can not be handled
in hardware return zero. */
+#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_size) \
+ ((byte_size) <= (REGISTER_SIZE))
+#endif
+
static int
can_use_hardware_watchpoint (v)
struct value *v;
{
int found_memory_cnt = 0;
+
+ /* Did the user specifically forbid us to use hardware watchpoints? */
+ if (! can_use_hw_watchpoints)
+ return 0;
/* Make sure all the intermediate values are in memory. Also make sure
we found at least one memory expression. Guards against watch 0x12345,
@@ -2707,7 +4411,7 @@ can_use_hardware_watchpoint (v)
{
if (v->lval == lval_memory)
{
- if (TYPE_LENGTH (VALUE_TYPE (v)) <= REGISTER_SIZE)
+ if (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (TYPE_LENGTH (VALUE_TYPE (v))))
found_memory_cnt++;
}
else if (v->lval != not_lval && v->modifiable == 0)
@@ -2780,7 +4484,7 @@ until_break_command (arg, from_tty)
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
- old_chain = make_cleanup(delete_breakpoint, breakpoint);
+ old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
/* Keep within the current frame */
@@ -2789,7 +4493,7 @@ until_break_command (arg, from_tty)
sal = find_pc_line (prev_frame->pc, 0);
sal.pc = prev_frame->pc;
breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
- make_cleanup(delete_breakpoint, breakpoint);
+ make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
}
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
@@ -2827,7 +4531,10 @@ struct sal_chain
struct symtab_and_line sal;
};
-#if 0
+/* Not really used -- invocation in handle_gnu_4_16_catch_command
+ had been commented out in the v.4.16 sources, and stays
+ disabled there now because "catch NAME" syntax isn't allowed.
+ pai/1997-07-11 */
/* This isn't used; I don't know what it was for. */
/* For each catch clause identified in ARGS, run FUNCTION
with that clause as an argument. */
@@ -2871,8 +4578,8 @@ map_catch_names (args, function)
#if 0
if (function (p))
{
- struct sal_chain *next
- = (struct sal_chain *)alloca (sizeof (struct sal_chain));
+ struct sal_chain *next = (struct sal_chain *)
+ alloca (sizeof (struct sal_chain));
next->next = sal_chain;
next->sal = get_catch_sal (p);
sal_chain = next;
@@ -2887,7 +4594,6 @@ map_catch_names (args, function)
while (*p == ' ' || *p == '\t') p++;
}
}
-#endif /* 0 */
/* This shares a lot of code with `print_frame_label_vars' from stack.c. */
@@ -3003,10 +4709,401 @@ get_catch_sals (this_level_only)
return sals;
}
+static void
+ep_skip_leading_whitespace (s)
+ char ** s;
+{
+ if ((s == NULL) || (*s == NULL))
+ return;
+ while (isspace(**s))
+ *s += 1;
+}
+
+/* This function examines a string, and attempts to find a token
+ that might be an event name in the leading characters. If a
+ possible match is found, a pointer to the last character of
+ the token is returned. Else, NULL is returned. */
+static char *
+ep_find_event_name_end (arg)
+ char * arg;
+{
+ char * s = arg;
+ char * event_name_end = NULL;
+
+ /* If we could depend upon the presense of strrpbrk, we'd use that... */
+ if (arg == NULL)
+ return NULL;
+
+ /* We break out of the loop when we find a token delimiter.
+ Basically, we're looking for alphanumerics and underscores;
+ anything else delimites the token. */
+ while (*s != '\0')
+ {
+ if (! isalnum(*s) && (*s != '_'))
+ break;
+ event_name_end = s;
+ s++;
+ }
+
+ return event_name_end;
+}
+
+
+/* This function attempts to parse an optional "if <cond>" clause
+ from the arg string. If one is not found, it returns NULL.
+
+ Else, it returns a pointer to the condition string. (It does not
+ attempt to evaluate the string against a particular block.) And,
+ it updates arg to point to the first character following the parsed
+ if clause in the arg string. */
+static char *
+ep_parse_optional_if_clause (arg)
+ char ** arg;
+{
+ char * cond_string;
+
+ if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace((*arg)[2]))
+ return NULL;
+
+ /* Skip the "if" keyword. */
+ (*arg) += 2;
+
+ /* Skip any extra leading whitespace, and record the start of the
+ condition string. */
+ ep_skip_leading_whitespace (arg);
+ cond_string = *arg;
+
+ /* Assume that the condition occupies the remainder of the arg string. */
+ (*arg) += strlen (cond_string);
+
+ return cond_string;
+}
+
+/* This function attempts to parse an optional filename from the arg
+ string. If one is not found, it returns NULL.
+
+ Else, it returns a pointer to the parsed filename. (This function
+ makes no attempt to verify that a file of that name exists, or is
+ accessible.) And, it updates arg to point to the first character
+ following the parsed filename in the arg string.
+
+ Note that clients needing to preserve the returned filename for
+ future access should copy it to their own buffers. */
+static char *
+ep_parse_optional_filename (arg)
+ char ** arg;
+{
+ static char filename [1024];
+ char * arg_p = *arg;
+ int i;
+ char c;
+
+ if ((*arg_p == '\0') || isspace (*arg_p))
+ return NULL;
+
+ for (i=0; ; i++)
+ {
+ c = *arg_p;
+ if (isspace (c))
+ c = '\0';
+ filename[i] = c;
+ if (c == '\0')
+ break;
+ arg_p++;
+ }
+ *arg = arg_p;
+
+ return filename;
+}
+
+/* Commands to deal with catching events, such as signals, exceptions,
+ process start/exit, etc. */
+
+typedef enum {catch_fork, catch_vfork} catch_fork_kind;
+
+static void
+catch_fork_command_1 (fork_kind, arg, tempflag, from_tty)
+ catch_fork_kind fork_kind;
+ char * arg;
+ int tempflag;
+ int from_tty;
+{
+ char * cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch [v]fork
+ catch [v]fork if <cond>
+
+ First, check if there's an if clause. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* If this target supports it, create a fork or vfork catchpoint
+ and enable reporting of such events. */
+ switch (fork_kind) {
+ case catch_fork :
+ create_fork_event_catchpoint (tempflag, cond_string);
+ break;
+ case catch_vfork :
+ create_vfork_event_catchpoint (tempflag, cond_string);
+ break;
+ default :
+ error ("unsupported or unknown fork kind; cannot catch it");
+ break;
+ }
+}
+
+static void
+catch_exec_command_1 (arg, tempflag, from_tty)
+ char * arg;
+ int tempflag;
+ int from_tty;
+{
+ char * cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch exec
+ catch exec if <cond>
+
+ First, check if there's an if clause. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* If this target supports it, create an exec catchpoint
+ and enable reporting of such events. */
+ create_exec_event_catchpoint (tempflag, cond_string);
+}
+
+#if defined(SOLIB_ADD)
+static void
+catch_load_command_1 (arg, tempflag, from_tty)
+ char * arg;
+ int tempflag;
+ int from_tty;
+{
+ char * dll_pathname = NULL;
+ char * cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch load
+ catch load if <cond>
+ catch load <filename>
+ catch load <filename> if <cond>
+
+ The user is not allowed to specify the <filename> after an
+ if clause.
+
+ We'll ignore the pathological case of a file named "if".
+
+ First, check if there's an if clause. If so, then there
+ cannot be a filename. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ /* If there was an if clause, then there cannot be a filename.
+ Else, there might be a filename and an if clause. */
+ if (cond_string == NULL)
+ {
+ dll_pathname = ep_parse_optional_filename (&arg);
+ ep_skip_leading_whitespace (&arg);
+ cond_string = ep_parse_optional_if_clause (&arg);
+ }
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* Create a load breakpoint that only triggers when a load of
+ the specified dll (or any dll, if no pathname was specified)
+ occurs. */
+ SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string);
+}
+
+static void
+catch_unload_command_1 (arg, tempflag, from_tty)
+ char * arg;
+ int tempflag;
+ int from_tty;
+{
+ char * dll_pathname = NULL;
+ char * cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch unload
+ catch unload if <cond>
+ catch unload <filename>
+ catch unload <filename> if <cond>
+
+ The user is not allowed to specify the <filename> after an
+ if clause.
+
+ We'll ignore the pathological case of a file named "if".
+
+ First, check if there's an if clause. If so, then there
+ cannot be a filename. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ /* If there was an if clause, then there cannot be a filename.
+ Else, there might be a filename and an if clause. */
+ if (cond_string == NULL)
+ {
+ dll_pathname = ep_parse_optional_filename (&arg);
+ ep_skip_leading_whitespace (&arg);
+ cond_string = ep_parse_optional_if_clause (&arg);
+ }
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* Create an unload breakpoint that only triggers when an unload of
+ the specified dll (or any dll, if no pathname was specified)
+ occurs. */
+ SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string);
+}
+#endif /* SOLIB_ADD */
+
/* Commands to deal with catching exceptions. */
+/* Set a breakpoint at the specified callback routine for an
+ exception event callback */
+
static void
-catch_command_1 (arg, tempflag, from_tty)
+create_exception_catchpoint (tempflag, cond_string, ex_event, sal)
+ int tempflag;
+ char * cond_string;
+ enum exception_event_kind ex_event;
+ struct symtab_and_line * sal;
+{
+ struct breakpoint * b;
+ int i;
+ int thread = -1; /* All threads. */
+
+ if (!sal) /* no exception support? */
+ return;
+
+ b = set_raw_breakpoint (*sal);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+ b->addr_string = NULL;
+ b->enable = enabled;
+ b->disposition = tempflag ? del : donttouch;
+ switch (ex_event)
+ {
+ case EX_EVENT_THROW:
+ b->type = bp_catch_throw;
+ break;
+ case EX_EVENT_CATCH:
+ b->type = bp_catch_catch;
+ break;
+ default: /* error condition */
+ b->type = bp_none;
+ b->enable = disabled;
+ error ("Internal error -- invalid catchpoint kind");
+ }
+ mention (b);
+}
+
+/* Deal with "catch catch" and "catch throw" commands */
+
+static void
+catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
+ enum exception_event_kind ex_event;
+ char * arg;
+ int tempflag;
+ int from_tty;
+{
+ char * cond_string = NULL;
+ struct symtab_and_line * sal = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ if ((ex_event != EX_EVENT_THROW) &&
+ (ex_event != EX_EVENT_CATCH))
+ error ("Unsupported or unknown exception event; cannot catch it");
+
+ /* See if we can find a callback routine */
+ sal = target_enable_exception_callback (ex_event, 1);
+
+ if (sal)
+ {
+ /* We have callbacks from the runtime system for exceptions.
+ Set a breakpoint on the sal found, if no errors */
+ if (sal != (struct symtab_and_line *) -1)
+ create_exception_catchpoint (tempflag, cond_string, ex_event, sal);
+ else
+ return; /* something went wrong with setting up callbacks */
+ }
+ else
+ {
+ /* No callbacks from runtime system for exceptions.
+ Try GNU C++ exception breakpoints using labels in debug info. */
+ if (ex_event == EX_EVENT_CATCH)
+ {
+ handle_gnu_4_16_catch_command (arg, tempflag, from_tty);
+ }
+ else if (ex_event == EX_EVENT_THROW)
+ {
+ /* Set a breakpoint on __raise_exception () */
+
+ fprintf_filtered (gdb_stderr, "Unsupported with this platform/compiler combination.\n");
+ fprintf_filtered (gdb_stderr, "Perhaps you can achieve the effect you want by setting\n");
+ fprintf_filtered (gdb_stderr, "a breakpoint on __raise_exception().\n");
+ }
+ }
+}
+
+/* Cover routine to allow wrapping target_enable_exception_catchpoints
+ inside a catch_errors */
+
+static int
+cover_target_enable_exception_callback (arg)
+ PTR arg;
+{
+ args_for_catchpoint_enable *args = arg;
+ struct symtab_and_line *sal;
+ sal = target_enable_exception_callback (args->kind, args->enable);
+ if (sal == NULL)
+ return 0;
+ else if (sal == (struct symtab_and_line *) -1)
+ return -1;
+ else
+ return 1; /*is valid*/
+}
+
+
+
+/* This is the original v.4.16 and earlier version of the
+ catch_command_1() function. Now that other flavours of "catch"
+ have been introduced, and since exception handling can be handled
+ in other ways (through target ops) also, this is used only for the
+ GNU C++ exception handling system.
+ Note: Only the "catch" flavour of GDB 4.16 is handled here. The
+ "catch NAME" is now no longer allowed in catch_command_1(). Also,
+ there was no code in GDB 4.16 for "catch throw".
+
+ Called from catch_exception_command_1 () */
+
+
+static void
+handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
char *arg;
int tempflag;
int from_tty;
@@ -3021,8 +5118,7 @@ catch_command_1 (arg, tempflag, from_tty)
char *save_arg;
int i;
- sal.line = sal.pc = sal.end = 0;
- sal.symtab = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', all active catch clauses
are breakpointed. */
@@ -3037,7 +5133,13 @@ catch_command_1 (arg, tempflag, from_tty)
{
/* Grab selected catch clauses. */
error ("catch NAME not implemented");
+
#if 0
+ /* Not sure why this code has been disabled. I'm leaving
+ it disabled. We can never come here now anyway
+ since we don't allow the "catch NAME" syntax.
+ pai/1997-07-11 */
+
/* This isn't used; I don't know what it was for. */
sals = map_catch_names (arg, catch_breakpoint);
#endif
@@ -3068,12 +5170,18 @@ catch_command_1 (arg, tempflag, from_tty)
sal = sals.sals[i];
if (from_tty)
- describe_other_breakpoints (sal.pc);
+ describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
- b->type = bp_breakpoint;
+ b->type = bp_breakpoint; /* Important -- this is an ordinary breakpoint.
+ For platforms with callback support for exceptions,
+ create_exception_catchpoint() will create special
+ bp types (bp_catch_catch and bp_catch_throw), and
+ there is code in insert_breakpoints() and elsewhere
+ that depends on that. */
+
b->cond = cond;
b->enable = enabled;
b->disposition = tempflag ? del : donttouch;
@@ -3089,11 +5197,161 @@ catch_command_1 (arg, tempflag, from_tty)
free ((PTR)sals.sals);
}
+#if 0
+/* This creates a temporary internal breakpoint
+ just to placate infrun */
+static struct breakpoint *
+create_temp_exception_breakpoint (pc)
+ CORE_ADDR pc;
+{
+ struct symtab_and_line sal;
+ struct breakpoint *b;
+
+ INIT_SAL(&sal);
+ sal.pc = pc;
+ sal.symtab = NULL;
+ sal.line = 0;
+
+ b = set_raw_breakpoint (sal);
+ if (!b)
+ error ("Internal error -- couldn't set temp exception breakpoint");
+
+ b->type = bp_breakpoint;
+ b->disposition = del;
+ b->enable = enabled;
+ b->silent = 1;
+ b->number = internal_breakpoint_number--;
+ return b;
+}
+#endif
+
+static void
+catch_command_1 (arg, tempflag, from_tty)
+ char *arg;
+ int tempflag;
+ int from_tty;
+{
+
+ /* The first argument may be an event name, such as "start" or "load".
+ If so, then handle it as such. If it doesn't match an event name,
+ then attempt to interpret it as an exception name. (This latter is
+ the v4.16-and-earlier GDB meaning of the "catch" command.)
+
+ First, try to find the bounds of what might be an event name. */
+ char * arg1_start = arg;
+ char * arg1_end;
+ int arg1_length;
+
+ if (arg1_start == NULL)
+ {
+ /* Old behaviour was to use pre-v-4.16 syntax */
+ /* catch_throw_command_1 (arg1_start, tempflag, from_tty); */
+ /* return; */
+ /* Now, this is not allowed */
+ error ("Catch requires an event name.");
+
+ }
+ arg1_end = ep_find_event_name_end (arg1_start);
+ if (arg1_end == NULL)
+ error ("catch requires an event");
+ arg1_length = arg1_end + 1 - arg1_start;
+
+ /* Try to match what we found against known event names. */
+ if (strncmp (arg1_start, "signal", arg1_length) == 0)
+ {
+ error ("Catch of signal not yet implemented");
+ }
+ else if (strncmp (arg1_start, "catch", arg1_length) == 0)
+ {
+ catch_exception_command_1 (EX_EVENT_CATCH, arg1_end+1, tempflag, from_tty);
+ }
+ else if (strncmp (arg1_start, "throw", arg1_length) == 0)
+ {
+ catch_exception_command_1 (EX_EVENT_THROW, arg1_end+1, tempflag, from_tty);
+ }
+ else if (strncmp (arg1_start, "thread_start", arg1_length) == 0)
+ {
+ error ("Catch of thread_start not yet implemented");
+ }
+ else if (strncmp (arg1_start, "thread_exit", arg1_length) == 0)
+ {
+ error ("Catch of thread_exit not yet implemented");
+ }
+ else if (strncmp (arg1_start, "thread_join", arg1_length) == 0)
+ {
+ error ("Catch of thread_join not yet implemented");
+ }
+ else if (strncmp (arg1_start, "start", arg1_length) == 0)
+ {
+ error ("Catch of start not yet implemented");
+ }
+ else if (strncmp (arg1_start, "exit", arg1_length) == 0)
+ {
+ error ("Catch of exit not yet implemented");
+ }
+ else if (strncmp (arg1_start, "fork", arg1_length) == 0)
+ {
+#if defined(CHILD_INSERT_FORK_CATCHPOINT)
+ catch_fork_command_1 (catch_fork, arg1_end+1, tempflag, from_tty);
+#else
+ error ("Catch of fork not yet implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "vfork", arg1_length) == 0)
+ {
+#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
+ catch_fork_command_1 (catch_vfork, arg1_end+1, tempflag, from_tty);
+#else
+ error ("Catch of vfork not yet implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "exec", arg1_length) == 0)
+ {
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+ catch_exec_command_1 (arg1_end+1, tempflag, from_tty);
+#else
+ error ("Catch of exec not yet implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "load", arg1_length) == 0)
+ {
+#if defined(SOLIB_ADD)
+ catch_load_command_1 (arg1_end+1, tempflag, from_tty);
+#else
+ error ("Catch of load not implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "unload", arg1_length) == 0)
+ {
+#if defined(SOLIB_ADD)
+ catch_unload_command_1 (arg1_end+1, tempflag, from_tty);
+#else
+ error ("Catch of load not implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "stop", arg1_length) == 0)
+ {
+ error ("Catch of stop not yet implemented");
+ }
+
+ /* This doesn't appear to be an event name */
+
+ else
+ {
+ /* Pre-v.4.16 behaviour was to treat the argument
+ as the name of an exception */
+ /* catch_throw_command_1 (arg1_start, tempflag, from_tty); */
+ /* Now this is not allowed */
+ error ("Unknown event kind specified for catch");
+
+ }
+}
+
/* Used by the gui, could be made a worker for other things. */
struct breakpoint *
set_breakpoint_sal (sal)
-struct symtab_and_line sal;
+ struct symtab_and_line sal;
{
struct breakpoint *b;
b = set_raw_breakpoint (sal);
@@ -3140,12 +5398,23 @@ catch_command (arg, from_tty)
catch_command_1 (arg, 0, from_tty);
}
+
+static void
+tcatch_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ catch_command_1 (arg, 1, from_tty);
+}
+
+
static void
clear_command (arg, from_tty)
char *arg;
int from_tty;
{
register struct breakpoint *b, *b1;
+ int default_match;
struct symtabs_and_lines sals;
struct symtab_and_line sal;
register struct breakpoint *found;
@@ -3154,34 +5423,68 @@ clear_command (arg, from_tty)
if (arg)
{
sals = decode_line_spec (arg, 1);
+ default_match = 0;
}
else
{
- sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line));
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ INIT_SAL (&sal); /* initialize to zeroes */
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
- sal.pc = 0;
+ sal.pc = default_breakpoint_address;
if (sal.symtab == 0)
error ("No source file specified.");
sals.sals[0] = sal;
sals.nelts = 1;
+
+ default_match = 1;
}
+ /* For each line spec given, delete bps which correspond
+ to it. We do this in two loops: the first loop looks at
+ the initial bp(s) in the chain which should be deleted,
+ the second goes down the rest of the chain looking ahead
+ one so it can take those bps off the chain without messing
+ up the chain. */
+
+
for (i = 0; i < sals.nelts; i++)
{
/* If exact pc given, clear bpts at that pc.
- But if sal.pc is zero, clear all bpts on specified line. */
+ If line given (pc == 0), clear all bpts on specified line.
+ If defaulting, clear all bpts on default line
+ or at default pc.
+
+ defaulting sal.pc != 0 tests to do
+
+ 0 1 pc
+ 1 1 pc _and_ line
+ 0 0 line
+ 1 0 <can't happen> */
+
sal = sals.sals[i];
found = (struct breakpoint *) 0;
+
+
while (breakpoint_chain
- && (sal.pc
- ? breakpoint_chain->address == sal.pc
- : (breakpoint_chain->source_file != NULL
- && sal.symtab != NULL
- && STREQ (breakpoint_chain->source_file,
- sal.symtab->filename)
- && breakpoint_chain->line_number == sal.line)))
+ /* Why don't we check here that this is not
+ a watchpoint, etc., as we do below?
+ I can't make it fail, but don't know
+ what's stopping the failure: a watchpoint
+ of the same address as "sal.pc" should
+ wind up being deleted. */
+
+ && ( ((sal.pc && (breakpoint_chain->address == sal.pc)) &&
+ (overlay_debugging == 0 ||
+ breakpoint_chain->section == sal.section))
+ || ((default_match || (0 == sal.pc))
+ && breakpoint_chain->source_file != NULL
+ && sal.symtab != NULL
+ && STREQ (breakpoint_chain->source_file, sal.symtab->filename)
+ && breakpoint_chain->line_number == sal.line)))
+
{
b1 = breakpoint_chain;
breakpoint_chain = b1->next;
@@ -3190,17 +5493,23 @@ clear_command (arg, from_tty)
}
ALL_BREAKPOINTS (b)
- while (b->next
- && b->next->type != bp_watchpoint
- && b->next->type != bp_hardware_watchpoint
- && b->next->type != bp_read_watchpoint
- && b->next->type != bp_access_watchpoint
- && (sal.pc
- ? b->next->address == sal.pc
- : (b->next->source_file != NULL
- && sal.symtab != NULL
- && STREQ (b->next->source_file, sal.symtab->filename)
- && b->next->line_number == sal.line)))
+
+ while (b->next
+ && b->next->type != bp_none
+ && b->next->type != bp_watchpoint
+ && b->next->type != bp_hardware_watchpoint
+ && b->next->type != bp_read_watchpoint
+ && b->next->type != bp_access_watchpoint
+ && ( ((sal.pc && (b->next->address == sal.pc)) &&
+ (overlay_debugging == 0 ||
+ b->next->section == sal.section))
+ || ((default_match || (0 == sal.pc))
+ && b->next->source_file != NULL
+ && sal.symtab != NULL
+ && STREQ (b->next->source_file, sal.symtab->filename)
+ && b->next->line_number == sal.line)))
+
+
{
b1 = b->next;
b->next = b1->next;
@@ -3231,17 +5540,26 @@ clear_command (arg, from_tty)
free ((PTR)sals.sals);
}
-/* Delete breakpoint in BS if they are `delete' breakpoints.
+/* Delete breakpoint in BS if they are `delete' breakpoints and
+ all breakpoints that are marked for deletion, whether hit or not.
This is called after any breakpoint is hit, or after errors. */
void
breakpoint_auto_delete (bs)
bpstat bs;
{
+ struct breakpoint *b, *temp;
+
for (; bs; bs = bs->next)
if (bs->breakpoint_at && bs->breakpoint_at->disposition == del
&& bs->stop)
delete_breakpoint (bs->breakpoint_at);
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->disposition == del_at_next_stop)
+ delete_breakpoint (b);
+ }
}
/* Delete a breakpoint and clean up all traces of it in the data structures. */
@@ -3253,15 +5571,55 @@ delete_breakpoint (bpt)
register struct breakpoint *b;
register bpstat bs;
+ if (bpt == NULL)
+ error ("Internal error (attempted to delete a NULL breakpoint)");
+
+
+ /* Has this bp already been deleted? This can happen because multiple
+ lists can hold pointers to bp's. bpstat lists are especial culprits.
+
+ One example of this happening is a watchpoint's scope bp. When the
+ scope bp triggers, we notice that the watchpoint is out of scope, and
+ delete it. We also delete its scope bp. But the scope bp is marked
+ "auto-deleting", and is already on a bpstat. That bpstat is then
+ checked for auto-deleting bp's, which are deleted.
+
+ A real solution to this problem might involve reference counts in bp's,
+ and/or giving them pointers back to their referencing bpstat's, and
+ teaching delete_breakpoint to only free a bp's storage when no more
+ references were extent. A cheaper bandaid was chosen. */
+ if (bpt->type == bp_none)
+ return;
+
if (delete_breakpoint_hook)
delete_breakpoint_hook (bpt);
if (bpt->inserted)
- remove_breakpoint (bpt);
+ remove_breakpoint (bpt, mark_uninserted);
if (breakpoint_chain == bpt)
breakpoint_chain = bpt->next;
+ /* If we have callback-style exception catchpoints, don't go through
+ the adjustments to the C++ runtime library etc. if the inferior
+ isn't actually running. target_enable_exception_callback for a
+ null target ops vector gives an undesirable error message, so we
+ check here and avoid it. Since currently (1997-09-17) only HP-UX aCC's
+ exceptions are supported in this way, it's OK for now. FIXME */
+ if (ep_is_exception_catchpoint (bpt) && target_has_execution)
+ {
+ static char message1[] = "Error in deleting catchpoint %d:\n";
+ static char message[sizeof (message1) + 30];
+ args_for_catchpoint_enable args;
+
+ sprintf (message, message1, bpt->number); /* Format possible error msg */
+ args.kind = bpt->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW;
+ args.enable = 0;
+ catch_errors (cover_target_enable_exception_callback, &args,
+ message, RETURN_MASK_ALL);
+ }
+
+
ALL_BREAKPOINTS (b)
if (b->next == bpt)
{
@@ -3269,19 +5627,44 @@ delete_breakpoint (bpt)
break;
}
- check_duplicates (bpt->address);
+ /* Before turning off the visuals for the bp, check to see that
+ there are no other bps at the same address. */
+ if (tui_version)
+ {
+ int clearIt;
+
+ ALL_BREAKPOINTS (b)
+ {
+ clearIt = (b->address != bpt->address);
+ if (!clearIt)
+ break;
+ }
+
+ if (clearIt)
+ {
+ TUIDO(((TuiOpaqueFuncPtr)tui_vAllSetHasBreakAt, bpt, 0));
+ TUIDO(((TuiOpaqueFuncPtr)tuiUpdateAllExecInfos));
+ }
+ }
+
+ check_duplicates (bpt->address, bpt->section);
/* If this breakpoint was inserted, and there is another breakpoint
at the same address, we need to insert the other breakpoint. */
if (bpt->inserted
&& bpt->type != bp_hardware_watchpoint
&& bpt->type != bp_read_watchpoint
- && bpt->type != bp_access_watchpoint)
+ && bpt->type != bp_access_watchpoint
+ && bpt->type != bp_catch_fork
+ && bpt->type != bp_catch_vfork
+ && bpt->type != bp_catch_exec)
{
ALL_BREAKPOINTS (b)
if (b->address == bpt->address
+ && b->section == bpt->section
&& !b->duplicate
&& b->enable != disabled
- && b->enable != shlib_disabled)
+ && b->enable != shlib_disabled
+ && b->enable != call_disabled)
{
int val;
val = target_insert_breakpoint (b->address, b->shadow_contents);
@@ -3303,35 +5686,77 @@ delete_breakpoint (bpt)
free (bpt->cond_string);
if (bpt->addr_string != NULL)
free (bpt->addr_string);
+ if (bpt->exp != NULL)
+ free (bpt->exp);
if (bpt->exp_string != NULL)
free (bpt->exp_string);
+ if (bpt->val != NULL)
+ value_free (bpt->val);
if (bpt->source_file != NULL)
free (bpt->source_file);
+ if (bpt->dll_pathname != NULL)
+ free (bpt->dll_pathname);
+ if (bpt->triggered_dll_pathname != NULL)
+ free (bpt->triggered_dll_pathname);
+ if (bpt->exec_pathname != NULL)
+ free (bpt->exec_pathname);
/* Be sure no bpstat's are pointing at it after it's been freed. */
/* FIXME, how can we find all bpstat's?
We just check stop_bpstat for now. */
for (bs = stop_bpstat; bs; bs = bs->next)
if (bs->breakpoint_at == bpt)
- bs->breakpoint_at = NULL;
+ {
+ bs->breakpoint_at = NULL;
+
+ /* we'd call bpstat_clear_actions, but that free's stuff and due
+ to the multiple pointers pointing to one item with no
+ reference counts found anywhere through out the bpstat's (how
+ do you spell fragile?), we don't want to free things twice --
+ better a memory leak than a corrupt malloc pool! */
+ bs->commands = NULL;
+ bs->old_val = NULL;
+ }
+ /* On the chance that someone will soon try again to delete this same
+ bp, we mark it as deleted before freeing its storage. */
+ bpt->type = bp_none;
+
free ((PTR)bpt);
}
-static void
+void
delete_command (arg, from_tty)
char *arg;
int from_tty;
{
+ struct breakpoint *b, *temp;
if (arg == 0)
{
+ int breaks_to_delete = 0;
+
+ /* Delete all breakpoints if no argument.
+ Do not delete internal or call-dummy breakpoints, these
+ have to be deleted with an explicit breakpoint number argument. */
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->type != bp_call_dummy &&
+ b->type != bp_shlib_event &&
+ b->number >= 0)
+ breaks_to_delete = 1;
+ }
+
/* Ask user only if there are some breakpoints to delete. */
if (!from_tty
- || (breakpoint_chain && query ("Delete all breakpoints? ")))
+ || (breaks_to_delete && query ("Delete all breakpoints? ")))
{
- /* No arg; clear all breakpoints. */
- while (breakpoint_chain)
- delete_breakpoint (breakpoint_chain);
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->type != bp_call_dummy &&
+ b->type != bp_shlib_event &&
+ b->number >= 0)
+ delete_breakpoint (b);
+ }
}
}
else
@@ -3344,7 +5769,7 @@ delete_command (arg, from_tty)
static int
breakpoint_re_set_one (bint)
- char *bint;
+ PTR bint;
{
struct breakpoint *b = (struct breakpoint *)bint; /* get past catch_errs */
struct value *mark;
@@ -3355,8 +5780,13 @@ breakpoint_re_set_one (bint)
switch (b->type)
{
+ case bp_none:
+ warning ("attempted to reset apparently deleted breakpoint #%d?\n", b->number);
+ return 0;
case bp_breakpoint:
case bp_hardware_breakpoint:
+ case bp_catch_load:
+ case bp_catch_unload:
if (b->addr_string == NULL)
{
/* Anything without a string can't be re-set. */
@@ -3410,8 +5840,10 @@ breakpoint_re_set_one (bint)
strlen (sals.sals[i].symtab->filename));
b->line_number = sals.sals[i].line;
b->address = sals.sals[i].pc;
-
- check_duplicates (b->address);
+
+ /* Used to check for duplicates here, but that can
+ cause trouble, as it doesn't check for disable
+ breakpoints. */
mention (b);
@@ -3419,7 +5851,14 @@ breakpoint_re_set_one (bint)
rather than once for every breakpoint. */
breakpoints_changed ();
}
+ b->section = sals.sals[i].section;
b->enable = save_enable; /* Restore it, this worked. */
+
+
+ /* Now that this is re-enabled, check_duplicates
+ can be used. */
+ check_duplicates (b->address, b->section);
+
}
free ((PTR)sals.sals);
break;
@@ -3437,9 +5876,13 @@ breakpoint_re_set_one (bint)
particular level, but that's going to be less stable than filenames
or functionnames. */
/* So for now, just use a global context. */
+ if (b->exp)
+ free ((PTR)b->exp);
b->exp = parse_expression (b->exp_string);
b->exp_valid_block = innermost_block;
mark = value_mark ();
+ if (b->val)
+ value_free (b->val);
b->val = evaluate_expression (b->exp);
release_value (b->val);
if (VALUE_LAZY (b->val))
@@ -3448,13 +5891,25 @@ breakpoint_re_set_one (bint)
if (b->cond_string != NULL)
{
s = b->cond_string;
+ if (b->cond)
+ free ((PTR)b->cond);
b->cond = parse_exp_1 (&s, (struct block *)0, 0);
}
if (b->enable == enabled)
mention (b);
value_free_to_mark (mark);
break;
-
+ case bp_catch_catch:
+ case bp_catch_throw:
+ break;
+ /* We needn't really do anything to reset these, since the mask
+ that requests them is unaffected by e.g., new libraries being
+ loaded. */
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ break;
+
default:
printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
/* fall through */
@@ -3499,8 +5954,7 @@ breakpoint_re_set ()
ALL_BREAKPOINTS_SAFE (b, temp)
{
sprintf (message, message1, b->number); /* Format possible error msg */
- catch_errors (breakpoint_re_set_one, (char *) b, message,
- RETURN_MASK_ALL);
+ catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
}
set_language (save_language);
input_radix = save_input_radix;
@@ -3509,6 +5963,7 @@ breakpoint_re_set ()
create_longjmp_breakpoint ("longjmp");
create_longjmp_breakpoint ("_longjmp");
create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint ("_siglongjmp");
create_longjmp_breakpoint (NULL);
#endif
@@ -3524,6 +5979,21 @@ breakpoint_re_set ()
If from_tty is nonzero, it prints a message to that effect,
which ends with a period (no newline). */
+/* Reset the thread number of this breakpoint:
+
+ - If the breakpoint is for all threads, leave it as-is.
+ - Else, reset it to the current thread for inferior_pid. */
+void
+breakpoint_re_set_thread (b)
+ struct breakpoint * b;
+{
+ if (b->thread != -1)
+ {
+ if (in_thread_list (inferior_pid))
+ b->thread = pid_to_thread_id (inferior_pid);
+ }
+}
+
void
set_ignore_count (bptnum, count, from_tty)
int bptnum, count, from_tty;
@@ -3628,113 +6098,6 @@ map_breakpoint_numbers (args, function)
}
void
-enable_breakpoint (bpt)
- struct breakpoint *bpt;
-{
- struct frame_info *save_selected_frame = NULL;
- int save_selected_frame_level = -1;
- int target_resources_ok, other_type_used;
- struct value *mark;
-
- if (bpt->type == bp_hardware_breakpoint)
- {
- int i;
- i = hw_breakpoint_used_count();
- target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
- bp_hardware_breakpoint, i+1, 0);
- if (target_resources_ok == 0)
- error ("No hardware breakpoint support in the target.");
- else if (target_resources_ok < 0)
- error ("Hardware breakpoints used exceeds limit.");
- }
- bpt->enable = enabled;
- check_duplicates (bpt->address);
-
- if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint ||
- bpt->type == bp_read_watchpoint || bpt->type == bp_access_watchpoint)
- {
- if (bpt->exp_valid_block != NULL)
- {
- struct frame_info *fr =
- find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
- if (fr == NULL)
- {
- printf_filtered ("\
-Cannot enable watchpoint %d because the block in which its expression\n\
-is valid is not currently in scope.\n", bpt->number);
- bpt->enable = disabled;
- return;
- }
-
- save_selected_frame = selected_frame;
- save_selected_frame_level = selected_frame_level;
- select_frame (fr, -1);
- }
-
- value_free (bpt->val);
- mark = value_mark ();
- bpt->val = evaluate_expression (bpt->exp);
- release_value (bpt->val);
- if (VALUE_LAZY (bpt->val))
- value_fetch_lazy (bpt->val);
-
- if (bpt->type == bp_hardware_watchpoint ||
- bpt->type == bp_read_watchpoint ||
- bpt->type == bp_access_watchpoint)
- {
- int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
- int mem_cnt = can_use_hardware_watchpoint (bpt->val);
-
- target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
- bpt->type, i + mem_cnt, other_type_used);
- /* we can consider of type is bp_hardware_watchpoint, convert to
- bp_watchpoint in the following condition */
- if (target_resources_ok < 0)
- {
- printf_filtered("\
-Cannot enable watchpoint %d because target watch resources\n\
-have been allocated for other watchpoints.\n", bpt->number);
- bpt->enable = disabled;
- value_free_to_mark (mark);
- return;
- }
- }
-
- if (save_selected_frame_level >= 0)
- select_frame (save_selected_frame, save_selected_frame_level);
- value_free_to_mark (mark);
- }
-
- if (modify_breakpoint_hook)
- modify_breakpoint_hook (bpt);
-}
-
-/* ARGSUSED */
-static void
-enable_command (args, from_tty)
- char *args;
- int from_tty;
-{
- struct breakpoint *bpt;
- if (args == 0)
- ALL_BREAKPOINTS (bpt)
- switch (bpt->type)
- {
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- case bp_read_watchpoint:
- case bp_access_watchpoint:
- enable_breakpoint (bpt);
- default:
- continue;
- }
- else
- map_breakpoint_numbers (args, enable_breakpoint);
-}
-
-void
disable_breakpoint (bpt)
struct breakpoint *bpt;
{
@@ -3746,7 +6109,7 @@ disable_breakpoint (bpt)
bpt->enable = disabled;
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
if (modify_breakpoint_hook)
modify_breakpoint_hook (bpt);
@@ -3763,7 +6126,17 @@ disable_command (args, from_tty)
ALL_BREAKPOINTS (bpt)
switch (bpt->type)
{
+ case bp_none:
+ warning ("attempted to disable apparently deleted breakpoint #%d?\n", bpt->number);
+ continue;
case bp_breakpoint:
+ case bp_catch_load:
+ case bp_catch_unload:
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ case bp_catch_catch:
+ case bp_catch_throw:
case bp_hardware_breakpoint:
case bp_watchpoint:
case bp_hardware_watchpoint:
@@ -3778,16 +6151,17 @@ disable_command (args, from_tty)
}
static void
-enable_once_breakpoint (bpt)
+do_enable_breakpoint (bpt, disposition)
struct breakpoint *bpt;
+ enum bpdisp disposition;
{
struct frame_info *save_selected_frame = NULL;
int save_selected_frame_level = -1;
int target_resources_ok, other_type_used;
struct value *mark;
- if (bpt->type == bp_hardware_breakpoint)
- {
+ if (bpt->type == bp_hardware_breakpoint)
+ {
int i;
i = hw_breakpoint_used_count();
target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
@@ -3799,8 +6173,8 @@ enable_once_breakpoint (bpt)
}
bpt->enable = enabled;
- bpt->disposition = disable;
- check_duplicates (bpt->address);
+ bpt->disposition = disposition;
+ check_duplicates (bpt->address, bpt->section);
breakpoints_changed ();
if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint ||
@@ -3809,7 +6183,12 @@ enable_once_breakpoint (bpt)
if (bpt->exp_valid_block != NULL)
{
struct frame_info *fr =
- find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
+
+ /* Ensure that we have the current frame. Else, this
+ next query may pessimistically be answered as, "No,
+ not within current scope". */
+ get_current_frame ();
+ fr = find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
if (fr == NULL)
{
printf_filtered ("\
@@ -3836,9 +6215,12 @@ is valid is not currently in scope.\n", bpt->number);
bpt->type == bp_access_watchpoint)
{
int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
- int mem_cnt = can_use_hardware_watchpoint(bpt->val);
+ int mem_cnt = can_use_hardware_watchpoint (bpt->val);
+
+ /* Hack around 'unused var' error for some targets here */
+ (void) mem_cnt, i;
target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
- bpt->type, i+mem_cnt, other_type_used);
+ bpt->type, i + mem_cnt, other_type_used);
/* we can consider of type is bp_hardware_watchpoint, convert to
bp_watchpoint in the following condition */
if (target_resources_ok < 0)
@@ -3846,15 +6228,71 @@ is valid is not currently in scope.\n", bpt->number);
printf_filtered("\
Cannot enable watchpoint %d because target watch resources\n\
have been allocated for other watchpoints.\n", bpt->number);
- bpt->enable = disabled;
- value_free_to_mark (mark);
+ bpt->enable = disabled;
+ value_free_to_mark (mark);
+ return;
}
}
if (save_selected_frame_level >= 0)
- select_frame (save_selected_frame, save_selected_frame_level);
+ select_and_print_frame (save_selected_frame, save_selected_frame_level);
value_free_to_mark (mark);
}
+ if (modify_breakpoint_hook)
+ modify_breakpoint_hook (bpt);
+}
+
+void
+enable_breakpoint (bpt)
+ struct breakpoint *bpt;
+{
+ do_enable_breakpoint (bpt, bpt->disposition);
+}
+
+/* The enable command enables the specified breakpoints (or all defined
+ breakpoints) so they once again become (or continue to be) effective
+ in stopping the inferior. */
+
+/* ARGSUSED */
+static void
+enable_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ register struct breakpoint *bpt;
+ if (args == 0)
+ ALL_BREAKPOINTS (bpt)
+ switch (bpt->type)
+ {
+ case bp_none:
+ warning ("attempted to enable apparently deleted breakpoint #%d?\n", bpt->number);
+ continue;
+ case bp_breakpoint:
+ case bp_catch_load:
+ case bp_catch_unload:
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ case bp_catch_catch:
+ case bp_catch_throw:
+ case bp_hardware_breakpoint:
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ enable_breakpoint (bpt);
+ default:
+ continue;
+ }
+ else
+ map_breakpoint_numbers (args, enable_breakpoint);
+}
+
+static void
+enable_once_breakpoint (bpt)
+ struct breakpoint *bpt;
+{
+ do_enable_breakpoint (bpt, disable);
}
/* ARGSUSED */
@@ -3870,11 +6308,7 @@ static void
enable_delete_breakpoint (bpt)
struct breakpoint *bpt;
{
- bpt->enable = enabled;
- bpt->disposition = del;
-
- check_duplicates (bpt->address);
- breakpoints_changed ();
+ do_enable_breakpoint (bpt, del);
}
/* ARGSUSED */
@@ -3911,6 +6345,8 @@ decode_line_spec_1 (string, funfirstline)
void
_initialize_breakpoint ()
{
+ struct cmd_list_element *c;
+
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful
before a breakpoint is set. */
@@ -3919,6 +6355,8 @@ _initialize_breakpoint ()
add_com ("ignore", class_breakpoint, ignore_command,
"Set ignore-count of breakpoint number N to COUNT.\n\
Usage is `ignore N COUNT'.");
+ if (xdb_commands)
+ add_com_alias("bc", "ignore", class_breakpoint, 1);
add_com ("commands", class_breakpoint, commands_command,
"Set commands to be executed when a breakpoint is hit.\n\
@@ -3939,6 +6377,9 @@ expression to be evaluated whenever breakpoint N is reached. ");
Like \"break\" except the breakpoint is only temporary,\n\
so it will be deleted when hit. Equivalent to \"break\" followed\n\
by using \"enable delete\" on the breakpoint number.");
+ add_com("txbreak", class_breakpoint, tbreak_at_finish_command,
+ "Set temporary breakpoint at procedure exit. Either there should\n\
+be no argument or the argument must be a depth.\n");
add_com ("hbreak", class_breakpoint, hbreak_command,
"Set a hardware assisted breakpoint. Args like \"break\" command.\n\
@@ -3957,6 +6398,15 @@ With no subcommand, breakpoints are enabled until you command otherwise.\n\
This is used to cancel the effect of the \"disable\" command.\n\
With a subcommand you can enable temporarily.",
&enablelist, "enable ", 1, &cmdlist);
+ if (xdb_commands)
+ add_com("ab", class_breakpoint, enable_command,
+ "Enable some breakpoints.\n\
+Give breakpoint numbers (separated by spaces) as arguments.\n\
+With no subcommand, breakpoints are enabled until you command otherwise.\n\
+This is used to cancel the effect of the \"disable\" command.\n\
+With a subcommand you can enable temporarily.");
+
+ add_com_alias ("en", "enable", class_breakpoint, 1);
add_abbrev_prefix_cmd ("breakpoints", class_breakpoint, enable_command,
"Enable some breakpoints.\n\
@@ -3993,6 +6443,12 @@ A disabled breakpoint is not forgotten, but has no effect until reenabled.",
&disablelist, "disable ", 1, &cmdlist);
add_com_alias ("dis", "disable", class_breakpoint, 1);
add_com_alias ("disa", "disable", class_breakpoint, 1);
+ if (xdb_commands)
+ add_com("sb", class_breakpoint, disable_command,
+ "Disable some breakpoints.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To disable all breakpoints, give no argument.\n\
+A disabled breakpoint is not forgotten, but has no effect until reenabled.");
add_cmd ("breakpoints", class_alias, disable_command,
"Disable some breakpoints.\n\
@@ -4011,6 +6467,11 @@ Also a prefix command for deletion of other GDB objects.\n\
The \"unset\" command is also an alias for \"delete\".",
&deletelist, "delete ", 1, &cmdlist);
add_com_alias ("d", "delete", class_breakpoint, 1);
+ if (xdb_commands)
+ add_com ("db", class_breakpoint, delete_command,
+ "Delete some breakpoints.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To delete all breakpoints, give no argument.\n");
add_cmd ("breakpoints", class_alias, delete_command,
"Delete some breakpoints or auto-display expressions.\n\
@@ -4047,6 +6508,56 @@ Do \"help breakpoints\" for info on other commands dealing with breakpoints.", N
add_com_alias ("bre", "break", class_run, 1);
add_com_alias ("brea", "break", class_run, 1);
+ add_com("xbreak", class_breakpoint, break_at_finish_command,
+ concat("Set breakpoint at procedure exit. \n\
+Argument may be function name, or \"*\" and an address.\n\
+If function is specified, break at end of code for that function.\n\
+If an address is specified, break at the end of the function that contains \n\
+that exact address.\n",
+"With no arg, uses current execution address of selected stack frame.\n\
+This is useful for breaking on return to a stack frame.\n\
+\n\
+Multiple breakpoints at one place are permitted, and useful if conditional.\n\
+\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL));
+ add_com_alias ("xb", "xbreak", class_breakpoint, 1);
+ add_com_alias ("xbr", "xbreak", class_breakpoint, 1);
+ add_com_alias ("xbre", "xbreak", class_breakpoint, 1);
+ add_com_alias ("xbrea", "xbreak", class_breakpoint, 1);
+
+ if (xdb_commands)
+ {
+ add_com_alias ("ba", "break", class_breakpoint, 1);
+ add_com_alias ("bu", "ubreak", class_breakpoint, 1);
+ add_com ("bx", class_breakpoint, break_at_finish_at_depth_command,
+ "Set breakpoint at procedure exit. Either there should\n\
+be no argument or the argument must be a depth.\n");
+ }
+
+ if (dbx_commands)
+ {
+ add_abbrev_prefix_cmd("stop", class_breakpoint, stop_command,
+ "Break in function/address or break at a line in the current file.",
+ &stoplist, "stop ", 1, &cmdlist);
+ add_cmd("in", class_breakpoint, stopin_command,
+ "Break in function or address.\n", &stoplist);
+ add_cmd("at", class_breakpoint, stopat_command,
+ "Break at a line in the current file.\n", &stoplist);
+ add_com("status", class_info, breakpoints_info,
+ concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint - normal breakpoint\n\
+\twatchpoint - watchpoint\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
+breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n",
+"Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.", NULL));
+ }
+
add_info ("breakpoints", breakpoints_info,
concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
The \"Type\" column indicates one of:\n\
@@ -4061,6 +6572,21 @@ are set to the address of the last breakpoint listed.\n\n\
Convenience variable \"$bpnum\" contains the number of the last\n\
breakpoint set.", NULL));
+ if (xdb_commands)
+ add_com("lb", class_breakpoint, breakpoints_info,
+ concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint - normal breakpoint\n\
+\twatchpoint - watchpoint\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
+breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n",
+"Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.", NULL));
+
#if MAINTENANCE_CMDS
add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints,
@@ -4085,18 +6611,49 @@ breakpoint set.", NULL),
#endif /* MAINTENANCE_CMDS */
add_com ("catch", class_breakpoint, catch_command,
- "Set breakpoints to catch exceptions that are raised.\n\
-Argument may be a single exception to catch, multiple exceptions\n\
-to catch, or the default exception \"default\". If no arguments\n\
-are given, breakpoints are set at all exception handlers catch clauses\n\
-within the current scope.\n\
-\n\
-A condition specified for the catch applies to all breakpoints set\n\
-with this command\n\
+ "Set catchpoints to catch events.\n\
+Raised signals may be caught:\n\
+\tcatch signal - all signals\n\
+\tcatch signal <signame> - a particular signal\n\
+Raised exceptions may be caught:\n\
+\tcatch throw - all exceptions, when thrown\n\
+\tcatch throw <exceptname> - a particular exception, when thrown\n\
+\tcatch catch - all exceptions, when caught\n\
+\tcatch catch <exceptname> - a particular exception, when caught\n\
+Thread or process events may be caught:\n\
+\tcatch thread_start - any threads, just after creation\n\
+\tcatch thread_exit - any threads, just before expiration\n\
+\tcatch thread_join - any threads, just after joins\n\
+Process events may be caught:\n\
+\tcatch start - any processes, just after creation\n\
+\tcatch exit - any processes, just before expiration\n\
+\tcatch fork - calls to fork()\n\
+\tcatch vfork - calls to vfork()\n\
+\tcatch exec - calls to exec()\n\
+Dynamically-linked library events may be caught:\n\
+\tcatch load - loads of any library\n\
+\tcatch load <libname> - loads of a particular library\n\
+\tcatch unload - unloads of any library\n\
+\tcatch unload <libname> - unloads of a particular library\n\
+The act of your program's execution stopping may also be caught:\n\
+\tcatch stop\n\n\
+C++ exceptions may be caught:\n\
+\tcatch throw - all exceptions, when thrown\n\
+\tcatch catch - all exceptions, when caught\n\
\n\
+Do \"help set follow-fork-mode\" for info on debugging your program\n\
+after a fork or vfork is caught.\n\n\
Do \"help breakpoints\" for info on other commands dealing with breakpoints.");
+
+ add_com ("tcatch", class_breakpoint, tcatch_command,
+ "Set temporary catchpoints to catch events.\n\
+Args like \"catch\" command.\n\
+Like \"catch\" except the catchpoint is only temporary,\n\
+so it will be deleted when hit. Equivalent to \"catch\" followed\n\
+by using \"enable delete\" on the catchpoint number.");
+
+add_com ("watch", class_breakpoint, watch_command,
- add_com ("watch", class_breakpoint, watch_command,
"Set a watchpoint for an expression.\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression changes.");
@@ -4114,4 +6671,16 @@ an expression is either read or written.");
add_info ("watchpoints", breakpoints_info,
"Synonym for ``info breakpoints''.");
+
+ c = add_set_cmd ("can-use-hw-watchpoints", class_support, var_zinteger,
+ (char *) &can_use_hw_watchpoints,
+ "Set debugger's willingness to use watchpoint hardware.\n\
+If zero, gdb will not use hardware for new watchpoints, even if\n\
+such is available. (However, any hardware watchpoints that were\n\
+created before setting this to nonzero, will continue to use watchpoint\n\
+hardware.)",
+ &setlist);
+ add_show_from_set (c, &showlist);
+
+ can_use_hw_watchpoints = 1;
}
diff --git a/contrib/gdb/gdb/breakpoint.h b/contrib/gdb/gdb/breakpoint.h
index 90970cd..e2febac 100644
--- a/contrib/gdb/gdb/breakpoint.h
+++ b/contrib/gdb/gdb/breakpoint.h
@@ -1,5 +1,5 @@
/* Data structures associated with breakpoints in GDB.
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 96, 98, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
possible like a single-step to wait_for_inferior). */
enum bptype {
+ bp_none = 0, /* Eventpoint has been deleted. */
bp_breakpoint, /* Normal breakpoint */
bp_hardware_breakpoint, /* Hardware assisted breakpoint */
bp_until, /* used by until command */
@@ -87,17 +88,55 @@ enum bptype {
when these significant events occur. GDB can then re-examine
the dynamic linker's data structures to discover any newly loaded
dynamic libraries. */
- bp_shlib_event
+ bp_shlib_event,
+
+ /* These breakpoints are used to implement the "catch load" command
+ on platforms whose dynamic linkers support such functionality. */
+ bp_catch_load,
+
+ /* These breakpoints are used to implement the "catch unload" command
+ on platforms whose dynamic linkers support such functionality. */
+ bp_catch_unload,
+
+ /* These are not really breakpoints, but are catchpoints that
+ implement the "catch fork", "catch vfork" and "catch exec" commands
+ on platforms whose kernel support such functionality. (I.e.,
+ kernels which can raise an event when a fork or exec occurs, as
+ opposed to the debugger setting breakpoints on functions named
+ "fork" or "exec".) */
+ bp_catch_fork,
+ bp_catch_vfork,
+ bp_catch_exec,
+
+ /* These are catchpoints to implement "catch catch" and "catch throw"
+ commands for C++ exception handling. */
+ bp_catch_catch,
+ bp_catch_throw
+
};
/* States of enablement of breakpoint. */
-enum enable { disabled, enabled, shlib_disabled};
+enum enable {
+ disabled, /* The eventpoint is inactive, and cannot trigger. */
+ enabled, /* The eventpoint is active, and can trigger. */
+ shlib_disabled, /* The eventpoint's address is within an unloaded solib.
+ The eventpoint will be automatically enabled & reset
+ when that solib is loaded. */
+ call_disabled /* The eventpoint has been disabled while a call into
+ the inferior is "in flight", because some eventpoints
+ interfere with the implementation of a call on some
+ targets. The eventpoint will be automatically enabled
+ & reset when the call "lands" (either completes, or
+ stops at another eventpoint). */
+};
+
/* Disposition of breakpoint. Ie: what to do after hitting it. */
enum bpdisp {
del, /* Delete it */
+ del_at_next_stop, /* Delete at next stop, whether hit or not */
disable, /* Disable it */
donttouch /* Leave it alone */
};
@@ -204,6 +243,24 @@ struct breakpoint
aborting, so you can back up to just before the abort. */
int hit_count;
+ /* Filename of a dynamically-linked library (dll), used for bp_catch_load
+ and bp_catch_unload (malloc'd), or NULL if any library is significant. */
+ char * dll_pathname;
+
+ /* Filename of a dll whose state change (e.g., load or unload)
+ triggered this catchpoint. This field is only vaid immediately
+ after this catchpoint has triggered. */
+ char * triggered_dll_pathname;
+
+ /* Process id of a child process whose forking triggered this catchpoint.
+ This field is only vaid immediately after this catchpoint has triggered. */
+ int forked_inferior_pid;
+
+ /* Filename of a program whose exec triggered this catchpoint. This
+ field is only vaid immediately after this catchpoint has triggered. */
+ char * exec_pathname;
+
+ asection *section;
};
/* The following stuff is an abstract data type "bpstat" ("breakpoint status").
@@ -274,6 +331,10 @@ enum bpstat_what_main_action {
keep checking. */
BPSTAT_WHAT_CHECK_SHLIBS,
+ /* Check the dynamic linker's data structures for new libraries, then
+ resume out of the dynamic linker's callback, stop and print. */
+ BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK,
+
/* This is just used to keep track of how many enums there are. */
BPSTAT_WHAT_LAST
};
@@ -294,6 +355,18 @@ struct bpstat_what bpstat_what PARAMS ((bpstat));
/* Find the bpstat associated with a breakpoint. NULL otherwise. */
bpstat bpstat_find_breakpoint PARAMS ((bpstat, struct breakpoint *));
+/* Find a step_resume breakpoint associated with this bpstat.
+ (If there are multiple step_resume bp's on the list, this function
+ will arbitrarily pick one.)
+
+ It is an error to use this function if BPSTAT doesn't contain a
+ step_resume breakpoint.
+
+ See wait_for_inferior's use of this function.
+ */
+extern struct breakpoint *
+bpstat_find_step_resume_breakpoint PARAMS ((bpstat));
+
/* Nonzero if a signal that we got in wait() was due to circumstances
explained by the BS. */
/* Currently that is true if we have hit a breakpoint, or if there is
@@ -305,6 +378,9 @@ bpstat bpstat_find_breakpoint PARAMS ((bpstat, struct breakpoint *));
just to things like whether watchpoints are set. */
extern int bpstat_should_step PARAMS ((void));
+/* Nonzero if there are enabled hardware watchpoints. */
+extern int bpstat_have_active_hw_watchpoints PARAMS ((void));
+
/* Print a message indicating what happened. Returns nonzero to
say that only the source line should be printed after this (zero
return means print the frame as well as the source line). */
@@ -325,6 +401,12 @@ extern void bpstat_do_actions PARAMS ((bpstat *));
/* Modify BS so that the actions will not be performed. */
extern void bpstat_clear_actions PARAMS ((bpstat));
+/* Given a bpstat that records zero or more triggered eventpoints, this
+ function returns another bpstat which contains only the catchpoints
+ on that first list, if any.
+ */
+extern void bpstat_get_triggered_catchpoints PARAMS ((bpstat, bpstat *));
+
/* Implementation: */
struct bpstats
{
@@ -349,6 +431,14 @@ struct bpstats
bpstat_print, or -1 if it can't deal with it. */
int (*print_it) PARAMS((bpstat bs));
};
+
+enum inf_context
+{
+ inf_starting,
+ inf_running,
+ inf_exited
+};
+
/* Prototypes for breakpoint-related functions. */
@@ -358,6 +448,8 @@ struct frame_info;
extern int breakpoint_here_p PARAMS ((CORE_ADDR));
+extern int breakpoint_inserted_here_p PARAMS ((CORE_ADDR));
+
extern int frame_in_dummy PARAMS ((struct frame_info *));
extern int breakpoint_thread_match PARAMS ((CORE_ADDR, int));
@@ -366,7 +458,9 @@ extern void until_break_command PARAMS ((char *, int));
extern void breakpoint_re_set PARAMS ((void));
-extern void clear_momentary_breakpoints PARAMS ((void));
+extern void breakpoint_re_set_thread PARAMS ((struct breakpoint *));
+
+extern int ep_is_exception_catchpoint PARAMS ((struct breakpoint *));
extern struct breakpoint *set_momentary_breakpoint
PARAMS ((struct symtab_and_line, struct frame_info *, enum bptype));
@@ -377,7 +471,7 @@ extern void set_default_breakpoint PARAMS ((int, CORE_ADDR, struct symtab *, int
extern void mark_breakpoints_out PARAMS ((void));
-extern void breakpoint_init_inferior PARAMS ((void));
+extern void breakpoint_init_inferior PARAMS ((enum inf_context));
extern void delete_breakpoint PARAMS ((struct breakpoint *));
@@ -387,16 +481,80 @@ extern void breakpoint_clear_ignore_counts PARAMS ((void));
extern void break_command PARAMS ((char *, int));
+extern void tbreak_command PARAMS ((char *, int));
+
extern int insert_breakpoints PARAMS ((void));
extern int remove_breakpoints PARAMS ((void));
+/* This function can be used to physically insert eventpoints from the
+ specified traced inferior process, without modifying the breakpoint
+ package's state. This can be useful for those targets which support
+ following the processes of a fork() or vfork() system call, when both
+ of the resulting two processes are to be followed. */
+extern int reattach_breakpoints PARAMS ((int));
+
+/* This function can be used to update the breakpoint package's state
+ after an exec() system call has been executed.
+
+ This function causes the following:
+
+ - All eventpoints are marked "not inserted".
+ - All eventpoints with a symbolic address are reset such that
+ the symbolic address must be reevaluated before the eventpoints
+ can be reinserted.
+ - The solib breakpoints are explicitly removed from the breakpoint
+ list.
+ - A step-resume breakpoint, if any, is explicitly removed from the
+ breakpoint list.
+ - All eventpoints without a symbolic address are removed from the
+ breakpoint list. */
+extern void update_breakpoints_after_exec PARAMS ((void));
+
+/* This function can be used to physically remove hardware breakpoints
+ and watchpoints from the specified traced inferior process, without
+ modifying the breakpoint package's state. This can be useful for
+ those targets which support following the processes of a fork() or
+ vfork() system call, when one of the resulting two processes is to
+ be detached and allowed to run free.
+
+ It is an error to use this function on the process whose id is
+ inferior_pid. */
+extern int detach_breakpoints PARAMS ((int));
+
extern void enable_longjmp_breakpoint PARAMS ((void));
extern void disable_longjmp_breakpoint PARAMS ((void));
extern void set_longjmp_resume_breakpoint PARAMS ((CORE_ADDR,
struct frame_info *));
+/* These functions respectively disable or reenable all currently
+ enabled watchpoints. When disabled, the watchpoints are marked
+ call_disabled. When reenabled, they are marked enabled.
+
+ The intended client of these functions is infcmd.c\run_stack_dummy.
+
+ The inferior must be stopped, and all breakpoints removed, when
+ these functions are used.
+
+ The need for these functions is that on some targets (e.g., HP-UX),
+ gdb is unable to unwind through the dummy frame that is pushed as
+ part of the implementation of a call command. Watchpoints can
+ cause the inferior to stop in places where this frame is visible,
+ and that can cause execution control to become very confused.
+
+ Note that if a user sets breakpoints in an interactively call
+ function, the call_disabled watchpoints will have been reenabled
+ when the first such breakpoint is reached. However, on targets
+ that are unable to unwind through the call dummy frame, watches
+ of stack-based storage may then be deleted, because gdb will
+ believe that their watched storage is out of scope. (Sigh.) */
+extern void
+disable_watchpoints_before_interactive_call_start PARAMS ((void));
+
+extern void
+enable_watchpoints_after_interactive_call_stop PARAMS ((void));
+
extern void clear_breakpoint_hit_counts PARAMS ((void));
@@ -419,6 +577,28 @@ extern void create_solib_event_breakpoint PARAMS ((CORE_ADDR));
extern void remove_solib_event_breakpoints PARAMS ((void));
+extern void disable_breakpoints_in_shlibs PARAMS ((int silent));
+
extern void re_enable_breakpoints_in_shlibs PARAMS ((void));
+extern void create_solib_load_event_breakpoint PARAMS ((char *, int, char *, char *));
+
+extern void create_solib_unload_event_breakpoint PARAMS ((char *, int, char *, char *));
+
+extern void create_fork_event_catchpoint PARAMS ((int, char *));
+
+extern void create_vfork_event_catchpoint PARAMS ((int, char *));
+
+extern void create_exec_event_catchpoint PARAMS ((int, char *));
+
+/* This function returns TRUE if ep is a catchpoint. */
+extern int ep_is_catchpoint PARAMS ((struct breakpoint *));
+
+/* This function returns TRUE if ep is a catchpoint of a
+ shared library (aka dynamically-linked library) event,
+ such as a library load or unload. */
+extern int ep_is_shlib_catchpoint PARAMS ((struct breakpoint *));
+
+extern struct breakpoint *set_breakpoint_sal PARAMS ((struct symtab_and_line));
+
#endif /* !defined (BREAKPOINT_H) */
diff --git a/contrib/gdb/gdb/buildsym.c b/contrib/gdb/gdb/buildsym.c
index 5a5847a..24b64be 100644
--- a/contrib/gdb/gdb/buildsym.c
+++ b/contrib/gdb/gdb/buildsym.c
@@ -1,6 +1,5 @@
/* Support routines for building symbol tables in GDB's internal format.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1995, 1996
- Free Software Foundation, Inc.
+ Copyright 1986-1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -36,53 +35,67 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdb_string.h"
/* Ask buildsym.h to define the vars it normally declares `extern'. */
-#define EXTERN /**/
+#define EXTERN /**/
#include "buildsym.h" /* Our own declarations */
#undef EXTERN
/* For cleanup_undefined_types and finish_global_stabs (somewhat
questionable--see comment where we call them). */
+
#include "stabsread.h"
-static int
-compare_line_numbers PARAMS ((const void *, const void *));
+/* List of free `struct pending' structures for reuse. */
-static struct blockvector *
-make_blockvector PARAMS ((struct objfile *));
+static struct pending *free_pendings;
+/* Non-zero if symtab has line number info. This prevents an
+ otherwise empty symtab from being tossed. */
+
+static int have_line_numbers;
+
+static int compare_line_numbers (const void *ln1p, const void *ln2p);
-/* Initial sizes of data structures. These are realloc'd larger if needed,
- and realloc'd down to the size actually used, when completed. */
+
+/* Initial sizes of data structures. These are realloc'd larger if
+ needed, and realloc'd down to the size actually used, when
+ completed. */
#define INITIAL_CONTEXT_STACK_SIZE 10
#define INITIAL_LINE_VECTOR_LENGTH 1000
-
+
/* Complaints about the symbols we have encountered. */
+struct complaint block_end_complaint =
+{"block end address less than block start address in %s (patched it)", 0, 0};
+
+struct complaint anon_block_end_complaint =
+{"block end address 0x%lx less than block start address 0x%lx (patched it)", 0, 0};
+
struct complaint innerblock_complaint =
- {"inner block not inside outer block in %s", 0, 0};
+{"inner block not inside outer block in %s", 0, 0};
struct complaint innerblock_anon_complaint =
- {"inner block not inside outer block", 0, 0};
-
-struct complaint blockvector_complaint =
- {"block at 0x%lx out of order", 0, 0};
+{"inner block (0x%lx-0x%lx) not inside outer block (0x%lx-0x%lx)", 0, 0};
+struct complaint blockvector_complaint =
+{"block at 0x%lx out of order", 0, 0};
/* maintain the lists of symbols and blocks */
/* Add a symbol to one of the lists of symbols. */
void
-add_symbol_to_list (symbol, listhead)
- struct symbol *symbol;
- struct pending **listhead;
+add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
{
register struct pending *link;
-
- /* We keep PENDINGSIZE symbols in each link of the list.
- If we don't have a link with room in it, add a new link. */
+
+ /* If this is an alias for another symbol, don't add it. */
+ if (symbol->ginfo.name && symbol->ginfo.name[0] == '#')
+ return;
+
+ /* We keep PENDINGSIZE symbols in each link of the list. If we
+ don't have a link with room in it, add a new link. */
if (*listhead == NULL || (*listhead)->nsyms == PENDINGSIZE)
{
if (free_pendings)
@@ -103,21 +116,18 @@ add_symbol_to_list (symbol, listhead)
(*listhead)->symbol[(*listhead)->nsyms++] = symbol;
}
-/* Find a symbol named NAME on a LIST. NAME need not be '\0'-terminated;
- LENGTH is the length of the name. */
+/* Find a symbol named NAME on a LIST. NAME need not be
+ '\0'-terminated; LENGTH is the length of the name. */
struct symbol *
-find_symbol_in_list (list, name, length)
- struct pending *list;
- char *name;
- int length;
+find_symbol_in_list (struct pending *list, char *name, int length)
{
int j;
char *pp;
while (list != NULL)
{
- for (j = list->nsyms; --j >= 0; )
+ for (j = list->nsyms; --j >= 0;)
{
pp = SYMBOL_NAME (list->symbol[j]);
if (*pp == *name && strncmp (pp, name, length) == 0 &&
@@ -131,61 +141,67 @@ find_symbol_in_list (list, name, length)
return (NULL);
}
-/* At end of reading syms, or in case of quit,
- really free as many `struct pending's as we can easily find. */
+/* At end of reading syms, or in case of quit, really free as many
+ `struct pending's as we can easily find. */
/* ARGSUSED */
void
-really_free_pendings (foo)
- int foo;
+really_free_pendings (int foo)
{
struct pending *next, *next1;
-#if 0
- struct pending_block *bnext, *bnext1;
-#endif
for (next = free_pendings; next; next = next1)
{
next1 = next->next;
- free ((PTR)next);
+ free ((void *) next);
}
free_pendings = NULL;
-#if 0 /* Now we make the links in the symbol_obstack, so don't free them. */
- for (bnext = pending_blocks; bnext; bnext = bnext1)
- {
- bnext1 = bnext->next;
- free ((PTR)bnext);
- }
-#endif
- pending_blocks = NULL;
+ free_pending_blocks ();
for (next = file_symbols; next != NULL; next = next1)
{
next1 = next->next;
- free ((PTR)next);
+ free ((void *) next);
}
file_symbols = NULL;
for (next = global_symbols; next != NULL; next = next1)
{
next1 = next->next;
- free ((PTR)next);
+ free ((void *) next);
}
global_symbols = NULL;
}
-/* Take one of the lists of symbols and make a block from it.
- Keep the order the symbols have in the list (reversed from the input file).
- Put the block on the list of pending blocks. */
+/* This function is called to discard any pending blocks. */
+
+void
+free_pending_blocks (void)
+{
+#if 0 /* Now we make the links in the
+ symbol_obstack, so don't free
+ them. */
+ struct pending_block *bnext, *bnext1;
+
+ for (bnext = pending_blocks; bnext; bnext = bnext1)
+ {
+ bnext1 = bnext->next;
+ free ((void *) bnext);
+ }
+#endif
+ pending_blocks = NULL;
+}
+
+/* Take one of the lists of symbols and make a block from it. Keep
+ the order the symbols have in the list (reversed from the input
+ file). Put the block on the list of pending blocks. */
void
-finish_block (symbol, listhead, old_blocks, start, end, objfile)
- struct symbol *symbol;
- struct pending **listhead;
- struct pending_block *old_blocks;
- CORE_ADDR start, end;
- struct objfile *objfile;
+finish_block (struct symbol *symbol, struct pending **listhead,
+ struct pending_block *old_blocks,
+ CORE_ADDR start, CORE_ADDR end,
+ struct objfile *objfile)
{
register struct pending *next, *next1;
register struct block *block;
@@ -200,11 +216,11 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
next;
i += next->nsyms, next = next->next)
{
- /*EMPTY*/;
+ /* EMPTY */ ;
}
- block = (struct block *) obstack_alloc (&objfile -> symbol_obstack,
- (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
+ block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
+ (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
/* Copy the symbols into the block. */
@@ -219,8 +235,9 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
BLOCK_START (block) = start;
BLOCK_END (block) = end;
- /* Superblock filled in when containing block is made */
+ /* Superblock filled in when containing block is made */
BLOCK_SUPERBLOCK (block) = NULL;
+
BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
/* Put the block in as the value of the symbol that names it. */
@@ -233,8 +250,9 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
if (TYPE_NFIELDS (ftype) <= 0)
{
- /* No parameter type information is recorded with the function's
- type. Set that from the type of the parameter symbols. */
+ /* No parameter type information is recorded with the
+ function's type. Set that from the type of the
+ parameter symbols. */
int nparams = 0, iparams;
struct symbol *sym;
for (i = 0; i < BLOCK_NSYMS (block); i++)
@@ -246,20 +264,21 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
case LOC_REF_ARG:
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_LOCAL_ARG:
nparams++;
break;
case LOC_UNDEF:
case LOC_CONST:
case LOC_STATIC:
+ case LOC_INDIRECT:
case LOC_REGISTER:
case LOC_LOCAL:
case LOC_TYPEDEF:
case LOC_LABEL:
case LOC_BLOCK:
case LOC_CONST_BYTES:
- case LOC_LOCAL_ARG:
case LOC_BASEREG:
- case LOC_BASEREG_ARG:
case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT:
default:
@@ -271,7 +290,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
TYPE_NFIELDS (ftype) = nparams;
TYPE_FIELDS (ftype) = (struct field *)
TYPE_ALLOC (ftype, nparams * sizeof (struct field));
-
+
for (i = iparams = 0; iparams < nparams; i++)
{
sym = BLOCK_SYM (block, i);
@@ -281,21 +300,22 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
case LOC_REF_ARG:
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_LOCAL_ARG:
TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
iparams++;
break;
case LOC_UNDEF:
case LOC_CONST:
case LOC_STATIC:
+ case LOC_INDIRECT:
case LOC_REGISTER:
case LOC_LOCAL:
case LOC_TYPEDEF:
case LOC_LABEL:
case LOC_BLOCK:
case LOC_CONST_BYTES:
- case LOC_LOCAL_ARG:
case LOC_BASEREG:
- case LOC_BASEREG_ARG:
case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT:
default:
@@ -320,9 +340,27 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
}
*listhead = NULL;
- /* Install this block as the superblock
- of all blocks made since the start of this scope
- that don't have superblocks yet. */
+#if 1
+ /* Check to be sure that the blocks have an end address that is
+ greater than starting address */
+
+ if (BLOCK_END (block) < BLOCK_START (block))
+ {
+ if (symbol)
+ {
+ complain (&block_end_complaint, SYMBOL_SOURCE_NAME (symbol));
+ }
+ else
+ {
+ complain (&anon_block_end_complaint, BLOCK_END (block), BLOCK_START (block));
+ }
+ /* Better than nothing */
+ BLOCK_END (block) = BLOCK_START (block);
+ }
+#endif
+
+ /* Install this block as the superblock of all blocks made since the
+ start of this scope that don't have superblocks yet. */
opblock = NULL;
for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
@@ -330,11 +368,11 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
if (BLOCK_SUPERBLOCK (pblock->block) == NULL)
{
#if 1
- /* Check to be sure the blocks are nested as we receive them.
- If the compiler/assembler/linker work, this just burns a small
- amount of time. */
+ /* Check to be sure the blocks are nested as we receive
+ them. If the compiler/assembler/linker work, this just
+ burns a small amount of time. */
if (BLOCK_START (pblock->block) < BLOCK_START (block) ||
- BLOCK_END (pblock->block) > BLOCK_END (block))
+ BLOCK_END (pblock->block) > BLOCK_END (block))
{
if (symbol)
{
@@ -343,10 +381,14 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
}
else
{
- complain (&innerblock_anon_complaint);
+ complain (&innerblock_anon_complaint, BLOCK_START (pblock->block),
+ BLOCK_END (pblock->block), BLOCK_START (block),
+ BLOCK_END (block));
}
- BLOCK_START (pblock->block) = BLOCK_START (block);
- BLOCK_END (pblock->block) = BLOCK_END (block);
+ if (BLOCK_START (pblock->block) < BLOCK_START (block))
+ BLOCK_START (pblock->block) = BLOCK_START (block);
+ if (BLOCK_END (pblock->block) > BLOCK_END (block))
+ BLOCK_END (pblock->block) = BLOCK_END (block);
}
#endif
BLOCK_SUPERBLOCK (pblock->block) = block;
@@ -354,15 +396,24 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
opblock = pblock;
}
- /* Record this block on the list of all blocks in the file.
- Put it after opblock, or at the beginning if opblock is 0.
- This puts the block in the list after all its subblocks. */
+ record_pending_block (objfile, block, opblock);
+}
+
+/* Record BLOCK on the list of all blocks in the file. Put it after
+ OPBLOCK, or at the beginning if opblock is NULL. This puts the
+ block in the list after all its subblocks.
+
+ Allocate the pending block struct in the symbol_obstack to save
+ time. This wastes a little space. FIXME: Is it worth it? */
+
+void
+record_pending_block (struct objfile *objfile, struct block *block,
+ struct pending_block *opblock)
+{
+ register struct pending_block *pblock;
- /* Allocate in the symbol_obstack to save time.
- It wastes a little space. */
pblock = (struct pending_block *)
- obstack_alloc (&objfile -> symbol_obstack,
- sizeof (struct pending_block));
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct pending_block));
pblock->block = block;
if (opblock)
{
@@ -376,9 +427,12 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
}
}
-static struct blockvector *
-make_blockvector (objfile)
- struct objfile *objfile;
+/* Note that this is only used in this file and in dstread.c, which
+ should be fixed to not need direct access to this function. When
+ that is done, it can be made static again. */
+
+struct blockvector *
+make_blockvector (struct objfile *objfile)
{
register struct pending_block *next;
register struct blockvector *blockvector;
@@ -386,18 +440,20 @@ make_blockvector (objfile)
/* Count the length of the list of blocks. */
- for (next = pending_blocks, i = 0; next; next = next->next, i++) {;}
+ for (next = pending_blocks, i = 0; next; next = next->next, i++)
+ {;
+ }
blockvector = (struct blockvector *)
- obstack_alloc (&objfile -> symbol_obstack,
+ obstack_alloc (&objfile->symbol_obstack,
(sizeof (struct blockvector)
+ (i - 1) * sizeof (struct block *)));
- /* Copy the blocks into the blockvector.
- This is done in reverse order, which happens to put
- the blocks into the proper order (ascending starting address).
- finish_block has hair to insert each block into the list
- after its subblocks in order to make sure this is true. */
+ /* Copy the blocks into the blockvector. This is done in reverse
+ order, which happens to put the blocks into the proper order
+ (ascending starting address). finish_block has hair to insert
+ each block into the list after its subblocks in order to make
+ sure this is true. */
BLOCKVECTOR_NBLOCKS (blockvector) = i;
for (next = pending_blocks; next; next = next->next)
@@ -405,7 +461,8 @@ make_blockvector (objfile)
BLOCKVECTOR_BLOCK (blockvector, --i) = next->block;
}
-#if 0 /* Now we make the links in the obstack, so don't free them. */
+#if 0 /* Now we make the links in the
+ obstack, so don't free them. */
/* Now free the links of the list, and empty the list. */
for (next = pending_blocks; next; next = next1)
@@ -416,28 +473,29 @@ make_blockvector (objfile)
#endif
pending_blocks = NULL;
-#if 1 /* FIXME, shut this off after a while to speed up symbol reading. */
- /* Some compilers output blocks in the wrong order, but we depend
- on their being in the right order so we can binary search.
- Check the order and moan about it. FIXME. */
+#if 1 /* FIXME, shut this off after a while
+ to speed up symbol reading. */
+ /* Some compilers output blocks in the wrong order, but we depend on
+ their being in the right order so we can binary search. Check the
+ order and moan about it. FIXME. */
if (BLOCKVECTOR_NBLOCKS (blockvector) > 1)
{
for (i = 1; i < BLOCKVECTOR_NBLOCKS (blockvector); i++)
{
- if (BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i-1))
- > BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)))
+ if (BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i - 1))
+ > BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i)))
{
/* FIXME-32x64: loses if CORE_ADDR doesn't fit in a
- long. Possible solutions include a version of
- complain which takes a callback, a
- sprintf_address_numeric to match
- print_address_numeric, or a way to set up a GDB_FILE
- * which causes sprintf rather than fprintf to be
- called. */
-
- complain (&blockvector_complaint,
- (unsigned long) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
+ long. Possible solutions include a version of
+ complain which takes a callback, a
+ sprintf_address_numeric to match
+ print_address_numeric, or a way to set up a GDB_FILE
+ which causes sprintf rather than fprintf to be
+ called. */
+
+ complain (&blockvector_complaint,
+ (unsigned long) BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i)));
}
}
}
@@ -445,22 +503,19 @@ make_blockvector (objfile)
return (blockvector);
}
-
-/* Start recording information about source code that came from an included
- (or otherwise merged-in) source file with a different name. NAME is
- the name of the file (cannot be NULL), DIRNAME is the directory in which
- it resides (or NULL if not known). */
+/* Start recording information about source code that came from an
+ included (or otherwise merged-in) source file with a different
+ name. NAME is the name of the file (cannot be NULL), DIRNAME is
+ the directory in which it resides (or NULL if not known). */
void
-start_subfile (name, dirname)
- char *name;
- char *dirname;
+start_subfile (char *name, char *dirname)
{
register struct subfile *subfile;
- /* See if this subfile is already known as a subfile of the
- current main source file. */
+ /* See if this subfile is already known as a subfile of the current
+ main source file. */
for (subfile = subfiles; subfile; subfile = subfile->next)
{
@@ -471,9 +526,9 @@ start_subfile (name, dirname)
}
}
- /* This subfile is not known. Add an entry for it.
- Make an entry for this subfile in the list of all subfiles
- of the current main source file. */
+ /* This subfile is not known. Add an entry for it. Make an entry
+ for this subfile in the list of all subfiles of the current main
+ source file. */
subfile = (struct subfile *) xmalloc (sizeof (struct subfile));
subfile->next = subfiles;
@@ -484,20 +539,20 @@ start_subfile (name, dirname)
subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name));
subfile->dirname =
(dirname == NULL) ? NULL : savestring (dirname, strlen (dirname));
-
+
/* Initialize line-number recording for this subfile. */
subfile->line_vector = NULL;
- /* Default the source language to whatever can be deduced from
- the filename. If nothing can be deduced (such as for a C/C++
- include file with a ".h" extension), then inherit whatever
- language the previous subfile had. This kludgery is necessary
- because there is no standard way in some object formats to
- record the source language. Also, when symtabs are allocated
- we try to deduce a language then as well, but it is too late
- for us to use that information while reading symbols, since
- symtabs aren't allocated until after all the symbols have
- been processed for a given source file. */
+ /* Default the source language to whatever can be deduced from the
+ filename. If nothing can be deduced (such as for a C/C++ include
+ file with a ".h" extension), then inherit whatever language the
+ previous subfile had. This kludgery is necessary because there
+ is no standard way in some object formats to record the source
+ language. Also, when symtabs are allocated we try to deduce a
+ language then as well, but it is too late for us to use that
+ information while reading symbols, since symtabs aren't allocated
+ until after all the symbols have been processed for a given
+ source file. */
subfile->language = deduce_language_from_filename (subfile->name);
if (subfile->language == language_unknown &&
@@ -506,15 +561,19 @@ start_subfile (name, dirname)
subfile->language = subfile->next->language;
}
+ /* Initialize the debug format string to NULL. We may supply it
+ later via a call to record_debugformat. */
+ subfile->debugformat = NULL;
+
/* cfront output is a C program, so in most ways it looks like a C
program. But to demangle we need to set the language to C++. We
can distinguish cfront code by the fact that it has #line
directives which specify a file name ending in .C.
-
- So if the filename of this subfile ends in .C, then change the language
- of any pending subfiles from C to C++. We also accept any other C++
- suffixes accepted by deduce_language_from_filename (in particular,
- some people use .cxx with cfront). */
+
+ So if the filename of this subfile ends in .C, then change the
+ language of any pending subfiles from C to C++. We also accept
+ any other C++ suffixes accepted by deduce_language_from_filename
+ (in particular, some people use .cxx with cfront). */
/* Likewise for f2c. */
if (subfile->name)
@@ -538,40 +597,38 @@ start_subfile (name, dirname)
}
}
-/* For stabs readers, the first N_SO symbol is assumed to be the source
- file name, and the subfile struct is initialized using that assumption.
- If another N_SO symbol is later seen, immediately following the first
- one, then the first one is assumed to be the directory name and the
- second one is really the source file name.
+/* For stabs readers, the first N_SO symbol is assumed to be the
+ source file name, and the subfile struct is initialized using that
+ assumption. If another N_SO symbol is later seen, immediately
+ following the first one, then the first one is assumed to be the
+ directory name and the second one is really the source file name.
- So we have to patch up the subfile struct by moving the old name value to
- dirname and remembering the new name. Some sanity checking is performed
- to ensure that the state of the subfile struct is reasonable and that the
- old name we are assuming to be a directory name actually is (by checking
- for a trailing '/'). */
+ So we have to patch up the subfile struct by moving the old name
+ value to dirname and remembering the new name. Some sanity
+ checking is performed to ensure that the state of the subfile
+ struct is reasonable and that the old name we are assuming to be a
+ directory name actually is (by checking for a trailing '/'). */
void
-patch_subfile_names (subfile, name)
- struct subfile *subfile;
- char *name;
+patch_subfile_names (struct subfile *subfile, char *name)
{
if (subfile != NULL && subfile->dirname == NULL && subfile->name != NULL
- && subfile->name[strlen(subfile->name)-1] == '/')
+ && subfile->name[strlen (subfile->name) - 1] == '/')
{
subfile->dirname = subfile->name;
subfile->name = savestring (name, strlen (name));
last_source_file = name;
/* Default the source language to whatever can be deduced from
- the filename. If nothing can be deduced (such as for a C/C++
- include file with a ".h" extension), then inherit whatever
- language the previous subfile had. This kludgery is necessary
- because there is no standard way in some object formats to
- record the source language. Also, when symtabs are allocated
- we try to deduce a language then as well, but it is too late
- for us to use that information while reading symbols, since
- symtabs aren't allocated until after all the symbols have
- been processed for a given source file. */
+ the filename. If nothing can be deduced (such as for a C/C++
+ include file with a ".h" extension), then inherit whatever
+ language the previous subfile had. This kludgery is
+ necessary because there is no standard way in some object
+ formats to record the source language. Also, when symtabs
+ are allocated we try to deduce a language then as well, but
+ it is too late for us to use that information while reading
+ symbols, since symtabs aren't allocated until after all the
+ symbols have been processed for a given source file. */
subfile->language = deduce_language_from_filename (subfile->name);
if (subfile->language == language_unknown &&
@@ -581,18 +638,17 @@ patch_subfile_names (subfile, name)
}
}
}
-
-/* Handle the N_BINCL and N_EINCL symbol types
- that act like N_SOL for switching source files
- (different subfiles, as we call them) within one object file,
- but using a stack rather than in an arbitrary order. */
+/* Handle the N_BINCL and N_EINCL symbol types that act like N_SOL for
+ switching source files (different subfiles, as we call them) within
+ one object file, but using a stack rather than in an arbitrary
+ order. */
void
-push_subfile ()
+push_subfile (void)
{
register struct subfile_stack *tem
- = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack));
+ = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack));
tem->next = subfile_stack;
subfile_stack = tem;
@@ -604,7 +660,7 @@ push_subfile ()
}
char *
-pop_subfile ()
+pop_subfile (void)
{
register char *name;
register struct subfile_stack *link = subfile_stack;
@@ -615,19 +671,15 @@ pop_subfile ()
}
name = link->name;
subfile_stack = link->next;
- free ((PTR)link);
+ free ((void *) link);
return (name);
}
-
-/* Add a linetable entry for line number LINE and address PC to the line
- vector for SUBFILE. */
+/* Add a linetable entry for line number LINE and address PC to the
+ line vector for SUBFILE. */
void
-record_line (subfile, line, pc)
- register struct subfile *subfile;
- int line;
- CORE_ADDR pc;
+record_line (register struct subfile *subfile, int line, CORE_ADDR pc)
{
struct linetable_entry *e;
/* Ignore the dummy line number in libg.o */
@@ -643,29 +695,30 @@ record_line (subfile, line, pc)
subfile->line_vector_length = INITIAL_LINE_VECTOR_LENGTH;
subfile->line_vector = (struct linetable *)
xmalloc (sizeof (struct linetable)
- + subfile->line_vector_length * sizeof (struct linetable_entry));
+ + subfile->line_vector_length * sizeof (struct linetable_entry));
subfile->line_vector->nitems = 0;
+ have_line_numbers = 1;
}
if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length)
{
subfile->line_vector_length *= 2;
subfile->line_vector = (struct linetable *)
- xrealloc ((char *) subfile->line_vector, (sizeof (struct linetable)
- + subfile->line_vector_length * sizeof (struct linetable_entry)));
+ xrealloc ((char *) subfile->line_vector,
+ (sizeof (struct linetable)
+ + (subfile->line_vector_length
+ * sizeof (struct linetable_entry))));
}
e = subfile->line_vector->item + subfile->line_vector->nitems++;
- e->line = line; e->pc = pc;
+ e->line = line;
+ e->pc = pc;
}
-
/* Needed in order to sort line tables from IBM xcoff files. Sigh! */
static int
-compare_line_numbers (ln1p, ln2p)
- const PTR ln1p;
- const PTR ln2p;
+compare_line_numbers (const void *ln1p, const void *ln2p)
{
struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
@@ -682,18 +735,14 @@ compare_line_numbers (ln1p, ln2p)
behavior (see comment at struct linetable in symtab.h). */
return ln1->line - ln2->line;
}
-
-/* Start a new symtab for a new source file.
- Called, for example, when a stabs symbol of type N_SO is seen, or when
- a DWARF TAG_compile_unit DIE is seen.
- It indicates the start of data for one original source file. */
+/* Start a new symtab for a new source file. Called, for example,
+ when a stabs symbol of type N_SO is seen, or when a DWARF
+ TAG_compile_unit DIE is seen. It indicates the start of data for
+ one original source file. */
void
-start_symtab (name, dirname, start_addr)
- char *name;
- char *dirname;
- CORE_ADDR start_addr;
+start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
{
last_source_file = name;
@@ -701,9 +750,10 @@ start_symtab (name, dirname, start_addr)
file_symbols = NULL;
global_symbols = NULL;
within_function = 0;
+ have_line_numbers = 0;
- /* Context stack is initially empty. Allocate first one with room for
- 10 levels; reuse it forever afterward. */
+ /* Context stack is initially empty. Allocate first one with room
+ for 10 levels; reuse it forever afterward. */
if (context_stack == NULL)
{
context_stack_size = INITIAL_CONTEXT_STACK_SIZE;
@@ -712,35 +762,33 @@ start_symtab (name, dirname, start_addr)
}
context_stack_depth = 0;
- /* Initialize the list of sub source files with one entry
- for this file (the top-level source file). */
+ /* Initialize the list of sub source files with one entry for this
+ file (the top-level source file). */
subfiles = NULL;
current_subfile = NULL;
start_subfile (name, dirname);
}
-/* Finish the symbol definitions for one main source file,
- close off all the lexical contexts for that file
- (creating struct block's for them), then make the struct symtab
- for that file and put it in the list of all such.
+/* Finish the symbol definitions for one main source file, close off
+ all the lexical contexts for that file (creating struct block's for
+ them), then make the struct symtab for that file and put it in the
+ list of all such.
- END_ADDR is the address of the end of the file's text.
- SECTION is the section number (in objfile->section_offsets) of
- the blockvector and linetable.
+ END_ADDR is the address of the end of the file's text. SECTION is
+ the section number (in objfile->section_offsets) of the blockvector
+ and linetable.
- Note that it is possible for end_symtab() to return NULL. In particular,
- for the DWARF case at least, it will return NULL when it finds a
- compilation unit that has exactly one DIE, a TAG_compile_unit DIE. This
- can happen when we link in an object file that was compiled from an empty
- source file. Returning NULL is probably not the correct thing to do,
- because then gdb will never know about this empty file (FIXME). */
+ Note that it is possible for end_symtab() to return NULL. In
+ particular, for the DWARF case at least, it will return NULL when
+ it finds a compilation unit that has exactly one DIE, a
+ TAG_compile_unit DIE. This can happen when we link in an object
+ file that was compiled from an empty source file. Returning NULL
+ is probably not the correct thing to do, because then gdb will
+ never know about this empty file (FIXME). */
struct symtab *
-end_symtab (end_addr, objfile, section)
- CORE_ADDR end_addr;
- struct objfile *objfile;
- int section;
+end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
{
register struct symtab *symtab = NULL;
register struct blockvector *blockvector;
@@ -748,25 +796,25 @@ end_symtab (end_addr, objfile, section)
register struct context_stack *cstk;
struct subfile *nextsub;
- /* Finish the lexical context of the last function in the file;
- pop the context stack. */
+ /* Finish the lexical context of the last function in the file; pop
+ the context stack. */
if (context_stack_depth > 0)
{
- context_stack_depth--;
- cstk = &context_stack[context_stack_depth];
+ cstk = pop_context ();
/* Make a block for the local symbols within. */
finish_block (cstk->name, &local_symbols, cstk->old_blocks,
cstk->start_addr, end_addr, objfile);
if (context_stack_depth > 0)
{
- /* This is said to happen with SCO. The old coffread.c code
- simply emptied the context stack, so we do the same. FIXME:
- Find out why it is happening. This is not believed to happen
- in most cases (even for coffread.c); it used to be an abort(). */
+ /* This is said to happen with SCO. The old coffread.c
+ code simply emptied the context stack, so we do the
+ same. FIXME: Find out why it is happening. This is not
+ believed to happen in most cases (even for coffread.c);
+ it used to be an abort(). */
static struct complaint msg =
- {"Context stack not empty in end_symtab", 0, 0};
+ {"Context stack not empty in end_symtab", 0, 0};
complain (&msg);
context_stack_depth = 0;
}
@@ -776,13 +824,12 @@ end_symtab (end_addr, objfile, section)
OBJF_REORDERED is true, then sort the pending blocks. */
if ((objfile->flags & OBJF_REORDERED) && pending_blocks)
{
- /* FIXME! Remove this horrid bubble sort and use qsort!!!
- It'd be a whole lot easier if they weren't in a linked list!!! */
+ /* FIXME! Remove this horrid bubble sort and use merge sort!!! */
int swapped;
do
{
struct pending_block *pb, *pbnext;
-
+
pb = pending_blocks;
pbnext = pb->next;
swapped = 0;
@@ -790,8 +837,8 @@ end_symtab (end_addr, objfile, section)
while (pbnext)
{
/* swap blocks if unordered! */
-
- if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block))
+
+ if (BLOCK_START (pb->block) < BLOCK_START (pbnext->block))
{
struct block *tmp = pb->block;
pb->block = pbnext->block;
@@ -801,13 +848,14 @@ end_symtab (end_addr, objfile, section)
pb = pbnext;
pbnext = pbnext->next;
}
- } while (swapped);
+ }
+ while (swapped);
}
/* Cleanup any undefined types that have been left hanging around
(this needs to be done before the finish_blocks so that
file_symbols is still good).
-
+
Both cleanup_undefined_types and finish_global_stabs are stabs
specific, but harmless for other symbol readers, since on gdb
startup or when finished reading stabs, the state is set so these
@@ -819,14 +867,17 @@ end_symtab (end_addr, objfile, section)
if (pending_blocks == NULL
&& file_symbols == NULL
- && global_symbols == NULL)
+ && global_symbols == NULL
+ && have_line_numbers == 0)
{
- /* Ignore symtabs that have no functions with real debugging info */
+ /* Ignore symtabs that have no functions with real debugging
+ info. */
blockvector = NULL;
}
else
{
- /* Define the STATIC_BLOCK & GLOBAL_BLOCK, and build the blockvector. */
+ /* Define the STATIC_BLOCK & GLOBAL_BLOCK, and build the
+ blockvector. */
finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr,
objfile);
finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
@@ -834,9 +885,10 @@ end_symtab (end_addr, objfile, section)
blockvector = make_blockvector (objfile);
}
-#ifdef PROCESS_LINENUMBER_HOOK
- PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */
+#ifndef PROCESS_LINENUMBER_HOOK
+#define PROCESS_LINENUMBER_HOOK()
#endif
+ PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */
/* Now create the symtab objects proper, one for each subfile. */
/* (The main file is the last one on the chain.) */
@@ -844,27 +896,28 @@ end_symtab (end_addr, objfile, section)
for (subfile = subfiles; subfile; subfile = nextsub)
{
int linetablesize = 0;
- /* If we have blocks of symbols, make a symtab.
- Otherwise, just ignore this file and any line number info in it. */
symtab = NULL;
+
+ /* If we have blocks of symbols, make a symtab. Otherwise, just
+ ignore this file and any line number info in it. */
if (blockvector)
{
if (subfile->line_vector)
{
linetablesize = sizeof (struct linetable) +
- subfile->line_vector->nitems * sizeof (struct linetable_entry);
+ subfile->line_vector->nitems * sizeof (struct linetable_entry);
#if 0
- /* I think this is artifact from before it went on the obstack.
- I doubt we'll need the memory between now and when we
- free it later in this function. */
+ /* I think this is artifact from before it went on the
+ obstack. I doubt we'll need the memory between now
+ and when we free it later in this function. */
/* First, shrink the linetable to make more memory. */
subfile->line_vector = (struct linetable *)
xrealloc ((char *) subfile->line_vector, linetablesize);
#endif
- /* Like the pending blocks, the line table may be scrambled
- in reordered executables. Sort it if OBJF_REORDERED is
- true. */
+ /* Like the pending blocks, the line table may be
+ scrambled in reordered executables. Sort it if
+ OBJF_REORDERED is true. */
if (objfile->flags & OBJF_REORDERED)
qsort (subfile->line_vector->item,
subfile->line_vector->nitems,
@@ -879,8 +932,8 @@ end_symtab (end_addr, objfile, section)
if (subfile->line_vector)
{
/* Reallocate the line table on the symbol obstack */
- symtab->linetable = (struct linetable *)
- obstack_alloc (&objfile -> symbol_obstack, linetablesize);
+ symtab->linetable = (struct linetable *)
+ obstack_alloc (&objfile->symbol_obstack, linetablesize);
memcpy (symtab->linetable, subfile->line_vector, linetablesize);
}
else
@@ -892,8 +945,8 @@ end_symtab (end_addr, objfile, section)
{
/* Reallocate the dirname on the symbol obstack */
symtab->dirname = (char *)
- obstack_alloc (&objfile -> symbol_obstack,
- strlen (subfile -> dirname) + 1);
+ obstack_alloc (&objfile->symbol_obstack,
+ strlen (subfile->dirname) + 1);
strcpy (symtab->dirname, subfile->dirname);
}
else
@@ -903,34 +956,47 @@ end_symtab (end_addr, objfile, section)
symtab->free_code = free_linetable;
symtab->free_ptr = NULL;
- /* Use whatever language we have been using for this subfile,
- not the one that was deduced in allocate_symtab from the
- filename. We already did our own deducing when we created
- the subfile, and we may have altered our opinion of what
- language it is from things we found in the symbols. */
+ /* Use whatever language we have been using for this
+ subfile, not the one that was deduced in allocate_symtab
+ from the filename. We already did our own deducing when
+ we created the subfile, and we may have altered our
+ opinion of what language it is from things we found in
+ the symbols. */
symtab->language = subfile->language;
+ /* Save the debug format string (if any) in the symtab */
+ if (subfile->debugformat != NULL)
+ {
+ symtab->debugformat = obsavestring (subfile->debugformat,
+ strlen (subfile->debugformat),
+ &objfile->symbol_obstack);
+ }
+
/* All symtabs for the main file and the subfiles share a
- blockvector, so we need to clear primary for everything but
- the main file. */
+ blockvector, so we need to clear primary for everything
+ but the main file. */
symtab->primary = 0;
}
if (subfile->name != NULL)
{
- free ((PTR) subfile->name);
+ free ((void *) subfile->name);
}
if (subfile->dirname != NULL)
{
- free ((PTR) subfile->dirname);
+ free ((void *) subfile->dirname);
}
if (subfile->line_vector != NULL)
{
- free ((PTR) subfile->line_vector);
+ free ((void *) subfile->line_vector);
+ }
+ if (subfile->debugformat != NULL)
+ {
+ free ((void *) subfile->debugformat);
}
nextsub = subfile->next;
- free ((PTR)subfile);
+ free ((void *) subfile);
}
/* Set this for the main source file. */
@@ -942,17 +1008,15 @@ end_symtab (end_addr, objfile, section)
last_source_file = NULL;
current_subfile = NULL;
- return (symtab);
+ return symtab;
}
-
-/* Push a context block. Args are an identifying nesting level (checkable
- when you pop it), and the starting PC address of this context. */
+/* Push a context block. Args are an identifying nesting level
+ (checkable when you pop it), and the starting PC address of this
+ context. */
struct context_stack *
-push_context (desc, valu)
- int desc;
- CORE_ADDR valu;
+push_context (int desc, CORE_ADDR valu)
{
register struct context_stack *new;
@@ -961,27 +1025,27 @@ push_context (desc, valu)
context_stack_size *= 2;
context_stack = (struct context_stack *)
xrealloc ((char *) context_stack,
- (context_stack_size * sizeof (struct context_stack)));
+ (context_stack_size * sizeof (struct context_stack)));
}
new = &context_stack[context_stack_depth++];
new->depth = desc;
new->locals = local_symbols;
+ new->params = param_symbols;
new->old_blocks = pending_blocks;
new->start_addr = valu;
new->name = NULL;
local_symbols = NULL;
+ param_symbols = NULL;
- return (new);
+ return new;
}
-
/* Compute a small integer hash code for the given name. */
int
-hashname (name)
- char *name;
+hashname (char *name)
{
register char *p = name;
register int total = p[0];
@@ -1006,11 +1070,45 @@ hashname (name)
}
return (total % HASHSIZE);
}
+
+
+void
+record_debugformat (char *format)
+{
+ current_subfile->debugformat = savestring (format, strlen (format));
+}
+
+/* Merge the first symbol list SRCLIST into the second symbol list
+ TARGETLIST by repeated calls to add_symbol_to_list(). This
+ procedure "frees" each link of SRCLIST by adding it to the
+ free_pendings list. Caller must set SRCLIST to a null list after
+ calling this function.
+
+ Void return. */
+void
+merge_symbol_lists (struct pending **srclist, struct pending **targetlist)
+{
+ register int i;
+
+ if (!srclist || !*srclist)
+ return;
+
+ /* Merge in elements from current link. */
+ for (i = 0; i < (*srclist)->nsyms; i++)
+ add_symbol_to_list ((*srclist)->symbol[i], targetlist);
+
+ /* Recurse on next. */
+ merge_symbol_lists (&(*srclist)->next, targetlist);
+
+ /* "Free" the current link. */
+ (*srclist)->next = free_pendings;
+ free_pendings = (*srclist);
+}
-/* Initialize anything that needs initializing when starting to read
- a fresh piece of a symbol file, e.g. reading in the stuff corresponding
- to a psymtab. */
+/* Initialize anything that needs initializing when starting to read a
+ fresh piece of a symbol file, e.g. reading in the stuff
+ corresponding to a psymtab. */
void
buildsym_init ()
@@ -1030,10 +1128,3 @@ buildsym_new_init ()
{
buildsym_init ();
}
-
-/* Initializer for this module */
-
-void
-_initialize_buildsym ()
-{
-}
diff --git a/contrib/gdb/gdb/buildsym.h b/contrib/gdb/gdb/buildsym.h
index 58529c7..e3a34c9 100644
--- a/contrib/gdb/gdb/buildsym.h
+++ b/contrib/gdb/gdb/buildsym.h
@@ -1,5 +1,5 @@
/* Build symbol tables in GDB's internal format.
- Copyright (C) 1986-1996 Free Software Foundation, Inc.
+ Copyright 1986-1993, 1996-1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -22,45 +22,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This module provides definitions used for creating and adding to
the symbol table. These routines are called from various symbol-
- file-reading routines.
+ file-reading routines.
They originated in dbxread.c of gdb-4.2, and were split out to
make xcoffread.c more maintainable by sharing code.
- Variables declared in this file can be defined by #define-ing
- the name EXTERN to null. It is used to declare variables that
- are normally extern, but which get defined in a single module
- using this technique. */
+ Variables declared in this file can be defined by #define-ing the
+ name EXTERN to null. It is used to declare variables that are
+ normally extern, but which get defined in a single module using
+ this technique. */
#ifndef EXTERN
#define EXTERN extern
#endif
-#define HASHSIZE 127 /* Size of things hashed via hashname() */
+#define HASHSIZE 127 /* Size of things hashed via
+ hashname() */
-/* Name of source file whose symbol data we are now processing.
- This comes from a symbol of type N_SO. */
+/* Name of source file whose symbol data we are now processing. This
+ comes from a symbol of type N_SO. */
EXTERN char *last_source_file;
-/* Core address of start of text of current source file.
- This too comes from the N_SO symbol. */
+/* Core address of start of text of current source file. This too
+ comes from the N_SO symbol. */
EXTERN CORE_ADDR last_source_start_addr;
-/* The list of sub-source-files within the current individual compilation.
- Each file gets its own symtab with its own linetable and associated info,
- but they all share one blockvector. */
+/* The list of sub-source-files within the current individual
+ compilation. Each file gets its own symtab with its own linetable
+ and associated info, but they all share one blockvector. */
struct subfile
-{
- struct subfile *next;
- char *name;
- char *dirname;
- struct linetable *line_vector;
- int line_vector_length;
- enum language language;
-};
+ {
+ struct subfile *next;
+ char *name;
+ char *dirname;
+ struct linetable *line_vector;
+ int line_vector_length;
+ enum language language;
+ char *debugformat;
+ };
EXTERN struct subfile *subfiles;
@@ -79,65 +81,85 @@ EXTERN unsigned char processing_gcc_compilation;
EXTERN unsigned char processing_acc_compilation;
+/* elz: added this flag to know when a block is compiled with HP
+ compilers (cc, aCC). This is necessary because of the macro
+ COERCE_FLOAT_TO_DOUBLE defined in tm_hppa.h, which causes a
+ coercion of float to double to always occur in parameter passing
+ for a function called by gdb (see the function value_arg_coerce in
+ valops.c). This is necessary only if the target was compiled with
+ gcc, not with HP compilers or with g++ */
+
+EXTERN unsigned char processing_hp_compilation;
+
/* Count symbols as they are processed, for error messages. */
EXTERN unsigned int symnum;
-/* Record the symbols defined for each context in a list.
- We don't create a struct block for the context until we
- know how long to make it. */
+/* Record the symbols defined for each context in a list. We don't
+ create a struct block for the context until we know how long to
+ make it. */
#define PENDINGSIZE 100
struct pending
-{
- struct pending *next;
- int nsyms;
- struct symbol *symbol[PENDINGSIZE];
-};
+ {
+ struct pending *next;
+ int nsyms;
+ struct symbol *symbol[PENDINGSIZE];
+ };
-/* List of free `struct pending' structures for reuse. */
+/* Here are the three lists that symbols are put on. */
-EXTERN struct pending *free_pendings;
+/* static at top level, and types */
-/* Here are the three lists that symbols are put on. */
+EXTERN struct pending *file_symbols;
+
+/* global functions and variables */
-EXTERN struct pending *file_symbols; /* static at top level, and types */
+EXTERN struct pending *global_symbols;
-EXTERN struct pending *global_symbols; /* global functions and variables */
+/* everything local to lexical context */
-EXTERN struct pending *local_symbols; /* everything local to lexic context */
+EXTERN struct pending *local_symbols;
-/* Stack representing unclosed lexical contexts
- (that will become blocks, eventually). */
+/* func params local to lexical context */
+
+EXTERN struct pending *param_symbols;
+
+/* Stack representing unclosed lexical contexts (that will become
+ blocks, eventually). */
struct context_stack
-{
- /* Outer locals at the time we entered */
+ {
+ /* Outer locals at the time we entered */
+
+ struct pending *locals;
- struct pending *locals;
+ /* Pending func params at the time we entered */
- /* Pointer into blocklist as of entry */
+ struct pending *params;
- struct pending_block *old_blocks;
+ /* Pointer into blocklist as of entry */
- /* Name of function, if any, defining context*/
+ struct pending_block *old_blocks;
- struct symbol *name;
+ /* Name of function, if any, defining context */
- /* PC where this context starts */
+ struct symbol *name;
- CORE_ADDR start_addr;
+ /* PC where this context starts */
- /* Temp slot for exception handling. */
+ CORE_ADDR start_addr;
- CORE_ADDR end_addr;
+ /* Temp slot for exception handling. */
- /* For error-checking matching push/pop */
+ CORE_ADDR end_addr;
- int depth;
+ /* For error-checking matching push/pop */
-};
+ int depth;
+
+ };
EXTERN struct context_stack *context_stack;
@@ -149,14 +171,14 @@ EXTERN int context_stack_depth;
EXTERN int context_stack_size;
-/* Macro "function" for popping contexts from the stack. Pushing is done
- by a real function, push_context. This returns a pointer to a struct
- context_stack. */
+/* Macro "function" for popping contexts from the stack. Pushing is
+ done by a real function, push_context. This returns a pointer to a
+ struct context_stack. */
#define pop_context() (&context_stack[--context_stack_depth]);
-/* Nonzero if within a function (so symbols should be local,
- if nothing says specifically). */
+/* Nonzero if within a function (so symbols should be local, if
+ nothing says specifically). */
EXTERN int within_function;
@@ -164,19 +186,24 @@ EXTERN int within_function;
This is used at the end to make the blockvector. */
struct pending_block
-{
- struct pending_block *next;
- struct block *block;
-};
+ {
+ struct pending_block *next;
+ struct block *block;
+ };
-EXTERN struct pending_block *pending_blocks;
+/* Pointer to the head of a linked list of symbol blocks which have
+ already been finalized (lexical contexts already closed) and which
+ are just waiting to be built into a blockvector when finalizing the
+ associated symtab. */
+EXTERN struct pending_block *pending_blocks;
+
struct subfile_stack
-{
- struct subfile_stack *next;
- char *name;
-};
+ {
+ struct subfile_stack *next;
+ char *name;
+ };
EXTERN struct subfile_stack *subfile_stack;
@@ -184,14 +211,13 @@ EXTERN struct subfile_stack *subfile_stack;
/* Function to invoke get the next symbol. Return the symbol name. */
-EXTERN char *(*next_symbol_text_func) PARAMS ((struct objfile *));
+EXTERN char *(*next_symbol_text_func) (struct objfile *);
/* Vector of types defined so far, indexed by their type numbers.
- Used for both stabs and coff.
- (In newer sun systems, dbx uses a pair of numbers in parens,
- as in "(SUBFILENUM,NUMWITHINSUBFILE)". Then these numbers must be
- translated through the type_translations hash table to get
- the index into the type vector.) */
+ Used for both stabs and coff. (In newer sun systems, dbx uses a
+ pair of numbers in parens, as in "(SUBFILENUM,NUMWITHINSUBFILE)".
+ Then these numbers must be translated through the type_translations
+ hash table to get the index into the type vector.) */
EXTERN struct type **type_vector;
@@ -199,61 +225,73 @@ EXTERN struct type **type_vector;
EXTERN int type_vector_length;
-/* Initial size of type vector. Is realloc'd larger if needed,
- and realloc'd down to the size actually used, when completed. */
+/* Initial size of type vector. Is realloc'd larger if needed, and
+ realloc'd down to the size actually used, when completed. */
#define INITIAL_TYPE_VECTOR_LENGTH 160
-extern void
-add_symbol_to_list PARAMS ((struct symbol *, struct pending **));
+extern void add_symbol_to_list (struct symbol *symbol,
+ struct pending **listhead);
+
+extern struct symbol *find_symbol_in_list (struct pending *list,
+ char *name, int length);
+
+extern void finish_block (struct symbol *symbol,
+ struct pending **listhead,
+ struct pending_block *old_blocks,
+ CORE_ADDR start, CORE_ADDR end,
+ struct objfile *objfile);
+
+extern void really_free_pendings (int foo);
+
+extern void start_subfile (char *name, char *dirname);
+
+extern void patch_subfile_names (struct subfile *subfile, char *name);
+
+extern void push_subfile (void);
+
+extern char *pop_subfile (void);
+
+extern struct symtab *end_symtab (CORE_ADDR end_addr,
+ struct objfile *objfile, int section);
-extern struct symbol *
-find_symbol_in_list PARAMS ((struct pending *, char *, int));
+/* Defined in stabsread.c. */
-extern void
-finish_block PARAMS ((struct symbol *, struct pending **,
- struct pending_block *, CORE_ADDR, CORE_ADDR,
- struct objfile *));
+extern void scan_file_globals (struct objfile *objfile);
-extern void
-really_free_pendings PARAMS ((int foo));
+extern void buildsym_new_init (void);
-extern void
-start_subfile PARAMS ((char *, char *));
+extern void buildsym_init (void);
-extern void
-patch_subfile_names PARAMS ((struct subfile *subfile, char *name));
+extern struct context_stack *push_context (int desc, CORE_ADDR valu);
-extern void
-push_subfile PARAMS ((void));
+extern void record_line (struct subfile *subfile, int line, CORE_ADDR pc);
-extern char *
-pop_subfile PARAMS ((void));
+extern void start_symtab (char *name, char *dirname, CORE_ADDR start_addr);
-extern struct symtab *
-end_symtab PARAMS ((CORE_ADDR, struct objfile *, int));
+extern int hashname (char *name);
-extern void
-scan_file_globals PARAMS ((struct objfile *));
+extern void free_pending_blocks (void);
-extern void
-buildsym_new_init PARAMS ((void));
+/* FIXME: Note that this is used only in buildsym.c and dstread.c,
+ which should be fixed to not need direct access to
+ make_blockvector. */
-extern void
-buildsym_init PARAMS ((void));
+extern struct blockvector *make_blockvector (struct objfile *objfile);
-extern struct context_stack *
-push_context PARAMS ((int, CORE_ADDR));
+/* FIXME: Note that this is used only in buildsym.c and dstread.c,
+ which should be fixed to not need direct access to
+ record_pending_block. */
-extern void
-record_line PARAMS ((struct subfile *, int, CORE_ADDR));
+extern void record_pending_block (struct objfile *objfile,
+ struct block *block,
+ struct pending_block *opblock);
-extern void
-start_symtab PARAMS ((char *, char *, CORE_ADDR));
+extern void record_debugformat (char *format);
-extern int
-hashname PARAMS ((char *));
+extern void merge_symbol_lists (struct pending **srclist,
+ struct pending **targetlist);
#undef EXTERN
-#endif /* defined (BUILDSYM_H) */
+#endif /* defined (BUILDSYM_H) */
diff --git a/contrib/gdb/gdb/c-exp.tab.c b/contrib/gdb/gdb/c-exp.tab.c
index 0c6249b..c9395fa 100644
--- a/contrib/gdb/gdb/c-exp.tab.c
+++ b/contrib/gdb/gdb/c-exp.tab.c
@@ -1,5 +1,6 @@
-/* A Bison parser, made from ./c-exp.y with Bison version GNU Bison version 1.24
+/* A Bison parser, made from c-exp.y
+ by GNU Bison version 1.25
*/
#define YYBISON 1 /* Identify Bison output. */
@@ -29,22 +30,25 @@
#define VARIABLE 280
#define ASSIGN_MODIFY 281
#define THIS 282
-#define ABOVE_COMMA 283
-#define OROR 284
-#define ANDAND 285
-#define EQUAL 286
-#define NOTEQUAL 287
-#define LEQ 288
-#define GEQ 289
-#define LSH 290
-#define RSH 291
-#define UNARY 292
-#define INCREMENT 293
-#define DECREMENT 294
-#define ARROW 295
-#define BLOCKNAME 296
-
-#line 38 "./c-exp.y"
+#define TRUEKEYWORD 283
+#define FALSEKEYWORD 284
+#define ABOVE_COMMA 285
+#define OROR 286
+#define ANDAND 287
+#define EQUAL 288
+#define NOTEQUAL 289
+#define LEQ 290
+#define GEQ 291
+#define LSH 292
+#define RSH 293
+#define UNARY 294
+#define INCREMENT 295
+#define DECREMENT 296
+#define ARROW 297
+#define BLOCKNAME 298
+#define FILENAME 299
+
+#line 38 "c-exp.y"
#include "defs.h"
@@ -59,6 +63,9 @@
#include "symfile.h" /* Required by objfiles.h. */
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+/* Flag indicating we're dealing with HP-compiled objects */
+extern int hp_som_som_object_present;
+
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitiously global symbol names, so we can have multiple
yacc generated parsers in gdb. Note that these are only the variables
@@ -119,7 +126,7 @@ void
yyerror PARAMS ((char *));
-#line 117 "./c-exp.y"
+#line 120 "c-exp.y"
typedef union
{
LONGEST lval;
@@ -144,28 +151,11 @@ typedef union
struct type **tvec;
int *ivec;
} YYSTYPE;
-#line 142 "./c-exp.y"
+#line 145 "c-exp.y"
/* YYSTYPE gets defined by %union */
static int
parse_number PARAMS ((char *, int, int, YYSTYPE *));
-
-#ifndef YYLTYPE
-typedef
- struct yyltype
- {
- int timestamp;
- int first_line;
- int first_column;
- int last_line;
- int last_column;
- char *text;
- }
- yyltype;
-
-#define YYLTYPE yyltype
-#endif
-
#include <stdio.h>
#ifndef __cplusplus
@@ -176,26 +166,26 @@ typedef
-#define YYFINAL 211
+#define YYFINAL 214
#define YYFLAG -32768
-#define YYNTBASE 66
+#define YYNTBASE 69
-#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 88)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 299 ? yytranslate[x] : 91)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 59, 2, 2, 2, 50, 36, 2, 57,
- 62, 48, 46, 28, 47, 55, 49, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 65, 2, 39,
- 30, 40, 31, 45, 2, 2, 2, 2, 2, 2,
+ 2, 2, 62, 2, 2, 2, 52, 38, 2, 59,
+ 65, 50, 48, 30, 49, 57, 51, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 68, 2, 41,
+ 32, 42, 33, 47, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 56, 2, 61, 35, 2, 2, 2, 2, 2, 2,
+ 58, 2, 64, 37, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 63, 34, 64, 60, 2, 2, 2, 2,
+ 2, 2, 66, 36, 67, 63, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -211,8 +201,8 @@ static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 29, 32, 33, 37, 38, 41, 42, 43,
- 44, 51, 52, 53, 54, 58
+ 26, 27, 28, 29, 31, 34, 35, 39, 40, 43,
+ 44, 45, 46, 53, 54, 55, 56, 60, 61
};
#if YYDEBUG != 0
@@ -223,107 +213,114 @@ static const short yyprhs[] = { 0,
95, 100, 105, 109, 113, 117, 121, 125, 129, 133,
137, 141, 145, 149, 153, 157, 161, 165, 169, 173,
177, 181, 185, 191, 195, 199, 201, 203, 205, 207,
- 209, 214, 216, 218, 220, 224, 228, 232, 237, 239,
- 242, 244, 246, 249, 252, 255, 259, 263, 265, 268,
- 270, 273, 275, 279, 282, 284, 287, 289, 292, 296,
- 299, 303, 305, 309, 311, 313, 315, 317, 320, 324,
- 327, 331, 335, 340, 343, 347, 349, 352, 355, 358,
- 361, 364, 367, 369, 372, 374, 380, 383, 386, 388,
- 390, 392, 394, 396, 400, 402, 404, 406, 408, 410
+ 209, 214, 216, 218, 220, 222, 224, 226, 230, 234,
+ 238, 243, 245, 248, 250, 252, 255, 258, 261, 265,
+ 269, 271, 274, 276, 279, 281, 285, 288, 290, 293,
+ 295, 298, 302, 305, 309, 311, 315, 317, 319, 321,
+ 323, 326, 330, 333, 337, 341, 346, 349, 353, 355,
+ 358, 361, 364, 367, 370, 373, 375, 378, 380, 386,
+ 389, 392, 394, 396, 398, 400, 402, 406, 408, 410,
+ 412, 414, 416
};
-static const short yyrhs[] = { 68,
- 0, 67, 0, 82, 0, 69, 0, 68, 28, 69,
- 0, 48, 69, 0, 36, 69, 0, 47, 69, 0,
- 59, 69, 0, 60, 69, 0, 52, 69, 0, 53,
- 69, 0, 69, 52, 0, 69, 53, 0, 13, 69,
- 0, 69, 54, 86, 0, 69, 54, 76, 0, 69,
- 54, 48, 69, 0, 69, 55, 86, 0, 69, 55,
- 76, 0, 69, 55, 48, 69, 0, 69, 56, 68,
- 61, 0, 0, 69, 57, 70, 72, 62, 0, 63,
- 0, 0, 69, 0, 72, 28, 69, 0, 64, 0,
- 71, 72, 73, 0, 71, 82, 73, 69, 0, 57,
- 82, 62, 69, 0, 57, 68, 62, 0, 69, 45,
- 69, 0, 69, 48, 69, 0, 69, 49, 69, 0,
- 69, 50, 69, 0, 69, 46, 69, 0, 69, 47,
- 69, 0, 69, 43, 69, 0, 69, 44, 69, 0,
- 69, 37, 69, 0, 69, 38, 69, 0, 69, 41,
- 69, 0, 69, 42, 69, 0, 69, 39, 69, 0,
- 69, 40, 69, 0, 69, 36, 69, 0, 69, 35,
- 69, 0, 69, 34, 69, 0, 69, 33, 69, 0,
- 69, 32, 69, 0, 69, 31, 69, 65, 69, 0,
- 69, 30, 69, 0, 69, 26, 69, 0, 3, 0,
- 8, 0, 4, 0, 75, 0, 25, 0, 13, 57,
- 82, 62, 0, 5, 0, 27, 0, 58, 0, 74,
- 15, 86, 0, 74, 15, 86, 0, 83, 15, 86,
- 0, 83, 15, 60, 86, 0, 76, 0, 15, 86,
- 0, 87, 0, 83, 0, 83, 22, 0, 83, 23,
- 0, 83, 78, 0, 83, 22, 78, 0, 83, 23,
- 78, 0, 48, 0, 48, 78, 0, 36, 0, 36,
- 78, 0, 79, 0, 57, 78, 62, 0, 79, 80,
- 0, 80, 0, 79, 81, 0, 81, 0, 56, 61,
- 0, 56, 3, 61, 0, 57, 62, 0, 57, 85,
- 62, 0, 77, 0, 83, 15, 48, 0, 7, 0,
- 21, 0, 19, 0, 20, 0, 19, 21, 0, 14,
- 19, 21, 0, 19, 19, 0, 19, 19, 21, 0,
- 14, 19, 19, 0, 14, 19, 19, 21, 0, 20,
- 21, 0, 14, 20, 21, 0, 24, 0, 19, 24,
- 0, 9, 86, 0, 10, 86, 0, 11, 86, 0,
- 12, 86, 0, 14, 84, 0, 14, 0, 18, 84,
- 0, 18, 0, 16, 86, 39, 82, 40, 0, 22,
- 83, 0, 23, 83, 0, 7, 0, 21, 0, 19,
- 0, 20, 0, 82, 0, 85, 28, 82, 0, 6,
- 0, 58, 0, 7, 0, 8, 0, 6, 0, 58,
- 0
+static const short yyrhs[] = { 71,
+ 0, 70, 0, 85, 0, 72, 0, 71, 30, 72,
+ 0, 50, 72, 0, 38, 72, 0, 49, 72, 0,
+ 62, 72, 0, 63, 72, 0, 54, 72, 0, 55,
+ 72, 0, 72, 54, 0, 72, 55, 0, 13, 72,
+ 0, 72, 56, 89, 0, 72, 56, 79, 0, 72,
+ 56, 50, 72, 0, 72, 57, 89, 0, 72, 57,
+ 79, 0, 72, 57, 50, 72, 0, 72, 58, 71,
+ 64, 0, 0, 72, 59, 73, 75, 65, 0, 66,
+ 0, 0, 72, 0, 75, 30, 72, 0, 67, 0,
+ 74, 75, 76, 0, 74, 85, 76, 72, 0, 59,
+ 85, 65, 72, 0, 59, 71, 65, 0, 72, 47,
+ 72, 0, 72, 50, 72, 0, 72, 51, 72, 0,
+ 72, 52, 72, 0, 72, 48, 72, 0, 72, 49,
+ 72, 0, 72, 45, 72, 0, 72, 46, 72, 0,
+ 72, 39, 72, 0, 72, 40, 72, 0, 72, 43,
+ 72, 0, 72, 44, 72, 0, 72, 41, 72, 0,
+ 72, 42, 72, 0, 72, 38, 72, 0, 72, 37,
+ 72, 0, 72, 36, 72, 0, 72, 35, 72, 0,
+ 72, 34, 72, 0, 72, 33, 72, 68, 72, 0,
+ 72, 32, 72, 0, 72, 26, 72, 0, 3, 0,
+ 8, 0, 4, 0, 78, 0, 25, 0, 13, 59,
+ 85, 65, 0, 5, 0, 27, 0, 28, 0, 29,
+ 0, 60, 0, 61, 0, 77, 15, 89, 0, 77,
+ 15, 89, 0, 86, 15, 89, 0, 86, 15, 63,
+ 89, 0, 79, 0, 15, 89, 0, 90, 0, 86,
+ 0, 86, 22, 0, 86, 23, 0, 86, 81, 0,
+ 86, 22, 81, 0, 86, 23, 81, 0, 50, 0,
+ 50, 81, 0, 38, 0, 38, 81, 0, 82, 0,
+ 59, 81, 65, 0, 82, 83, 0, 83, 0, 82,
+ 84, 0, 84, 0, 58, 64, 0, 58, 3, 64,
+ 0, 59, 65, 0, 59, 88, 65, 0, 80, 0,
+ 86, 15, 50, 0, 7, 0, 21, 0, 19, 0,
+ 20, 0, 19, 21, 0, 14, 19, 21, 0, 19,
+ 19, 0, 19, 19, 21, 0, 14, 19, 19, 0,
+ 14, 19, 19, 21, 0, 20, 21, 0, 14, 20,
+ 21, 0, 24, 0, 19, 24, 0, 9, 89, 0,
+ 10, 89, 0, 11, 89, 0, 12, 89, 0, 14,
+ 87, 0, 14, 0, 18, 87, 0, 18, 0, 16,
+ 89, 41, 85, 42, 0, 22, 86, 0, 23, 86,
+ 0, 7, 0, 21, 0, 19, 0, 20, 0, 85,
+ 0, 88, 30, 85, 0, 6, 0, 60, 0, 7,
+ 0, 8, 0, 6, 0, 60, 0
};
#endif
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 223, 224, 227, 234, 235, 240, 243, 246, 250, 254,
- 258, 262, 266, 270, 274, 278, 284, 291, 295, 302,
- 310, 314, 318, 322, 328, 332, 335, 339, 343, 346,
- 353, 359, 365, 371, 375, 379, 383, 387, 391, 395,
- 399, 403, 407, 411, 415, 419, 423, 427, 431, 435,
- 439, 443, 447, 451, 455, 461, 468, 479, 486, 489,
- 493, 501, 526, 533, 550, 561, 577, 590, 615, 616,
- 650, 708, 714, 715, 716, 718, 720, 724, 726, 728,
- 730, 732, 735, 737, 742, 749, 751, 755, 757, 761,
- 763, 775, 776, 781, 783, 785, 787, 789, 791, 793,
- 795, 797, 799, 801, 803, 805, 807, 809, 812, 815,
- 818, 821, 823, 825, 827, 829, 836, 837, 840, 841,
- 847, 853, 862, 867, 874, 875, 876, 877, 880, 881
+ 230, 231, 234, 241, 242, 247, 250, 253, 257, 261,
+ 265, 269, 273, 277, 281, 285, 291, 299, 303, 309,
+ 317, 321, 325, 329, 335, 339, 342, 346, 350, 353,
+ 360, 366, 372, 378, 382, 386, 390, 394, 398, 402,
+ 406, 410, 414, 418, 422, 426, 430, 434, 438, 442,
+ 446, 450, 454, 458, 462, 468, 475, 486, 493, 496,
+ 500, 508, 533, 538, 545, 554, 562, 568, 579, 595,
+ 608, 632, 633, 667, 725, 731, 732, 733, 735, 737,
+ 741, 743, 745, 747, 749, 752, 754, 759, 766, 768,
+ 772, 774, 778, 780, 792, 793, 798, 800, 802, 804,
+ 806, 808, 810, 812, 814, 816, 818, 820, 822, 824,
+ 826, 829, 832, 835, 838, 840, 842, 844, 849, 856,
+ 857, 860, 861, 867, 873, 882, 887, 894, 895, 896,
+ 897, 900, 901
};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
static const char * const yytname[] = { "$","error","$undefined.","INT","FLOAT",
"STRING","NAME","TYPENAME","NAME_OR_INT","STRUCT","CLASS","UNION","ENUM","SIZEOF",
"UNSIGNED","COLONCOLON","TEMPLATE","ERROR","SIGNED_KEYWORD","LONG","SHORT","INT_KEYWORD",
"CONST_KEYWORD","VOLATILE_KEYWORD","DOUBLE_KEYWORD","VARIABLE","ASSIGN_MODIFY",
-"THIS","','","ABOVE_COMMA","'='","'?'","OROR","ANDAND","'|'","'^'","'&'","EQUAL",
-"NOTEQUAL","'<'","'>'","LEQ","GEQ","LSH","RSH","'@'","'+'","'-'","'*'","'/'",
-"'%'","UNARY","INCREMENT","DECREMENT","ARROW","'.'","'['","'('","BLOCKNAME",
-"'!'","'~'","']'","')'","'{'","'}'","':'","start","type_exp","exp1","exp","@1",
-"lcurly","arglist","rcurly","block","variable","qualified_name","ptype","abs_decl",
-"direct_abs_decl","array_mod","func_mod","type","typebase","typename","nonempty_typelist",
-"name","name_not_typename",""
+"THIS","TRUEKEYWORD","FALSEKEYWORD","','","ABOVE_COMMA","'='","'?'","OROR","ANDAND",
+"'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'","'>'","LEQ","GEQ","LSH","RSH","'@'",
+"'+'","'-'","'*'","'/'","'%'","UNARY","INCREMENT","DECREMENT","ARROW","'.'",
+"'['","'('","BLOCKNAME","FILENAME","'!'","'~'","']'","')'","'{'","'}'","':'",
+"start","type_exp","exp1","exp","@1","lcurly","arglist","rcurly","block","variable",
+"qualified_name","ptype","abs_decl","direct_abs_decl","array_mod","func_mod",
+"type","typebase","typename","nonempty_typelist","name","name_not_typename", NULL
};
#endif
static const short yyr1[] = { 0,
- 66, 66, 67, 68, 68, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 70, 69, 71, 72, 72, 72, 73, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 74, 74, 75, 76, 76, 75, 75,
- 75, 77, 77, 77, 77, 77, 77, 78, 78, 78,
- 78, 78, 79, 79, 79, 79, 79, 80, 80, 81,
- 81, 82, 82, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 84, 84,
- 84, 84, 85, 85, 86, 86, 86, 86, 87, 87
+ 69, 69, 70, 71, 71, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 73, 72, 74, 75, 75, 75, 76, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 77, 77, 77, 78, 79,
+ 79, 78, 78, 78, 80, 80, 80, 80, 80, 80,
+ 81, 81, 81, 81, 81, 82, 82, 82, 82, 82,
+ 83, 83, 84, 84, 85, 85, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 87, 87, 87, 87, 88, 88, 89, 89, 89,
+ 89, 90, 90
};
static const short yyr2[] = { 0,
@@ -333,238 +330,235 @@ static const short yyr2[] = { 0,
4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 5, 3, 3, 1, 1, 1, 1, 1,
- 4, 1, 1, 1, 3, 3, 3, 4, 1, 2,
- 1, 1, 2, 2, 2, 3, 3, 1, 2, 1,
- 2, 1, 3, 2, 1, 2, 1, 2, 3, 2,
- 3, 1, 3, 1, 1, 1, 1, 2, 3, 2,
- 3, 3, 4, 2, 3, 1, 2, 2, 2, 2,
- 2, 2, 1, 2, 1, 5, 2, 2, 1, 1,
- 1, 1, 1, 3, 1, 1, 1, 1, 1, 1
+ 4, 1, 1, 1, 1, 1, 1, 3, 3, 3,
+ 4, 1, 2, 1, 1, 2, 2, 2, 3, 3,
+ 1, 2, 1, 2, 1, 3, 2, 1, 2, 1,
+ 2, 3, 2, 3, 1, 3, 1, 1, 1, 1,
+ 2, 3, 2, 3, 3, 4, 2, 3, 1, 2,
+ 2, 2, 2, 2, 2, 1, 2, 1, 5, 2,
+ 2, 1, 1, 1, 1, 1, 3, 1, 1, 1,
+ 1, 1, 1
};
static const short yydefact[] = { 0,
- 56, 58, 62, 129, 94, 57, 0, 0, 0, 0,
- 0, 113, 0, 0, 115, 96, 97, 95, 0, 0,
- 106, 60, 63, 0, 0, 0, 0, 0, 0, 130,
- 0, 0, 25, 2, 1, 4, 26, 0, 59, 69,
- 92, 3, 72, 71, 125, 127, 128, 126, 108, 109,
- 110, 111, 0, 15, 0, 119, 121, 122, 120, 112,
- 70, 0, 121, 122, 114, 100, 98, 107, 104, 117,
- 118, 7, 8, 6, 11, 12, 0, 0, 9, 10,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 56, 58, 62, 132, 97, 57, 0, 0, 0, 0,
+ 0, 116, 0, 0, 118, 99, 100, 98, 0, 0,
+ 109, 60, 63, 64, 65, 0, 0, 0, 0, 0,
+ 0, 133, 67, 0, 0, 25, 2, 1, 4, 26,
+ 0, 59, 72, 95, 3, 75, 74, 128, 130, 131,
+ 129, 111, 112, 113, 114, 0, 15, 0, 122, 124,
+ 125, 123, 115, 73, 0, 124, 125, 117, 103, 101,
+ 110, 107, 120, 121, 7, 8, 6, 11, 12, 0,
+ 0, 9, 10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 13, 14, 0, 0, 0, 23, 27,
- 0, 0, 0, 0, 73, 74, 80, 78, 0, 0,
- 75, 82, 85, 87, 0, 0, 102, 99, 105, 0,
- 101, 33, 0, 5, 55, 54, 0, 52, 51, 50,
- 49, 48, 42, 43, 46, 47, 44, 45, 40, 41,
- 34, 38, 39, 35, 36, 37, 127, 0, 17, 16,
- 0, 20, 19, 0, 26, 0, 29, 30, 0, 66,
- 93, 0, 67, 76, 77, 81, 79, 0, 88, 90,
- 0, 123, 72, 0, 0, 84, 86, 61, 103, 0,
- 32, 0, 18, 21, 22, 0, 28, 31, 68, 89,
- 83, 0, 0, 91, 116, 53, 24, 124, 0, 0,
- 0
+ 0, 0, 0, 0, 0, 0, 13, 14, 0, 0,
+ 0, 23, 27, 0, 0, 0, 0, 76, 77, 83,
+ 81, 0, 0, 78, 85, 88, 90, 0, 0, 105,
+ 102, 108, 0, 104, 33, 0, 5, 55, 54, 0,
+ 52, 51, 50, 49, 48, 42, 43, 46, 47, 44,
+ 45, 40, 41, 34, 38, 39, 35, 36, 37, 130,
+ 0, 17, 16, 0, 20, 19, 0, 26, 0, 29,
+ 30, 0, 69, 96, 0, 70, 79, 80, 84, 82,
+ 0, 91, 93, 0, 126, 75, 0, 0, 87, 89,
+ 61, 106, 0, 32, 0, 18, 21, 22, 0, 28,
+ 31, 71, 92, 86, 0, 0, 94, 119, 53, 24,
+ 127, 0, 0, 0
};
-static const short yydefgoto[] = { 209,
- 34, 77, 36, 165, 37, 111, 168, 38, 39, 40,
- 41, 121, 122, 123, 124, 182, 55, 60, 184, 173,
- 44
+static const short yydefgoto[] = { 212,
+ 37, 80, 39, 168, 40, 114, 171, 41, 42, 43,
+ 44, 124, 125, 126, 127, 185, 58, 63, 187, 176,
+ 47
};
-static const short yypact[] = { 241,
--32768,-32768,-32768,-32768,-32768,-32768, 5, 5, 5, 5,
- 302, 24, 5, 5, 73, 66, 27,-32768, 212, 212,
--32768,-32768,-32768, 241, 241, 241, 241, 241, 241, 32,
- 241, 241,-32768,-32768, -1, 523, 241, 42,-32768,-32768,
--32768,-32768, 3,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, 241, 43, 52,-32768, 70, 50,-32768,-32768,
--32768, 64,-32768,-32768,-32768, 60,-32768,-32768,-32768,-32768,
--32768, 43, 43, 43, 43, 43, -7, 44, 43, 43,
- 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
- 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
- 241, 241, 241,-32768,-32768, 439, 458, 241,-32768, 523,
- -18, 41, 5, 8, 16, 16, 16, 16, 4, 382,
--32768, -34,-32768,-32768, 45, 26, 83,-32768,-32768, 212,
--32768,-32768, 241, 523, 523, 523, 487, 575, 599, 622,
- 644, 665, 684, 684, 143, 143, 143, 143, 226, 226,
- 69, 287, 287, 43, 43, 43, 94, 241,-32768,-32768,
- 241,-32768,-32768, -11, 241, 241,-32768,-32768, 241, 95,
--32768, 5,-32768,-32768,-32768,-32768,-32768, 67,-32768,-32768,
- 49,-32768, 13, -4, 152,-32768,-32768, 363,-32768, 72,
- 43, 241, 43, 43,-32768, 12, 523, 43,-32768,-32768,
--32768, 65, 212,-32768,-32768, 550,-32768,-32768, 127, 129,
--32768
+static const short yypact[] = { 205,
+-32768,-32768,-32768,-32768,-32768,-32768, 46, 46, 46, 46,
+ 269, 57, 46, 46, 100, 134, -14,-32768, 228, 228,
+-32768,-32768,-32768,-32768,-32768, 205, 205, 205, 205, 205,
+ 205, 21,-32768, 205, 205,-32768,-32768, -16, 504, 205,
+ 22,-32768,-32768,-32768,-32768, 107,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768, 205, 14, 23,-32768, 7,
+ 24,-32768,-32768,-32768, 10,-32768,-32768,-32768, 34,-32768,
+-32768,-32768,-32768,-32768, 14, 14, 14, 14, 14, -26,
+ -21, 14, 14, 205, 205, 205, 205, 205, 205, 205,
+ 205, 205, 205, 205, 205, 205, 205, 205, 205, 205,
+ 205, 205, 205, 205, 205, 205,-32768,-32768, 419, 438,
+ 205,-32768, 504, -25, -2, 46, 53, 8, 8, 8,
+ 8, -1, 359,-32768, -41,-32768,-32768, 9, 42, 54,
+-32768,-32768, 228,-32768,-32768, 205, 504, 504, 504, 467,
+ 556, 580, 603, 625, 646, 665, 665, 254, 254, 254,
+ 254, 124, 124, 356, 416, 416, 14, 14, 14, 89,
+ 205,-32768,-32768, 205,-32768,-32768, -17, 205, 205,-32768,
+-32768, 205, 93,-32768, 46,-32768,-32768,-32768,-32768,-32768,
+ 45,-32768,-32768, 50,-32768, 146, -22, 128,-32768,-32768,
+ 333,-32768, 68, 14, 205, 14, 14,-32768, -3, 504,
+ 14,-32768,-32768,-32768, 67, 228,-32768,-32768, 531,-32768,
+-32768, 125, 126,-32768
};
static const short yypgoto[] = {-32768,
--32768, 6, 51,-32768,-32768, 14, 53,-32768,-32768, -65,
--32768, 40,-32768, 47, 55, 1, 0, 163,-32768, -5,
+-32768, 3, -5,-32768,-32768, -44, 12,-32768,-32768, -76,
+-32768, 79,-32768, 11, 16, 1, 0, 113,-32768, 2,
-32768
};
-#define YYLAST 741
-
-
-static const short yytable[] = { 43,
- 42, 49, 50, 51, 52, 35, 178, 61, 62, 166,
- 45, 46, 47, 45, 46, 47, 81, 114, 70, 71,
- 81, 119, 185, 203, 115, 116, 81, 202, 43, 78,
- 56, 45, 46, 47, 115, 116, 43, 112, 117, 166,
- 159, 162, 57, 58, 59, 167, -64, 69, 117, 195,
- 118, 117, 43, 125, 132, 171, 113, 204, 119, 120,
- 118, 54, 48, 118, 179, 48, 126, 172, 119, 120,
- 129, 119, 120, 207, 72, 73, 74, 75, 76, 56,
- 131, 79, 80, 48, 66, 172, 67, 110, 127, 68,
- 128, 63, 64, 59, 104, 105, 106, 107, 108, 109,
- 160, 163, 130, 189, 167, 133, 188, 170, -94, -65,
- 201, 205, 171, 164, 99, 100, 101, 102, 103, 183,
- 104, 105, 106, 107, 108, 109, 210, 200, 211, 183,
- 190, 134, 135, 136, 137, 138, 139, 140, 141, 142,
- 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
- 153, 154, 155, 156, 174, 175, 176, 177, 5, 181,
- 7, 8, 9, 10, 169, 12, 199, 14, 186, 15,
- 16, 17, 18, 19, 20, 21, 187, 65, 196, 0,
- 0, 0, 0, 191, 183, 96, 97, 98, 99, 100,
- 101, 102, 103, 0, 104, 105, 106, 107, 108, 109,
- 0, 0, 183, 208, 0, 0, 0, 0, 193, 0,
- 0, 194, 0, 180, 0, 110, 197, 0, 5, 198,
- 7, 8, 9, 10, 0, 12, 0, 14, 0, 15,
- 16, 17, 18, 19, 20, 21, 0, 0, 191, 0,
- 0, 0, 206, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 0, 15, 16,
- 17, 18, 19, 20, 21, 22, 0, 23, 0, 0,
- 98, 99, 100, 101, 102, 103, 24, 104, 105, 106,
- 107, 108, 109, 0, 0, 0, 0, 25, 26, 0,
- 0, 0, 27, 28, 0, 0, 0, 29, 30, 31,
- 32, 0, 0, 33, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 0, 15,
- 16, 17, 18, 19, 20, 21, 22, 0, 23, 0,
- 0, 0, 0, 0, 101, 102, 103, 24, 104, 105,
- 106, 107, 108, 109, 0, 0, 0, 0, 25, 26,
- 0, 0, 0, 27, 28, 0, 0, 0, 53, 30,
- 31, 32, 0, 0, 33, 1, 2, 3, 4, 5,
+#define YYLAST 724
+
+
+static const short yytable[] = { 46,
+ 45, 181, 38, 84, 169, 57, 72, 206, 52, 53,
+ 54, 55, 84, 84, 64, 65, 122, 188, 73, 74,
+ 75, 76, 77, 78, 79, 130, 169, 131, 82, 83,
+ 46, 81, 162, 165, 113, -66, 116, 129, 135, 46,
+ 115, 170, 207, 136, 132, 120, 198, 48, 49, 50,
+ 133, 48, 49, 50, 134, 46, 128, 121, 48, 49,
+ 50, 210, 182, 59, 170, 122, 123, 107, 108, 109,
+ 110, 111, 112, 191, 192, 60, 61, 62, 137, 138,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 51, 174, -97, 175, 51, 59, -68, 203, 208,
+ 163, 166, 51, 167, 204, 175, 174, 173, 66, 67,
+ 62, 117, 186, 199, 213, 214, 172, 68, 118, 119,
+ 194, 0, 186, 193, 5, 189, 7, 8, 9, 10,
+ 190, 12, 0, 14, 120, 15, 16, 17, 18, 19,
+ 20, 21, 69, 0, 70, 196, 121, 71, 197, 0,
+ 205, 0, 113, 200, 122, 123, 201, 118, 119, 0,
+ 101, 102, 103, 104, 105, 106, 202, 107, 108, 109,
+ 110, 111, 112, 120, 0, 194, 0, 186, 0, 209,
+ 0, 0, 183, 0, 0, 121, 177, 178, 179, 180,
+ 0, 184, 0, 122, 123, 186, 211, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 0, 15, 16, 17, 18, 19, 20, 21, 22,
+ 0, 23, 24, 25, 5, 0, 7, 8, 9, 10,
+ 0, 12, 26, 14, 0, 15, 16, 17, 18, 19,
+ 20, 21, 0, 27, 28, 0, 0, 0, 29, 30,
+ 0, 0, 0, 31, 32, 33, 34, 35, 0, 0,
+ 36, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 0, 15, 16, 17, 18,
+ 19, 20, 21, 22, 0, 23, 24, 25, 99, 100,
+ 101, 102, 103, 104, 105, 106, 26, 107, 108, 109,
+ 110, 111, 112, 0, 0, 0, 0, 27, 28, 0,
+ 0, 0, 29, 30, 0, 0, 0, 56, 32, 33,
+ 34, 35, 0, 0, 36, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 0,
- 15, 16, 17, 18, 19, 20, 21, 22, 5, 23,
- 7, 8, 9, 10, 0, 12, 0, 14, 0, 15,
- 16, 17, 18, 19, 20, 21, 0, 0, 0, 0,
- 0, 0, 0, 0, 27, 28, 0, 117, 0, 29,
- 30, 31, 32, 0, 0, 33, 0, 0, 0, 118,
- 0, 0, 0, 0, 0, 0, 0, 119, 120, 0,
- 0, 0, 0, 180, 45, 157, 47, 7, 8, 9,
+ 15, 16, 17, 18, 19, 20, 21, 22, 0, 23,
+ 24, 25, 0, 0, 0, 5, 0, 7, 8, 9,
+ 10, 0, 12, 0, 14, 0, 15, 16, 17, 18,
+ 19, 20, 21, 0, 0, 0, 29, 30, 0, 0,
+ 0, 31, 32, 33, 34, 35, 120, 0, 36, 0,
+ 0, 0, 0, 102, 103, 104, 105, 106, 121, 107,
+ 108, 109, 110, 111, 112, 0, 122, 123, 0, 0,
+ 0, 0, 0, 183, 48, 160, 50, 7, 8, 9,
10, 0, 12, 0, 14, 0, 15, 16, 17, 18,
- 19, 20, 21, 45, 157, 47, 7, 8, 9, 10,
+ 19, 20, 21, 48, 160, 50, 7, 8, 9, 10,
0, 12, 0, 14, 0, 15, 16, 17, 18, 19,
- 20, 21, 0, 0, 0, 0, 158, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 48, 0, 0, 0,
- 0, 0, 0, 0, 0, 161, 0, 0, 0, 0,
- 0, 0, 82, 0, 0, 48, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 103, 0, 104, 105,
- 106, 107, 108, 109, 0, 0, 0, 0, 82, 0,
- 0, 192, 83, 84, 85, 86, 87, 88, 89, 90,
+ 20, 21, 0, 0, 0, 104, 105, 106, 161, 107,
+ 108, 109, 110, 111, 112, 0, 0, 0, 51, 0,
+ 0, 0, 0, 0, 0, 0, 0, 164, 0, 0,
+ 0, 0, 85, 0, 0, 0, 0, 51, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 0,
+ 107, 108, 109, 110, 111, 112, 0, 0, 0, 85,
+ 0, 0, 0, 0, 195, 86, 87, 88, 89, 90,
91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
- 101, 102, 103, 0, 104, 105, 106, 107, 108, 109,
- 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 101, 102, 103, 104, 105, 106, 0, 107, 108, 109,
+ 110, 111, 112, 87, 88, 89, 90, 91, 92, 93,
94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
- 0, 104, 105, 106, 107, 108, 109, 86, 87, 88,
+ 104, 105, 106, 0, 107, 108, 109, 110, 111, 112,
89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
- 99, 100, 101, 102, 103, 0, 104, 105, 106, 107,
- 108, 109, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99, 100, 101, 102, 103, 0,
- 104, 105, 106, 107, 108, 109, 88, 89, 90, 91,
+ 99, 100, 101, 102, 103, 104, 105, 106, 0, 107,
+ 108, 109, 110, 111, 112, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 0, 107, 108, 109, 110, 111, 112, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
- 102, 103, 0, 104, 105, 106, 107, 108, 109, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 0, 104, 105, 106, 107, 108,
- 109, 90, 91, 92, 93, 94, 95, 96, 97, 98,
- 99, 100, 101, 102, 103, 0, 104, 105, 106, 107,
- 108, 109, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 0, 104, 105, 106, 107, 108,
- 109
+ 102, 103, 104, 105, 106, 0, 107, 108, 109, 110,
+ 111, 112, 92, 93, 94, 95, 96, 97, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 0, 107, 108,
+ 109, 110, 111, 112, 93, 94, 95, 96, 97, 98,
+ 99, 100, 101, 102, 103, 104, 105, 106, 0, 107,
+ 108, 109, 110, 111, 112, 95, 96, 97, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 0, 107, 108,
+ 109, 110, 111, 112
};
static const short yycheck[] = { 0,
- 0, 7, 8, 9, 10, 0, 3, 13, 14, 28,
- 6, 7, 8, 6, 7, 8, 28, 15, 19, 20,
- 28, 56, 57, 28, 22, 23, 28, 15, 29, 29,
- 7, 6, 7, 8, 22, 23, 37, 37, 36, 28,
- 106, 107, 19, 20, 21, 64, 15, 21, 36, 61,
- 48, 36, 53, 53, 62, 48, 15, 62, 56, 57,
- 48, 11, 58, 48, 61, 58, 15, 60, 56, 57,
- 21, 56, 57, 62, 24, 25, 26, 27, 28, 7,
- 21, 31, 32, 58, 19, 60, 21, 37, 19, 24,
- 21, 19, 20, 21, 52, 53, 54, 55, 56, 57,
- 106, 107, 39, 21, 64, 62, 62, 113, 15, 15,
- 62, 40, 48, 108, 46, 47, 48, 49, 50, 120,
- 52, 53, 54, 55, 56, 57, 0, 61, 0, 130,
- 130, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 115, 116, 117, 118, 7, 120,
- 9, 10, 11, 12, 112, 14, 172, 16, 122, 18,
- 19, 20, 21, 22, 23, 24, 122, 15, 165, -1,
- -1, -1, -1, 133, 185, 43, 44, 45, 46, 47,
- 48, 49, 50, -1, 52, 53, 54, 55, 56, 57,
- -1, -1, 203, 203, -1, -1, -1, -1, 158, -1,
- -1, 161, -1, 62, -1, 165, 166, -1, 7, 169,
- 9, 10, 11, 12, -1, 14, -1, 16, -1, 18,
- 19, 20, 21, 22, 23, 24, -1, -1, 188, -1,
- -1, -1, 192, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, -1, 18, 19,
- 20, 21, 22, 23, 24, 25, -1, 27, -1, -1,
- 45, 46, 47, 48, 49, 50, 36, 52, 53, 54,
- 55, 56, 57, -1, -1, -1, -1, 47, 48, -1,
- -1, -1, 52, 53, -1, -1, -1, 57, 58, 59,
- 60, -1, -1, 63, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16, -1, 18,
- 19, 20, 21, 22, 23, 24, 25, -1, 27, -1,
- -1, -1, -1, -1, 48, 49, 50, 36, 52, 53,
- 54, 55, 56, 57, -1, -1, -1, -1, 47, 48,
- -1, -1, -1, 52, 53, -1, -1, -1, 57, 58,
- 59, 60, -1, -1, 63, 3, 4, 5, 6, 7,
+ 0, 3, 0, 30, 30, 11, 21, 30, 7, 8,
+ 9, 10, 30, 30, 13, 14, 58, 59, 19, 20,
+ 26, 27, 28, 29, 30, 19, 30, 21, 34, 35,
+ 31, 31, 109, 110, 40, 15, 15, 15, 65, 40,
+ 40, 67, 65, 65, 21, 38, 64, 6, 7, 8,
+ 41, 6, 7, 8, 21, 56, 56, 50, 6, 7,
+ 8, 65, 64, 7, 67, 58, 59, 54, 55, 56,
+ 57, 58, 59, 65, 21, 19, 20, 21, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 60, 50, 15, 63, 60, 7, 15, 64, 42,
+ 109, 110, 60, 111, 65, 63, 50, 116, 19, 20,
+ 21, 15, 123, 168, 0, 0, 115, 15, 22, 23,
+ 136, -1, 133, 133, 7, 125, 9, 10, 11, 12,
+ 125, 14, -1, 16, 38, 18, 19, 20, 21, 22,
+ 23, 24, 19, -1, 21, 161, 50, 24, 164, -1,
+ 15, -1, 168, 169, 58, 59, 172, 22, 23, -1,
+ 47, 48, 49, 50, 51, 52, 175, 54, 55, 56,
+ 57, 58, 59, 38, -1, 191, -1, 188, -1, 195,
+ -1, -1, 65, -1, -1, 50, 118, 119, 120, 121,
+ -1, 123, -1, 58, 59, 206, 206, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, -1, 18, 19, 20, 21, 22, 23, 24, 25,
+ -1, 27, 28, 29, 7, -1, 9, 10, 11, 12,
+ -1, 14, 38, 16, -1, 18, 19, 20, 21, 22,
+ 23, 24, -1, 49, 50, -1, -1, -1, 54, 55,
+ -1, -1, -1, 59, 60, 61, 62, 63, -1, -1,
+ 66, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, -1, 18, 19, 20, 21,
+ 22, 23, 24, 25, -1, 27, 28, 29, 45, 46,
+ 47, 48, 49, 50, 51, 52, 38, 54, 55, 56,
+ 57, 58, 59, -1, -1, -1, -1, 49, 50, -1,
+ -1, -1, 54, 55, -1, -1, -1, 59, 60, 61,
+ 62, 63, -1, -1, 66, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, -1,
- 18, 19, 20, 21, 22, 23, 24, 25, 7, 27,
- 9, 10, 11, 12, -1, 14, -1, 16, -1, 18,
- 19, 20, 21, 22, 23, 24, -1, -1, -1, -1,
- -1, -1, -1, -1, 52, 53, -1, 36, -1, 57,
- 58, 59, 60, -1, -1, 63, -1, -1, -1, 48,
- -1, -1, -1, -1, -1, -1, -1, 56, 57, -1,
- -1, -1, -1, 62, 6, 7, 8, 9, 10, 11,
+ 18, 19, 20, 21, 22, 23, 24, 25, -1, 27,
+ 28, 29, -1, -1, -1, 7, -1, 9, 10, 11,
+ 12, -1, 14, -1, 16, -1, 18, 19, 20, 21,
+ 22, 23, 24, -1, -1, -1, 54, 55, -1, -1,
+ -1, 59, 60, 61, 62, 63, 38, -1, 66, -1,
+ -1, -1, -1, 48, 49, 50, 51, 52, 50, 54,
+ 55, 56, 57, 58, 59, -1, 58, 59, -1, -1,
+ -1, -1, -1, 65, 6, 7, 8, 9, 10, 11,
12, -1, 14, -1, 16, -1, 18, 19, 20, 21,
22, 23, 24, 6, 7, 8, 9, 10, 11, 12,
-1, 14, -1, 16, -1, 18, 19, 20, 21, 22,
- 23, 24, -1, -1, -1, -1, 48, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 58, -1, -1, -1,
- -1, -1, -1, -1, -1, 48, -1, -1, -1, -1,
- -1, -1, 26, -1, -1, 58, 30, 31, 32, 33,
+ 23, 24, -1, -1, -1, 50, 51, 52, 50, 54,
+ 55, 56, 57, 58, 59, -1, -1, -1, 60, -1,
+ -1, -1, -1, -1, -1, -1, -1, 50, -1, -1,
+ -1, -1, 26, -1, -1, -1, -1, 60, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, -1, 52, 53,
- 54, 55, 56, 57, -1, -1, -1, -1, 26, -1,
- -1, 65, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, -1, 52, 53, 54, 55, 56, 57,
- 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- -1, 52, 53, 54, 55, 56, 57, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, -1, 52, 53, 54, 55,
- 56, 57, 34, 35, 36, 37, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, -1,
- 52, 53, 54, 55, 56, 57, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, -1, 52, 53, 54, 55, 56, 57, 36,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, -1,
+ 54, 55, 56, 57, 58, 59, -1, -1, -1, 26,
+ -1, -1, -1, -1, 68, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, -1, 52, 53, 54, 55, 56,
- 57, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, -1, 52, 53, 54, 55,
- 56, 57, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, -1, 52, 53, 54, 55, 56,
- 57
+ 47, 48, 49, 50, 51, 52, -1, 54, 55, 56,
+ 57, 58, 59, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, -1, 54, 55, 56, 57, 58, 59,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, -1, 54,
+ 55, 56, 57, 58, 59, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, -1, 54, 55, 56, 57, 58, 59, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, -1, 54, 55, 56, 57,
+ 58, 59, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, -1, 54, 55,
+ 56, 57, 58, 59, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, -1, 54,
+ 55, 56, 57, 58, 59, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, -1, 54, 55,
+ 56, 57, 58, 59
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/unsupported/share/bison.simple"
+#line 3 "/stone/jimb/main-98r2/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -717,16 +711,16 @@ int yyparse (void);
#endif
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
-#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
#ifndef __cplusplus
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (from, to, count)
- char *from;
+__yy_memcpy (to, from, count)
char *to;
+ char *from;
int count;
{
register char *f = from;
@@ -742,7 +736,7 @@ __yy_memcpy (from, to, count)
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (char *from, char *to, int count)
+__yy_memcpy (char *to, char *from, int count)
{
register char *f = from;
register char *t = to;
@@ -755,7 +749,7 @@ __yy_memcpy (char *from, char *to, int count)
#endif
#endif
-#line 192 "/usr/unsupported/share/bison.simple"
+#line 196 "/stone/jimb/main-98r2/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -764,14 +758,20 @@ __yy_memcpy (char *from, char *to, int count)
to the proper pointer type. */
#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#else
-#define YYPARSE_PARAM
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
#define YYPARSE_PARAM_DECL
-#endif
+#endif /* not YYPARSE_PARAM */
int
-yyparse(YYPARSE_PARAM)
+yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
register int yystate;
@@ -888,12 +888,12 @@ yynewstate:
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
@@ -1054,63 +1054,63 @@ yyreduce:
switch (yyn) {
case 3:
-#line 228 "./c-exp.y"
+#line 235 "c-exp.y"
{ write_exp_elt_opcode(OP_TYPE);
write_exp_elt_type(yyvsp[0].tval);
write_exp_elt_opcode(OP_TYPE);;
break;}
case 5:
-#line 236 "./c-exp.y"
+#line 243 "c-exp.y"
{ write_exp_elt_opcode (BINOP_COMMA); ;
break;}
case 6:
-#line 241 "./c-exp.y"
+#line 248 "c-exp.y"
{ write_exp_elt_opcode (UNOP_IND); ;
break;}
case 7:
-#line 244 "./c-exp.y"
+#line 251 "c-exp.y"
{ write_exp_elt_opcode (UNOP_ADDR); ;
break;}
case 8:
-#line 247 "./c-exp.y"
+#line 254 "c-exp.y"
{ write_exp_elt_opcode (UNOP_NEG); ;
break;}
case 9:
-#line 251 "./c-exp.y"
+#line 258 "c-exp.y"
{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ;
break;}
case 10:
-#line 255 "./c-exp.y"
+#line 262 "c-exp.y"
{ write_exp_elt_opcode (UNOP_COMPLEMENT); ;
break;}
case 11:
-#line 259 "./c-exp.y"
+#line 266 "c-exp.y"
{ write_exp_elt_opcode (UNOP_PREINCREMENT); ;
break;}
case 12:
-#line 263 "./c-exp.y"
+#line 270 "c-exp.y"
{ write_exp_elt_opcode (UNOP_PREDECREMENT); ;
break;}
case 13:
-#line 267 "./c-exp.y"
+#line 274 "c-exp.y"
{ write_exp_elt_opcode (UNOP_POSTINCREMENT); ;
break;}
case 14:
-#line 271 "./c-exp.y"
+#line 278 "c-exp.y"
{ write_exp_elt_opcode (UNOP_POSTDECREMENT); ;
break;}
case 15:
-#line 275 "./c-exp.y"
+#line 282 "c-exp.y"
{ write_exp_elt_opcode (UNOP_SIZEOF); ;
break;}
case 16:
-#line 279 "./c-exp.y"
+#line 286 "c-exp.y"
{ write_exp_elt_opcode (STRUCTOP_PTR);
write_exp_string (yyvsp[0].sval);
write_exp_elt_opcode (STRUCTOP_PTR); ;
break;}
case 17:
-#line 285 "./c-exp.y"
+#line 292 "c-exp.y"
{ /* exp->type::name becomes exp->*(&type::name) */
/* Note: this doesn't work if name is a
static member! FIXME */
@@ -1118,17 +1118,17 @@ case 17:
write_exp_elt_opcode (STRUCTOP_MPTR); ;
break;}
case 18:
-#line 292 "./c-exp.y"
+#line 300 "c-exp.y"
{ write_exp_elt_opcode (STRUCTOP_MPTR); ;
break;}
case 19:
-#line 296 "./c-exp.y"
+#line 304 "c-exp.y"
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
write_exp_string (yyvsp[0].sval);
write_exp_elt_opcode (STRUCTOP_STRUCT); ;
break;}
case 20:
-#line 303 "./c-exp.y"
+#line 310 "c-exp.y"
{ /* exp.type::name becomes exp.*(&type::name) */
/* Note: this doesn't work if name is a
static member! FIXME */
@@ -1136,161 +1136,161 @@ case 20:
write_exp_elt_opcode (STRUCTOP_MEMBER); ;
break;}
case 21:
-#line 311 "./c-exp.y"
+#line 318 "c-exp.y"
{ write_exp_elt_opcode (STRUCTOP_MEMBER); ;
break;}
case 22:
-#line 315 "./c-exp.y"
+#line 322 "c-exp.y"
{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ;
break;}
case 23:
-#line 321 "./c-exp.y"
+#line 328 "c-exp.y"
{ start_arglist (); ;
break;}
case 24:
-#line 323 "./c-exp.y"
+#line 330 "c-exp.y"
{ write_exp_elt_opcode (OP_FUNCALL);
write_exp_elt_longcst ((LONGEST) end_arglist ());
write_exp_elt_opcode (OP_FUNCALL); ;
break;}
case 25:
-#line 329 "./c-exp.y"
+#line 336 "c-exp.y"
{ start_arglist (); ;
break;}
case 27:
-#line 336 "./c-exp.y"
+#line 343 "c-exp.y"
{ arglist_len = 1; ;
break;}
case 28:
-#line 340 "./c-exp.y"
+#line 347 "c-exp.y"
{ arglist_len++; ;
break;}
case 29:
-#line 344 "./c-exp.y"
+#line 351 "c-exp.y"
{ yyval.lval = end_arglist () - 1; ;
break;}
case 30:
-#line 347 "./c-exp.y"
+#line 354 "c-exp.y"
{ write_exp_elt_opcode (OP_ARRAY);
write_exp_elt_longcst ((LONGEST) 0);
write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
write_exp_elt_opcode (OP_ARRAY); ;
break;}
case 31:
-#line 354 "./c-exp.y"
+#line 361 "c-exp.y"
{ write_exp_elt_opcode (UNOP_MEMVAL);
write_exp_elt_type (yyvsp[-2].tval);
write_exp_elt_opcode (UNOP_MEMVAL); ;
break;}
case 32:
-#line 360 "./c-exp.y"
+#line 367 "c-exp.y"
{ write_exp_elt_opcode (UNOP_CAST);
write_exp_elt_type (yyvsp[-2].tval);
write_exp_elt_opcode (UNOP_CAST); ;
break;}
case 33:
-#line 366 "./c-exp.y"
+#line 373 "c-exp.y"
{ ;
break;}
case 34:
-#line 372 "./c-exp.y"
+#line 379 "c-exp.y"
{ write_exp_elt_opcode (BINOP_REPEAT); ;
break;}
case 35:
-#line 376 "./c-exp.y"
+#line 383 "c-exp.y"
{ write_exp_elt_opcode (BINOP_MUL); ;
break;}
case 36:
-#line 380 "./c-exp.y"
+#line 387 "c-exp.y"
{ write_exp_elt_opcode (BINOP_DIV); ;
break;}
case 37:
-#line 384 "./c-exp.y"
+#line 391 "c-exp.y"
{ write_exp_elt_opcode (BINOP_REM); ;
break;}
case 38:
-#line 388 "./c-exp.y"
+#line 395 "c-exp.y"
{ write_exp_elt_opcode (BINOP_ADD); ;
break;}
case 39:
-#line 392 "./c-exp.y"
+#line 399 "c-exp.y"
{ write_exp_elt_opcode (BINOP_SUB); ;
break;}
case 40:
-#line 396 "./c-exp.y"
+#line 403 "c-exp.y"
{ write_exp_elt_opcode (BINOP_LSH); ;
break;}
case 41:
-#line 400 "./c-exp.y"
+#line 407 "c-exp.y"
{ write_exp_elt_opcode (BINOP_RSH); ;
break;}
case 42:
-#line 404 "./c-exp.y"
+#line 411 "c-exp.y"
{ write_exp_elt_opcode (BINOP_EQUAL); ;
break;}
case 43:
-#line 408 "./c-exp.y"
+#line 415 "c-exp.y"
{ write_exp_elt_opcode (BINOP_NOTEQUAL); ;
break;}
case 44:
-#line 412 "./c-exp.y"
+#line 419 "c-exp.y"
{ write_exp_elt_opcode (BINOP_LEQ); ;
break;}
case 45:
-#line 416 "./c-exp.y"
+#line 423 "c-exp.y"
{ write_exp_elt_opcode (BINOP_GEQ); ;
break;}
case 46:
-#line 420 "./c-exp.y"
+#line 427 "c-exp.y"
{ write_exp_elt_opcode (BINOP_LESS); ;
break;}
case 47:
-#line 424 "./c-exp.y"
+#line 431 "c-exp.y"
{ write_exp_elt_opcode (BINOP_GTR); ;
break;}
case 48:
-#line 428 "./c-exp.y"
+#line 435 "c-exp.y"
{ write_exp_elt_opcode (BINOP_BITWISE_AND); ;
break;}
case 49:
-#line 432 "./c-exp.y"
+#line 439 "c-exp.y"
{ write_exp_elt_opcode (BINOP_BITWISE_XOR); ;
break;}
case 50:
-#line 436 "./c-exp.y"
+#line 443 "c-exp.y"
{ write_exp_elt_opcode (BINOP_BITWISE_IOR); ;
break;}
case 51:
-#line 440 "./c-exp.y"
+#line 447 "c-exp.y"
{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ;
break;}
case 52:
-#line 444 "./c-exp.y"
+#line 451 "c-exp.y"
{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ;
break;}
case 53:
-#line 448 "./c-exp.y"
+#line 455 "c-exp.y"
{ write_exp_elt_opcode (TERNOP_COND); ;
break;}
case 54:
-#line 452 "./c-exp.y"
+#line 459 "c-exp.y"
{ write_exp_elt_opcode (BINOP_ASSIGN); ;
break;}
case 55:
-#line 456 "./c-exp.y"
+#line 463 "c-exp.y"
{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
write_exp_elt_opcode (yyvsp[-1].opcode);
write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ;
break;}
case 56:
-#line 462 "./c-exp.y"
+#line 469 "c-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (yyvsp[0].typed_val_int.type);
write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val));
write_exp_elt_opcode (OP_LONG); ;
break;}
case 57:
-#line 469 "./c-exp.y"
+#line 476 "c-exp.y"
{ YYSTYPE val;
parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val);
write_exp_elt_opcode (OP_LONG);
@@ -1300,14 +1300,14 @@ case 57:
;
break;}
case 58:
-#line 480 "./c-exp.y"
+#line 487 "c-exp.y"
{ write_exp_elt_opcode (OP_DOUBLE);
write_exp_elt_type (yyvsp[0].typed_val_float.type);
write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval);
write_exp_elt_opcode (OP_DOUBLE); ;
break;}
case 61:
-#line 494 "./c-exp.y"
+#line 501 "c-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
CHECK_TYPEDEF (yyvsp[-1].tval);
@@ -1315,7 +1315,7 @@ case 61:
write_exp_elt_opcode (OP_LONG); ;
break;}
case 62:
-#line 502 "./c-exp.y"
+#line 509 "c-exp.y"
{ /* C strings are converted into array constants with
an explicit null byte added at the end. Thus
the array upper bound is the string length.
@@ -1339,29 +1339,42 @@ case 62:
write_exp_elt_opcode (OP_ARRAY); ;
break;}
case 63:
-#line 527 "./c-exp.y"
+#line 534 "c-exp.y"
{ write_exp_elt_opcode (OP_THIS);
write_exp_elt_opcode (OP_THIS); ;
break;}
case 64:
-#line 534 "./c-exp.y"
+#line 539 "c-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_bool);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_opcode (OP_LONG); ;
+ break;}
+case 65:
+#line 546 "c-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_bool);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_opcode (OP_LONG); ;
+ break;}
+case 66:
+#line 555 "c-exp.y"
{
- if (yyvsp[0].ssym.sym != 0)
- yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym);
+ if (yyvsp[0].ssym.sym)
+ yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym);
else
- {
- struct symtab *tem =
- lookup_symtab (copy_name (yyvsp[0].ssym.stoken));
- if (tem)
- yyval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK);
- else
- error ("No file or function \"%s\".",
- copy_name (yyvsp[0].ssym.stoken));
- }
+ error ("No file or function \"%s\".",
+ copy_name (yyvsp[0].ssym.stoken));
;
break;}
-case 65:
-#line 551 "./c-exp.y"
+case 67:
+#line 563 "c-exp.y"
+{
+ yyval.bval = yyvsp[0].bval;
+ ;
+ break;}
+case 68:
+#line 569 "c-exp.y"
{ struct symbol *tem
= lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval,
VAR_NAMESPACE, (int *) NULL,
@@ -1371,8 +1384,8 @@ case 65:
copy_name (yyvsp[0].sval));
yyval.bval = SYMBOL_BLOCK_VALUE (tem); ;
break;}
-case 66:
-#line 562 "./c-exp.y"
+case 69:
+#line 580 "c-exp.y"
{ struct symbol *sym;
sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval,
VAR_NAMESPACE, (int *) NULL,
@@ -1387,8 +1400,8 @@ case 66:
write_exp_elt_sym (sym);
write_exp_elt_opcode (OP_VAR_VALUE); ;
break;}
-case 67:
-#line 578 "./c-exp.y"
+case 70:
+#line 596 "c-exp.y"
{
struct type *type = yyvsp[-2].tval;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
@@ -1402,8 +1415,8 @@ case 67:
write_exp_elt_opcode (OP_SCOPE);
;
break;}
-case 68:
-#line 591 "./c-exp.y"
+case 71:
+#line 609 "c-exp.y"
{
struct type *type = yyvsp[-3].tval;
struct stoken tmp_token;
@@ -1412,23 +1425,22 @@ case 68:
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
- if (!STREQ (type_name_no_tag (type), yyvsp[0].sval.ptr))
- error ("invalid destructor `%s::~%s'",
- type_name_no_tag (type), yyvsp[0].sval.ptr);
-
tmp_token.ptr = (char*) alloca (yyvsp[0].sval.length + 2);
tmp_token.length = yyvsp[0].sval.length + 1;
tmp_token.ptr[0] = '~';
memcpy (tmp_token.ptr+1, yyvsp[0].sval.ptr, yyvsp[0].sval.length);
tmp_token.ptr[tmp_token.length] = 0;
+
+ /* Check for valid destructor name. */
+ destructor_name_p (tmp_token.ptr, type);
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
write_exp_string (tmp_token);
write_exp_elt_opcode (OP_SCOPE);
;
break;}
-case 70:
-#line 617 "./c-exp.y"
+case 73:
+#line 634 "c-exp.y"
{
char *name = copy_name (yyvsp[0].sval);
struct symbol *sym;
@@ -1461,8 +1473,8 @@ case 70:
error ("No symbol \"%s\" in current context.", name);
;
break;}
-case 71:
-#line 651 "./c-exp.y"
+case 74:
+#line 668 "c-exp.y"
{ struct symbol *sym = yyvsp[0].ssym.sym;
if (sym)
@@ -1518,244 +1530,244 @@ case 71:
}
;
break;}
-case 75:
-#line 717 "./c-exp.y"
+case 78:
+#line 734 "c-exp.y"
{ yyval.tval = follow_types (yyvsp[-1].tval); ;
break;}
-case 76:
-#line 719 "./c-exp.y"
+case 79:
+#line 736 "c-exp.y"
{ yyval.tval = follow_types (yyvsp[-2].tval); ;
break;}
-case 77:
-#line 721 "./c-exp.y"
+case 80:
+#line 738 "c-exp.y"
{ yyval.tval = follow_types (yyvsp[-2].tval); ;
break;}
-case 78:
-#line 725 "./c-exp.y"
+case 81:
+#line 742 "c-exp.y"
{ push_type (tp_pointer); yyval.voidval = 0; ;
break;}
-case 79:
-#line 727 "./c-exp.y"
+case 82:
+#line 744 "c-exp.y"
{ push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; ;
break;}
-case 80:
-#line 729 "./c-exp.y"
+case 83:
+#line 746 "c-exp.y"
{ push_type (tp_reference); yyval.voidval = 0; ;
break;}
-case 81:
-#line 731 "./c-exp.y"
+case 84:
+#line 748 "c-exp.y"
{ push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; ;
break;}
-case 83:
-#line 736 "./c-exp.y"
+case 86:
+#line 753 "c-exp.y"
{ yyval.voidval = yyvsp[-1].voidval; ;
break;}
-case 84:
-#line 738 "./c-exp.y"
+case 87:
+#line 755 "c-exp.y"
{
push_type_int (yyvsp[0].lval);
push_type (tp_array);
;
break;}
-case 85:
-#line 743 "./c-exp.y"
+case 88:
+#line 760 "c-exp.y"
{
push_type_int (yyvsp[0].lval);
push_type (tp_array);
yyval.voidval = 0;
;
break;}
-case 86:
-#line 750 "./c-exp.y"
+case 89:
+#line 767 "c-exp.y"
{ push_type (tp_function); ;
break;}
-case 87:
-#line 752 "./c-exp.y"
+case 90:
+#line 769 "c-exp.y"
{ push_type (tp_function); ;
break;}
-case 88:
-#line 756 "./c-exp.y"
+case 91:
+#line 773 "c-exp.y"
{ yyval.lval = -1; ;
break;}
-case 89:
-#line 758 "./c-exp.y"
+case 92:
+#line 775 "c-exp.y"
{ yyval.lval = yyvsp[-1].typed_val_int.val; ;
break;}
-case 90:
-#line 762 "./c-exp.y"
+case 93:
+#line 779 "c-exp.y"
{ yyval.voidval = 0; ;
break;}
-case 91:
-#line 764 "./c-exp.y"
+case 94:
+#line 781 "c-exp.y"
{ free ((PTR)yyvsp[-1].tvec); yyval.voidval = 0; ;
break;}
-case 93:
-#line 777 "./c-exp.y"
+case 96:
+#line 794 "c-exp.y"
{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ;
break;}
-case 94:
-#line 782 "./c-exp.y"
+case 97:
+#line 799 "c-exp.y"
{ yyval.tval = yyvsp[0].tsym.type; ;
break;}
-case 95:
-#line 784 "./c-exp.y"
+case 98:
+#line 801 "c-exp.y"
{ yyval.tval = builtin_type_int; ;
break;}
-case 96:
-#line 786 "./c-exp.y"
+case 99:
+#line 803 "c-exp.y"
{ yyval.tval = builtin_type_long; ;
break;}
-case 97:
-#line 788 "./c-exp.y"
+case 100:
+#line 805 "c-exp.y"
{ yyval.tval = builtin_type_short; ;
break;}
-case 98:
-#line 790 "./c-exp.y"
+case 101:
+#line 807 "c-exp.y"
{ yyval.tval = builtin_type_long; ;
break;}
-case 99:
-#line 792 "./c-exp.y"
+case 102:
+#line 809 "c-exp.y"
{ yyval.tval = builtin_type_unsigned_long; ;
break;}
-case 100:
-#line 794 "./c-exp.y"
+case 103:
+#line 811 "c-exp.y"
{ yyval.tval = builtin_type_long_long; ;
break;}
-case 101:
-#line 796 "./c-exp.y"
+case 104:
+#line 813 "c-exp.y"
{ yyval.tval = builtin_type_long_long; ;
break;}
-case 102:
-#line 798 "./c-exp.y"
+case 105:
+#line 815 "c-exp.y"
{ yyval.tval = builtin_type_unsigned_long_long; ;
break;}
-case 103:
-#line 800 "./c-exp.y"
+case 106:
+#line 817 "c-exp.y"
{ yyval.tval = builtin_type_unsigned_long_long; ;
break;}
-case 104:
-#line 802 "./c-exp.y"
+case 107:
+#line 819 "c-exp.y"
{ yyval.tval = builtin_type_short; ;
break;}
-case 105:
-#line 804 "./c-exp.y"
+case 108:
+#line 821 "c-exp.y"
{ yyval.tval = builtin_type_unsigned_short; ;
break;}
-case 106:
-#line 806 "./c-exp.y"
+case 109:
+#line 823 "c-exp.y"
{ yyval.tval = builtin_type_double; ;
break;}
-case 107:
-#line 808 "./c-exp.y"
+case 110:
+#line 825 "c-exp.y"
{ yyval.tval = builtin_type_long_double; ;
break;}
-case 108:
-#line 810 "./c-exp.y"
+case 111:
+#line 827 "c-exp.y"
{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval),
expression_context_block); ;
break;}
-case 109:
-#line 813 "./c-exp.y"
+case 112:
+#line 830 "c-exp.y"
{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval),
expression_context_block); ;
break;}
-case 110:
-#line 816 "./c-exp.y"
+case 113:
+#line 833 "c-exp.y"
{ yyval.tval = lookup_union (copy_name (yyvsp[0].sval),
expression_context_block); ;
break;}
-case 111:
-#line 819 "./c-exp.y"
+case 114:
+#line 836 "c-exp.y"
{ yyval.tval = lookup_enum (copy_name (yyvsp[0].sval),
expression_context_block); ;
break;}
-case 112:
-#line 822 "./c-exp.y"
+case 115:
+#line 839 "c-exp.y"
{ yyval.tval = lookup_unsigned_typename (TYPE_NAME(yyvsp[0].tsym.type)); ;
break;}
-case 113:
-#line 824 "./c-exp.y"
+case 116:
+#line 841 "c-exp.y"
{ yyval.tval = builtin_type_unsigned_int; ;
break;}
-case 114:
-#line 826 "./c-exp.y"
+case 117:
+#line 843 "c-exp.y"
{ yyval.tval = lookup_signed_typename (TYPE_NAME(yyvsp[0].tsym.type)); ;
break;}
-case 115:
-#line 828 "./c-exp.y"
+case 118:
+#line 845 "c-exp.y"
{ yyval.tval = builtin_type_int; ;
break;}
-case 116:
-#line 830 "./c-exp.y"
+case 119:
+#line 850 "c-exp.y"
{ yyval.tval = lookup_template_type(copy_name(yyvsp[-3].sval), yyvsp[-1].tval,
expression_context_block);
;
break;}
-case 117:
-#line 836 "./c-exp.y"
+case 120:
+#line 856 "c-exp.y"
{ yyval.tval = yyvsp[0].tval; ;
break;}
-case 118:
-#line 837 "./c-exp.y"
+case 121:
+#line 857 "c-exp.y"
{ yyval.tval = yyvsp[0].tval; ;
break;}
-case 120:
-#line 842 "./c-exp.y"
+case 123:
+#line 862 "c-exp.y"
{
yyval.tsym.stoken.ptr = "int";
yyval.tsym.stoken.length = 3;
yyval.tsym.type = builtin_type_int;
;
break;}
-case 121:
-#line 848 "./c-exp.y"
+case 124:
+#line 868 "c-exp.y"
{
yyval.tsym.stoken.ptr = "long";
yyval.tsym.stoken.length = 4;
yyval.tsym.type = builtin_type_long;
;
break;}
-case 122:
-#line 854 "./c-exp.y"
+case 125:
+#line 874 "c-exp.y"
{
yyval.tsym.stoken.ptr = "short";
yyval.tsym.stoken.length = 5;
yyval.tsym.type = builtin_type_short;
;
break;}
-case 123:
-#line 863 "./c-exp.y"
+case 126:
+#line 883 "c-exp.y"
{ yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2);
yyval.ivec[0] = 1; /* Number of types in vector */
yyval.tvec[1] = yyvsp[0].tval;
;
break;}
-case 124:
-#line 868 "./c-exp.y"
+case 127:
+#line 888 "c-exp.y"
{ int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1);
yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len);
yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval;
;
break;}
-case 125:
-#line 874 "./c-exp.y"
+case 128:
+#line 894 "c-exp.y"
{ yyval.sval = yyvsp[0].ssym.stoken; ;
break;}
-case 126:
-#line 875 "./c-exp.y"
+case 129:
+#line 895 "c-exp.y"
{ yyval.sval = yyvsp[0].ssym.stoken; ;
break;}
-case 127:
-#line 876 "./c-exp.y"
+case 130:
+#line 896 "c-exp.y"
{ yyval.sval = yyvsp[0].tsym.stoken; ;
break;}
-case 128:
-#line 877 "./c-exp.y"
+case 131:
+#line 897 "c-exp.y"
{ yyval.sval = yyvsp[0].ssym.stoken; ;
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 487 "/usr/unsupported/share/bison.simple"
+#line 498 "/stone/jimb/main-98r2/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1951,7 +1963,7 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 891 "./c-exp.y"
+#line 911 "c-exp.y"
/* Take care of parsing a number (anything that starts with a digit).
@@ -1971,7 +1983,7 @@ parse_number (p, len, parsed_float, putithere)
here, and we do kind of silly things like cast to unsigned. */
register LONGEST n = 0;
register LONGEST prevn = 0;
- unsigned LONGEST un;
+ ULONGEST un;
register int i = 0;
register int c;
@@ -1984,34 +1996,38 @@ parse_number (p, len, parsed_float, putithere)
/* We have found a "L" or "U" suffix. */
int found_suffix = 0;
- unsigned LONGEST high_bit;
+ ULONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
if (parsed_float)
{
- char c;
-
/* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+ p[len] = 0; /* null-terminate the token */
if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
- sscanf (p, "%g", &putithere->typed_val_float.dval);
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
- sscanf (p, "%lg", &putithere->typed_val_float.dval);
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
else
{
-#ifdef PRINTF_HAS_LONG_DOUBLE
- sscanf (p, "%Lg", &putithere->typed_val_float.dval);
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
#else
/* Scan it into a double, then assign it to the long double.
This at least wins with values representable in the range
of doubles. */
double temp;
- sscanf (p, "%lg", &temp);
+ num = sscanf (p, "%lg%c", &temp,&c);
putithere->typed_val_float.dval = temp;
#endif
}
-
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
/* See if it has `f' or `l' suffix (float or long double). */
c = tolower (p[len - 1]);
@@ -2107,7 +2123,7 @@ parse_number (p, len, parsed_float, putithere)
on 0x123456789 when LONGEST is 32 bits. */
if (c != 'l' && c != 'u' && n != 0)
{
- if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
+ if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
error ("Numeric constant too large.");
}
prevn = n;
@@ -2125,11 +2141,11 @@ parse_number (p, len, parsed_float, putithere)
the case where it is we just always shift the value more than
once, with fewer bits each time. */
- un = (unsigned LONGEST)n >> 2;
+ un = (ULONGEST)n >> 2;
if (long_p == 0
&& (un >> (TARGET_INT_BIT - 2)) == 0)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
/* A large decimal (not hex or octal) constant (between INT_MAX
and UINT_MAX) is a long or unsigned long, according to ANSI,
@@ -2143,20 +2159,19 @@ parse_number (p, len, parsed_float, putithere)
else if (long_p <= 1
&& (un >> (TARGET_LONG_BIT - 2)) == 0)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
unsigned_type = builtin_type_unsigned_long;
signed_type = builtin_type_long;
}
else
{
- high_bit = (((unsigned LONGEST)1)
- << (TARGET_LONG_LONG_BIT - 32 - 1)
- << 16
- << 16);
- if (high_bit == 0)
+ int shift;
+ if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT)
/* A long long does not fit in a LONGEST. */
- high_bit =
- (unsigned LONGEST)1 << (sizeof (LONGEST) * HOST_CHAR_BIT - 1);
+ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
+ else
+ shift = (TARGET_LONG_LONG_BIT - 1);
+ high_bit = (ULONGEST) 1 << shift;
unsigned_type = builtin_type_unsigned_long_long;
signed_type = builtin_type_long_long;
}
@@ -2228,9 +2243,15 @@ yylex ()
int tempbufindex;
static char *tempbuf;
static int tempbufsize;
-
+ struct symbol * sym_class = NULL;
+ char * token_string = NULL;
+ int class_prefix = 0;
+ int unquoted_expr;
+
retry:
+ unquoted_expr = 1;
+
tokstart = lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
@@ -2282,6 +2303,7 @@ yylex ()
if (namelen > 2)
{
lexptr = tokstart + namelen;
+ unquoted_expr = 0;
if (lexptr[-1] != '\'')
error ("Unmatched single quote.");
namelen -= 2;
@@ -2466,15 +2488,45 @@ yylex ()
(c == '_' || c == '$' || (c >= '0' && c <= '9')
|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
{
- if (c == '<')
- {
- int i = namelen;
- while (tokstart[++i] && tokstart[i] != '>');
- if (tokstart[i] == '>')
- namelen = i;
- }
- c = tokstart[++namelen];
- }
+ /* Template parameter lists are part of the name.
+ FIXME: This mishandles `print $a<4&&$a>3'. */
+
+ if (c == '<')
+ {
+ if (hp_som_som_object_present)
+ {
+ /* Scan ahead to get rest of the template specification. Note
+ that we look ahead only when the '<' adjoins non-whitespace
+ characters; for comparison expressions, e.g. "a < b > c",
+ there must be spaces before the '<', etc. */
+
+ char * p = find_template_name_end (tokstart + namelen);
+ if (p)
+ namelen = p - tokstart;
+ break;
+ }
+ else
+ {
+ int i = namelen;
+ int nesting_level = 1;
+ while (tokstart[++i])
+ {
+ if (tokstart[i] == '<')
+ nesting_level++;
+ else if (tokstart[i] == '>')
+ {
+ if (--nesting_level == 0)
+ break;
+ }
+ }
+ if (tokstart[i] == '>')
+ namelen = i;
+ else
+ break;
+ }
+ }
+ c = tokstart[++namelen];
+ }
/* The token "if" terminates the expression and is NOT
removed from the input stream. */
@@ -2510,9 +2562,13 @@ yylex ()
return DOUBLE_KEYWORD;
break;
case 5:
- if (current_language->la_language == language_cplus
- && STREQN (tokstart, "class", 5))
- return CLASS;
+ if (current_language->la_language == language_cplus)
+ {
+ if (STREQN (tokstart, "false", 5))
+ return FALSEKEYWORD;
+ if (STREQN (tokstart, "class", 5))
+ return CLASS;
+ }
if (STREQN (tokstart, "union", 5))
return UNION;
if (STREQN (tokstart, "short", 5))
@@ -2525,17 +2581,22 @@ yylex ()
return ENUM;
if (STREQN (tokstart, "long", 4))
return LONG;
- if (current_language->la_language == language_cplus
- && STREQN (tokstart, "this", 4))
- {
- static const char this_name[] =
- { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
-
- if (lookup_symbol (this_name, expression_context_block,
- VAR_NAMESPACE, (int *) NULL,
- (struct symtab **) NULL))
- return THIS;
- }
+ if (current_language->la_language == language_cplus)
+ {
+ if (STREQN (tokstart, "true", 4))
+ return TRUEKEYWORD;
+
+ if (STREQN (tokstart, "this", 4))
+ {
+ static const char this_name[] =
+ { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ }
break;
case 3:
if (STREQN (tokstart, "int", 3))
@@ -2553,7 +2614,25 @@ yylex ()
write_dollar_variable (yylval.sval);
return VARIABLE;
}
-
+
+ /* Look ahead and see if we can consume more of the input
+ string to get a reasonable class/namespace spec or a
+ fully-qualified name. This is a kludge to get around the
+ HP aCC compiler's generation of symbol names with embedded
+ colons for namespace and nested classes. */
+ if (unquoted_expr)
+ {
+ /* Only do it if not inside single quotes */
+ sym_class = parse_nested_classes_for_hpacc (yylval.sval.ptr, yylval.sval.length,
+ &token_string, &class_prefix, &lexptr);
+ if (sym_class)
+ {
+ /* Replace the current token with the bigger one we found */
+ yylval.sval.ptr = token_string;
+ yylval.sval.length = strlen (token_string);
+ }
+ }
+
/* Use token-type BLOCKNAME for symbols that happen to be defined as
functions or symtabs. If this is not so, then ...
Use token-type TYPENAME for symbols that happen to be defined
@@ -2573,13 +2652,25 @@ yylex ()
/* Call lookup_symtab, not lookup_partial_symtab, in case there are
no psymtabs (coff, xcoff, or some future change to blow away the
psymtabs once once symbols are read). */
- if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
- lookup_symtab (tmp))
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this;
return BLOCKNAME;
}
+ else if (!sym)
+ { /* See if it's a file name. */
+ struct symtab *symtab;
+
+ symtab = lookup_symtab (tmp);
+
+ if (symtab)
+ {
+ yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+ return FILENAME;
+ }
+ }
+
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
#if 1
diff --git a/contrib/gdb/gdb/c-exp.y b/contrib/gdb/gdb/c-exp.y
index f1156e6..377f92a 100644
--- a/contrib/gdb/gdb/c-exp.y
+++ b/contrib/gdb/gdb/c-exp.y
@@ -1,5 +1,5 @@
/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994
+ Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
@@ -49,6 +49,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "symfile.h" /* Required by objfiles.h. */
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+/* Flag indicating we're dealing with HP-compiled objects */
+extern int hp_som_som_object_present;
+
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitiously global symbol names, so we can have multiple
yacc generated parsers in gdb. Note that these are only the variables
@@ -195,6 +198,9 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
/* C++ */
%token THIS
+%token TRUEKEYWORD
+%token FALSEKEYWORD
+
%left ','
%left ABOVE_COMMA
@@ -214,6 +220,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
%right UNARY INCREMENT DECREMENT
%right ARROW '.' '[' '('
%token <ssym> BLOCKNAME
+%token <bval> FILENAME
%type <bval> block
%left COLONCOLON
@@ -288,6 +295,7 @@ exp : exp ARROW qualified_name
write_exp_elt_opcode (UNOP_ADDR);
write_exp_elt_opcode (STRUCTOP_MPTR); }
;
+
exp : exp ARROW '*' exp
{ write_exp_elt_opcode (STRUCTOP_MPTR); }
;
@@ -298,7 +306,6 @@ exp : exp '.' name
write_exp_elt_opcode (STRUCTOP_STRUCT); }
;
-
exp : exp '.' qualified_name
{ /* exp.type::name becomes exp.*(&type::name) */
/* Note: this doesn't work if name is a
@@ -528,22 +535,33 @@ exp : THIS
write_exp_elt_opcode (OP_THIS); }
;
+exp : TRUEKEYWORD
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_bool);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : FALSEKEYWORD
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_bool);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
/* end of C++. */
block : BLOCKNAME
{
- if ($1.sym != 0)
- $$ = SYMBOL_BLOCK_VALUE ($1.sym);
+ if ($1.sym)
+ $$ = SYMBOL_BLOCK_VALUE ($1.sym);
else
- {
- struct symtab *tem =
- lookup_symtab (copy_name ($1.stoken));
- if (tem)
- $$ = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK);
- else
- error ("No file or function \"%s\".",
- copy_name ($1.stoken));
- }
+ error ("No file or function \"%s\".",
+ copy_name ($1.stoken));
+ }
+ | FILENAME
+ {
+ $$ = $1;
}
;
@@ -596,15 +614,14 @@ qualified_name: typebase COLONCOLON name
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
- if (!STREQ (type_name_no_tag (type), $4.ptr))
- error ("invalid destructor `%s::~%s'",
- type_name_no_tag (type), $4.ptr);
-
tmp_token.ptr = (char*) alloca ($4.length + 2);
tmp_token.length = $4.length + 1;
tmp_token.ptr[0] = '~';
memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
tmp_token.ptr[tmp_token.length] = 0;
+
+ /* Check for valid destructor name. */
+ destructor_name_p (tmp_token.ptr, type);
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
write_exp_string (tmp_token);
@@ -826,6 +843,9 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
{ $$ = lookup_signed_typename (TYPE_NAME($2.type)); }
| SIGNED_KEYWORD
{ $$ = builtin_type_int; }
+ /* It appears that this rule for templates is never
+ reduced; template recognition happens by lookahead
+ in the token processing code in yylex. */
| TEMPLATE name '<' type '>'
{ $$ = lookup_template_type(copy_name($2), $4,
expression_context_block);
@@ -907,7 +927,7 @@ parse_number (p, len, parsed_float, putithere)
here, and we do kind of silly things like cast to unsigned. */
register LONGEST n = 0;
register LONGEST prevn = 0;
- unsigned LONGEST un;
+ ULONGEST un;
register int i = 0;
register int c;
@@ -920,34 +940,38 @@ parse_number (p, len, parsed_float, putithere)
/* We have found a "L" or "U" suffix. */
int found_suffix = 0;
- unsigned LONGEST high_bit;
+ ULONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
if (parsed_float)
{
- char c;
-
/* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+ p[len] = 0; /* null-terminate the token */
if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
- sscanf (p, "%g", &putithere->typed_val_float.dval);
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
- sscanf (p, "%lg", &putithere->typed_val_float.dval);
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
else
{
-#ifdef PRINTF_HAS_LONG_DOUBLE
- sscanf (p, "%Lg", &putithere->typed_val_float.dval);
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
#else
/* Scan it into a double, then assign it to the long double.
This at least wins with values representable in the range
of doubles. */
double temp;
- sscanf (p, "%lg", &temp);
+ num = sscanf (p, "%lg%c", &temp,&c);
putithere->typed_val_float.dval = temp;
#endif
}
-
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
/* See if it has `f' or `l' suffix (float or long double). */
c = tolower (p[len - 1]);
@@ -1043,7 +1067,7 @@ parse_number (p, len, parsed_float, putithere)
on 0x123456789 when LONGEST is 32 bits. */
if (c != 'l' && c != 'u' && n != 0)
{
- if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
+ if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
error ("Numeric constant too large.");
}
prevn = n;
@@ -1061,11 +1085,11 @@ parse_number (p, len, parsed_float, putithere)
the case where it is we just always shift the value more than
once, with fewer bits each time. */
- un = (unsigned LONGEST)n >> 2;
+ un = (ULONGEST)n >> 2;
if (long_p == 0
&& (un >> (TARGET_INT_BIT - 2)) == 0)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
/* A large decimal (not hex or octal) constant (between INT_MAX
and UINT_MAX) is a long or unsigned long, according to ANSI,
@@ -1079,20 +1103,19 @@ parse_number (p, len, parsed_float, putithere)
else if (long_p <= 1
&& (un >> (TARGET_LONG_BIT - 2)) == 0)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
unsigned_type = builtin_type_unsigned_long;
signed_type = builtin_type_long;
}
else
{
- high_bit = (((unsigned LONGEST)1)
- << (TARGET_LONG_LONG_BIT - 32 - 1)
- << 16
- << 16);
- if (high_bit == 0)
+ int shift;
+ if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT)
/* A long long does not fit in a LONGEST. */
- high_bit =
- (unsigned LONGEST)1 << (sizeof (LONGEST) * HOST_CHAR_BIT - 1);
+ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
+ else
+ shift = (TARGET_LONG_LONG_BIT - 1);
+ high_bit = (ULONGEST) 1 << shift;
unsigned_type = builtin_type_unsigned_long_long;
signed_type = builtin_type_long_long;
}
@@ -1164,9 +1187,15 @@ yylex ()
int tempbufindex;
static char *tempbuf;
static int tempbufsize;
-
+ struct symbol * sym_class = NULL;
+ char * token_string = NULL;
+ int class_prefix = 0;
+ int unquoted_expr;
+
retry:
+ unquoted_expr = 1;
+
tokstart = lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
@@ -1218,6 +1247,7 @@ yylex ()
if (namelen > 2)
{
lexptr = tokstart + namelen;
+ unquoted_expr = 0;
if (lexptr[-1] != '\'')
error ("Unmatched single quote.");
namelen -= 2;
@@ -1402,15 +1432,45 @@ yylex ()
(c == '_' || c == '$' || (c >= '0' && c <= '9')
|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
{
- if (c == '<')
- {
- int i = namelen;
- while (tokstart[++i] && tokstart[i] != '>');
- if (tokstart[i] == '>')
- namelen = i;
- }
- c = tokstart[++namelen];
- }
+ /* Template parameter lists are part of the name.
+ FIXME: This mishandles `print $a<4&&$a>3'. */
+
+ if (c == '<')
+ {
+ if (hp_som_som_object_present)
+ {
+ /* Scan ahead to get rest of the template specification. Note
+ that we look ahead only when the '<' adjoins non-whitespace
+ characters; for comparison expressions, e.g. "a < b > c",
+ there must be spaces before the '<', etc. */
+
+ char * p = find_template_name_end (tokstart + namelen);
+ if (p)
+ namelen = p - tokstart;
+ break;
+ }
+ else
+ {
+ int i = namelen;
+ int nesting_level = 1;
+ while (tokstart[++i])
+ {
+ if (tokstart[i] == '<')
+ nesting_level++;
+ else if (tokstart[i] == '>')
+ {
+ if (--nesting_level == 0)
+ break;
+ }
+ }
+ if (tokstart[i] == '>')
+ namelen = i;
+ else
+ break;
+ }
+ }
+ c = tokstart[++namelen];
+ }
/* The token "if" terminates the expression and is NOT
removed from the input stream. */
@@ -1446,9 +1506,13 @@ yylex ()
return DOUBLE_KEYWORD;
break;
case 5:
- if (current_language->la_language == language_cplus
- && STREQN (tokstart, "class", 5))
- return CLASS;
+ if (current_language->la_language == language_cplus)
+ {
+ if (STREQN (tokstart, "false", 5))
+ return FALSEKEYWORD;
+ if (STREQN (tokstart, "class", 5))
+ return CLASS;
+ }
if (STREQN (tokstart, "union", 5))
return UNION;
if (STREQN (tokstart, "short", 5))
@@ -1461,17 +1525,22 @@ yylex ()
return ENUM;
if (STREQN (tokstart, "long", 4))
return LONG;
- if (current_language->la_language == language_cplus
- && STREQN (tokstart, "this", 4))
- {
- static const char this_name[] =
- { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
-
- if (lookup_symbol (this_name, expression_context_block,
- VAR_NAMESPACE, (int *) NULL,
- (struct symtab **) NULL))
- return THIS;
- }
+ if (current_language->la_language == language_cplus)
+ {
+ if (STREQN (tokstart, "true", 4))
+ return TRUEKEYWORD;
+
+ if (STREQN (tokstart, "this", 4))
+ {
+ static const char this_name[] =
+ { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ }
break;
case 3:
if (STREQN (tokstart, "int", 3))
@@ -1489,7 +1558,25 @@ yylex ()
write_dollar_variable (yylval.sval);
return VARIABLE;
}
-
+
+ /* Look ahead and see if we can consume more of the input
+ string to get a reasonable class/namespace spec or a
+ fully-qualified name. This is a kludge to get around the
+ HP aCC compiler's generation of symbol names with embedded
+ colons for namespace and nested classes. */
+ if (unquoted_expr)
+ {
+ /* Only do it if not inside single quotes */
+ sym_class = parse_nested_classes_for_hpacc (yylval.sval.ptr, yylval.sval.length,
+ &token_string, &class_prefix, &lexptr);
+ if (sym_class)
+ {
+ /* Replace the current token with the bigger one we found */
+ yylval.sval.ptr = token_string;
+ yylval.sval.length = strlen (token_string);
+ }
+ }
+
/* Use token-type BLOCKNAME for symbols that happen to be defined as
functions or symtabs. If this is not so, then ...
Use token-type TYPENAME for symbols that happen to be defined
@@ -1509,13 +1596,25 @@ yylex ()
/* Call lookup_symtab, not lookup_partial_symtab, in case there are
no psymtabs (coff, xcoff, or some future change to blow away the
psymtabs once once symbols are read). */
- if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
- lookup_symtab (tmp))
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this;
return BLOCKNAME;
}
+ else if (!sym)
+ { /* See if it's a file name. */
+ struct symtab *symtab;
+
+ symtab = lookup_symtab (tmp);
+
+ if (symtab)
+ {
+ yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+ return FILENAME;
+ }
+ }
+
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
#if 1
diff --git a/contrib/gdb/gdb/c-lang.c b/contrib/gdb/gdb/c-lang.c
index 66ee3e1..e7aa055 100644
--- a/contrib/gdb/gdb/c-lang.c
+++ b/contrib/gdb/gdb/c-lang.c
@@ -25,17 +25,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h"
#include "c-lang.h"
+static void c_emit_char PARAMS ((int c, GDB_FILE *stream, int quoter));
+
/* Print the character C on STREAM as part of the contents of a literal
string whose delimiter is QUOTER. Note that that format for printing
characters and strings is language specific. */
static void
-emit_char (c, stream, quoter)
+c_emit_char (c, stream, quoter)
register int c;
GDB_FILE *stream;
int quoter;
{
-
c &= 0xFF; /* Avoid sign bit follies */
if (PRINT_LITERAL_FORM (c))
@@ -83,21 +84,23 @@ c_printchar (c, stream)
int c;
GDB_FILE *stream;
{
- fputs_filtered ("'", stream);
- emit_char (c, stream, '\'');
- fputs_filtered ("'", stream);
+ fputc_filtered ('\'', stream);
+ LA_EMIT_CHAR (c, stream, '\'');
+ fputc_filtered ('\'', stream);
}
/* Print the character string STRING, printing at most LENGTH characters.
- Printing stops early if the number hits print_max; repeat counts
- are printed as appropriate. Print ellipses at the end if we
- had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
+ LENGTH is -1 if the string is nul terminated. Each character is WIDTH bytes
+ long. Printing stops early if the number hits print_max; repeat counts are
+ printed as appropriate. Print ellipses at the end if we had to stop before
+ printing LENGTH characters, or if FORCE_ELLIPSES. */
void
-c_printstr (stream, string, length, force_ellipses)
+c_printstr (stream, string, length, width, force_ellipses)
GDB_FILE *stream;
char *string;
unsigned int length;
+ int width;
int force_ellipses;
{
register unsigned int i;
@@ -111,7 +114,9 @@ c_printstr (stream, string, length, force_ellipses)
/* If the string was not truncated due to `set print elements', and
the last byte of it is a null, we don't print that, in traditional C
style. */
- if ((!force_ellipses) && length > 0 && string[length-1] == '\0')
+ if (!force_ellipses
+ && length > 0
+ && extract_unsigned_integer (string + (length - 1) * width, width) == '\0')
length--;
if (length == 0)
@@ -127,6 +132,7 @@ c_printstr (stream, string, length, force_ellipses)
unsigned int rep1;
/* Number of repetitions we have detected so far. */
unsigned int reps;
+ unsigned long current_char;
QUIT;
@@ -136,9 +142,13 @@ c_printstr (stream, string, length, force_ellipses)
need_comma = 0;
}
+ current_char = extract_unsigned_integer (string + i * width, width);
+
rep1 = i + 1;
reps = 1;
- while (rep1 < length && string[rep1] == string[i])
+ while (rep1 < length
+ && extract_unsigned_integer (string + rep1 * width, width)
+ == current_char)
{
++rep1;
++reps;
@@ -154,7 +164,7 @@ c_printstr (stream, string, length, force_ellipses)
fputs_filtered ("\", ", stream);
in_quotes = 0;
}
- c_printchar (string[i], stream);
+ LA_PRINT_CHAR (current_char, stream);
fprintf_filtered (stream, " <repeats %u times>", reps);
i = rep1 - 1;
things_printed += repeat_count_threshold;
@@ -170,7 +180,7 @@ c_printstr (stream, string, length, force_ellipses)
fputs_filtered ("\"", stream);
in_quotes = 1;
}
- emit_char (string[i], stream, '"');
+ LA_EMIT_CHAR (current_char, stream, '"');
++things_printed;
}
}
@@ -235,10 +245,17 @@ c_create_fundamental_type (objfile, typeid)
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0, "void", objfile);
break;
+ case FT_BOOLEAN:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "bool", objfile);
+
+ break;
case FT_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0, "char", objfile);
+ TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN;
break;
case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
@@ -324,6 +341,12 @@ c_create_fundamental_type (objfile, typeid)
type = init_type (TYPE_CODE_FLT,
TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
0, "long double", objfile);
+ break;
+ case FT_TEMPLATE_ARG:
+ type = init_type (TYPE_CODE_TEMPLATE_ARG,
+ 0,
+ 0, "<template arg>", objfile);
+
break;
}
return (type);
@@ -369,7 +392,7 @@ const struct op_print c_op_print_tab[] =
{NULL, 0, 0, 0}
};
-struct type ** const (c_builtin_types[]) =
+struct type ** CONST_PTR (c_builtin_types[]) =
{
&builtin_type_int,
&builtin_type_long,
@@ -402,6 +425,7 @@ const struct language_defn c_language_defn = {
evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
+ c_emit_char, /* Print a single char */
c_create_fundamental_type, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
@@ -417,10 +441,33 @@ const struct language_defn c_language_defn = {
LANG_MAGIC
};
+struct type ** const (cplus_builtin_types[]) =
+{
+ &builtin_type_int,
+ &builtin_type_long,
+ &builtin_type_short,
+ &builtin_type_char,
+ &builtin_type_float,
+ &builtin_type_double,
+ &builtin_type_void,
+ &builtin_type_long_long,
+ &builtin_type_signed_char,
+ &builtin_type_unsigned_char,
+ &builtin_type_unsigned_short,
+ &builtin_type_unsigned_int,
+ &builtin_type_unsigned_long,
+ &builtin_type_unsigned_long_long,
+ &builtin_type_long_double,
+ &builtin_type_complex,
+ &builtin_type_double_complex,
+ &builtin_type_bool,
+ 0
+};
+
const struct language_defn cplus_language_defn = {
"c++", /* Language name */
language_cplus,
- c_builtin_types,
+ cplus_builtin_types,
range_check_off,
type_check_off,
c_parse,
@@ -428,6 +475,7 @@ const struct language_defn cplus_language_defn = {
evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
+ c_emit_char, /* Print a single char */
c_create_fundamental_type, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
@@ -454,6 +502,7 @@ const struct language_defn asm_language_defn = {
evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
+ c_emit_char, /* Print a single char */
c_create_fundamental_type, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
diff --git a/contrib/gdb/gdb/c-lang.h b/contrib/gdb/gdb/c-lang.h
index fbd8b69..28486fd 100644
--- a/contrib/gdb/gdb/c-lang.h
+++ b/contrib/gdb/gdb/c-lang.h
@@ -1,5 +1,5 @@
/* C language support definitions for GDB, the GNU debugger.
- Copyright 1992 Free Software Foundation, Inc.
+ Copyright 1992, 1996 Free Software Foundation, Inc.
This file is part of GDB.
@@ -17,9 +17,12 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ifdef __STDC__ /* Forward decls for prototypes */
-struct value;
-#endif
+
+#if !defined (C_LANG_H)
+#define C_LANG_H 1
+
+#include "value.h"
+
extern int
c_parse PARAMS ((void)); /* Defined in c-exp.y */
@@ -31,7 +34,7 @@ extern void /* Defined in c-typeprint.c */
c_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
extern int
-c_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
+c_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *, int, int,
int, enum val_prettyprint));
extern int
@@ -41,11 +44,13 @@ c_value_print PARAMS ((struct value *, GDB_FILE *, int, enum val_prettyprint));
extern void c_printchar PARAMS ((int, GDB_FILE*));
-extern void c_printstr PARAMS ((GDB_FILE *, char *, unsigned int, int));
+extern void c_printstr PARAMS ((GDB_FILE *stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses));
extern struct type * c_create_fundamental_type PARAMS ((struct objfile*, int));
-extern struct type ** const (c_builtin_types[]);
+extern struct type ** CONST_PTR (c_builtin_types[]);
/* These are in c-typeprint.c: */
@@ -55,17 +60,12 @@ c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
extern void
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
-extern void
-cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
- GDB_FILE *));
/* These are in cp-valprint.c */
-extern void
-cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
- GDB_FILE *));
-
extern int vtblprint; /* Controls printing of vtbl's */
+extern int static_field_print;
+
extern void
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
@@ -73,7 +73,7 @@ extern void
cp_print_class_method PARAMS ((char *, struct type *, GDB_FILE *));
extern void
-cp_print_value_fields PARAMS ((struct type *, char *, CORE_ADDR,
+cp_print_value_fields PARAMS ((struct type *, struct type *, char *, int, CORE_ADDR,
GDB_FILE *, int, int, enum val_prettyprint,
struct type**, int));
@@ -82,3 +82,6 @@ cp_is_vtbl_ptr_type PARAMS ((struct type *));
extern int
cp_is_vtbl_member PARAMS ((struct type *));
+
+
+#endif /* !defined (C_LANG_H) */
diff --git a/contrib/gdb/gdb/c-typeprint.c b/contrib/gdb/gdb/c-typeprint.c
index a7a5341..e155503 100644
--- a/contrib/gdb/gdb/c-typeprint.c
+++ b/contrib/gdb/gdb/c-typeprint.c
@@ -1,5 +1,5 @@
/* Support for printing C and C++ types for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991, 1993, 1994, 1995, 1996
+ Copyright 1986, 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1998, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -38,11 +38,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <ctype.h>
-static void
-c_type_print_args PARAMS ((struct type *, GDB_FILE *));
+/* Flag indicating target was compiled by HP compiler */
+extern int hp_som_som_object_present;
static void
-c_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *, int, int, int));
+c_type_print_args PARAMS ((struct type *, GDB_FILE *));
static void
cp_type_print_derivation_info PARAMS ((GDB_FILE *, struct type *));
@@ -50,6 +50,10 @@ cp_type_print_derivation_info PARAMS ((GDB_FILE *, struct type *));
void
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
+static void
+c_type_print_cv_qualifier PARAMS ((struct type *, GDB_FILE *, int, int));
+
+
/* Print a description of a type in the format of a
typedef for the current language.
@@ -135,50 +139,16 @@ c_print_type (type, varstring, stream, show, level)
fputs_filtered (" ", stream);
c_type_print_varspec_prefix (type, stream, show, 0);
- fputs_filtered (varstring, stream);
-
- /* For demangled function names, we have the arglist as part of the name,
- so don't print an additional pair of ()'s */
-
- demangled_args = strchr(varstring, '(') != NULL;
- c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
-
-}
+ if (varstring != NULL)
+ {
+ fputs_filtered (varstring, stream);
-/* Print the C++ method arguments ARGS to the file STREAM. */
+ /* For demangled function names, we have the arglist as part of the name,
+ so don't print an additional pair of ()'s */
-void
-cp_type_print_method_args (args, prefix, varstring, staticp, stream)
- struct type **args;
- char *prefix;
- char *varstring;
- int staticp;
- GDB_FILE *stream;
-{
- int i;
-
- fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI);
- fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI);
- fputs_filtered (" (", stream);
- if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID)
- {
- i = !staticp; /* skip the class variable */
- while (1)
- {
- type_print (args[i++], "", stream, 0);
- if (!args[i])
- {
- fprintf_filtered (stream, " ...");
- break;
- }
- else if (args[i]->code != TYPE_CODE_VOID)
- {
- fprintf_filtered (stream, ", ");
- }
- else break;
- }
+ demangled_args = strchr(varstring, '(') != NULL;
+ c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
}
- fprintf_filtered (stream, ")");
}
/* If TYPE is a derived type, then print out derivation information.
@@ -203,7 +173,10 @@ cp_type_print_method_args (args, prefix, varstring, staticp, stream)
}
In general, gdb should try to print the types as closely as possible to
- the form that they appear in the source code. */
+ the form that they appear in the source code.
+ Note that in case of protected derivation gcc will not say 'protected'
+ but 'private'. The HP's aCC compiler emits specific information for
+ derivation via protected inheritance, so gdb can print it out */
static void
cp_type_print_derivation_info (stream, type)
@@ -217,7 +190,8 @@ cp_type_print_derivation_info (stream, type)
{
fputs_filtered (i == 0 ? ": " : ", ", stream);
fprintf_filtered (stream, "%s%s ",
- BASETYPE_VIA_PUBLIC (type, i) ? "public" : "private",
+ BASETYPE_VIA_PUBLIC (type, i) ? "public"
+ : (TYPE_FIELD_PROTECTED (type, i) ? "protected" : "private"),
BASETYPE_VIA_VIRTUAL(type, i) ? " virtual" : "");
name = type_name_no_tag (TYPE_BASECLASS (type, i));
fprintf_filtered (stream, "%s", name ? name : "(null)");
@@ -227,6 +201,47 @@ cp_type_print_derivation_info (stream, type)
fputs_filtered (" ", stream);
}
}
+/* Print the C++ method arguments ARGS to the file STREAM. */
+
+void
+cp_type_print_method_args (args, prefix, varstring, staticp, stream)
+ struct type **args;
+ char *prefix;
+ char *varstring;
+ int staticp;
+ GDB_FILE *stream;
+{
+ int i;
+
+ fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI);
+ fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI);
+ fputs_filtered ("(", stream);
+ if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID)
+ {
+ i = !staticp; /* skip the class variable */
+ while (1)
+ {
+ type_print (args[i++], "", stream, 0);
+ if (!args[i])
+ {
+ fprintf_filtered (stream, " ...");
+ break;
+ }
+ else if (args[i]->code != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ else break;
+ }
+ }
+ else if (current_language->la_language == language_cplus)
+ {
+ fprintf_filtered (stream, "void");
+ }
+
+ fprintf_filtered (stream, ")");
+}
+
/* Print any asterisks or open-parentheses needed before the
variable name (to describe its type).
@@ -257,6 +272,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
case TYPE_CODE_PTR:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
fprintf_filtered (stream, "*");
+ c_type_print_cv_qualifier (type, stream, 1, 0);
break;
case TYPE_CODE_MEMBER:
@@ -274,7 +290,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
case TYPE_CODE_METHOD:
if (passed_a_ptr)
- fprintf_unfiltered (stream, "(");
+ fprintf_filtered (stream, "(");
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
if (passed_a_ptr)
{
@@ -287,6 +303,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
case TYPE_CODE_REF:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
fprintf_filtered (stream, "&");
+ c_type_print_cv_qualifier (type, stream, 1, 0);
break;
case TYPE_CODE_FUNC:
@@ -323,6 +340,43 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
}
}
+/* Print out "const" and "volatile" attributes.
+ TYPE is a pointer to the type being printed out.
+ STREAM is the output destination.
+ NEED_SPACE = 1 indicates an initial white space is needed */
+
+static void
+c_type_print_cv_qualifier (type, stream, need_pre_space, need_post_space)
+ struct type *type;
+ GDB_FILE *stream;
+ int need_pre_space;
+ int need_post_space;
+{
+ int flag = 0;
+
+ if (TYPE_CONST (type))
+ {
+ if (need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "const");
+ flag = 1;
+ }
+
+ if (TYPE_VOLATILE (type))
+ {
+ if (flag || need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "volatile");
+ flag = 1;
+ }
+
+ if (flag && need_post_space)
+ fprintf_filtered (stream, " ");
+}
+
+
+
+
static void
c_type_print_args (type, stream)
struct type *type;
@@ -339,6 +393,11 @@ c_type_print_args (type, stream)
{
fprintf_filtered (stream, "...");
}
+ else if ((args[1]->code == TYPE_CODE_VOID) &&
+ (current_language->la_language == language_cplus))
+ {
+ fprintf_filtered (stream, "void");
+ }
else
{
for (i = 1;
@@ -358,6 +417,11 @@ c_type_print_args (type, stream)
}
}
}
+ else if (current_language->la_language == language_cplus)
+ {
+ fprintf_filtered (stream, "void");
+ }
+
fprintf_filtered (stream, ")");
}
@@ -365,7 +429,7 @@ c_type_print_args (type, stream)
needed after the variable name (to describe its type).
Args work like c_type_print_varspec_prefix. */
-static void
+void
c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
struct type *type;
GDB_FILE *stream;
@@ -425,15 +489,20 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
if (!demangled_args)
{ int i, len = TYPE_NFIELDS (type);
fprintf_filtered (stream, "(");
- for (i = 0; i < len; i++)
- {
- if (i > 0)
- {
- fputs_filtered (", ", stream);
- wrap_here (" ");
- }
- c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
- }
+ if ((len == 0) && (current_language->la_language == language_cplus))
+ {
+ fprintf_filtered (stream, "void");
+ }
+ else
+ for (i = 0; i < len; i++)
+ {
+ if (i > 0)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (" ");
+ }
+ c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+ }
fprintf_filtered (stream, ")");
}
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
@@ -490,7 +559,11 @@ c_type_print_base (type, stream, show, level)
register int lastval;
char *mangled_name;
char *demangled_name;
+ char *demangled_no_static;
enum {s_none, s_public, s_private, s_protected} section_type;
+ int need_access_label = 0;
+ int j, len2;
+
QUIT;
wrap_here (" ");
@@ -509,6 +582,7 @@ c_type_print_base (type, stream, show, level)
if (show <= 0
&& TYPE_NAME (type) != NULL)
{
+ c_type_print_cv_qualifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
return;
}
@@ -528,21 +602,48 @@ c_type_print_base (type, stream, show, level)
break;
case TYPE_CODE_STRUCT:
- if (HAVE_CPLUS_STRUCT (type))
- {
- fprintf_filtered (stream, "class ");
- }
- else
- {
- fprintf_filtered (stream, "struct ");
- }
+ c_type_print_cv_qualifier (type, stream, 0, 1);
+ /* Note TYPE_CODE_STRUCT and TYPE_CODE_CLASS have the same value,
+ * so we use another means for distinguishing them.
+ */
+ if (HAVE_CPLUS_STRUCT (type)) {
+ switch (TYPE_DECLARED_TYPE(type)) {
+ case DECLARED_TYPE_CLASS:
+ fprintf_filtered (stream, "class ");
+ break;
+ case DECLARED_TYPE_UNION:
+ fprintf_filtered (stream, "union ");
+ break;
+ case DECLARED_TYPE_STRUCT:
+ fprintf_filtered (stream, "struct ");
+ break;
+ default:
+ /* If there is a CPLUS_STRUCT, assume class if not
+ * otherwise specified in the declared_type field.
+ */
+ fprintf_filtered (stream, "class ");
+ break;
+ } /* switch */
+ } else {
+ /* If not CPLUS_STRUCT, then assume it's a C struct */
+ fprintf_filtered (stream, "struct ");
+ }
goto struct_union;
case TYPE_CODE_UNION:
+ c_type_print_cv_qualifier (type, stream, 0, 1);
fprintf_filtered (stream, "union ");
struct_union:
- if (TYPE_TAG_NAME (type) != NULL)
+
+ /* Print the tag if it exists.
+ * The HP aCC compiler emits
+ * a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
+ * tag for unnamed struct/union/enum's, which we don't
+ * want to print.
+ */
+ if (TYPE_TAG_NAME (type) != NULL &&
+ strncmp(TYPE_TAG_NAME(type), "{unnamed", 8))
{
fputs_filtered (TYPE_TAG_NAME (type), stream);
if (show > 0)
@@ -574,6 +675,72 @@ c_type_print_base (type, stream, show, level)
section_type = s_none;
+ /* For a class, if all members are private, there's no need
+ for a "private:" label; similarly, for a struct or union
+ masquerading as a class, if all members are public, there's
+ no need for a "public:" label. */
+
+ if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_CLASS) ||
+ (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_TEMPLATE))
+ {
+ QUIT;
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ if (!TYPE_FIELD_PRIVATE (type, i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ QUIT;
+ if (!need_access_label)
+ {
+ len2 = TYPE_NFN_FIELDS (type);
+ for (j = 0; j < len2; j++)
+ {
+ len = TYPE_FN_FIELDLIST_LENGTH (type, j);
+ for (i = 0; i < len; i++)
+ if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ if (need_access_label)
+ break;
+ }
+ }
+ }
+ else if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_STRUCT) ||
+ (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION))
+ {
+ QUIT;
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ if (TYPE_FIELD_PRIVATE (type, i) || TYPE_FIELD_PROTECTED (type, i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ QUIT;
+ if (!need_access_label)
+ {
+ len2 = TYPE_NFN_FIELDS (type);
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ len = TYPE_FN_FIELDLIST_LENGTH (type, j);
+ for (i = 0; i < len; i++)
+ if (TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i) ||
+ TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, j), i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ if (need_access_label)
+ break;
+ }
+ }
+ }
+
/* If there is a base class for this type,
do not print the field that it occupies. */
@@ -582,6 +749,11 @@ c_type_print_base (type, stream, show, level)
{
QUIT;
/* Don't print out virtual function table. */
+ /* HP ANSI C++ case */
+ if (TYPE_HAS_VTABLE(type) && (STREQN (TYPE_FIELD_NAME (type, i), "__vfp", 5)))
+ continue;
+ /* Other compilers */
+ /* pai:: FIXME : check for has_vtable < 0 */
if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
&& is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
continue;
@@ -589,7 +761,7 @@ c_type_print_base (type, stream, show, level)
/* If this is a C++ class we can print the various C++ section
labels. */
- if (HAVE_CPLUS_STRUCT (type))
+ if (HAVE_CPLUS_STRUCT (type) && need_access_label)
{
if (TYPE_FIELD_PROTECTED (type, i))
{
@@ -646,7 +818,6 @@ c_type_print_base (type, stream, show, level)
fprintf_filtered (stream, "\n");
/* C++: print out the methods */
-
for (i = 0; i < len; i++)
{
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
@@ -658,11 +829,11 @@ c_type_print_base (type, stream, show, level)
{
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
int is_full_physname_constructor =
- ((physname[0]=='_' && physname[1]=='_' &&
- (isdigit(physname[2])
- || physname[2]=='Q'
- || physname[2]=='t'))
- || (strncmp(physname, "__ct__", 6) == 0));
+ ((physname[0] == '_' && physname[1] == '_'
+ && strchr ("0123456789Qt", physname[2]))
+ || STREQN (physname, "__ct__", 6)
+ || DESTRUCTOR_PREFIX_P (physname)
+ || STREQN (physname, "__dt__", 6));
QUIT;
if (TYPE_FN_FIELD_PROTECTED (f, j))
@@ -699,64 +870,112 @@ c_type_print_base (type, stream, show, level)
if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
{
/* Keep GDB from crashing here. */
- fprintf_unfiltered (stream, "<undefined type> %s;\n",
+ fprintf_filtered (stream, "<undefined type> %s;\n",
TYPE_FN_FIELD_PHYSNAME (f, j));
break;
}
- else if (!is_constructor && !is_full_physname_constructor)
+ else if (!is_constructor && /* constructors don't have declared types */
+ !is_full_physname_constructor && /* " " */
+ !strstr (method_name, "operator ")) /* Not a type conversion operator */
+ /* (note space -- other operators don't have it) */
{
type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
"", stream, -1);
fputs_filtered (" ", stream);
}
if (TYPE_FN_FIELD_STUB (f, j))
+ /* Build something we can demangle. */
+ mangled_name = gdb_mangle_name (type, i, j);
+ else
+ mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ demangled_name =
+ cplus_demangle (mangled_name,
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
{
- /* Build something we can demangle. */
- mangled_name = gdb_mangle_name (type, i, j);
- demangled_name =
- cplus_demangle (mangled_name,
- DMGL_ANSI | DMGL_PARAMS);
- if (demangled_name == NULL)
- fprintf_filtered (stream, "<badly mangled name %s>",
- mangled_name);
+ /* in some cases (for instance with the HP demangling),
+ if a function has more than 10 arguments,
+ the demangling will fail.
+ Let's try to reconstruct the function signature from
+ the symbol information */
+ if (!TYPE_FN_FIELD_STUB (f, j))
+ cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
+ method_name,
+ TYPE_FN_FIELD_STATIC_P (f, j),
+ stream);
else
+ fprintf_filtered (stream, "<badly mangled name '%s'>",
+ mangled_name);
+ }
+ else
+ {
+ char *p;
+ char *demangled_no_class = demangled_name;
+
+ while (p = strchr (demangled_no_class, ':'))
+ {
+ demangled_no_class = p;
+ if (*++demangled_no_class == ':')
+ ++demangled_no_class;
+ }
+ /* get rid of the static word appended by the demangler */
+ p = strstr (demangled_no_class, " static");
+ if (p != NULL)
{
- char *demangled_no_class =
- strchr (demangled_name, ':');
-
- if (demangled_no_class == NULL)
- demangled_no_class = demangled_name;
- else
- {
- if (*++demangled_no_class == ':')
- ++demangled_no_class;
- }
- fputs_filtered (demangled_no_class, stream);
- free (demangled_name);
+ int length = p - demangled_no_class;
+ demangled_no_static = (char *) xmalloc (length + 1);
+ strncpy (demangled_no_static, demangled_no_class, length);
+ *(demangled_no_static + length) = '\0';
+ fputs_filtered (demangled_no_static, stream);
+ free (demangled_no_static);
}
- free (mangled_name);
+ else
+ fputs_filtered (demangled_no_class, stream);
+ free (demangled_name);
}
- else if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
- && is_cplus_marker (TYPE_FN_FIELD_PHYSNAME (f, j)[1]))
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1,
- "~", method_name, 0, stream);
- else
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
- method_name,
- TYPE_FN_FIELD_STATIC_P (f, j),
- stream);
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ free (mangled_name);
fprintf_filtered (stream, ";\n");
}
}
+ if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
+ fprintfi_filtered (level, stream, " (Local at %s:%d)\n",
+ TYPE_LOCALTYPE_FILE (type),
+ TYPE_LOCALTYPE_LINE (type));
+
fprintfi_filtered (level, stream, "}");
}
+ if (TYPE_CODE(type) == TYPE_CODE_TEMPLATE)
+ goto go_back;
break;
case TYPE_CODE_ENUM:
- fprintf_filtered (stream, "enum ");
- if (TYPE_TAG_NAME (type) != NULL)
+ c_type_print_cv_qualifier (type, stream, 0, 1);
+ /* HP C supports sized enums */
+ if (hp_som_som_object_present)
+ switch (TYPE_LENGTH (type))
+ {
+ case 1:
+ fputs_filtered ("char ", stream);
+ break;
+ case 2:
+ fputs_filtered ("short ", stream);
+ break;
+ default:
+ break;
+ }
+ fprintf_filtered (stream, "enum ");
+ /* Print the tag name if it exists.
+ The aCC compiler emits a spurious
+ "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
+ tag for unnamed struct/union/enum's, which we don't
+ want to print. */
+ if (TYPE_TAG_NAME (type) != NULL &&
+ strncmp(TYPE_TAG_NAME(type), "{unnamed", 8))
{
fputs_filtered (TYPE_TAG_NAME (type), stream);
if (show > 0)
@@ -809,6 +1028,36 @@ c_type_print_base (type, stream, show, level)
fprintf_filtered (stream, "<range type>");
break;
+ case TYPE_CODE_TEMPLATE:
+ /* Called on "ptype t" where "t" is a template.
+ Prints the template header (with args), e.g.:
+ template <class T1, class T2> class "
+ and then merges with the struct/union/class code to
+ print the rest of the definition. */
+ c_type_print_cv_qualifier (type, stream, 0, 1);
+ fprintf_filtered (stream, "template <");
+ for (i = 0; i < TYPE_NTEMPLATE_ARGS(type); i++) {
+ struct template_arg templ_arg;
+ templ_arg = TYPE_TEMPLATE_ARG(type, i);
+ fprintf_filtered (stream, "class %s", templ_arg.name);
+ if (i < TYPE_NTEMPLATE_ARGS(type)-1)
+ fprintf_filtered (stream, ", ");
+ }
+ fprintf_filtered (stream, "> class ");
+ /* Yuck, factor this out to a subroutine so we can call
+ it and return to the point marked with the "goback:" label... - RT */
+ goto struct_union;
+go_back:
+ if (TYPE_NINSTANTIATIONS(type) > 0) {
+ fprintf_filtered (stream, "\ntemplate instantiations:\n");
+ for (i = 0; i < TYPE_NINSTANTIATIONS(type); i++) {
+ fprintf_filtered(stream, " ");
+ c_type_print_base (TYPE_INSTANTIATION(type, i), stream, 0, level);
+ if (i < TYPE_NINSTANTIATIONS(type)-1) fprintf_filtered(stream, "\n");
+ }
+ }
+ break;
+
default:
/* Handle types not explicitly handled by the other cases,
such as fundamental types. For these, just print whatever
@@ -816,6 +1065,7 @@ c_type_print_base (type, stream, show, level)
is no type name, then complain. */
if (TYPE_NAME (type) != NULL)
{
+ c_type_print_cv_qualifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
}
else
@@ -829,3 +1079,11 @@ c_type_print_base (type, stream, show, level)
}
}
+
+
+
+
+
+
+
+
diff --git a/contrib/gdb/gdb/c-valprint.c b/contrib/gdb/gdb/c-valprint.c
index a16f87c..7a9c6be 100644
--- a/contrib/gdb/gdb/c-valprint.c
+++ b/contrib/gdb/gdb/c-valprint.c
@@ -1,5 +1,5 @@
/* Support for printing C values for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
@@ -43,10 +43,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
The PRETTY parameter controls prettyprinting. */
int
-c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
+c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, recurse,
pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -65,9 +66,9 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
{
- elttype = check_typedef (TYPE_TARGET_TYPE (type));
eltlen = TYPE_LENGTH (elttype);
len = TYPE_LENGTH (type) / eltlen;
if (prettyprint_arrays)
@@ -89,13 +90,13 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
/* Look for a NULL char. */
for (temp_len = 0;
- valaddr[temp_len]
+ (valaddr + embedded_offset)[temp_len]
&& temp_len < len && temp_len < print_max;
temp_len++);
len = temp_len;
}
- LA_PRINT_STRING (stream, valaddr, len, 0);
+ LA_PRINT_STRING (stream, valaddr + embedded_offset, len, eltlen, 0);
i = len;
}
else
@@ -112,7 +113,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
i = 0;
}
- val_print_array_elements (type, valaddr, address, stream,
+ val_print_array_elements (type, valaddr + embedded_offset, address, stream,
format, deref_ref, recurse, pretty, i);
fprintf_filtered (stream, "}");
}
@@ -125,7 +126,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
case TYPE_CODE_PTR:
if (format && format != 's')
{
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
break;
}
if (vtblprint && cp_is_vtbl_ptr_type(type))
@@ -133,25 +134,26 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
/* Print the unmangled name if desired. */
/* Print vtable entry - we only get here if we ARE using
-fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
- print_address_demangle(extract_address (valaddr, TYPE_LENGTH (type)),
+ print_address_demangle(extract_address (valaddr + embedded_offset, TYPE_LENGTH (type)),
stream, demangle);
break;
}
elttype = check_typedef (TYPE_TARGET_TYPE (type));
if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
{
- cp_print_class_method (valaddr, type, stream);
+ cp_print_class_method (valaddr + embedded_offset, type, stream);
}
else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
{
- cp_print_class_member (valaddr,
+ cp_print_class_member (valaddr + embedded_offset,
TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
stream, "&");
}
else
{
- addr = unpack_pointer (type, valaddr);
+ addr = unpack_pointer (type, valaddr + embedded_offset);
print_unpacked_pointer:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
{
@@ -168,17 +170,19 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
/* For a pointer to char or unsigned char, also print the string
pointed to, unless pointer is null. */
+ /* FIXME: need to handle wchar_t here... */
+
if (TYPE_LENGTH (elttype) == 1
&& TYPE_CODE (elttype) == TYPE_CODE_INT
&& (format == 0 || format == 's')
&& addr != 0)
{
- i = val_print_string (addr, 0, stream);
+ i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
}
else if (cp_is_vtbl_member(type))
{
/* print vtbl's nicely */
- CORE_ADDR vt_address = unpack_pointer (type, valaddr);
+ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
struct minimal_symbol *msymbol =
lookup_minimal_symbol_by_pc (vt_address);
@@ -210,8 +214,8 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
wtype = TYPE_TARGET_TYPE(type);
}
- vt_val = value_at (wtype, vt_address);
- val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val),
+ vt_val = value_at (wtype, vt_address, NULL);
+ val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
VALUE_ADDRESS (vt_val), stream, format,
deref_ref, recurse + 1, pretty);
if (pretty)
@@ -237,7 +241,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
elttype = check_typedef (TYPE_TARGET_TYPE (type));
if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
{
- cp_print_class_member (valaddr,
+ cp_print_class_member (valaddr + embedded_offset,
TYPE_DOMAIN_TYPE (elttype),
stream, "");
break;
@@ -246,7 +250,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
fprintf_filtered (stream, "@");
print_address_numeric
- (extract_address (valaddr,
+ (extract_address (valaddr + embedded_offset,
TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream);
if (deref_ref)
fputs_filtered (": ", stream);
@@ -260,11 +264,17 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
value_at
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
- valaddr));
+ valaddr + embedded_offset),
+ NULL);
val_print (VALUE_TYPE (deref_val),
- VALUE_CONTENTS (deref_val),
- VALUE_ADDRESS (deref_val), stream, format,
- deref_ref, recurse + 1, pretty);
+ VALUE_CONTENTS (deref_val),
+ 0,
+ VALUE_ADDRESS (deref_val),
+ stream,
+ format,
+ deref_ref,
+ recurse,
+ pretty);
}
else
fputs_filtered ("???", stream);
@@ -284,23 +294,25 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
/* Print the unmangled name if desired. */
/* Print vtable entry - we only get here if NOT using
-fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
- print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
- TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
- stream, demangle);
+ print_address_demangle (extract_address (
+ valaddr + embedded_offset +
+ TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8,
+ TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))),
+ stream, demangle);
}
else
- cp_print_value_fields (type, valaddr, address, stream, format,
+ cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format,
recurse, pretty, NULL, 0);
break;
case TYPE_CODE_ENUM:
if (format)
{
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
break;
}
len = TYPE_NFIELDS (type);
- val = unpack_long (type, valaddr);
+ val = unpack_long (type, valaddr + embedded_offset);
for (i = 0; i < len; i++)
{
QUIT;
@@ -322,7 +334,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
case TYPE_CODE_FUNC:
if (format)
{
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
break;
}
/* FIXME, we should consider, at least for ANSI C language, eliminating
@@ -337,10 +349,10 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
case TYPE_CODE_BOOL:
format = format ? format : output_format;
if (format)
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
else
{
- val = unpack_long (type, valaddr);
+ val = unpack_long (type, valaddr + embedded_offset);
if (val == 0)
fputs_filtered ("false", stream);
else if (val == 1)
@@ -364,11 +376,11 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
format = format ? format : output_format;
if (format)
{
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
}
else
{
- val_print_type_code_int (type, valaddr, stream);
+ val_print_type_code_int (type, valaddr + embedded_offset, stream);
/* C and C++ has no single byte int type, char is used instead.
Since we don't know whether the value is really intended to
be used as an integer or a character, print the character
@@ -376,7 +388,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
if (TYPE_LENGTH (type) == 1)
{
fputs_filtered (" ", stream);
- LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset),
stream);
}
}
@@ -386,28 +398,32 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
format = format ? format : output_format;
if (format)
{
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
}
else
{
fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%u" : "%d",
- unpack_long (type, valaddr));
+ unpack_long (type, valaddr + embedded_offset));
fputs_filtered (" ", stream);
- LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), stream);
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset), stream);
}
break;
case TYPE_CODE_FLT:
if (format)
{
- print_scalar_formatted (valaddr, type, format, 0, stream);
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
}
else
{
- print_floating (valaddr, type, stream);
+ print_floating (valaddr + embedded_offset, type, stream);
}
break;
+ case TYPE_CODE_METHOD:
+ cp_print_class_method (valaddr + embedded_offset, lookup_pointer_type (type), stream);
+ break;
+
case TYPE_CODE_VOID:
fprintf_filtered (stream, "void");
break;
@@ -438,7 +454,9 @@ c_value_print (val, stream, format, pretty)
enum val_prettyprint pretty;
{
struct type *type = VALUE_TYPE (val);
-
+ struct type * real_type;
+ int full, top, using_enc;
+
/* If it is a pointer, indicate what it points to.
Print type also if it is a reference.
@@ -457,13 +475,61 @@ c_value_print (val, stream, format, pretty)
{
/* Print nothing */
}
+ else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+ {
+ /* Pointer to class, check real type of object */
+ fprintf_filtered (stream, "(");
+ type = value_rtti_target_type (val, &full, &top, &using_enc);
+ if (type)
+ {
+ /* RTTI entry found */
+ type = lookup_pointer_type (type);
+ type_print (type, "", stream, -1);
+ }
+ else
+ {
+ /* No RTTI fields, do whatever we can */
+ type = VALUE_ENCLOSING_TYPE (val);
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, " ?");
+ }
+ fprintf_filtered (stream, ") ");
+ }
else
{
+ /* normal case */
fprintf_filtered (stream, "(");
type_print (type, "", stream, -1);
fprintf_filtered (stream, ") ");
}
}
- return (val_print (type, VALUE_CONTENTS (val),
- VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
+ if (objectprint && (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_CLASS))
+ {
+ /* Attempt to determine real type of object */
+ real_type = value_rtti_type (val, &full, &top, &using_enc);
+ if (real_type)
+ {
+ /* We have RTTI information, so use it */
+ val = value_full_object (val, real_type, full, top, using_enc);
+ fprintf_filtered (stream, "(%s%s) ",
+ TYPE_NAME (real_type),
+ full ? "" : " [incomplete object]");
+ /* Print out object: enclosing type is same as real_type if full */
+ return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
+ VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+ }
+ else if (type != VALUE_ENCLOSING_TYPE (val))
+ {
+ /* No RTTI information, so let's do our best */
+ fprintf_filtered (stream, "(%s ?) ",
+ TYPE_NAME (VALUE_ENCLOSING_TYPE (val)));
+ return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
+ VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+ }
+ /* Otherwise, we end up at the return outside this "if" */
+ }
+
+ return val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val),
+ VALUE_ADDRESS (val),
+ stream, format, 1, 0, pretty);
}
diff --git a/contrib/gdb/gdb/ch-exp.c b/contrib/gdb/gdb/ch-exp.c
index f6f522a..45436a3 100644
--- a/contrib/gdb/gdb/ch-exp.c
+++ b/contrib/gdb/gdb/ch-exp.c
@@ -55,11 +55,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "symfile.h" /* Required by objfiles.h. */
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+#ifdef __GNUC__
+#define INLINE __inline__
+#endif
+
typedef union
{
LONGEST lval;
- unsigned LONGEST ulval;
+ ULONGEST ulval;
struct {
LONGEST val;
struct type *type;
@@ -87,7 +91,7 @@ enum ch_terminal {
CHARACTER_STRING_LITERAL,
BIT_STRING_LITERAL,
TYPENAME,
- FIELD_NAME,
+ DOT_FIELD_NAME, /* '.' followed by <field name> */
CASE,
OF,
ESAC,
@@ -131,13 +135,55 @@ enum ch_terminal {
};
/* Forward declarations. */
-static void parse_expr ();
-static void parse_primval ();
-static void parse_untyped_expr ();
-static int parse_opt_untyped_expr ();
-static void parse_if_expression_body PARAMS((void));
+
static void write_lower_upper_value PARAMS ((enum exp_opcode, struct type *));
-static enum ch_terminal ch_lex ();
+static enum ch_terminal match_bitstring_literal PARAMS ((void));
+static enum ch_terminal match_integer_literal PARAMS ((void));
+static enum ch_terminal match_character_literal PARAMS ((void));
+static enum ch_terminal match_string_literal PARAMS ((void));
+static enum ch_terminal match_float_literal PARAMS ((void));
+static enum ch_terminal match_float_literal PARAMS ((void));
+static int decode_integer_literal PARAMS ((LONGEST *, char **));
+static int decode_integer_value PARAMS ((int, char **, LONGEST *));
+static char *match_simple_name_string PARAMS ((void));
+static void growbuf_by_size PARAMS ((int));
+static void parse_untyped_expr PARAMS ((void));
+static void parse_if_expression PARAMS ((void));
+static void parse_else_alternative PARAMS ((void));
+static void parse_then_alternative PARAMS ((void));
+static void parse_expr PARAMS ((void));
+static void parse_operand0 PARAMS ((void));
+static void parse_operand1 PARAMS ((void));
+static void parse_operand2 PARAMS ((void));
+static void parse_operand3 PARAMS ((void));
+static void parse_operand4 PARAMS ((void));
+static void parse_operand5 PARAMS ((void));
+static void parse_operand6 PARAMS ((void));
+static void parse_primval PARAMS ((void));
+static void parse_tuple PARAMS ((struct type *));
+static void parse_opt_element_list PARAMS ((struct type *));
+static void parse_tuple_element PARAMS ((struct type *));
+static void parse_named_record_element PARAMS ((void));
+static void parse_call PARAMS ((void));
+static struct type *parse_mode_or_normal_call PARAMS ((void));
+#if 0
+static struct type *parse_mode_call PARAMS ((void));
+#endif
+static void parse_unary_call PARAMS ((void));
+static int parse_opt_untyped_expr PARAMS ((void));
+static void parse_case_label PARAMS ((void));
+static int expect PARAMS ((enum ch_terminal, char *));
+static void parse_expr PARAMS ((void));
+static void parse_primval PARAMS ((void));
+static void parse_untyped_expr PARAMS ((void));
+static int parse_opt_untyped_expr PARAMS ((void));
+static void parse_if_expression_body PARAMS((void));
+static enum ch_terminal ch_lex PARAMS ((void));
+INLINE static enum ch_terminal PEEK_TOKEN PARAMS ((void));
+static enum ch_terminal peek_token_ PARAMS ((int));
+static void forward_token_ PARAMS ((void));
+static void require PARAMS ((enum ch_terminal));
+static int check_token PARAMS ((enum ch_terminal));
#define MAX_LOOK_AHEAD 2
static enum ch_terminal terminal_buffer[MAX_LOOK_AHEAD+1] = {
@@ -147,10 +193,7 @@ static YYSTYPE val_buffer[MAX_LOOK_AHEAD+1];
/*int current_token, lookahead_token;*/
-#ifdef __GNUC__
-__inline__
-#endif
-static enum ch_terminal
+INLINE static enum ch_terminal
PEEK_TOKEN()
{
if (terminal_buffer[0] == TOKEN_NOT_READ)
@@ -214,7 +257,7 @@ forward_token_()
/* Skip the next token.
if it isn't TOKEN, the parser is broken. */
-void
+static void
require(token)
enum ch_terminal token;
{
@@ -227,7 +270,7 @@ require(token)
FORWARD_TOKEN();
}
-int
+static int
check_token (token)
enum ch_terminal token;
{
@@ -240,8 +283,8 @@ check_token (token)
/* return 0 if expected token was not found,
else return 1.
*/
-int
-expect(token, message)
+static int
+expect (token, message)
enum ch_terminal token;
char *message;
{
@@ -408,7 +451,9 @@ parse_unary_call ()
/* Parse NAME '(' MODENAME ')'. */
-struct type *
+#if 0
+
+static struct type *
parse_mode_call ()
{
struct type *type;
@@ -422,7 +467,9 @@ parse_mode_call ()
return type;
}
-struct type *
+#endif
+
+static struct type *
parse_mode_or_normal_call ()
{
struct type *type;
@@ -486,9 +533,11 @@ static void
parse_named_record_element ()
{
struct stoken label;
+ char buf[256];
label = PEEK_LVAL ().sval;
- expect (FIELD_NAME, "expected a field name here `%s'", lexptr);
+ sprintf (buf, "expected a field name here `%s'", lexptr);
+ expect (DOT_FIELD_NAME, buf);
if (check_token (','))
parse_named_record_element ();
else if (check_token (':'))
@@ -500,12 +549,13 @@ parse_named_record_element ()
write_exp_elt_opcode (OP_LABELED);
}
-/* Returns one or nore TREE_LIST nodes, in reverse order. */
+/* Returns one or more TREE_LIST nodes, in reverse order. */
static void
-parse_tuple_element ()
+parse_tuple_element (type)
+ struct type *type;
{
- if (PEEK_TOKEN () == FIELD_NAME)
+ if (PEEK_TOKEN () == DOT_FIELD_NAME)
{
/* Parse a labelled structure tuple. */
parse_named_record_element ();
@@ -517,7 +567,32 @@ parse_tuple_element ()
if (check_token ('*'))
{
expect (')', "missing ')' after '*' case label list");
- error ("(*) not implemented in case label list");
+ if (type)
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ /* do this as a range from low to high */
+ struct type *range_type = TYPE_FIELD_TYPE (type, 0);
+ LONGEST low_bound, high_bound;
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ error ("cannot determine bounds for (*)");
+ /* lower bound */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (range_type);
+ write_exp_elt_longcst (low_bound);
+ write_exp_elt_opcode (OP_LONG);
+ /* upper bound */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (range_type);
+ write_exp_elt_longcst (high_bound);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_opcode (BINOP_RANGE);
+ }
+ else
+ error ("(*) in invalid context");
+ }
+ else
+ error ("(*) only possible with modename in front of tuple (mode[..])");
}
else
{
@@ -543,14 +618,15 @@ parse_tuple_element ()
/* Matches: a COMMA-separated list of tuple elements.
Returns a list (of TREE_LIST nodes). */
static void
-parse_opt_element_list ()
+parse_opt_element_list (type)
+ struct type *type;
{
arglist_len = 0;
if (PEEK_TOKEN () == ']')
return;
for (;;)
{
- parse_tuple_element ();
+ parse_tuple_element (type);
arglist_len++;
if (PEEK_TOKEN () == ']')
break;
@@ -566,17 +642,21 @@ static void
parse_tuple (mode)
struct type *mode;
{
+ struct type *type;
+ if (mode)
+ type = check_typedef (mode);
+ else
+ type = 0;
require ('[');
start_arglist ();
- parse_opt_element_list ();
+ parse_opt_element_list (type);
expect (']', "missing ']' after tuple");
write_exp_elt_opcode (OP_ARRAY);
write_exp_elt_longcst ((LONGEST) 0);
write_exp_elt_longcst ((LONGEST) end_arglist () - 1);
write_exp_elt_opcode (OP_ARRAY);
- if (mode)
+ if (type)
{
- struct type *type = check_typedef (mode);
if (TYPE_CODE (type) != TYPE_CODE_ARRAY
&& TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_SET)
@@ -765,7 +845,7 @@ parse_primval ()
{
switch (PEEK_TOKEN ())
{
- case FIELD_NAME:
+ case DOT_FIELD_NAME:
write_exp_elt_opcode (STRUCTOP_STRUCT);
write_exp_string (PEEK_LVAL ().sval);
write_exp_elt_opcode (STRUCTOP_STRUCT);
@@ -2057,7 +2137,7 @@ ch_lex ()
inputname = match_simple_name_string ();
if (!inputname)
return '.';
- return FIELD_NAME;
+ return DOT_FIELD_NAME;
}
return (ILLEGAL_TOKEN);
@@ -2072,7 +2152,6 @@ write_lower_upper_value (opcode, type)
write_exp_elt_opcode (opcode);
else
{
- extern LONGEST type_lower_upper ();
struct type *result_type;
LONGEST val = type_lower_upper (opcode, type, &result_type);
write_exp_elt_opcode (OP_LONG);
diff --git a/contrib/gdb/gdb/ch-lang.c b/contrib/gdb/gdb/ch-lang.c
index 8504d67..c54e8bb 100644
--- a/contrib/gdb/gdb/ch-lang.c
+++ b/contrib/gdb/gdb/ch-lang.c
@@ -26,6 +26,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h"
#include "ch-lang.h"
+static value_ptr
+evaluate_subexp_chill PARAMS ((struct type *, struct expression *, int *, enum noside));
+
+static value_ptr
+value_chill_max_min PARAMS ((enum exp_opcode, value_ptr));
+
+static value_ptr
+value_chill_card PARAMS ((value_ptr));
+
+static value_ptr
+ value_chill_length PARAMS ((value_ptr));
+
+static struct type *
+chill_create_fundamental_type PARAMS ((struct objfile *, int));
+
+static void
+chill_printstr PARAMS ((GDB_FILE *stream, char *string, unsigned int length, int width, int force_ellipses));
+
+static void
+chill_printchar PARAMS ((int, GDB_FILE *));
/* For now, Chill uses a simple mangling algorithm whereby you simply
discard everything after the occurance of two successive CPLUS_MARKER
@@ -91,10 +111,11 @@ chill_printchar (c, stream)
*/
static void
-chill_printstr (stream, string, length, force_ellipses)
+chill_printstr (stream, string, length, width, force_ellipses)
GDB_FILE *stream;
char *string;
unsigned int length;
+ int width;
int force_ellipses;
{
register unsigned int i;
@@ -310,7 +331,7 @@ struct type *builtin_type_chill_long;
struct type *builtin_type_chill_ulong;
struct type *builtin_type_chill_real;
-struct type ** const (chill_builtin_types[]) =
+struct type ** CONST_PTR (chill_builtin_types[]) =
{
&builtin_type_chill_bool,
&builtin_type_chill_char,
@@ -608,6 +629,7 @@ const struct language_defn chill_language_defn = {
evaluate_subexp_chill,
chill_printchar, /* print a character constant */
chill_printstr, /* function to print a string constant */
+ NULL, /* Function to print a single char */
chill_create_fundamental_type,/* Create fundamental type in this language */
chill_print_type, /* Print a type using appropriate syntax */
chill_val_print, /* Print a value using appropriate syntax */
diff --git a/contrib/gdb/gdb/ch-lang.h b/contrib/gdb/gdb/ch-lang.h
index f09a35b..6525c30 100644
--- a/contrib/gdb/gdb/ch-lang.h
+++ b/contrib/gdb/gdb/ch-lang.h
@@ -31,9 +31,12 @@ extern void /* Defined in ch-typeprint.c */
chill_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
extern int
-chill_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
+chill_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *, int, int,
int, enum val_prettyprint));
extern int
chill_value_print PARAMS ((struct value *, GDB_FILE *,
int, enum val_prettyprint));
+
+extern LONGEST
+type_lower_upper PARAMS ((enum exp_opcode, struct type *, struct type **));
diff --git a/contrib/gdb/gdb/ch-valprint.c b/contrib/gdb/gdb/ch-valprint.c
index de66d46..663ba64 100644
--- a/contrib/gdb/gdb/ch-valprint.c
+++ b/contrib/gdb/gdb/ch-valprint.c
@@ -36,6 +36,13 @@ static void
chill_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int,
enum val_prettyprint, struct type **));
+static void
+chill_print_type_scalar PARAMS ((struct type *, LONGEST, GDB_FILE *));
+
+static void
+chill_val_print_array_elements PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *,
+ int, int, int, enum val_prettyprint));
+
/* Print integral scalar data VAL, of type TYPE, onto stdio stream STREAM.
Used to print data from type structures in a specified type. For example,
@@ -43,7 +50,7 @@ chill_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int,
allows the ranges to be printed in their "natural" form rather than as
decimal integer values. */
-void
+static void
chill_print_type_scalar (type, val, stream)
struct type *type;
LONGEST val;
@@ -154,7 +161,7 @@ chill_val_print_array_elements (type, valaddr, address, stream,
chill_print_type_scalar (index_type, low_bound + i + reps - 1,
stream);
fputs_filtered ("): ", stream);
- val_print (elttype, valaddr + i * eltlen, 0, stream, format,
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
deref_ref, recurse + 1, pretty);
i = rep1 - 1;
@@ -163,7 +170,7 @@ chill_val_print_array_elements (type, valaddr, address, stream,
else
{
fputs_filtered ("): ", stream);
- val_print (elttype, valaddr + i * eltlen, 0, stream, format,
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
deref_ref, recurse + 1, pretty);
annotate_elt ();
things_printed++;
@@ -176,49 +183,6 @@ chill_val_print_array_elements (type, valaddr, address, stream,
}
}
-/* In certain cases it could happen, that an array type doesn't
- have a length (this have to do with seizing). The reason is
- shown in the following stabs:
-
- .stabs "m_x:Tt81=s36i:1,0,32;ar:82=ar80;0;1;83=xsm_struct:,32,256;;",128,0,25,0
-
- .stabs "m_struct:Tt83=s16f1:9,0,16;f2:85=*84,32,32;f3:84,64,64;;",128,0,10,0
-
- When processing t81, the array ar80 doesn't have a length, cause
- struct m_struct is specified extern at thse moment. Afterwards m_struct
- gets specified and updated, but not the surrounding type.
-
- So we walk through array's till we find a type with a length and
- calculate the array length.
-
- FIXME: Where may this happen too ?
- */
-
-static void
-calculate_array_length (type)
- struct type *type;
-{
- struct type *target_type;
- struct type *range_type;
- LONGEST lower_bound, upper_bound;
-
- if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
- /* not an array, stop processing */
- return;
-
- target_type = TYPE_TARGET_TYPE (type);
- range_type = TYPE_FIELD_TYPE (type, 0);
- lower_bound = TYPE_FIELD_BITPOS (range_type, 0);
- upper_bound = TYPE_FIELD_BITPOS (range_type, 1);
-
- if (TYPE_LENGTH (target_type) == 0 &&
- TYPE_CODE (target_type) == TYPE_CODE_ARRAY)
- /* we've got another array */
- calculate_array_length (target_type);
-
- TYPE_LENGTH (type) = (upper_bound - lower_bound + 1) * TYPE_LENGTH (target_type);
-}
-
/* Print data of type TYPE located at VALADDR (within GDB), which came from
the inferior at address ADDRESS, onto stdio stream STREAM according to
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
@@ -233,10 +197,11 @@ calculate_array_length (type)
The PRETTY parameter controls prettyprinting. */
int
-chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
- pretty)
+chill_val_print (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -254,10 +219,6 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
- if (TYPE_LENGTH (type) == 0)
- /* see comment function calculate_array_length */
- calculate_array_length (type);
-
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
{
if (prettyprint_arrays)
@@ -369,9 +330,8 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
&& /* If print_max is UINT_MAX, the alloca below will fail.
In that case don't try to print the string. */
print_max < UINT_MAX)
- {
- i = val_print_string (addr, 0, stream);
- }
+ i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
+
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return (i + (print_max && i != print_max));
@@ -379,7 +339,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
case TYPE_CODE_STRING:
i = TYPE_LENGTH (type);
- LA_PRINT_STRING (stream, valaddr, i, 0);
+ LA_PRINT_STRING (stream, valaddr, i, 1, 0);
/* Return number of characters printed, plus one for the terminating
null if we have "reached the end". */
return (i + (print_max && i != print_max));
@@ -429,7 +389,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
if (need_comma)
fputs_filtered (", ", stream);
- chill_print_type_scalar (range, i, stream);
+ chill_print_type_scalar (range, (LONGEST) i, stream);
need_comma = 1;
/* Look for a continuous range of true elements. */
@@ -440,7 +400,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
while (i+1 <= high_bound
&& value_bit_index (type, valaddr, ++i))
j = i;
- chill_print_type_scalar (range, j, stream);
+ chill_print_type_scalar (range, (LONGEST) j, stream);
}
}
}
@@ -462,13 +422,17 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
switch (TYPE_CODE (inner))
{
case TYPE_CODE_STRING:
- if (length > TYPE_LENGTH (type))
+ if (length > TYPE_LENGTH (type) - 2)
{
fprintf_filtered (stream,
- "<dynamic length %ld > static length %d>",
+ "<dynamic length %ld > static length %d> *invalid*",
length, TYPE_LENGTH (type));
+
+ /* Don't print the string; doing so might produce a
+ segfault. */
+ return length;
}
- LA_PRINT_STRING (stream, data_addr, length, 0);
+ LA_PRINT_STRING (stream, data_addr, length, 1, 0);
return length;
default:
break;
@@ -499,9 +463,11 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
value_at
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
- valaddr));
+ valaddr),
+ NULL);
val_print (VALUE_TYPE (deref_val),
VALUE_CONTENTS (deref_val),
+ 0,
VALUE_ADDRESS (deref_val), stream, format,
deref_ref, recurse + 1, pretty);
}
@@ -511,13 +477,13 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
break;
case TYPE_CODE_ENUM:
- c_val_print (type, valaddr, address, stream, format,
+ c_val_print (type, valaddr, 0, address, stream, format,
deref_ref, recurse, pretty);
break;
case TYPE_CODE_RANGE:
if (TYPE_TARGET_TYPE (type))
- chill_val_print (TYPE_TARGET_TYPE (type), valaddr, address, stream,
+ chill_val_print (TYPE_TARGET_TYPE (type), valaddr, 0, address, stream,
format, deref_ref, recurse, pretty);
break;
@@ -529,7 +495,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
default:
/* Let's defer printing to the C printer, rather than
print an error message. FIXME! */
- c_val_print (type, valaddr, address, stream, format,
+ c_val_print (type, valaddr, 0, address, stream, format,
deref_ref, recurse, pretty);
}
gdb_flush (stream);
@@ -598,13 +564,13 @@ chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i));
- chill_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
+ chill_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
stream, format, 0, recurse + 1, pretty);
}
else
{
chill_val_print (TYPE_FIELD_TYPE (type, i),
- valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
0, stream, format, 0, recurse + 1, pretty);
}
}
@@ -651,13 +617,13 @@ chill_value_print (val, stream, format, pretty)
fprintf_filtered (stream, ")");
}
fprintf_filtered (stream, "(");
- i = val_print (type, valaddr, VALUE_ADDRESS (val),
+ i = val_print (type, valaddr, 0, VALUE_ADDRESS (val),
stream, format, 1, 0, pretty);
fprintf_filtered (stream, ")");
return i;
}
}
- return (val_print (type, VALUE_CONTENTS (val),
+ return (val_print (type, VALUE_CONTENTS (val), 0,
VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
}
diff --git a/contrib/gdb/gdb/coff-solib.c b/contrib/gdb/gdb/coff-solib.c
index c0cfcf5..6be6869 100644
--- a/contrib/gdb/gdb/coff-solib.c
+++ b/contrib/gdb/gdb/coff-solib.c
@@ -94,7 +94,10 @@ coff_solib_add (arg_string, from_tty, target)
0, /* addr */
0, /* not mainline */
0, /* not mapped */
- 0); /* Not readnow */
+ 0, /* Not readnow */
+ 0, /* Not user loaded */
+ 1); /* Is a solib */
+
libsize -= len * 4;
lib += len * 4;
}
diff --git a/contrib/gdb/gdb/coff-solib.h b/contrib/gdb/gdb/coff-solib.h
index d154234..43375cc 100644
--- a/contrib/gdb/gdb/coff-solib.h
+++ b/contrib/gdb/gdb/coff-solib.h
@@ -49,6 +49,136 @@ coff_solib_add PARAMS ((char *, int, struct target_ops *));
extern void
coff_solib_create_inferior_hook PARAMS((void)); /* solib.c */
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.)
+
+ This functionality is presently not implemented for this target.
+ */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0)
+
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+(0)
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_RESTART() \
+ (0)
+
/* If we can't set a breakpoint, and it's in a shared library, just
disable it. */
diff --git a/contrib/gdb/gdb/coffread.c b/contrib/gdb/gdb/coffread.c
index bd2a700..340e77f 100644
--- a/contrib/gdb/gdb/coffread.c
+++ b/contrib/gdb/gdb/coffread.c
@@ -1,5 +1,5 @@
/* Read coff symbol tables and convert to internal format, for GDB.
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996
+ Copyright 1987, 88, 89, 90, 91, 92, 93, 94, 96, 97, 1998
Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
+#include "demangle.h"
#include "breakpoint.h"
#include "bfd.h"
@@ -129,6 +130,10 @@ static unsigned local_linesz;
static unsigned local_symesz;
static unsigned local_auxesz;
+/* This is set if this is a PE format file. */
+
+static int pe_file;
+
/* Chain of typedefs of pointers to empty struct/union types.
They are chained thru the SYMBOL_VALUE_CHAIN. */
@@ -245,7 +250,7 @@ static void coff_end_symtab PARAMS ((struct objfile *));
static void complete_symtab PARAMS ((char *, CORE_ADDR, unsigned int));
-static void coff_start_symtab PARAMS ((void));
+static void coff_start_symtab PARAMS ((char *));
static void coff_record_line PARAMS ((int, CORE_ADDR));
@@ -323,7 +328,7 @@ static int cs_to_section PARAMS ((struct coff_symbol *, struct objfile *));
struct find_targ_sec_arg {
int targ_index;
- int *resultp;
+ asection **resultp;
};
static void find_targ_sec PARAMS ((bfd *, asection *, void *));
@@ -335,15 +340,7 @@ static void find_targ_sec (abfd, sect, 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;
- }
+ *args->resultp = sect;
}
/* Return the section number (SECT_OFF_*) that CS points to. */
@@ -352,14 +349,47 @@ cs_to_section (cs, objfile)
struct coff_symbol *cs;
struct objfile *objfile;
{
- int off = SECT_OFF_TEXT;
+ asection *sect = NULL;
struct find_targ_sec_arg args;
+ int off = SECT_OFF_TEXT;
+
args.targ_index = cs->c_secnum;
- args.resultp = &off;
+ args.resultp = &sect;
bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ if (sect != NULL)
+ {
+ /* This is the section. Figure out what SECT_OFF_* code it is. */
+ if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+ off = SECT_OFF_TEXT;
+ else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+ off = SECT_OFF_DATA;
+ else
+ off = SECT_OFF_BSS;
+ }
return off;
}
+/* Return the address of the section of a COFF symbol. */
+
+static CORE_ADDR cs_section_address PARAMS ((struct coff_symbol *, bfd *));
+
+static CORE_ADDR
+cs_section_address (cs, abfd)
+ struct coff_symbol *cs;
+ bfd *abfd;
+{
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ CORE_ADDR addr = 0;
+
+ args.targ_index = cs->c_secnum;
+ args.resultp = &sect;
+ bfd_map_over_sections (abfd, find_targ_sec, &args);
+ if (sect != NULL)
+ addr = bfd_get_section_vma (objfile->obfd, sect);
+ return addr;
+}
+
/* 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.
@@ -439,19 +469,21 @@ coff_record_line (line, pc)
it indicates the start of data for one original source file. */
static void
-coff_start_symtab ()
+coff_start_symtab (name)
+ char *name;
{
start_symtab (
/* We fill in the filename later. start_symtab puts
this pointer into last_source_file and we put it in
subfiles->name, which end_symtab frees; that's why
it must be malloc'd. */
- savestring ("", 0),
+ savestring (name, strlen(name)),
/* We never know the directory name for COFF. */
NULL,
/* The start address is irrelevant, since we set
last_source_start_addr in coff_end_symtab. */
0);
+ record_debugformat ("COFF");
/* Initialize the source file line number information for this file. */
@@ -514,7 +546,6 @@ coff_end_symtab (objfile)
before (or because doing it now is simply an artifact of how this
file used to be written). */
subfiles->line_vector = line_vector;
- subfiles->name = last_source_file;
symtab = end_symtab (current_source_end_addr, objfile, 0);
@@ -537,10 +568,7 @@ record_minimal_symbol (name, address, type, objfile)
/* We don't want TDESC entry points in the minimal symbol table */
if (name[0] == '@') return;
- prim_record_minimal_symbol
- (obsavestring (name, strlen (name), &objfile->symbol_obstack),
- address, type,
- objfile);
+ prim_record_minimal_symbol (name, address, type, objfile);
}
/* coff_symfile_init ()
@@ -561,7 +589,7 @@ coff_symfile_init (objfile)
struct objfile *objfile;
{
/* Allocate struct to keep track of stab reading. */
- objfile->sym_stab_info = (PTR)
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
@@ -644,7 +672,7 @@ coff_symfile_read (objfile, section_offsets, mainline)
int stabstrsize;
info = (struct coff_symfile_info *) objfile -> sym_private;
- dbxinfo = (struct dbx_symfile_info *) objfile->sym_stab_info;
+ dbxinfo = objfile->sym_stab_info;
symfile_bfd = abfd; /* Kludge for swap routines */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
@@ -669,7 +697,15 @@ coff_symfile_read (objfile, section_offsets, mainline)
temp_sym = (char *) xmalloc
(cdata->local_symesz + cdata->local_auxesz);
temp_aux = temp_sym + cdata->local_symesz;
- back_to = make_cleanup (free_current_contents, &temp_sym);
+ back_to = make_cleanup ((make_cleanup_func) free_current_contents, &temp_sym);
+
+ /* We need to know whether this is a PE file, because in PE files,
+ unlike standard COFF files, symbol values are stored as offsets
+ from the section address, rather than as absolute addresses.
+ FIXME: We should use BFD to read the symbol table, and thus avoid
+ this problem. */
+ pe_file = strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0;
+
/* End of warning */
/* Read the line number table, all at once. */
@@ -677,7 +713,7 @@ coff_symfile_read (objfile, section_offsets, mainline)
info->max_lineno_offset = 0;
bfd_map_over_sections (abfd, find_linenos, (PTR) info);
- make_cleanup (free_linetab, 0);
+ make_cleanup ((make_cleanup_func) free_linetab, 0);
val = init_lineno (abfd, info->min_lineno_offset,
info->max_lineno_offset - info->min_lineno_offset);
if (val < 0)
@@ -685,13 +721,13 @@ coff_symfile_read (objfile, section_offsets, mainline)
/* Now read the string table, all at once. */
- make_cleanup (free_stringtab, 0);
+ make_cleanup ((make_cleanup_func) free_stringtab, 0);
val = init_stringtab (abfd, stringtab_offset);
if (val < 0)
error ("\"%s\": can't get string table", name);
init_minimal_symbol_collection ();
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
@@ -824,7 +860,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
xmalloc (type_vector_length * sizeof (struct type *));
memset (type_vector, 0, type_vector_length * sizeof (struct type *));
- coff_start_symtab ();
+ coff_start_symtab ("");
symnum = 0;
while (symnum < nsyms)
@@ -833,19 +869,12 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
read_one_sym (cs, &main_sym, &main_aux);
-#ifdef SEM
- temp_sem_val = cs->c_name[0] << 24 | cs->c_name[1] << 16 |
- cs->c_name[2] << 8 | cs->c_name[3];
- if (int_sem_val == temp_sem_val)
- last_coffsem = (int) strtol (cs->c_name+4, (char **) NULL, 10);
-#endif
-
if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
{
if (last_source_file)
coff_end_symtab (objfile);
- coff_start_symtab ();
+ coff_start_symtab ("_globals_");
complete_symtab ("_globals_", 0, 0);
/* done with all files, everything from here on out is globals */
}
@@ -896,12 +925,23 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
if (last_source_file)
{
coff_end_symtab (objfile);
- coff_start_symtab ();
+ coff_start_symtab (filestring);
}
in_source_file = 1;
break;
+ /* C_LABEL is used for labels and static functions. Including
+ it here allows gdb to see static functions when no debug
+ info is available. */
+ case C_LABEL:
+ /* However, labels within a function can make weird backtraces,
+ so filter them out (from phdm@macqel.be). */
+ if (within_function)
+ break;
case C_STAT:
+ case C_THUMBLABEL:
+ case C_THUMBSTAT:
+ case C_THUMBSTATFUNC:
if (cs->c_name[0] == '.')
{
if (STREQ (cs->c_name, ".text")) {
@@ -933,6 +973,8 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
that look like this. Ignore them. */
break;
/* fall in for static symbols that don't start with '.' */
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
case C_EXT:
{
/* Record it in the minimal symbols regardless of
@@ -959,13 +1001,16 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
/* The address has already been relocated; make sure that
objfile_relocate doesn't relocate it again. */
sec = -2;
- ms_type = cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
+ ms_type = cs->c_sclass == C_EXT
+ || cs->c_sclass == C_THUMBEXT ?
+ mst_bss : mst_file_bss;
}
else
{
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
- if (cs->c_sclass != C_STAT)
+ if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+ || cs->c_sclass == C_THUMBEXT)
tmpaddr += ANOFFSET (section_offsets, sec);
switch (sec)
@@ -973,15 +1018,23 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
case SECT_OFF_TEXT:
case SECT_OFF_RODATA:
ms_type =
- cs->c_sclass == C_STAT ? mst_file_text : mst_text;
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+ || cs->c_sclass == C_THUMBEXT ?
+ mst_text : mst_file_text;
+#ifdef SMASH_TEXT_ADDRESS
+ if (tmpaddr & 1) /* FIXME: delete this line */
+ SMASH_TEXT_ADDRESS (tmpaddr);
+#endif
break;
case SECT_OFF_DATA:
ms_type =
- cs->c_sclass == C_STAT ? mst_file_data : mst_data;
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+ mst_data : mst_file_data;
break;
case SECT_OFF_BSS:
ms_type =
- cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+ mst_data : mst_file_data;
break;
default:
ms_type = mst_unknown;
@@ -990,15 +1043,17 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
}
if (cs->c_name[0] != '@' /* Skip tdesc symbols */)
- prim_record_minimal_symbol_and_info
- (obsavestring (cs->c_name, strlen (cs->c_name),
- &objfile->symbol_obstack),
- tmpaddr,
- ms_type,
- NULL,
- sec,
- objfile);
-
+ {
+ struct minimal_symbol *msym;
+
+ msym = prim_record_minimal_symbol_and_info
+ (cs->c_name, tmpaddr, ms_type, (char *)cs->c_sclass, sec,
+ NULL, objfile);
+#ifdef COFF_MAKE_MSYMBOL_SPECIAL
+ if(msym)
+ COFF_MAKE_MSYMBOL_SPECIAL(cs->c_sclass, msym);
+#endif
+ }
if (SDB_TYPE (cs->c_type))
{
struct symbol *sym;
@@ -1177,7 +1232,40 @@ read_one_sym (cs, sym, aux)
if (!SDB_TYPE (cs->c_type))
cs->c_type = 0;
+#if 0
+ if (cs->c_sclass & 128)
+ printf("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
+#endif
+
symnum += 1 + cs->c_naux;
+
+ /* The PE file format stores symbol values as offsets within the
+ section, rather than as absolute addresses. We correct that
+ here, if the symbol has an appropriate storage class. FIXME: We
+ should use BFD to read the symbols, rather than duplicating the
+ work here. */
+ if (pe_file)
+ {
+ switch (cs->c_sclass)
+ {
+ case C_EXT:
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
+ case C_SECTION:
+ case C_NT_WEAK:
+ case C_STAT:
+ case C_THUMBSTAT:
+ case C_THUMBSTATFUNC:
+ case C_LABEL:
+ case C_THUMBLABEL:
+ case C_BLOCK:
+ case C_FCN:
+ case C_EFCN:
+ if (cs->c_secnum != 0)
+ cs->c_value += cs_section_address (cs, symfile_bfd);
+ break;
+ }
+ }
}
/* Support for string table handling */
@@ -1481,8 +1569,10 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
memset (sym, 0, sizeof (struct symbol));
name = cs->c_name;
name = EXTERNAL_NAME (name, objfile->obfd);
- SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name,
- strlen (name));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+ SYMBOL_LANGUAGE (sym) = language_auto;
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
/* default assumptions */
SYMBOL_VALUE (sym) = cs->c_value;
@@ -1496,9 +1586,11 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
lookup_function_type (decode_function_type (cs, cs->c_type, aux));
SYMBOL_CLASS (sym) = LOC_BLOCK;
- if (cs->c_sclass == C_STAT)
+ if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
+ || cs->c_sclass == C_THUMBSTATFUNC)
add_symbol_to_list (sym, &file_symbols);
- else if (cs->c_sclass == C_EXT)
+ else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+ || cs->c_sclass == C_THUMBEXTFUNC)
add_symbol_to_list (sym, &global_symbols);
}
else
@@ -1514,6 +1606,8 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
add_symbol_to_list (sym, &local_symbols);
break;
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
case C_EXT:
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
@@ -1521,6 +1615,8 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
add_symbol_to_list (sym, &global_symbols);
break;
+ case C_THUMBSTAT:
+ case C_THUMBSTATFUNC:
case C_STAT:
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
@@ -1544,6 +1640,7 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
add_symbol_to_list (sym, &local_symbols);
break;
+ case C_THUMBLABEL:
case C_LABEL:
break;
@@ -1817,7 +1914,11 @@ decode_base_type (cs, c_type, aux)
return lookup_fundamental_type (current_objfile, FT_INTEGER);
case T_LONG:
- return lookup_fundamental_type (current_objfile, FT_LONG);
+ if (cs->c_sclass == C_FIELD
+ && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+ return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+ else
+ return lookup_fundamental_type (current_objfile, FT_LONG);
case T_FLOAT:
return lookup_fundamental_type (current_objfile, FT_FLOAT);
@@ -1913,7 +2014,11 @@ decode_base_type (cs, c_type, aux)
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
case T_ULONG:
- return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+ if (cs->c_sclass == C_FIELD
+ && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+ else
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
}
complain (&unexpected_type_complaint, cs->c_name);
return lookup_fundamental_type (current_objfile, FT_VOID);
@@ -1974,9 +2079,9 @@ coff_read_struct_type (index, length, lastsym)
obsavestring (name,
strlen (name),
&current_objfile->symbol_obstack);
- list->field.type = decode_type (ms, ms->c_type, &sub_aux);
- list->field.bitpos = 8 * ms->c_value;
- list->field.bitsize = 0;
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+ FIELD_BITPOS (list->field) = 8 * ms->c_value;
+ FIELD_BITSIZE (list->field) = 0;
nfields++;
break;
@@ -1992,9 +2097,9 @@ coff_read_struct_type (index, length, lastsym)
obsavestring (name,
strlen (name),
&current_objfile->symbol_obstack);
- list->field.type = decode_type (ms, ms->c_type, &sub_aux);
- list->field.bitpos = ms->c_value;
- list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size;
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+ FIELD_BITPOS (list->field) = ms->c_value;
+ FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
nfields++;
break;
@@ -2041,6 +2146,7 @@ coff_read_enum_type (index, length, lastsym)
int o_nsyms;
register int n;
char *name;
+ int unsigned_enum = 1;
type = coff_alloc_type (index);
if (within_function)
@@ -2113,35 +2219,19 @@ coff_read_enum_type (index, length, lastsym)
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
- TYPE_FIELD_VALUE (type, n) = 0;
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ if (SYMBOL_VALUE (xsym) < 0)
+ unsigned_enum = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
}
if (syms == osyms)
break;
}
- return type;
-}
+ if (unsigned_enum)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
-struct section_offsets *
-coff_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets)
- + sizeof (section_offsets->offsets) * SECT_OFF_MAX);
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- ANOFFSET (section_offsets, i) = addr;
-
- return section_offsets;
+ return type;
}
/* Register our ability to parse symbols for coff BFD files. */
@@ -2153,7 +2243,8 @@ static struct sym_fns coff_sym_fns =
coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
coff_symfile_read, /* sym_read: read a symbol file into symtab */
coff_symfile_finish, /* sym_finish: finished with file, cleanup */
- coff_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ default_symfile_offsets,
+ /* sym_offsets: xlate external to internal form */
NULL /* next: pointer to next struct sym_fns */
};
diff --git a/contrib/gdb/gdb/command.c b/contrib/gdb/gdb/command.c
index a5477dd..58af567 100644
--- a/contrib/gdb/gdb/command.c
+++ b/contrib/gdb/gdb/command.c
@@ -1,5 +1,5 @@
/* Handle lists of commands, their decoding and documentation, for GDB.
- Copyright 1986, 1989, 1990, 1991 Free Software Foundation, Inc.
+ Copyright 1986, 1989, 1990, 1991, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,35 +19,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcmd.h"
#include "symtab.h"
#include "value.h"
-#include "wait.h"
#include <ctype.h>
#include "gdb_string.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_WAIT_H
+# include <wait.h>
+#else
+# ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+# endif
+#endif
+
+#include "wait.h"
+
/* Prototypes for local functions */
-static void
-undef_cmd_error PARAMS ((char *, char *));
+static void undef_cmd_error PARAMS ((char *, char *));
-static void
-show_user PARAMS ((char *, int));
+static void show_user PARAMS ((char *, int));
-static void
-show_user_1 PARAMS ((struct cmd_list_element *, GDB_FILE *));
+static void show_user_1 PARAMS ((struct cmd_list_element *, GDB_FILE *));
-static void
-make_command PARAMS ((char *, int));
+static void make_command PARAMS ((char *, int));
-static void
-shell_escape PARAMS ((char *, int));
+static void shell_escape PARAMS ((char *, int));
-static int
-parse_binary_operation PARAMS ((char *));
+static int parse_binary_operation PARAMS ((char *));
-static void
-print_doc_line PARAMS ((GDB_FILE *, char *));
+static void print_doc_line PARAMS ((GDB_FILE *, char *));
+
+void _initialize_command PARAMS ((void));
/* Add element named NAME.
CLASS is the top level category into which commands are broken down
@@ -61,7 +65,10 @@ print_doc_line PARAMS ((GDB_FILE *, char *));
It should start with ? for a command that is an abbreviation
or with * for a command that most users don't need to know about.
- Add this command to command list *LIST. */
+ Add this command to command list *LIST.
+
+ Returns a pointer to the added command (not necessarily the head
+ of *LIST). */
struct cmd_list_element *
add_cmd (name, class, fun, doc, list)
@@ -73,9 +80,26 @@ add_cmd (name, class, fun, doc, list)
{
register struct cmd_list_element *c
= (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
+ struct cmd_list_element *p;
delete_cmd (name, list);
- c->next = *list;
+
+ if (*list == NULL || STRCMP ((*list)->name, name) >= 0)
+ {
+ c->next = *list;
+ *list = c;
+ }
+ else
+ {
+ p = *list;
+ while (p->next && STRCMP (p->next->name, name) <= 0)
+ {
+ p = p->next;
+ }
+ c->next = p->next;
+ p->next = c;
+ }
+
c->name = name;
c->class = class;
c->function.cfunc = fun;
@@ -93,7 +117,7 @@ add_cmd (name, class, fun, doc, list)
c->user_commands = NULL;
c->hookee = NULL;
c->cmd_pointer = NULL;
- *list = c;
+
return c;
}
@@ -261,14 +285,14 @@ add_set_enum_cmd (name, class, enumlist, var, doc, list)
{
struct cmd_list_element *c
= add_set_cmd (name, class, var_enum, var, doc, list);
-
c->enums = enumlist;
return c;
}
/* Where SETCMD has already been added, add the corresponding show
- command to LIST and return a pointer to it. */
+ command to LIST and return a pointer to the added command (not
+ necessarily the head of LIST). */
struct cmd_list_element *
add_show_from_set (setcmd, list)
struct cmd_list_element *setcmd;
@@ -276,6 +300,7 @@ add_show_from_set (setcmd, list)
{
struct cmd_list_element *showcmd =
(struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
+ struct cmd_list_element *p;
memcpy (showcmd, setcmd, sizeof (struct cmd_list_element));
delete_cmd (showcmd->name, list);
@@ -288,8 +313,22 @@ add_show_from_set (setcmd, list)
else
fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
- showcmd->next = *list;
- *list = showcmd;
+ if (*list == NULL || STRCMP ((*list)->name, showcmd->name) >= 0)
+ {
+ showcmd->next = *list;
+ *list = showcmd;
+ }
+ else
+ {
+ p = *list;
+ while (p->next && STRCMP (p->next->name, showcmd->name) <= 0)
+ {
+ p = p->next;
+ }
+ showcmd->next = p->next;
+ p->next = showcmd;
+ }
+
return showcmd;
}
@@ -520,7 +559,38 @@ help_cmd_list (list, class, prefix, recurse, stream)
help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
}
}
+
+/* Search the input clist for 'command'. Return the command if
+ found (or NULL if not), and return the number of commands
+ found in nfound */
+
+static struct cmd_list_element *
+find_cmd(command, len, clist, ignore_help_classes, nfound)
+ char *command;
+ struct cmd_list_element *clist;
+ int ignore_help_classes;
+ int *nfound;
+{
+ struct cmd_list_element *found, *c;
+
+ found = (struct cmd_list_element *)NULL;
+ *nfound = 0;
+ for (c = clist; c; c = c->next)
+ if (!strncmp (command, c->name, len)
+ && (!ignore_help_classes || c->function.cfunc))
+ {
+ found = c;
+ (*nfound)++;
+ if (c->name[len] == '\0')
+ {
+ *nfound = 1;
+ break;
+ }
+ }
+ return found;
+}
+
/* This routine takes a line of TEXT and a CLIST in which to start the
lookup. When it returns it will have incremented the text pointer past
the section of text it matched, set *RESULT_LIST to point to the list in
@@ -574,7 +644,10 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
so that "set args_foo()" doesn't get interpreted as
"set args _foo()". */
for (p = *text;
- *p && (isalnum(*p) || *p == '-' || *p == '_');
+ *p && (isalnum(*p) || *p == '-' || *p == '_' ||
+ (tui_version &&
+ (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
+ (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
p++)
;
@@ -585,32 +658,35 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
len = p - *text;
/* *text and p now bracket the first command word to lookup (and
- it's length is len). We copy this into a local temporary,
- converting to lower case as we go. */
+ it's length is len). We copy this into a local temporary */
+
command = (char *) alloca (len + 1);
for (tmp = 0; tmp < len; tmp++)
{
char x = (*text)[tmp];
- command[tmp] = isupper(x) ? tolower(x) : x;
+ command[tmp] = x;
}
command[len] = '\0';
/* Look it up. */
found = 0;
nfound = 0;
- for (c = clist; c; c = c->next)
- if (!strncmp (command, c->name, len)
- && (!ignore_help_classes || c->function.cfunc))
- {
- found = c;
- nfound++;
- if (c->name[len] == '\0')
- {
- nfound = 1;
- break;
- }
- }
+ found = find_cmd(command, len, clist, ignore_help_classes, &nfound);
+
+ /*
+ ** We didn't find the command in the entered case, so lower case it
+ ** and search again.
+ */
+ if (!found || nfound == 0)
+ {
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = command[tmp];
+ command[tmp] = isupper(x) ? tolower(x) : x;
+ }
+ found = find_cmd(command, len, clist, ignore_help_classes, &nfound);
+ }
/* If nothing matches, we have a simple failure. */
if (nfound == 0)
@@ -649,7 +725,7 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
}
else if (c == (struct cmd_list_element *) -1)
{
- /* We've gotten this far properley, but the next step
+ /* We've gotten this far properly, but the next step
is ambiguous. We need to set the result list to the best
we've found (if an inferior hasn't already set it). */
if (result_list != NULL)
@@ -739,7 +815,7 @@ lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes)
q = (char *) alloca (p - *line + 1);
strncpy (q, *line, p - *line);
- q[p-*line] = '\0';
+ q[p - *line] = '\0';
undef_cmd_error (cmdtype, q);
}
}
@@ -1230,11 +1306,26 @@ do_setshow_command (arg, from_tty, c)
int i;
int len;
int nmatches;
- char *match;
+ char *match = NULL;
char *p;
- p = strchr (arg, ' ');
+ /* if no argument was supplied, print an informative error message */
+ if (arg == NULL)
+ {
+ char msg[1024];
+ strcpy (msg, "Requires an argument. Valid arguments are ");
+ for (i = 0; c->enums[i]; i++)
+ {
+ if (i != 0)
+ strcat (msg, ", ");
+ strcat (msg, c->enums[i]);
+ }
+ strcat (msg, ".");
+ error (msg);
+ }
+ p = strchr (arg, ' ');
+
if (p)
len = p - arg;
else
@@ -1273,9 +1364,11 @@ do_setshow_command (arg, from_tty, c)
case var_string:
{
unsigned char *p;
+
fputs_filtered ("\"", gdb_stdout);
- for (p = *(unsigned char **) c->var; *p != '\0'; p++)
- gdb_printchar (*p, gdb_stdout, '"');
+ if (*(unsigned char **)c->var)
+ for (p = *(unsigned char **) c->var; *p != '\0'; p++)
+ gdb_printchar (*p, gdb_stdout, '"');
fputs_filtered ("\"", gdb_stdout);
}
break;
@@ -1283,7 +1376,8 @@ do_setshow_command (arg, from_tty, c)
case var_filename:
case var_enum:
fputs_filtered ("\"", gdb_stdout);
- fputs_filtered (*(char **) c->var, gdb_stdout);
+ if (*(char **)c->var)
+ fputs_filtered (*(char **) c->var, gdb_stdout);
fputs_filtered ("\"", gdb_stdout);
break;
case var_boolean:
@@ -1457,6 +1551,10 @@ _initialize_command ()
add_com ("shell", class_support, shell_escape,
"Execute the rest of the line as a shell command. \n\
With no arguments, run an inferior shell.");
+
+ if (xdb_commands)
+ add_com_alias("!", "shell", class_support, 0);
+
add_com ("make", class_support, make_command,
"Run the ``make'' program using the rest of the line as arguments.");
add_cmd ("user", no_class, show_user,
diff --git a/contrib/gdb/gdb/complaints.c b/contrib/gdb/gdb/complaints.c
index 9db8b4a..e38038d 100644
--- a/contrib/gdb/gdb/complaints.c
+++ b/contrib/gdb/gdb/complaints.c
@@ -20,11 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "complaints.h"
#include "gdbcmd.h"
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
/* Structure to manage complaints about symbol file contents. */
diff --git a/contrib/gdb/gdb/complaints.h b/contrib/gdb/gdb/complaints.h
index 022bc19..4b9b5de 100644
--- a/contrib/gdb/gdb/complaints.h
+++ b/contrib/gdb/gdb/complaints.h
@@ -18,6 +18,10 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#if !defined (COMPLAINTS_H)
+#define COMPLAINTS_H
+
+
/* Support for complaining about things in the symbol file that aren't
catastrophic.
@@ -44,3 +48,6 @@ complain PARAMS ((struct complaint *, ...));
extern void
clear_complaints PARAMS ((int, int));
+
+
+#endif /* !defined (COMPLAINTS_H) */
diff --git a/contrib/gdb/gdb/config.in b/contrib/gdb/gdb/config.in
index a5c51ad..d6bfe94 100644
--- a/contrib/gdb/gdb/config.in
+++ b/contrib/gdb/gdb/config.in
@@ -1,5 +1,17 @@
/* config.in. Generated automatically from configure.in by autoheader. */
+/* Whether malloc must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Whether realloc must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_REALLOC
+
+/* Whether free must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_FREE
+
+/* Whether strerror must be declared even if <string.h> is included. */
+#undef NEED_DECLARATION_STRERROR
+
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
@@ -7,48 +19,180 @@
#undef _ALL_SOURCE
#endif
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
/* Define if the `long double' type works. */
#undef HAVE_LONG_DOUBLE
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
-/* Define if on MINIX. */
-#undef _MINIX
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
-/* Define if the system does not provide POSIX.1 features except
- with this defined. */
-#undef _POSIX_1_SOURCE
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
-/* Define if fpregset_t type is available. */
-#undef HAVE_FPREGSET_T
+/* Define if ioctl argument PIOCSET is available. */
+#undef HAVE_PROCFS_PIOCSET
-/* Define if gregset_t type is available. */
-#undef HAVE_GREGSET_T
+/* /proc PID entries are directories containing the files
+ ctl as map status */
+#undef HAVE_MULTIPLE_PROC_FDS
+
+/* Define if the `long long' type works. */
+#undef CC_HAS_LONG_LONG
+
+/* Define if the "ll" format works to print long long ints. */
+#undef PRINTF_HAS_LONG_LONG
/* Define if the "%Lg" format works to print long doubles. */
#undef PRINTF_HAS_LONG_DOUBLE
+/* Define if the "%Lg" format works to scan long doubles. */
+#undef SCANF_HAS_LONG_DOUBLE
+
+/* Define if using Solaris thread debugging. */
+#undef HAVE_THREAD_DB_LIB
+
+/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#undef sys_quotactl
+
+/* Define if you have HPUX threads */
+#undef HAVE_HPUX_THREAD_SUPPORT
+
+/* Define if you want to use the memory mapped malloc package (mmalloc). */
+#undef USE_MMALLOC
+
+/* Define if the runtime uses a routine from mmalloc before gdb has a chance
+ to initialize mmalloc, and we want to force checking to be used anyway.
+ This may cause spurious memory corruption messages if the runtime tries
+ to explicitly deallocate that memory when gdb calls exit. */
+#undef MMCHECK_FORCE
+
+/* Define if you want to use the full-screen terminal user interface. */
+#undef TUI
+
+/* Define if <proc_service.h> on solaris uses int instead of
+ size_t, and assorted other type changes. */
+#undef PROC_SERVICE_IS_OLD
+
+/* Set to true if the save_state_t structure is present */
+#define HAVE_STRUCT_SAVE_STATE_T 0
+
+/* Set to true if the save_state_t structure has the ss_wide member */
+#define HAVE_STRUCT_MEMBER_SS_WIDE 0
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the bcopy function. */
+#undef HAVE_BCOPY
+
+/* Define if you have the btowc function. */
+#undef HAVE_BTOWC
+
+/* Define if you have the bzero function. */
+#undef HAVE_BZERO
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
+/* Define if you have the isascii function. */
+#undef HAVE_ISASCII
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
/* Define if you have the sbrk function. */
#undef HAVE_SBRK
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
/* Define if you have the setpgid function. */
#undef HAVE_SETPGID
-/* Define if you have the valloc function. */
-#undef HAVE_VALLOC
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <asm/debugreg.h> header file. */
+#undef HAVE_ASM_DEBUGREG_H
+
+/* Define if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
/* Define if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
@@ -59,24 +203,57 @@
/* Define if you have the <link.h> header file. */
#undef HAVE_LINK_H
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <objlist.h> header file. */
+#undef HAVE_OBJLIST_H
+
+/* Define if you have the <ptrace.h> header file. */
+#undef HAVE_PTRACE_H
+
/* Define if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H
/* Define if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
-/* Define if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
+/* Define if you have the <sys/debugreg.h> header file. */
+#undef HAVE_SYS_DEBUGREG_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/procfs.h> header file. */
#undef HAVE_SYS_PROCFS_H
+/* Define if you have the <sys/ptrace.h> header file. */
+#undef HAVE_SYS_PTRACE_H
+
+/* Define if you have the <sys/reg.h> header file. */
+#undef HAVE_SYS_REG_H
+
+/* Define if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
/* Define if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
@@ -86,5 +263,63 @@
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Define if you have the <wait.h> header file. */
+#undef HAVE_WAIT_H
+
+/* Define if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define if you have the <wctype.h> header file. */
+#undef HAVE_WCTYPE_H
+
/* Define if you have the dl library (-ldl). */
#undef HAVE_LIBDL
+
+/* Define if you have the m library (-lm). */
+#undef HAVE_LIBM
+
+/* Define if you have the w library (-lw). */
+#undef HAVE_LIBW
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define if malloc is not declared in system header files. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Define if realloc is not declared in system header files. */
+#undef NEED_DECLARATION_REALLOC
+
+/* Define if free is not declared in system header files. */
+#undef NEED_DECLARATION_FREE
+
+/* Define if strerror is not declared in system header files. */
+#undef NEED_DECLARATION_STRERROR
+
+/* Define if strdup is not declared in system header files. */
+#undef NEED_DECLARATION_STRDUP
+
+/* Define if <sys/procfs.h> has pstatus_t. */
+#undef HAVE_PSTATUS_T
+
+/* Define if <sys/procfs.h> has prrun_t. */
+#undef HAVE_PRRUN_T
+
+/* Define if <sys/procfs.h> has gregset_t. */
+#undef HAVE_GREGSET_T
+
+/* Define if <sys/procfs.h> has fpregset_t. */
+#undef HAVE_FPREGSET_T
+
diff --git a/contrib/gdb/gdb/config/alpha/alpha-linux.mh b/contrib/gdb/gdb/config/alpha/alpha-linux.mh
new file mode 100644
index 0000000..aa4a069
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/alpha-linux.mh
@@ -0,0 +1,9 @@
+# Host: Little-endian Alpha running Linux
+XDEPFILES= ser-tcp.o
+XM_FILE= xm-alphalinux.h
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o core-regset.o alpha-nat.o \
+ fork-child.o solib.o
+
+MMALLOC =
+MMALLOC_CFLAGS = -DNO_MMALLOC
diff --git a/contrib/gdb/gdb/config/alpha/alpha-linux.mt b/contrib/gdb/gdb/config/alpha/alpha-linux.mt
new file mode 100644
index 0000000..7789252
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/alpha-linux.mt
@@ -0,0 +1,3 @@
+# Target: Little-endian Alpha
+TDEPFILES= alpha-tdep.o
+TM_FILE= tm-alphalinux.h
diff --git a/contrib/gdb/gdb/config/alpha/alpha-osf1.mh b/contrib/gdb/gdb/config/alpha/alpha-osf1.mh
new file mode 100644
index 0000000..6ed0f95
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/alpha-osf1.mh
@@ -0,0 +1,5 @@
+# Host: Little-endian Alpha running OSF/1-1.x
+XDEPFILES=
+XM_FILE= xm-alphaosf.h
+NAT_FILE= nm-osf.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o fork-child.o osfsolib.o
diff --git a/contrib/gdb/gdb/config/alpha/alpha-osf1.mt b/contrib/gdb/gdb/config/alpha/alpha-osf1.mt
new file mode 100644
index 0000000..98f87c1
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/alpha-osf1.mt
@@ -0,0 +1,3 @@
+# Target: Little-endian Alpha
+TDEPFILES= alpha-tdep.o
+TM_FILE= tm-alpha.h
diff --git a/contrib/gdb/gdb/config/alpha/alpha-osf2.mh b/contrib/gdb/gdb/config/alpha/alpha-osf2.mh
new file mode 100644
index 0000000..569b6fd
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/alpha-osf2.mh
@@ -0,0 +1,5 @@
+# Host: Little-endian Alpha running OSF/1-2.x using procfs
+XDEPFILES=
+XM_FILE= xm-alphaosf.h
+NAT_FILE= nm-osf2.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o fork-child.o osfsolib.o procfs.o
diff --git a/contrib/gdb/gdb/config/alpha/alpha-osf3.mh b/contrib/gdb/gdb/config/alpha/alpha-osf3.mh
new file mode 100644
index 0000000..4997531
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/alpha-osf3.mh
@@ -0,0 +1,5 @@
+# Host: Little-endian Alpha running OSF/1-3.x and higher using procfs
+XDEPFILES=
+XM_FILE= xm-alphaosf.h
+NAT_FILE= nm-osf3.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o fork-child.o osfsolib.o procfs.o
diff --git a/contrib/gdb/gdb/config/alpha/nm-linux.h b/contrib/gdb/gdb/config/alpha/nm-linux.h
new file mode 100644
index 0000000..eedb1a9
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/nm-linux.h
@@ -0,0 +1,66 @@
+/* Native definitions for alpha running Linux.
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ argument regs. A0_REGNUM points at 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 */
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+extern int
+get_longjmp_target PARAMS ((CORE_ADDR *));
+
+/* Tell gdb that we can attach and detach other processes */
+#define ATTACH_DETACH
+
+/* ptrace register ``addresses'' are absolute. */
+
+#define U_REGS_OFFSET 0
+
+#define PTRACE_ARG3_TYPE long
+
+/* ptrace transfers longs, the ptrace man page is lying. */
+
+#define PTRACE_XFER_TYPE long
+
+/* The alpha does not step over a breakpoint, the manpage is lying again. */
+
+#define CANNOT_STEP_BREAKPOINT
+
+/* Linux has shared libraries. */
+
+#define GDB_TARGET_HAS_SHARED_LIBS
+
+/* Support for shared libraries. */
+
+#include "solib.h"
+
+#ifdef __ELF__
+#define SVR4_SHARED_LIBS
+#define TARGET_ELF64
+#endif
+
+/* This is a lie. It's actually in stdio.h. */
+
+#define PSIGNAL_IN_SIGNAL_H
+
+/* Given a pointer to either a gregset_t or fpregset_t, return a
+ pointer to the first register. */
+#define ALPHA_REGSET_BASE(regsetp) ((long *) (regsetp))
diff --git a/contrib/gdb/gdb/config/alpha/nm-osf.h b/contrib/gdb/gdb/config/alpha/nm-osf.h
new file mode 100644
index 0000000..e06140d
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/nm-osf.h
@@ -0,0 +1,56 @@
+/* Native definitions for alpha running OSF/1.
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ argument regs. A0_REGNUM points at 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 */
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+extern int
+get_longjmp_target PARAMS ((CORE_ADDR *));
+
+/* ptrace register ``addresses'' are absolute. */
+
+#define U_REGS_OFFSET 0
+
+/* FIXME: Shouldn't the default definition in inferior.h be int* ? */
+
+#define PTRACE_ARG3_TYPE int*
+
+/* ptrace transfers longs, the ptrace man page is lying. */
+
+#define PTRACE_XFER_TYPE long
+
+/* The alpha does not step over a breakpoint, the manpage is lying again. */
+
+#define CANNOT_STEP_BREAKPOINT
+
+/* OSF/1 has shared libraries. */
+
+#define GDB_TARGET_HAS_SHARED_LIBS
+
+/* Support for shared libraries. */
+
+#include "solib.h"
+
+/* Given a pointer to either a gregset_t or fpregset_t, return a
+ pointer to the first register. */
+#define ALPHA_REGSET_BASE(regsetp) ((regsetp)->regs)
diff --git a/contrib/gdb/gdb/config/alpha/nm-osf2.h b/contrib/gdb/gdb/config/alpha/nm-osf2.h
new file mode 100644
index 0000000..01725ef
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/nm-osf2.h
@@ -0,0 +1,54 @@
+/* Native definitions for alpha running OSF/1-2.x, using procfs.
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Get generic OSF/1 definitions. */
+#include "alpha/nm-osf.h"
+
+/* OSF/1-2.x has optional /proc support, try to use it instead of ptrace. */
+#define USE_PROC_FS
+#define HAVE_OPTIONAL_PROC_FS
+
+/* OSF/1 doesn't provide the standard fault definitions, so don't use them. */
+#define FAULTED_USE_SIGINFO
+
+/* Don't trace faults under OSF/1, rely on the posting of the appropriate
+ signal if fault tracing is disabled.
+ Tracing T_IFAULT under Alpha OSF/1 causes a `floating point enable'
+ fault from which we cannot continue (except by disabling the
+ tracing).
+ And as OSF/1 doesn't provide the standard fault definitions, the
+ mapping of faults to appropriate signals in procfs_wait is difficult. */
+#define PROCFS_DONT_TRACE_FAULTS
+
+/* Work around some peculiarities in the OSF/1 procfs implementation. */
+#define PROCFS_SIGPEND_OFFSET
+#define PROCFS_NEED_PIOCSSIG_FOR_KILL
+#define PROCFS_DONT_PIOCSSIG_CURSIG
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size PARAMS ((void));
+
+/* poll() doesn't seem to work properly for /proc in this version of the OS.
+ If we only specify POLLPRI, things hang. It seems to get better when we set
+ POLLOUT, but that always returns POLLNVAL!!! Also, POLLOUT causes problems
+ on other OSes. */
+
+#define LOSING_POLL
diff --git a/contrib/gdb/gdb/config/alpha/nm-osf3.h b/contrib/gdb/gdb/config/alpha/nm-osf3.h
new file mode 100644
index 0000000..a1871a6
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/nm-osf3.h
@@ -0,0 +1,26 @@
+/* Native definitions for alpha running OSF/1-3.x and higher, using procfs.
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* OSF/1-3.x fixes some OSF/1-2.x procfs peculiarities and adds
+ a new one. */
+#include "alpha/nm-osf2.h"
+
+#undef PROCFS_NEED_PIOCSSIG_FOR_KILL
+#undef PROCFS_DONT_PIOCSSIG_CURSIG
+#define PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
diff --git a/contrib/gdb/gdb/config/alpha/tm-alpha.h b/contrib/gdb/gdb/config/alpha/tm-alpha.h
new file mode 100644
index 0000000..d9b9812
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/tm-alpha.h
@@ -0,0 +1,479 @@
+/* Definitions to make GDB run on an Alpha box under OSF1. This is
+ also used by the Alpha/Netware and Alpha/Linux targets.
+ Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_ALPHA_H
+#define TM_ALPHA_H
+
+#include "bfd.h"
+#include "coff/sym.h" /* Needed for PDR below. */
+#include "coff/symconst.h"
+
+#ifdef __STDC__
+struct frame_info;
+struct type;
+struct value;
+struct symbol;
+#endif
+
+#if !defined (TARGET_BYTE_ORDER)
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/* Redefine some target bit sizes from the default. */
+
+#define TARGET_LONG_BIT 64
+#define TARGET_LONG_LONG_BIT 64
+#define TARGET_PTR_BIT 64
+
+/* Floating point is IEEE compliant */
+#define IEEE_FLOAT
+
+/* Number of traps that happen between exec'ing the shell
+ * to run an inferior, and when we finally get to
+ * the inferior code. This is 2 on most implementations.
+ */
+#define START_INFERIOR_TRAPS_EXPECTED 3
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(pc) pc = alpha_skip_prologue(pc, 0)
+extern CORE_ADDR alpha_skip_prologue PARAMS ((CORE_ADDR addr, int lenient));
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+#define SAVED_PC_AFTER_CALL(frame) alpha_saved_pc_after_call(frame)
+extern CORE_ADDR
+alpha_saved_pc_after_call PARAMS ((struct frame_info *));
+
+/* Are we currently handling a signal ? */
+
+#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("__sigtramp", (name)))
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+#define BREAKPOINT {0x80, 0, 0, 0} /* call_pal bpt */
+
+/* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+
+#ifndef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 4
+#endif
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 8
+
+/* Number of machine registers */
+
+#define NUM_REGS 66
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define REGISTER_NAMES \
+ { "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", \
+ "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp", \
+ "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9", \
+ "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
+ "pc", "vfp", \
+ }
+
+/* Register numbers of various important registers.
+ Note that most of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and FP_REGNUM is a "phony" register number which is too large
+ to be an actual register number as far as the user is concerned
+ but serves to get the desired value when passed to read_register. */
+
+#define V0_REGNUM 0 /* Function integer return value */
+#define T7_REGNUM 8 /* Return address register for OSF/1 __add* */
+#define GCC_FP_REGNUM 15 /* Used by gcc as frame register */
+#define A0_REGNUM 16 /* Loc of first arg during a subr call */
+#define T9_REGNUM 23 /* Return address register for OSF/1 __div* */
+#define T12_REGNUM 27 /* Contains start addr of current proc */
+#define SP_REGNUM 30 /* Contains address of top of stack */
+#define RA_REGNUM 26 /* Contains return address value */
+#define ZERO_REGNUM 31 /* Read-only register, always 0 */
+#define FP0_REGNUM 32 /* Floating point register 0 */
+#define FPA0_REGNUM 48 /* First float arg during a subr call */
+#define PC_REGNUM 64 /* Contains program counter */
+#define FP_REGNUM 65 /* Virtual frame pointer */
+
+#define CANNOT_FETCH_REGISTER(regno) \
+ ((regno) == FP_REGNUM || (regno) == ZERO_REGNUM)
+#define CANNOT_STORE_REGISTER(regno) \
+ ((regno) == FP_REGNUM || (regno) == ZERO_REGNUM)
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+#define REGISTER_BYTES (NUM_REGS * 8)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) ((N) * 8)
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On Alphas, all regs are 8 bytes. */
+
+#define REGISTER_RAW_SIZE(N) 8
+
+/* Number of bytes of storage in the program's representation
+ for register N. On Alphas, all regs are 8 bytes. */
+
+#define REGISTER_VIRTUAL_SIZE(N) 8
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+ from raw format to virtual format.
+ The alpha needs a conversion between register and memory format if
+ the register is a floating point register and
+ memory format is float, as the register format must be double
+ or
+ memory format is an integer with 4 bytes or less, as the representation
+ of integers in floating point registers is different. */
+
+#define REGISTER_CONVERTIBLE(N) ((N) >= FP0_REGNUM && (N) < FP0_REGNUM + 32)
+
+/* Convert data from raw format for register REGNUM in buffer FROM
+ to virtual format with type TYPE in buffer TO. */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM, TYPE, FROM, TO) \
+ alpha_register_convert_to_virtual (REGNUM, TYPE, FROM, TO)
+extern void
+alpha_register_convert_to_virtual PARAMS ((int, struct type *, char *, char *));
+
+/* Convert data from virtual format with type TYPE in buffer FROM
+ to raw format for register REGNUM in buffer TO. */
+
+#define REGISTER_CONVERT_TO_RAW(TYPE, REGNUM, FROM, TO) \
+ alpha_register_convert_to_raw (TYPE, REGNUM, FROM, TO)
+extern void
+alpha_register_convert_to_raw PARAMS ((struct type *, int, char *, char *));
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) \
+ ? builtin_type_double : builtin_type_long) \
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. Handled by alpha_push_arguments. */
+
+#define STORE_STRUCT_RETURN(addr, sp) /**/
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ alpha_extract_return_value(TYPE, REGBUF, VALBUF)
+extern void
+alpha_extract_return_value PARAMS ((struct type *, char *, char *));
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ alpha_store_return_value(TYPE, VALBUF)
+extern void
+alpha_store_return_value PARAMS ((struct type *, char *));
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+/* The address is passed in a0 upon entry to the function, but when
+ the function exits, the compiler has copied the value to v0. This
+ convention is specified by the System V ABI, so I think we can rely
+ on it. */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ (extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
+ REGISTER_RAW_SIZE (V0_REGNUM)))
+
+/* Structures are returned by ref in extra arg0 */
+#define USE_STRUCT_CONVENTION(gcc_p, type) 1
+
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer. */
+
+#define FRAME_CHAIN(thisframe) (CORE_ADDR) alpha_frame_chain (thisframe)
+extern CORE_ADDR alpha_frame_chain PARAMS ((struct frame_info *));
+
+/* Define other aspects of the stack frame. */
+
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+/* We handle this differently for alpha, and maybe we should not */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) {(FRAMELESS) = 0;}
+
+/* Saved Pc. */
+
+#define FRAME_SAVED_PC(FRAME) (alpha_frame_saved_pc(FRAME))
+extern CORE_ADDR
+alpha_frame_saved_pc PARAMS ((struct frame_info *));
+
+/* The alpha has two different virtual pointers for arguments and locals.
+
+ The virtual argument pointer is pointing to the bottom of the argument
+ transfer area, which is located immediately below the virtual frame
+ pointer. Its size is fixed for the native compiler, it is either zero
+ (for the no arguments case) or large enough to hold all argument registers.
+ gcc uses a variable sized argument transfer area. As it has
+ to stay compatible with the native debugging tools it has to use the same
+ virtual argument pointer and adjust the argument offsets accordingly.
+
+ The virtual local pointer is localoff bytes below the virtual frame
+ pointer, the value of localoff is obtained from the PDR. */
+
+#define ALPHA_NUM_ARG_REGS 6
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame - (ALPHA_NUM_ARG_REGS * 8))
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame - (fi)->localoff)
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+#define FRAME_NUM_ARGS(num, fi) ((num) = -1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+extern void alpha_find_saved_regs PARAMS ((struct frame_info *));
+
+#define FRAME_INIT_SAVED_REGS(frame_info) \
+ do { \
+ if ((frame_info)->saved_regs == NULL) \
+ alpha_find_saved_regs (frame_info); \
+ (frame_info)->saved_regs[SP_REGNUM] = (frame_info)->frame; \
+ } while (0)
+
+
+/* Things needed for making the inferior call functions. */
+
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+ sp = alpha_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))
+extern CORE_ADDR
+alpha_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int, CORE_ADDR));
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME alpha_push_dummy_frame()
+extern void
+alpha_push_dummy_frame PARAMS ((void));
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME alpha_pop_frame()
+extern void
+alpha_pop_frame PARAMS ((void));
+
+/* Alpha OSF/1 inhibits execution of code on the stack.
+ But there is no need for a dummy on the alpha. PUSH_ARGUMENTS
+ takes care of all argument handling and bp_call_dummy takes care
+ of stopping the dummy. */
+
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+
+/* On the Alpha the call dummy code is never copied to user space,
+ stopping the user call is achieved via a bp_call_dummy breakpoint.
+ But we need a fake CALL_DUMMY definition to enable the proper
+ call_function_by_hand and to avoid zero length array warnings
+ in valops.c */
+
+#define CALL_DUMMY { 0 } /* Content doesn't matter. */
+
+#define CALL_DUMMY_START_OFFSET (0)
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+
+extern CORE_ADDR alpha_call_dummy_address PARAMS ((void));
+#define CALL_DUMMY_ADDRESS() alpha_call_dummy_address()
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at DUMMYNAME.
+ We only have to set RA_REGNUM to the dummy breakpoint address
+ and T12_REGNUM (the `procedure value register') to the function address. */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+{ \
+ CORE_ADDR bp_address = CALL_DUMMY_ADDRESS (); \
+ if (bp_address == 0) \
+ error ("no place to put call"); \
+ write_register (RA_REGNUM, bp_address); \
+ write_register (T12_REGNUM, fun); \
+}
+
+/* There's a mess in stack frame creation. See comments in blockframe.c
+ near reference to INIT_FRAME_PC_FIRST. */
+
+#define INIT_FRAME_PC(fromleaf, prev) /* nada */
+
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
+ (prev)->pc = ((fromleaf) ? SAVED_PC_AFTER_CALL ((prev)->next) : \
+ (prev)->next ? FRAME_SAVED_PC ((prev)->next) : read_pc ());
+
+/* Special symbol found in blocks associated with routines. We can hang
+ alpha_extra_func_info_t's off of this. */
+
+#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+extern void ecoff_relocate_efi PARAMS ((struct symbol *, CORE_ADDR));
+
+/* Specific information about a procedure.
+ This overlays the ALPHA's PDR records,
+ alpharead.c (ab)uses this to save memory */
+
+typedef struct alpha_extra_func_info {
+ long numargs; /* number of args to procedure (was iopt) */
+ PDR pdr; /* Procedure descriptor record */
+} *alpha_extra_func_info_t;
+
+/* Define the extra_func_info that mipsread.c needs.
+ FIXME: We should define our own PDR interface, perhaps in a separate
+ header file. This would get rid of the <bfd.h> inclusion in all sources
+ and would abstract the mips/alpha interface from ecoff. */
+#define mips_extra_func_info alpha_extra_func_info
+#define mips_extra_func_info_t alpha_extra_func_info_t
+
+#define EXTRA_FRAME_INFO \
+ int localoff; \
+ int pc_reg; \
+ alpha_extra_func_info_t proc_desc;
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci)
+extern void
+init_extra_frame_info PARAMS ((struct frame_info *));
+
+#define PRINT_EXTRA_FRAME_INFO(fi) \
+ { \
+ if (fi && fi->proc_desc && fi->proc_desc->pdr.framereg < NUM_REGS) \
+ printf_filtered (" frame pointer is at %s+%d\n", \
+ REGISTER_NAME (fi->proc_desc->pdr.framereg), \
+ fi->proc_desc->pdr.frameoffset); \
+ }
+
+/* It takes two values to specify a frame on the ALPHA. Sigh.
+
+ In fact, at the moment, the *PC* is the primary value that sets up
+ a frame. The PC is looked up to see what function it's in; symbol
+ information from that function tells us which register is the frame
+ pointer base, and what offset from there is the "virtual frame pointer".
+ (This is usually an offset from SP.) FIXME -- this should be cleaned
+ up so that the primary value is the SP, and the PC is used to disambiguate
+ multiple functions with the same SP that are at different stack levels. */
+
+#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
+extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
+
+/* This is used by heuristic_proc_start. It should be shot it the head. */
+#ifndef VM_MIN_ADDRESS
+#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
+#endif
+
+/* If PC is in a shared library trampoline code, return the PC
+ where the function itself actually starts. If not, return 0. */
+#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)
+
+/* If the current gcc for for this target does not produce correct debugging
+ information for float parameters, both prototyped and unprototyped, then
+ define this macro. This forces gdb to always assume that floats are
+ passed as doubles and then converted in the callee.
+
+ For the alpha, it appears that the debug info marks the parameters as
+ floats regardless of whether the function is prototyped, but the actual
+ values are always passed in as doubles. Thus by setting this to 1, both
+ types of calls will work. */
+
+#define COERCE_FLOAT_TO_DOUBLE 1
+
+/* Return TRUE if procedure descriptor PROC is a procedure descriptor
+ that refers to a dynamically generated sigtramp function.
+
+ OSF/1 doesn't use dynamic sigtramp functions, so this is always
+ FALSE. */
+
+#define PROC_DESC_IS_DYN_SIGTRAMP(proc) (0)
+#define SET_PROC_DESC_IS_DYN_SIGTRAMP(proc)
+
+/* If PC is inside a dynamically generated sigtramp function, return
+ how many bytes the program counter is beyond the start of that
+ function. Otherwise, return a negative value.
+
+ OSF/1 doesn't use dynamic sigtramp functions, so this always
+ returns -1. */
+
+#define DYNAMIC_SIGTRAMP_OFFSET(pc) (-1)
+
+/* Translate a signal handler frame into the address of the sigcontext
+ structure. */
+
+#define SIGCONTEXT_ADDR(frame) \
+ (read_memory_integer ((frame)->next ? frame->next->frame : frame->frame, 8))
+
+/* If FRAME refers to a sigtramp frame, return the address of the next
+ frame. */
+
+#define FRAME_PAST_SIGTRAMP_FRAME(frame, pc) \
+ (alpha_osf_skip_sigtramp_frame (frame, pc))
+extern CORE_ADDR alpha_osf_skip_sigtramp_frame PARAMS ((struct frame_info *, CORE_ADDR));
+
+#endif /* TM_ALPHA_H */
diff --git a/contrib/gdb/gdb/config/alpha/tm-alphalinux.h b/contrib/gdb/gdb/config/alpha/tm-alphalinux.h
new file mode 100644
index 0000000..d836a70
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/tm-alphalinux.h
@@ -0,0 +1,80 @@
+/* Definitions to make GDB run on an Alpha box under Linux. The
+ definitions here are used when the _target_ system is running Linux.
+ Copyright 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_LINUXALPHA_H
+#define TM_LINUXALPHA_H
+
+#include "alpha/tm-alpha.h"
+
+/* Are we currently handling a signal ? */
+
+extern long alpha_linux_sigtramp_offset PARAMS ((CORE_ADDR));
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) (alpha_linux_sigtramp_offset (pc) >= 0)
+
+/* Get start and end address of sigtramp handler. */
+
+#define SIGTRAMP_START(pc) (pc - alpha_linux_sigtramp_offset (pc))
+#define SIGTRAMP_END(pc) (SIGTRAMP_START(pc) + 3*4)
+
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. This is 2
+ on Linux and most implementations. */
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* Return TRUE if procedure descriptor PROC is a procedure descriptor
+ that refers to a dynamically generated sigtramp function. */
+
+#undef PROC_DESC_IS_DYN_SIGTRAMP
+#define PROC_SIGTRAMP_MAGIC 0x0e0f0f0f
+#define PROC_DESC_IS_DYN_SIGTRAMP(proc) ((proc)->pdr.isym \
+ == PROC_SIGTRAMP_MAGIC)
+#undef SET_PROC_DESC_IS_DYN_SIGTRAMP
+#define SET_PROC_DESC_IS_DYN_SIGTRAMP(proc) ((proc)->pdr.isym \
+ = PROC_SIGTRAMP_MAGIC)
+
+/* If PC is inside a dynamically generated sigtramp function, return
+ how many bytes the program counter is beyond the start of that
+ function. Otherwise, return a negative value. */
+
+#undef DYNAMIC_SIGTRAMP_OFFSET
+#define DYNAMIC_SIGTRAMP_OFFSET(pc) (alpha_linux_sigtramp_offset (pc))
+
+/* Translate a signal handler frame into the address of the sigcontext
+ structure. */
+
+#undef SIGCONTEXT_ADDR
+#define SIGCONTEXT_ADDR(frame) ((frame)->frame - 0x298)
+
+/* If FRAME refers to a sigtramp frame, return the address of the next frame.
+
+ Under Linux, sigtramp handlers have dynamically generated procedure
+ descriptors that make this hack unnecessary. */
+
+#undef FRAME_PAST_SIGTRAMP_FRAME
+#define FRAME_PAST_SIGTRAMP_FRAME(frame, pc) (0)
+
+/* We need this for the SOLIB_TRAMPOLINE stuff. */
+#include "tm-sysv4.h"
+
+#endif /* TM_LINUXALPHA_H */
diff --git a/contrib/gdb/gdb/config/alpha/xm-alphalinux.h b/contrib/gdb/gdb/config/alpha/xm-alphalinux.h
new file mode 100644
index 0000000..a7aeab0
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/xm-alphalinux.h
@@ -0,0 +1,29 @@
+/* Host definitions for GDB running on an Alpha under Linux
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (HOST_BYTE_ORDER)
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/* The alpha has no siginterrupt routine. */
+#define NO_SIGINTERRUPT
+
+#define HAVE_TERMIOS
+#define HAVE_SIGSETMASK 1
+#define USG
diff --git a/contrib/gdb/gdb/config/alpha/xm-alphaosf.h b/contrib/gdb/gdb/config/alpha/xm-alphaosf.h
new file mode 100644
index 0000000..40b7fe0
--- /dev/null
+++ b/contrib/gdb/gdb/config/alpha/xm-alphaosf.h
@@ -0,0 +1,27 @@
+/* Host definitions for GDB running on an alpha under OSF/1
+ Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (HOST_BYTE_ORDER)
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/* The alpha has no siginterrupt routine. */
+#define NO_SIGINTERRUPT
+
+#define HAVE_TERMIOS
diff --git a/contrib/gdb/gdb/config/i386/cygwin.mh b/contrib/gdb/gdb/config/i386/cygwin.mh
new file mode 100644
index 0000000..d93acb6
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/cygwin.mh
@@ -0,0 +1,6 @@
+MH_CFLAGS=
+XM_FILE=xm-cygwin.h
+XDEPFILES=ser-tcp.o
+NATDEPFILES= win32-nat.o
+NAT_FILE=../nm-empty.h
+XM_CLIBS=
diff --git a/contrib/gdb/gdb/config/i386/cygwin.mt b/contrib/gdb/gdb/config/i386/cygwin.mt
new file mode 100644
index 0000000..4dfc0c2
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/cygwin.mt
@@ -0,0 +1,6 @@
+# Target: Intel 386 run win32
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-cygwin.h
+
+
+
diff --git a/contrib/gdb/gdb/config/i386/fbsd.mh b/contrib/gdb/gdb/config/i386/fbsd.mh
index 881fa65..499ed48 100644
--- a/contrib/gdb/gdb/config/i386/fbsd.mh
+++ b/contrib/gdb/gdb/config/i386/fbsd.mh
@@ -1,5 +1,5 @@
# Host: Intel 386 running FreeBSD
-XDEPFILES=
+XDEPFILES= ser-tcp.o
NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o core-aout.o i386b-nat.o
XM_FILE= xm-i386bsd.h
NAT_FILE= nm-fbsd.h
diff --git a/contrib/gdb/gdb/config/i386/fbsd.mt b/contrib/gdb/gdb/config/i386/fbsd.mt
index 790e137..e644f1c 100644
--- a/contrib/gdb/gdb/config/i386/fbsd.mt
+++ b/contrib/gdb/gdb/config/i386/fbsd.mt
@@ -1,3 +1,3 @@
# Target: Intel 386 running FreeBSD
TDEPFILES= i386-tdep.o i387-tdep.o solib.o
-TM_FILE= tm-i386bsd.h
+TM_FILE= tm-fbsd.h
diff --git a/contrib/gdb/gdb/config/i386/go32.mh b/contrib/gdb/gdb/config/i386/go32.mh
index 521c7b7..311ee1c 100644
--- a/contrib/gdb/gdb/config/i386/go32.mh
+++ b/contrib/gdb/gdb/config/i386/go32.mh
@@ -1,7 +1,6 @@
MH_CFLAGS=-D__GO32__ -D__MSDOS__
XDEPFILES= go32-xdep.o
XM_FILE= xm-go32.h
-TERMCAP=
HOST_IPC=-DDOS_IPC
SER_HARDWIRE= ser-go32.o
CC=i386-go32-gcc -O2 -fno-omit-frame-pointer
diff --git a/contrib/gdb/gdb/config/i386/i386aix.mh b/contrib/gdb/gdb/config/i386/i386aix.mh
index 751f813..cea05f0 100644
--- a/contrib/gdb/gdb/config/i386/i386aix.mh
+++ b/contrib/gdb/gdb/config/i386/i386aix.mh
@@ -6,7 +6,5 @@ XDEPFILES=
NAT_FILE= nm-i386aix.h
NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o i386aix-nat.o
-TERMCAP=-lcurses
-
# Use gcc. Only coff output can be debugged
CC=gcc
diff --git a/contrib/gdb/gdb/config/i386/i386dgux.mh b/contrib/gdb/gdb/config/i386/i386dgux.mh
index bc2cee2..e05ebcd 100644
--- a/contrib/gdb/gdb/config/i386/i386dgux.mh
+++ b/contrib/gdb/gdb/config/i386/i386dgux.mh
@@ -7,8 +7,3 @@ XM_CLIBS= -lsocket -lnsl
NAT_FILE= nm-i386v4.h
NATDEPFILES= corelow.o core-regset.o solib.o procfs.o fork-child.o i386v4-nat.o
-
-# SVR4 comes standard with terminfo, and in some implementations, the
-# old termcap descriptions are incomplete. So ensure that we use the
-# new terminfo interface and latest terminal descriptions.
-TERMCAP=-lcurses
diff --git a/contrib/gdb/gdb/config/i386/i386gnu.mh b/contrib/gdb/gdb/config/i386/i386gnu.mh
index af3186e..4ceac7e 100644
--- a/contrib/gdb/gdb/config/i386/i386gnu.mh
+++ b/contrib/gdb/gdb/config/i386/i386gnu.mh
@@ -1,8 +1,11 @@
# Host: Intel 386 running the GNU Hurd
XDEPFILES= i387-tdep.o
-NATDEPFILES= i386gnu-nat.o gnu-nat.o fork-child.o solib.o notify_S.o process_reply_S.o msg_reply_S.o msg_U.o exc_request_U.o exc_request_S.o
+NATDEPFILES= i386gnu-nat.o gnu-nat.o fork-child.o solib.o corelow.o notify_S.o process_reply_S.o msg_reply_S.o msg_U.o exc_request_U.o exc_request_S.o
XM_FILE= xm-i386gnu.h
NAT_FILE= nm-gnu.h
+MH_CFLAGS = -D_GNU_SOURCE
+
+XM_CLIBS = -lshouldbeinlibc
# Use our own user stubs for the msg rpcs, so we can make them time out, in
# case the program is fucked, or we guess the wrong signal thread.
@@ -26,11 +29,3 @@ MIGCOM = $(MIG) -cc cat - /dev/null
%_U.h %_U.c: %.defs
$(CPP) $(CPPFLAGS) $($*-MIGUFLAGS) -x c $< \
| $(MIGCOM) -sheader /dev/null -server /dev/null -user $*_U.c -header $*_U.h
-
-gnu-nat.o: process_reply_S.h exc_request_S.h notify_S.h msg_reply_S.h exc_request_U.h msg_U.h
-
-gnu-nat.o i386gnu-nat.o: gnu-nat.h
-
-# Don't use the mmalloc library in Mach 3.
-MMALLOC =
-MMALLOC_DISABLE = -DNO_MMALLOC
diff --git a/contrib/gdb/gdb/config/i386/i386m3.mh b/contrib/gdb/gdb/config/i386/i386m3.mh
index 66f9847..0a83ebf7 100644
--- a/contrib/gdb/gdb/config/i386/i386m3.mh
+++ b/contrib/gdb/gdb/config/i386/i386m3.mh
@@ -5,7 +5,3 @@ NATDEPFILES= i386m3-nat.o m3-nat.o fork-child.o
NAT_CLIBS= -lmachid -lnetname -lmach
XM_FILE= xm-i386m3.h
NAT_FILE= nm-m3.h
-
-# Don't use the mmalloc library in Mach 3.
-MMALLOC =
-MMALLOC_DISABLE = -DNO_MMALLOC
diff --git a/contrib/gdb/gdb/config/i386/i386mk.mh b/contrib/gdb/gdb/config/i386/i386mk.mh
index cf1da57..849677c 100644
--- a/contrib/gdb/gdb/config/i386/i386mk.mh
+++ b/contrib/gdb/gdb/config/i386/i386mk.mh
@@ -2,7 +2,3 @@
XDEPFILES= os-mach3.o i386mach3-xdep.o i387-tdep.o
XM_FILE= xm-i386osf1mk.h
-
-# Don't use the mmalloc library in Mach 3.
-MMALLOC =
-MMALLOC_DISABLE = -DNO_MMALLOC
diff --git a/contrib/gdb/gdb/config/i386/i386mk.mt b/contrib/gdb/gdb/config/i386/i386mk.mt
index aa2f6a4..fc59442 100644
--- a/contrib/gdb/gdb/config/i386/i386mk.mt
+++ b/contrib/gdb/gdb/config/i386/i386mk.mt
@@ -1,6 +1,6 @@
# Target: Intel 386 with a.out in osf 1/mk
TDEPFILES= i386-tdep.o
TM_FILE= tm-i386osf1mk.h
+
TM_CFLAGS= -I/usr/mach3/include
TM_CLIBS= /usr/mach3/ccs/lib/libmachid.a /usr/mach3/ccs/lib/libnetname.a /usr/mach3/ccs/lib/libmach.a
-OBJFORMATS= dbxread.o
diff --git a/contrib/gdb/gdb/config/i386/i386sco5.mh b/contrib/gdb/gdb/config/i386/i386sco5.mh
index 441a59c..3bea87a 100644
--- a/contrib/gdb/gdb/config/i386/i386sco5.mh
+++ b/contrib/gdb/gdb/config/i386/i386sco5.mh
@@ -12,6 +12,6 @@ XDEPFILES= ser-tcp.o
XM_CLIBS= -lPW -lsocket
NAT_FILE= nm-i386sco5.h
-NATDEPFILES= infptrace.o inftarg.o fork-child.o corefile.o core-aout.o corelow.o \
- i386v-nat.o solib.o
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corefile.o core-aout.o \
+ corelow.o i386v-nat.o solib.o
diff --git a/contrib/gdb/gdb/config/i386/i386sco5.mt b/contrib/gdb/gdb/config/i386/i386sco5.mt
new file mode 100644
index 0000000..54dc68d
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/i386sco5.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SCO Open Server 5
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386sco5.h
diff --git a/contrib/gdb/gdb/config/i386/i386sol2.mh b/contrib/gdb/gdb/config/i386/i386sol2.mh
index d73ded2..ff24294 100644
--- a/contrib/gdb/gdb/config/i386/i386sol2.mh
+++ b/contrib/gdb/gdb/config/i386/i386sol2.mh
@@ -3,10 +3,5 @@
XM_FILE= xm-i386v4.h
XDEPFILES=
-NAT_FILE= nm-i386v4.h
+NAT_FILE= nm-i386sol2.h
NATDEPFILES= core-regset.o procfs.o fork-child.o i386v4-nat.o corelow.o
-
-# SVR4 comes standard with terminfo, and in some implementations, the
-# old termcap descriptions are incomplete. So ensure that we use the
-# new terminfo interface and latest terminal descriptions.
-TERMCAP=-ltermlib
diff --git a/contrib/gdb/gdb/config/i386/i386sol2.mt b/contrib/gdb/gdb/config/i386/i386sol2.mt
index 0bbf9b36..80b576f 100644
--- a/contrib/gdb/gdb/config/i386/i386sol2.mt
+++ b/contrib/gdb/gdb/config/i386/i386sol2.mt
@@ -1,3 +1,3 @@
# Target: Intel 386 running SVR4
TDEPFILES= i386-tdep.o i387-tdep.o solib.o
-TM_FILE= tm-i386v4.h
+TM_FILE= tm-i386sol2.h
diff --git a/contrib/gdb/gdb/config/i386/i386v4.mh b/contrib/gdb/gdb/config/i386/i386v4.mh
index aa70125..4653887 100644
--- a/contrib/gdb/gdb/config/i386/i386v4.mh
+++ b/contrib/gdb/gdb/config/i386/i386v4.mh
@@ -7,8 +7,3 @@ XM_CLIBS= -lsocket -lnsl
NAT_FILE= nm-i386v4.h
NATDEPFILES= corelow.o core-regset.o solib.o procfs.o fork-child.o i386v4-nat.o
-
-# SVR4 comes standard with terminfo, and in some implementations, the
-# old termcap descriptions are incomplete. So ensure that we use the
-# new terminfo interface and latest terminal descriptions.
-TERMCAP=-ltermlib
diff --git a/contrib/gdb/gdb/config/i386/i386v42mp.mh b/contrib/gdb/gdb/config/i386/i386v42mp.mh
new file mode 100644
index 0000000..94b6c06
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/i386v42mp.mh
@@ -0,0 +1,11 @@
+# Host: Intel 386 running SVR4
+
+XM_FILE= xm-i386v4.h
+XDEPFILES=
+# for network communication
+XM_CLIBS= -lsocket -lnsl
+
+# we don't want nm-i386v4.h since that defines LOSING_POLL which isn't
+# appropriate for i386v42mp
+NAT_FILE= nm-i386v42mp.h
+NATDEPFILES= corelow.o core-regset.o solib.o procfs.o fork-child.o i386v4-nat.o
diff --git a/contrib/gdb/gdb/config/i386/i386v42mp.mt b/contrib/gdb/gdb/config/i386/i386v42mp.mt
new file mode 100644
index 0000000..0b2dea8
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/i386v42mp.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SVR4.2MP
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386v42mp.h
diff --git a/contrib/gdb/gdb/config/i386/linux.mh b/contrib/gdb/gdb/config/i386/linux.mh
index 13c3310..30de91d 100644
--- a/contrib/gdb/gdb/config/i386/linux.mh
+++ b/contrib/gdb/gdb/config/i386/linux.mh
@@ -1,13 +1,7 @@
-# Host: Intel 386 running Linux
+# Host: Intel 386 running GNU/Linux
XM_FILE= xm-linux.h
XDEPFILES= ser-tcp.o
-# Needed for frexp() in libiberty for older a.out based systems and should be
-# harmless to include for newer linux systems.
-XM_CLIBS= -lm
-
NAT_FILE= nm-linux.h
NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o core-aout.o core-regset.o i386v-nat.o i386v4-nat.o
-
-GDBSERVER_DEPFILES= low-linux.o
diff --git a/contrib/gdb/gdb/config/i386/linux.mt b/contrib/gdb/gdb/config/i386/linux.mt
index b9d7404..66cc97d 100644
--- a/contrib/gdb/gdb/config/i386/linux.mt
+++ b/contrib/gdb/gdb/config/i386/linux.mt
@@ -1,3 +1,5 @@
-# Target: Intel 386 with a.out and ELF
+# Target: Intel 386 running GNU/Linux
TDEPFILES= i386-tdep.o i387-tdep.o
TM_FILE= tm-linux.h
+
+GDBSERVER_DEPFILES= low-linux.o
diff --git a/contrib/gdb/gdb/config/i386/nbsd.mh b/contrib/gdb/gdb/config/i386/nbsd.mh
index 5b3bd2b..c76b897 100644
--- a/contrib/gdb/gdb/config/i386/nbsd.mh
+++ b/contrib/gdb/gdb/config/i386/nbsd.mh
@@ -1,5 +1,5 @@
# Host: Intel 386 running NetBSD
-XDEPFILES=
+XDEPFILES= ser-tcp.o
NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386b-nat.o
XM_FILE= xm-nbsd.h
NAT_FILE= nm-nbsd.h
diff --git a/contrib/gdb/gdb/config/i386/ncr3000.mh b/contrib/gdb/gdb/config/i386/ncr3000.mh
index 1dbe1d1..4f60756 100644
--- a/contrib/gdb/gdb/config/i386/ncr3000.mh
+++ b/contrib/gdb/gdb/config/i386/ncr3000.mh
@@ -14,8 +14,3 @@ XDEPFILES=
NAT_FILE= nm-i386v4.h
NATDEPFILES= corelow.o core-regset.o procfs.o fork-child.o i386v4-nat.o
-
-# SVR4 comes standard with terminfo, and in some implementations, the
-# old termcap descriptions are incomplete. So ensure that we use the
-# new terminfo interface and latest terminal descriptions.
-TERMCAP=-ltermlib
diff --git a/contrib/gdb/gdb/config/i386/nm-fbsd.h b/contrib/gdb/gdb/config/i386/nm-fbsd.h
index f04f352..727623c 100644
--- a/contrib/gdb/gdb/config/i386/nm-fbsd.h
+++ b/contrib/gdb/gdb/config/i386/nm-fbsd.h
@@ -29,9 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <machine/vmparam.h>
#define KERNEL_U_ADDR USRSTACK
-#define FLOAT_INFO extern i386_float_info (); \
- i386_float_info ()
-
#define REGISTER_U_ADDR(addr, blockend, regno) \
(addr) = i386_register_u_addr ((blockend),(regno));
diff --git a/contrib/gdb/gdb/config/i386/nm-i386sco.h b/contrib/gdb/gdb/config/i386/nm-i386sco.h
index f15a8e9..33ab6de 100644
--- a/contrib/gdb/gdb/config/i386/nm-i386sco.h
+++ b/contrib/gdb/gdb/config/i386/nm-i386sco.h
@@ -35,12 +35,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern int
i386_register_u_addr PARAMS ((int, int));
-/*
- * SysV doesn't always have a <ptrace.h> or <sys/ptrace.h> file
- * (why, I don't know), and we don't need it.
- */
-#define NO_PTRACE_H
-
/* When calling functions on SCO, sometimes we get an error writing some
of the segment registers. This would appear to be a kernel
bug/non-feature. */
diff --git a/contrib/gdb/gdb/config/i386/nm-i386sco5.h b/contrib/gdb/gdb/config/i386/nm-i386sco5.h
index dcc14e4..10e749b 100644
--- a/contrib/gdb/gdb/config/i386/nm-i386sco5.h
+++ b/contrib/gdb/gdb/config/i386/nm-i386sco5.h
@@ -1,7 +1,8 @@
/* Native support for SCO OpenServer 5
- Copyright 1996 Free Software Foundation, Inc.
- By Robert Lipe <robertl@dgii.com>. Based on
- work by Ian Lance Taylor <ian@cygnus.com. and
+ Copyright 1996, 1998 Free Software Foundation, Inc.
+ Re-written by J. Kean Johnston <jkj@sco.com>.
+ Originally written by Robert Lipe <robertl@dgii.com>, based on
+ work by Ian Lance Taylor <ian@cygnus.com> and
Martin Walker <maw@netcom.com>.
This file is part of GDB.
@@ -20,22 +21,19 @@ 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. */
-/* SCO OpenServer 5 is a superset of 3.2v4. It is actually quite
- close to SVR4 [ elf, dynamic libes, mmap ] but misses a few things
- like /proc. */
-
+/* Basically, its a lot like the older versions ... */
#include "i386/nm-i386sco.h"
-/* Since the native compilers [ and linkers ] are licensed from USL,
- we'll try convincing GDB of this... */
-
-#include "solib.h" /* Pick up shared library support */
+/* ... but it can do a lot of SVR4 type stuff too. */
#define SVR4_SHARED_LIBS
+#include "solib.h" /* Pick up shared library support */
#define ATTACH_DETACH
-/* SCO, does not provide <sys/ptrace.h>. infptrace.c does not
+/* SCO does not provide <sys/ptrace.h>. infptrace.c does not
have defaults for these values. */
#define PTRACE_ATTACH 10
#define PTRACE_DETACH 11
+
+
diff --git a/contrib/gdb/gdb/config/i386/nm-i386sol2.h b/contrib/gdb/gdb/config/i386/nm-i386sol2.h
new file mode 100644
index 0000000..2ae966c
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/nm-i386sol2.h
@@ -0,0 +1,35 @@
+/* Native support for i386 running Solaris 2.
+ Copyright 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "nm-sysv4.h"
+
+#ifdef HAVE_THREAD_DB_LIB
+
+#ifdef __STDC__
+struct objfile;
+#endif
+
+#define target_new_objfile(OBJFILE) sol_thread_new_objfile (OBJFILE)
+
+void sol_thread_new_objfile PARAMS ((struct objfile *objfile));
+
+#define FIND_NEW_THREADS sol_find_new_threads
+void sol_find_new_threads PARAMS ((void));
+
+#endif
diff --git a/contrib/gdb/gdb/config/i386/nm-i386v.h b/contrib/gdb/gdb/config/i386/nm-i386v.h
index babdd7c..8e6877e 100644
--- a/contrib/gdb/gdb/config/i386/nm-i386v.h
+++ b/contrib/gdb/gdb/config/i386/nm-i386v.h
@@ -34,5 +34,3 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern int
i386_register_u_addr PARAMS ((int, int));
-
-#define NO_PTRACE_H
diff --git a/contrib/gdb/gdb/config/i386/nm-i386v4.h b/contrib/gdb/gdb/config/i386/nm-i386v4.h
index 59d69f8..8722a40 100644
--- a/contrib/gdb/gdb/config/i386/nm-i386v4.h
+++ b/contrib/gdb/gdb/config/i386/nm-i386v4.h
@@ -1,5 +1,5 @@
/* Native support for i386 running SVR4.
- Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
+ Copyright 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc.
Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
This file is part of GDB.
@@ -19,3 +19,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "nm-sysv4.h"
+
+/* Poll causes GDB to hang, at least under Unixware 1.1.2. */
+#define LOSING_POLL
diff --git a/contrib/gdb/gdb/config/i386/nm-i386v42mp.h b/contrib/gdb/gdb/config/i386/nm-i386v42mp.h
new file mode 100644
index 0000000..6ffd128
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/nm-i386v42mp.h
@@ -0,0 +1,22 @@
+/* Native support for i386 running SVR4.
+ Copyright 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "nm-sysv4.h"
+
diff --git a/contrib/gdb/gdb/config/i386/nm-linux.h b/contrib/gdb/gdb/config/i386/nm-linux.h
index d6d3a5d..ad0b8db 100644
--- a/contrib/gdb/gdb/config/i386/nm-linux.h
+++ b/contrib/gdb/gdb/config/i386/nm-linux.h
@@ -1,5 +1,5 @@
-/* Native support for linux, for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1989, 1992, 1996
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+ Copyright (C) 1986, 1987, 1989, 1992, 1996, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -33,11 +33,7 @@ extern int kernel_u_size PARAMS ((void));
#define U_REGS_OFFSET 0
-/* Linux uses the SYSV i386v-nat.c support, but doesn't have <sys/reg.h> */
-
-#define NO_SYS_REG_H
-
-/* Linux supports the 386 hardware debugging registers. */
+/* GNU/Linux supports the 386 hardware debugging registers. */
#define TARGET_HAS_HARDWARE_WATCHPOINTS
@@ -54,7 +50,7 @@ extern int kernel_u_size PARAMS ((void));
/* Use these macros for watchpoint insertion/removal. */
#define target_insert_watchpoint(addr, len, type) \
- i386_insert_watchpoint (inferior_pid, addr, len, 2)
+ i386_insert_watchpoint (inferior_pid, addr, len, type)
#define target_remove_watchpoint(addr, len, type) \
i386_remove_watchpoint (inferior_pid, addr, len)
@@ -63,20 +59,15 @@ extern int kernel_u_size PARAMS ((void));
shared libraries. */
#ifdef HAVE_LINK_H
-#include "solib.h" /* Support for shared libraries. */
#define SVR4_SHARED_LIBS
+#include "solib.h" /* Support for shared libraries. */
#endif
-#if 0
-/* We need prototypes for these somewhere, and this file is the logical
- spot, but they can't go here because CORE_ADDR is not defined at the
- time this file is included in defs.h. FIXME - fnf */
extern CORE_ADDR
-i386_stopped_by_watchpoint PARAM ((int));
+i386_stopped_by_watchpoint PARAMS ((int));
extern int
i386_insert_watchpoint PARAMS ((int pid, CORE_ADDR addr, int len, int rw));
extern int
i386_remove_watchpoint PARAMS ((int pid, CORE_ADDR addr, int len));
-#endif
#endif /* #ifndef NM_LINUX_H */
diff --git a/contrib/gdb/gdb/config/i386/nm-symmetry.h b/contrib/gdb/gdb/config/i386/nm-symmetry.h
index e8fb6b9..80cf097 100644
--- a/contrib/gdb/gdb/config/i386/nm-symmetry.h
+++ b/contrib/gdb/gdb/config/i386/nm-symmetry.h
@@ -43,5 +43,4 @@ extern int child_wait PARAMS ((int, struct target_waitstatus *));
#define KERNEL_U_ADDR (VA_UAREA) /* ptx */
#else
#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG)) /* dynix */
-#define NO_PTRACE_H
#endif
diff --git a/contrib/gdb/gdb/config/i386/tm-cygwin.h b/contrib/gdb/gdb/config/i386/tm-cygwin.h
new file mode 100644
index 0000000..b1ad894
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/tm-cygwin.h
@@ -0,0 +1,127 @@
+/* Macro definitions for i386 running under the win32 API Unix.
+ Copyright 1995, 1996 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "i386/tm-i386v.h"
+
+#undef MAX_REGISTER_RAW_SIZE
+#undef MAX_REGISTER_VIRTUAL_SIZE
+#undef NUM_REGS
+#undef REGISTER_BYTE
+#undef REGISTER_BYTES
+#undef REGISTER_CONVERTIBLE
+#undef REGISTER_CONVERT_TO_RAW
+#undef REGISTER_CONVERT_TO_VIRTUAL
+#undef REGISTER_NAMES
+#undef REGISTER_RAW_SIZE
+#undef REGISTER_VIRTUAL_SIZE
+#undef REGISTER_VIRTUAL_TYPE
+
+/* Number of machine registers */
+
+#define NUM_REGS 24
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+/* the order of the first 8 registers must match the compiler's
+ * numbering scheme (which is the same as the 386 scheme)
+ * also, this table must match regmap in i386-pinsn.c.
+ */
+
+#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
+ "esp", "ebp", "esi", "edi", \
+ "eip", "ps", "cs", "ss", \
+ "ds", "es", "fs", "gs", \
+ "st", "st(1)","st(2)","st(3)",\
+ "st(4)","st(5)","st(6)","st(7)",}
+
+#define FP0_REGNUM 16
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+
+#define REGISTER_BYTES (16 * 4 + 8 * 10)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) (((N) < 16) ? (N) * 4 : (((N) - 16) * 10) + (16 * 4))
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+
+#define REGISTER_RAW_SIZE(N) (((N) < 16) ? 4 : 10)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (((N) < 16) ? 4 : 10)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 10
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 10
+
+/* Nonzero if register N requires conversion
+ from raw format to virtual format. */
+
+#define REGISTER_CONVERTIBLE(N) \
+ ((N < FP0_REGNUM) ? 0 : 1)
+
+/* Convert data from raw format for register REGNUM in buffer FROM
+ to virtual format with type TYPE in buffer TO. */
+extern void
+i387_to_double PARAMS ((char *, char *));
+
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
+{ \
+ double val; \
+ i387_to_double ((FROM), (char *)&val); \
+ store_floating ((TO), TYPE_LENGTH (TYPE), val); \
+}
+
+extern void
+double_to_i387 PARAMS ((char *, char *));
+
+#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
+{ \
+ double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
+ double_to_i387((char *)&val, (TO)); \
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N < FP0_REGNUM) ? builtin_type_int : \
+ builtin_type_double)
+
+#define NAMES_HAVE_UNDERSCORE
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) skip_trampoline_code (pc, name)
+#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc, 0)
+extern CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR pc, char *name));
+
+extern char *cygwin_pid_to_str PARAMS ((int pid));
+#define target_pid_to_str(PID) cygwin_pid_to_str (PID)
diff --git a/contrib/gdb/gdb/config/i386/tm-fbsd.h b/contrib/gdb/gdb/config/i386/tm-fbsd.h
new file mode 100644
index 0000000..9933e10
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/tm-fbsd.h
@@ -0,0 +1,32 @@
+/* Target macro definitions for i386 running FreeBSD
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "i386/tm-i386bsd.h"
+
+
+#undef NUM_REGS
+#define NUM_REGS 14
+
+
+#undef IN_SOLIB_CALL_TRAMPOLINE
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) STREQ (name, "_DYNAMIC")
+
+
+extern i386_float_info ();
+#define FLOAT_INFO i386_float_info ()
diff --git a/contrib/gdb/gdb/config/i386/tm-i386.h b/contrib/gdb/gdb/config/i386/tm-i386.h
index 8f8090b..e2039e5 100644
--- a/contrib/gdb/gdb/config/i386/tm-i386.h
+++ b/contrib/gdb/gdb/config/i386/tm-i386.h
@@ -59,7 +59,7 @@ extern int i386_skip_prologue PARAMS ((int));
/* Stack grows downward. */
-#define INNER_THAN <
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
/* Sequence of bytes for breakpoint instruction. */
@@ -70,10 +70,6 @@ extern int i386_skip_prologue PARAMS ((int));
#define DECR_PC_AFTER_BREAK 1
-/* Nonzero if instruction at PC is a return instruction. */
-
-#define ABOUT_TO_RETURN(pc) (read_memory_integer ((pc), 1) == 0xc3)
-
/* Say how long (ordinary) registers are. This is a piece of bogosity
used in push_word and a few other places; REGISTER_RAW_SIZE is the
real way to know how big a register is. */
@@ -158,8 +154,10 @@ extern int i386_skip_prologue PARAMS ((int));
subroutine will return. This is called from call_function. */
#define STORE_STRUCT_RETURN(ADDR, SP) \
- { (SP) -= sizeof (ADDR); \
- write_memory ((SP), (char *) &(ADDR), sizeof (ADDR)); }
+ { char buf[REGISTER_SIZE]; \
+ (SP) -= sizeof (ADDR); \
+ store_address (buf, sizeof (ADDR), ADDR); \
+ write_memory ((SP), buf, sizeof (ADDR)); }
/* Extract from an array REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
diff --git a/contrib/gdb/gdb/config/i386/tm-i386bsd.h b/contrib/gdb/gdb/config/i386/tm-i386bsd.h
index 0b0e3d9..8b8c3a9 100644
--- a/contrib/gdb/gdb/config/i386/tm-i386bsd.h
+++ b/contrib/gdb/gdb/config/i386/tm-i386bsd.h
@@ -32,8 +32,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
the user area. Using constants here allows for cross debugging.
These are tested for BSDI but should work on 386BSD. */
-#define SIGTRAMP_START 0xfdbfdfc0
-#define SIGTRAMP_END 0xfdbfe000
+#define SIGTRAMP_START(pc) 0xfdbfdfc0
+#define SIGTRAMP_END(pc) 0xfdbfe000
/* Saved Pc. Get it from sigcontext if within sigtramp. */
diff --git a/contrib/gdb/gdb/config/i386/tm-i386nw.h b/contrib/gdb/gdb/config/i386/tm-i386nw.h
index 43a1e1a..e5cdade 100644
--- a/contrib/gdb/gdb/config/i386/tm-i386nw.h
+++ b/contrib/gdb/gdb/config/i386/tm-i386nw.h
@@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Stop backtracing when we wander into main. */
-#define FRAME_CHAIN_VALID_ALTERNATE
+#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi)
/* Offsets (in target ints) into jmp_buf. Not defined in any system header
diff --git a/contrib/gdb/gdb/config/i386/tm-i386os9k.h b/contrib/gdb/gdb/config/i386/tm-i386os9k.h
index 75de74e..2b48641 100644
--- a/contrib/gdb/gdb/config/i386/tm-i386os9k.h
+++ b/contrib/gdb/gdb/config/i386/tm-i386os9k.h
@@ -50,8 +50,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* On 386 bsd, sigtramp is above the user stack and immediately below
the user area. Using constants here allows for cross debugging.
These are tested for BSDI but should work on 386BSD. */
-#define SIGTRAMP_START 0xfdbfdfc0
-#define SIGTRAMP_END 0xfdbfe000
+#define SIGTRAMP_START(pc) 0xfdbfdfc0
+#define SIGTRAMP_END(pc) 0xfdbfe000
/* Saved Pc. Get it from sigcontext if within sigtramp. */
diff --git a/contrib/gdb/gdb/config/i386/tm-i386sco5.h b/contrib/gdb/gdb/config/i386/tm-i386sco5.h
new file mode 100644
index 0000000..ffac5b3
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/tm-i386sco5.h
@@ -0,0 +1,62 @@
+/* Macro definitions for GDB on an Intel i386 running SCO Open Server 5.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Written by J. Kean Johnston (jkj@sco.com).
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_I386SCO5_H
+#define TM_I386SCO5_H 1
+
+/* Pick up most of what we need from the generic i386 target include file. */
+
+#include "i386/tm-i386.h"
+
+/* Pick up more stuff from the generic SYSV and SVR4 host include files. */
+#include "i386/tm-i386v.h"
+#include "tm-sysv4.h"
+
+#define KERNEL_U_SIZE kernel_u_size()
+
+/*
+ * SCO is unlike other SVR3 targets in that it has SVR4 style shared
+ * libs, with a slight twist. We expect 3 traps (2 for the exec and
+ * one for the dynamic loader). After the third trap we insert the
+ * SOLIB breakpoints, then wait for the 4th trap.
+ */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 3
+
+/* We can also do hardware watchpoints */
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+/* After a watchpoint trap, the PC points to the instruction which
+ caused the trap. But we can continue over it without disabling the
+ trap. */
+#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_STEPPABLE_WATCHPOINT
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ i386_stopped_by_watchpoint (inferior_pid)
+
+#define target_insert_watchpoint(addr, len, type) \
+ i386_insert_watchpoint (inferior_pid, addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type) \
+ i386_remove_watchpoint (inferior_pid, addr, len)
+
+#endif /* ifndef TM_I386SCO5_H */
diff --git a/contrib/gdb/gdb/config/i386/tm-i386sol2.h b/contrib/gdb/gdb/config/i386/tm-i386sol2.h
new file mode 100644
index 0000000..dbd6317
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/tm-i386sol2.h
@@ -0,0 +1,64 @@
+/* Macro definitions for GDB on an Intel i386 running Solaris 2.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_I386SOL2_H
+#define TM_I386SOL2_H 1
+
+#include "i386/tm-i386v4.h"
+
+/* Signal handler frames under Solaris 2 are recognized by a return address
+ of 0xFFFFFFFF, the third parameter on the signal handler stack is
+ a pointer to an ucontext. */
+#undef sigtramp_saved_pc
+#undef I386V4_SIGTRAMP_SAVED_PC
+#define SIGCONTEXT_PC_OFFSET (36 + 14 * 4)
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) (pc == 0xFFFFFFFF)
+
+/* The SunPRO compiler puts out 0 instead of the address in N_SO symbols,
+ and for SunPRO 3.0, N_FUN symbols too. */
+#define SOFUN_ADDRESS_MAYBE_MISSING
+
+extern char *sunpro_static_transform_name PARAMS ((char *));
+#define STATIC_TRANSFORM_NAME(x) sunpro_static_transform_name (x)
+#define IS_STATIC_TRANSFORM_NAME(name) ((name)[0] == '.')
+
+#define FAULTED_USE_SIGINFO
+
+/* Macros to extract process id and thread id from a composite pid/tid */
+#define PIDGET(pid) ((pid) & 0xffff)
+#define TIDGET(pid) (((pid) >> 16) & 0xffff)
+
+/* Macro to extract carry from given regset. */
+#define PS_FLAG_CARRY 0x1 /* Carry bit in PS */
+#define PROCFS_GET_CARRY(regset) ((regset)[EFL] & PS_FLAG_CARRY)
+
+#ifdef HAVE_THREAD_DB_LIB
+
+extern char *solaris_pid_to_str PARAMS ((int pid));
+#define target_pid_to_str(PID) solaris_pid_to_str (PID)
+
+#else
+
+extern char *procfs_pid_to_str PARAMS ((int pid));
+#define target_pid_to_str(PID) procfs_pid_to_str (PID)
+
+#endif
+
+#endif /* ifndef TM_I386SOL2_H */
diff --git a/contrib/gdb/gdb/config/i386/tm-i386v.h b/contrib/gdb/gdb/config/i386/tm-i386v.h
index 235558b..bb31cb0 100644
--- a/contrib/gdb/gdb/config/i386/tm-i386v.h
+++ b/contrib/gdb/gdb/config/i386/tm-i386v.h
@@ -100,8 +100,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#undef STORE_STRUCT_RETURN
#define STORE_STRUCT_RETURN(ADDR, SP) \
- { (SP) -= sizeof (ADDR); \
- write_memory ((SP), (char *) &(ADDR), sizeof (ADDR)); }
+ { char buf[REGISTER_SIZE]; \
+ (SP) -= sizeof (ADDR); \
+ store_address (buf, sizeof (ADDR), ADDR); \
+ write_memory ((SP), buf, sizeof (ADDR)); }
/* Extract from an array REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
diff --git a/contrib/gdb/gdb/config/i386/tm-i386v4.h b/contrib/gdb/gdb/config/i386/tm-i386v4.h
index 0a1e56d..eafff01 100644
--- a/contrib/gdb/gdb/config/i386/tm-i386v4.h
+++ b/contrib/gdb/gdb/config/i386/tm-i386v4.h
@@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Use the alternate method of determining valid frame chains. */
-#define FRAME_CHAIN_VALID_ALTERNATE
+#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi)
/* 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
diff --git a/contrib/gdb/gdb/config/i386/tm-i386v42mp.h b/contrib/gdb/gdb/config/i386/tm-i386v42mp.h
new file mode 100644
index 0000000..81df85b
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/tm-i386v42mp.h
@@ -0,0 +1,44 @@
+/* Macro definitions for GDB on an Intel i386 running SVR4.2MP
+ Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com)
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_I386V42MP_H
+#define TM_I386V42MP_H 1
+
+/* pick up more generic x86 sysv4 stuff */
+
+#include "i386/tm-i386v4.h"
+
+/* procfs on this architecture has multiple fds (ctl, as, map, status)
+ including a control fd */
+
+#ifndef HAVE_MULTIPLE_PROC_FDS
+#define HAVE_MULTIPLE_PROC_FDS
+#endif
+
+/* procfs on this architecture communicates with read/write instead
+ of ioctl */
+
+#define PROCFS_USE_READ_WRITE
+
+/* define to select for other sysv4.2mp weirdness */
+
+#define UNIXWARE
+
+#endif /* ifndef TM_I386V42MP_H */
diff --git a/contrib/gdb/gdb/config/i386/tm-linux.h b/contrib/gdb/gdb/config/i386/tm-linux.h
index d8cbf26..417d151 100644
--- a/contrib/gdb/gdb/config/i386/tm-linux.h
+++ b/contrib/gdb/gdb/config/i386/tm-linux.h
@@ -1,4 +1,4 @@
-/* Definitions to target GDB to Linux on 386.
+/* Definitions to target GDB to GNU/Linux on 386.
Copyright 1992, 1993 Free Software Foundation, Inc.
This file is part of GDB.
@@ -32,4 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "tm-sysv4.h"
+/* The following works around a problem with /usr/include/sys/procfs.h */
+#define sys_quotactl 1
+
#endif /* #ifndef TM_LINUX_H */
diff --git a/contrib/gdb/gdb/config/i386/windows.mh b/contrib/gdb/gdb/config/i386/windows.mh
new file mode 100644
index 0000000..3933a6e
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/windows.mh
@@ -0,0 +1,17 @@
+# gdbwin.o and ser-win32s.c have to be named because they have
+# _initialize functions that need to be found by init.c
+# gui.ores has to be named, or else msvc won't link it in.
+XDEPFILES = \
+ mswin/gdbwin.o \
+ mswin/ser-win32s.o \
+ mswin/gui.ores \
+ mswin/libwingdb.a
+
+$(XDEPFILES):
+ rootme=`pwd` ; export rootme ; \
+ ( cd mswin ; \
+ $(MAKE) $(FLAGS_TO_PASS) all )
+
+XM_FILE=xm-windows.h
+MMALLOC=
+SER_HARDWIRE =
diff --git a/contrib/gdb/gdb/config/i386/xm-cygwin.h b/contrib/gdb/gdb/config/i386/xm-cygwin.h
new file mode 100644
index 0000000..f0b8227
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/xm-cygwin.h
@@ -0,0 +1,34 @@
+/* Definitions for hosting on WIN32, for GDB.
+ Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+#include "fopen-bin.h"
+
+#define GDBINIT_FILENAME "gdb.ini"
+
+#define SLASH_P(X) ((X)=='\\' || (X) == '/')
+#define ROOTED_P(X) ((SLASH_P((X)[0]))|| ((X)[1] ==':'))
+#define SLASH_CHAR '/'
+#define SLASH_STRING "/"
+
+/* Define this if source files use \r\n rather than just \n. */
+#define CRLF_SOURCE_FILES
+
+#define HAVE_SIGSETMASK 0
diff --git a/contrib/gdb/gdb/config/i386/xm-i386bsd.h b/contrib/gdb/gdb/config/i386/xm-i386bsd.h
index 8a852a2..e5c4c89 100644
--- a/contrib/gdb/gdb/config/i386/xm-i386bsd.h
+++ b/contrib/gdb/gdb/config/i386/xm-i386bsd.h
@@ -19,5 +19,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
-#include <machine/limits.h> /* for INT_MIN, to avoid "INT_MIN
- redefined" warnings from defs.h */
+#include <machine/limits.h> /* for INT_MIN */
diff --git a/contrib/gdb/gdb/config/i386/xm-i386m3.h b/contrib/gdb/gdb/config/i386/xm-i386m3.h
index 615c80b..b667409 100644
--- a/contrib/gdb/gdb/config/i386/xm-i386m3.h
+++ b/contrib/gdb/gdb/config/i386/xm-i386m3.h
@@ -19,11 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
-/* Avoid "INT_MIN redefined" warnings -- by defining it here, exactly
- the same as in the system <machine/machtypes.h> file. */
-#undef INT_MIN
-#define INT_MIN 0x80000000
-
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH 1
diff --git a/contrib/gdb/gdb/config/i386/xm-i386mach.h b/contrib/gdb/gdb/config/i386/xm-i386mach.h
index c50da67..eb47bfb 100644
--- a/contrib/gdb/gdb/config/i386/xm-i386mach.h
+++ b/contrib/gdb/gdb/config/i386/xm-i386mach.h
@@ -19,11 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
-/* Avoid "INT_MIN redefined" warnings -- by defining it here, exactly
- the same as in the system <machine/machtypes.h> file. */
-#undef INT_MIN
-#define INT_MIN 0x80000000
-
/* This is the amount to subtract from u.u_ar0
to get the offset in the core file of the register values. */
diff --git a/contrib/gdb/gdb/config/i386/xm-i386mk.h b/contrib/gdb/gdb/config/i386/xm-i386mk.h
index 7bbe02f..661c9cb 100644
--- a/contrib/gdb/gdb/config/i386/xm-i386mk.h
+++ b/contrib/gdb/gdb/config/i386/xm-i386mk.h
@@ -22,4 +22,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define EMULATOR_BASE 0xa0000000
#define EMULATOR_END 0xa0040000
-#include "xm-i386mach3.h"
+#include "i386/xm-i386m3.h"
diff --git a/contrib/gdb/gdb/config/i386/xm-i386v4.h b/contrib/gdb/gdb/config/i386/xm-i386v4.h
index 7d5aff0..7f782db 100644
--- a/contrib/gdb/gdb/config/i386/xm-i386v4.h
+++ b/contrib/gdb/gdb/config/i386/xm-i386v4.h
@@ -25,13 +25,3 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Pick up more stuff from the generic SVR4 host include file. */
#include "xm-sysv4.h"
-
-/* If you expect to use the mmalloc package to obtain mapped symbol files,
- for now you have to specify some parameters that determine how gdb places
- the mappings in it's address space. See the comments in map_to_address()
- for details. This is expected to only be a short term solution. Yes it
- is a kludge.
- FIXME: Make this more automatic. */
-
-#define MMAP_BASE_ADDRESS 0x81000000 /* First mapping here */
-#define MMAP_INCREMENT 0x01000000 /* Increment to next mapping */
diff --git a/contrib/gdb/gdb/config/i386/xm-linux.h b/contrib/gdb/gdb/config/i386/xm-linux.h
index 5004926..217c6d4 100644
--- a/contrib/gdb/gdb/config/i386/xm-linux.h
+++ b/contrib/gdb/gdb/config/i386/xm-linux.h
@@ -1,4 +1,4 @@
-/* Native support for linux, for GDB, the GNU debugger.
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of GDB.
@@ -33,14 +33,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Need R_OK etc, but USG isn't defined. */
#include <unistd.h>
-/* If you expect to use the mmalloc package to obtain mapped symbol files,
- for now you have to specify some parameters that determine how gdb places
- the mappings in it's address space. See the comments in map_to_address()
- for details. This is expected to only be a short term solution. Yes it
- is a kludge.
- FIXME: Make this more automatic. */
-
-#define MMAP_BASE_ADDRESS 0x20000000 /* First mapping here */
-#define MMAP_INCREMENT 0x01000000 /* Increment to next mapping */
-
#endif /* #ifndef XM_LINUX_H */
diff --git a/contrib/gdb/gdb/config/i386/xm-windows.h b/contrib/gdb/gdb/config/i386/xm-windows.h
new file mode 100644
index 0000000..e083010
--- /dev/null
+++ b/contrib/gdb/gdb/config/i386/xm-windows.h
@@ -0,0 +1,35 @@
+/* Definitions for hosting on WIN32, built with Microsoft Visual C/C++, for GDB.
+ Copyright 1996, 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "i386/xm-cygwin.h"
+
+#undef PRINTF_HAS_LONG_LONG
+#undef HAVE_UNISTD_H
+#undef HAVE_TERMIO_H
+#undef HAVE_TERMIOS_H
+#undef HAVE_SGTTY_H
+#undef HAVE_SBRK
+#define CANT_FORK
+
+#define MALLOC_INCOMPATIBLE
+
+#include <malloc.h>
+
+#define SIGQUIT 3
+#define SIGTRAP 5
diff --git a/contrib/gdb/gdb/configure b/contrib/gdb/gdb/configure
index e8a1ad9..f70d046 100644
--- a/contrib/gdb/gdb/configure
+++ b/contrib/gdb/gdb/configure
@@ -1,8 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.8
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
@@ -12,23 +12,21 @@ ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
- --enable-netrom "
+ --disable-nls do not use Native Language Support"
ac_help="$ac_help
- --enable-gm "
+ --with-included-gettext use the GNU gettext library included here"
ac_help="$ac_help
- --enable-sim-powerpc "
+ --enable-tui Enable full-screen terminal user interface"
ac_help="$ac_help
- --enable-gdbtk "
+ --enable-netrom Enable NetROM support"
ac_help="$ac_help
- --with-x use the X Window System"
-ac_help="$ac_help
- --with-tclinclude directory where tcl private headers are"
+ --enable-build-warnings Enable build-time compiler warnings if gcc is used"
ac_help="$ac_help
- --with-tcllib directory where the tcl library is"
+ --with-mmalloc Use memory mapped malloc package"
ac_help="$ac_help
- --with-tkinclude directory where the tk private headers are"
+ --with-x use the X Window System"
ac_help="$ac_help
- --with-tklib directory where the tk library is"
+ --enable-shared Use shared libraries"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -67,6 +65,9 @@ mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
ac_prev=
for ac_option
@@ -348,7 +349,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.8"
+ echo "configure generated by autoconf version 2.13"
exit 0 ;;
-with-* | --with-*)
@@ -450,11 +451,14 @@ do
done
# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
@@ -515,8 +519,11 @@ ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+ac_exeext=
+ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
@@ -535,14 +542,16 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:546: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc"
@@ -563,15 +572,17 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:576: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@@ -606,10 +617,92 @@ else
echo "$ac_t""no" 1>&6
fi
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:627: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:659: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 670 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:701: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:706: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -618,7 +711,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:622: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:715: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -626,36 +719,50 @@ fi
fi
echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
if test $ac_cv_prog_gcc = yes; then
GCC=yes
- if test "${CFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:734: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo 'void f(){}' > conftest.c
if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_gcc_g=yes
+ ac_cv_prog_cc_g=yes
else
- ac_cv_prog_gcc_g=no
+ ac_cv_prog_cc_g=no
fi
rm -f conftest*
fi
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
- if test $ac_cv_prog_gcc_g = yes; then
- CFLAGS="-g -O"
- else
- CFLAGS="-O"
- fi
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
fi
else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:766: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -670,39 +777,62 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 674 "configure"
+#line 781 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:680: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:787: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 689 "configure"
+#line 798 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:695: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:804: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 815 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:821: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CPP=/lib/cpp
fi
rm -f conftest*
fi
rm -f conftest*
+fi
+rm -f conftest*
ac_cv_prog_CPP="$CPP"
fi
CPP="$ac_cv_prog_CPP"
@@ -712,8 +842,9 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for AIX""... $ac_c" 1>&6
+echo "configure:846: checking for AIX" >&5
cat > conftest.$ac_ext <<EOF
-#line 717 "configure"
+#line 848 "configure"
#include "confdefs.h"
#ifdef _AIX
yes
@@ -734,24 +865,817 @@ fi
rm -f conftest*
-ac_safe=`echo "minix/config.h" | tr './\055' '___'`
-echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:870: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:894: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ cat > conftest.$ac_ext <<EOF
+#line 910 "configure"
+#include "confdefs.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+
+int main() {
+
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+
+; return 0; }
+EOF
+if { (eval echo configure:947: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_prog_cc_stdc="$ac_arg"; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CC="$ac_save_CC"
+
+fi
+
+if test -z "$am_cv_prog_cc_stdc"; then
+ echo "$ac_t""none needed" 1>&6
+else
+ echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1018: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:1039: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1057: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+ALL_LINGUAS=
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1082: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1111: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1139: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1144 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1169 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1187 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1208 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1243: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1248 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1297: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1318: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1325 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1332: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:1358: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1363 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1391: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1396 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1426: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1431 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1459: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1464 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:1524: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1529 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1554: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1559 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:1609: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1617 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:1636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1661: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 744 "configure"
+#line 1666 "configure"
#include "confdefs.h"
-#include <minix/config.h>
+#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:749: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1671: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
@@ -759,66 +1683,1078 @@ rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
- MINIX=yes
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
else
echo "$ac_t""no" 1>&6
-MINIX=
fi
+done
-if test "$MINIX" = yes; then
- cat >> confdefs.h <<\EOF
-#define _POSIX_SOURCE 1
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1700: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1705 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
EOF
+if { (eval echo configure:1728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
- cat >> confdefs.h <<\EOF
-#define _POSIX_1_SOURCE 2
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:1753: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1761 "configure"
+#include "confdefs.h"
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:1901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
cat >> confdefs.h <<\EOF
-#define _MINIX 1
+#define HAVE_MMAP 1
EOF
fi
-echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-if test -d /etc/conf/kconfig.d &&
- grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
-then
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1929: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1934 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1939: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
- ISC=yes # If later tests want to check for ISC.
- cat >> confdefs.h <<\EOF
-#define _POSIX_SOURCE 1
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
- if test "$GCC" = yes; then
- CC="$CC -posix"
- else
- CC="$CC -Xp"
- fi
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1969: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1974 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
else
echo "$ac_t""no" 1>&6
- ISC=
fi
+done
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2026: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2031 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:2088: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2093 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:2100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:2121: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:2141: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:2160: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2165 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2170: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:2187: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2192 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2199: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:2215: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2223 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:2250: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2255 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2290: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2324: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2329 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2379: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2415: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 2447 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:2455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2487: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2521: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2557: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:2647: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:2675: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2680 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2685: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+
+CONFIG_OBS=
+CONFIG_DEPS=
+CONFIG_SRCS=
+
+configdirs="doc testsuite"
+
+
+. ${srcdir}/configure.host
+
+. ${srcdir}/configure.tgt
+
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -827,27 +2763,30 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:2772: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall installbsd scoinst install; do
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
@@ -858,7 +2797,7 @@ else
;;
esac
done
- IFS="$ac_save_ifs"
+ IFS="$ac_save_IFS"
fi
if test "${ac_cv_path_install+set}" = set; then
@@ -877,50 +2816,9 @@ echo "$ac_t""$INSTALL" 1>&6
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-
-# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`$ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
-build=`$ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
if test $host != $build; then
ac_tool_prefix=${host_alias}-
@@ -931,14 +2829,16 @@ fi
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2833: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$AR"; then
ac_cv_prog_AR="$AR" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
@@ -961,14 +2861,16 @@ fi
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2865: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
@@ -991,14 +2893,16 @@ if test -n "$ac_tool_prefix"; then
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2897: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="ranlib"
@@ -1026,14 +2930,16 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2934: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$YACC"; then
ac_cv_prog_YACC="$YACC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_YACC="$ac_prog"
@@ -1054,143 +2960,6 @@ test -n "$YACC" && break
done
test -n "$YACC" || YACC="yacc"
-for ac_prog in mawk gawk nawk awk
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_AWK="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-AWK="$ac_cv_prog_AWK"
-if test -n "$AWK"; then
- echo "$ac_t""$AWK" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$AWK" && break
-done
-
-
-ac_aux_dir=
-for ac_dir in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Do some error checking and defaulting for the host and target type.
-# The inputs are:
-# configure --host=HOST --target=TARGET --build=BUILD NONOPT
-#
-# The rules are:
-# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
-# 2. Host defaults to nonopt.
-# 3. If nonopt is not specified, then host defaults to the current host,
-# as determined by config.guess.
-# 4. Target and build default to nonopt.
-# 5. If nonopt is not specified, then target and build default to host.
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-case $host---$target---$nonopt in
-NONE---*---* | *---NONE---* | *---*---NONE) ;;
-*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
-esac
-
-
-# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`$ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking target system type""... $ac_c" 1>&6
-
-target_alias=$target
-case "$target_alias" in
-NONE)
- case $nonopt in
- NONE) target_alias=$host_alias ;;
- *) target_alias=$nonopt ;;
- esac ;;
-esac
-
-target=`$ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$target" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
-
-build=`$ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
-
-test "$host_alias" != "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
if test "$program_transform_name" = s,x,x,; then
program_transform_name=
@@ -1212,38 +2981,55 @@ test "$program_suffix" != NONE &&
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:2986: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- if test "$cross_compiling" = yes; then
- ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 1225 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 2991 "configure"
#include "confdefs.h"
-main(){return(0);}
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
EOF
-{ (eval echo configure:1229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_c_cross=no
+if { (eval echo configure:3008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
else
- ac_cv_c_cross=yes
-fi
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
fi
-rm -fr conftest*
+rm -f conftest*
fi
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:3028: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1247 "configure"
+#line 3033 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1251,13 +3037,15 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1255: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:3041: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
ac_cv_header_stdc=yes
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_stdc=no
fi
@@ -1266,7 +3054,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1270 "configure"
+#line 3058 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1284,7 +3072,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1288 "configure"
+#line 3076 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1304,8 +3092,8 @@ if test $ac_cv_header_stdc = yes; then
if test "$cross_compiling" = yes; then
:
else
-cat > conftest.$ac_ext <<EOF
-#line 1309 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 3097 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1316,15 +3104,19 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-{ (eval echo configure:1320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:3108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_header_stdc=no
fi
-fi
rm -fr conftest*
fi
+
+fi
fi
echo "$ac_t""$ac_cv_header_stdc" 1>&6
@@ -1335,26 +3127,34 @@ EOF
fi
-for ac_hdr in limits.h memory.h string.h strings.h unistd.h termios.h termio.h sgtty.h stddef.h sys/procfs.h link.h endian.h
+
+for ac_hdr in ctype.h curses.h endian.h link.h \
+ memory.h objlist.h ptrace.h sgtty.h stddef.h stdlib.h \
+ string.h sys/procfs.h sys/ptrace.h sys/reg.h \
+ term.h termio.h termios.h unistd.h wait.h sys/wait.h \
+ wchar.h wctype.h asm/debugreg.h sys/debugreg.h
do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3140: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1347 "configure"
+#line 3145 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1352: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:3150: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
@@ -1362,7 +3162,7 @@ rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define $ac_tr_hdr 1
EOF
@@ -1373,11 +3173,12 @@ fi
done
echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
+echo "configure:3177: checking whether stat file-mode macros are broken" >&5
if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1381 "configure"
+#line 3182 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1428,23 +3229,101 @@ EOF
fi
-for ac_func in setpgid sbrk
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:3234: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3239 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:3288: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+
+for ac_func in setpgid sbrk sigaction isascii bzero bcopy btowc
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3312: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1439 "configure"
+#line 3317 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -1457,16 +3336,18 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
@@ -1479,94 +3360,986 @@ else
fi
done
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:3367: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3372 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:3379: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
-echo $ac_n "checking for gregset_t type""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'gdb_cv_have_gregset_t'+set}'`\" = set"; then
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:3400: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1489 "configure"
+#line 3405 "configure"
#include "confdefs.h"
-#include <sys/procfs.h>
-int main() { return 0; }
-int t() {
-gregset_t *gregsetp = 0
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:3433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:3465: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3470 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3495: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3500 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:3550: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3558 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:3577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+
+echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6
+echo "configure:3600: checking whether malloc must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3605 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) malloc
; return 0; }
EOF
-if { (eval echo configure:1497: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3626: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
- gdb_cv_have_gregset_t=yes
+ bfd_cv_decl_needed_malloc=no
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- gdb_cv_have_gregset_t=no
+ bfd_cv_decl_needed_malloc=yes
fi
rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_malloc" 1>&6
+if test $bfd_cv_decl_needed_malloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_MALLOC 1
+EOF
fi
-echo "$ac_t""$gdb_cv_have_gregset_t" 1>&6
-if test $gdb_cv_have_gregset_t = yes; then
+echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6
+echo "configure:3647: checking whether realloc must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3652 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) realloc
+; return 0; }
+EOF
+if { (eval echo configure:3673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_realloc=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_realloc=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_realloc" 1>&6
+if test $bfd_cv_decl_needed_realloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_REALLOC 1
+EOF
+
+fi
+
+echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
+echo "configure:3694: checking whether free must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3699 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) free
+; return 0; }
+EOF
+if { (eval echo configure:3720: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6
+if test $bfd_cv_decl_needed_free = yes; then
cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_FREE 1
+EOF
+
+fi
+
+echo $ac_n "checking whether strerror must be declared""... $ac_c" 1>&6
+echo "configure:3741: checking whether strerror must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strerror'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3746 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strerror
+; return 0; }
+EOF
+if { (eval echo configure:3767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strerror=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strerror=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strerror" 1>&6
+if test $bfd_cv_decl_needed_strerror = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRERROR 1
+EOF
+
+fi
+
+echo $ac_n "checking whether strdup must be declared""... $ac_c" 1>&6
+echo "configure:3788: checking whether strdup must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strdup'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3793 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strdup
+; return 0; }
+EOF
+if { (eval echo configure:3814: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strdup=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strdup=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strdup" 1>&6
+if test $bfd_cv_decl_needed_strdup = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRDUP 1
+EOF
+
+fi
+
+
+
+# The following save_state_t checkery is only necessary for HPUX
+# versions earlier than 10.20. When those fade from memory, this
+# could be expunged. --jsm 1999-03-22
+
+echo $ac_n "checking for HPUX save_state structure""... $ac_c" 1>&6
+echo "configure:3841: checking for HPUX save_state structure" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3843 "configure"
+#include "confdefs.h"
+#include <machine/save_state.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "save_state_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ gdb_cv_hpux_savestate=yes
+else
+ rm -rf conftest*
+ gdb_cv_hpux_savestate=no
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 3858 "configure"
+#include "confdefs.h"
+#include <machine/save_state.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ss_wide" >/dev/null 2>&1; then
+ rm -rf conftest*
+ gdb_cv_hpux_sswide=yes
+else
+ rm -rf conftest*
+ gdb_cv_hpux_sswide=no
+fi
+rm -f conftest*
+
+if test $gdb_cv_hpux_savestate = yes
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_SAVE_STATE_T 1
+EOF
+
+fi
+if test $gdb_cv_hpux_sswide = yes
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_MEMBER_SS_WIDE 1
+EOF
+
+fi
+echo "$ac_t""$gdb_cv_hpux_sswide" 1>&6
+
+
+# If we are configured native on GNU/Linux, work around problems with
+# sys/procfs.h
+# Also detect which type of /proc is in use, such as for Unixware.
+
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ i[3456]86-*-linux*)
+ cat >> confdefs.h <<\EOF
+#define START_INFERIOR_TRAPS_EXPECTED 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define sys_quotactl 1
+EOF
+
+ ;;
+ esac
+ echo $ac_n "checking for directory proc entries""... $ac_c" 1>&6
+echo "configure:3907: checking for directory proc entries" >&5
+# The [gdb_host != sun4sol2] hack is because Solaris does provide the
+# multiple procfs files as of Solaris 2.6, but GDB can't use it right now.
+ if test "$ac_cv_header_sys_procfs_h" = yes -a "$gdb_host" != sun4sol2 \
+ -a -d /proc/$$ \
+ -a -f /proc/$$/ctl \
+ -a -f /proc/$$/as \
+ -a -f /proc/$$/map \
+ -a -f /proc/$$/status; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_MULTIPLE_PROC_FDS 1
+EOF
+
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+fi
+
+if test "$ac_cv_header_sys_procfs_h" = yes; then
+ echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:3928: checking for pstatus_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3933 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+pstatus_t avar
+; return 0; }
+EOF
+if { (eval echo configure:3940: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pstatus_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pstatus_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pstatus_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PSTATUS_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6
+
+ echo $ac_n "checking for prrun_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:3962: checking for prrun_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prrun_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3967 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+prrun_t avar
+; return 0; }
+EOF
+if { (eval echo configure:3974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prrun_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prrun_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prrun_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRRUN_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prrun_t" 1>&6
+
+ echo $ac_n "checking for gregset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:3996: checking for gregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_gregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4001 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+gregset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_gregset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_gregset_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_gregset_t = yes; then
+ cat >> confdefs.h <<\EOF
#define HAVE_GREGSET_T 1
EOF
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_gregset_t" 1>&6
+
+ echo $ac_n "checking for fpregset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4030: checking for fpregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_fpregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4035 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+fpregset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4042: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_fpregset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_fpregset_t=no
+
fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_fpregset_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_FPREGSET_T 1
+EOF
-echo $ac_n "checking for fpregset_t type""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'gdb_cv_have_fpregset_t'+set}'`\" = set"; then
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_fpregset_t" 1>&6
+
+
+
+ echo $ac_n "checking for PIOCSET ioctl entry in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4066: checking for PIOCSET ioctl entry in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_procfs_piocset'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1521 "configure"
+#line 4071 "configure"
#include "confdefs.h"
+#include <unistd.h>
+#include <sys/types.h>
#include <sys/procfs.h>
-int main() { return 0; }
-int t() {
-fpregset_t *fpregsetp = 0
+
+int main() {
+
+ int dummy;;
+ dummy = ioctl(0, PIOCSET, &dummy);
+
+; return 0; }
+EOF
+if { (eval echo configure:4084: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_procfs_piocset=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_procfs_piocset=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_procfs_piocset" 1>&6
+ if test $gdb_cv_have_procfs_piocset = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PROCFS_PIOCSET 1
+EOF
+
+ fi
+fi
+
+echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
+echo "configure:4106: checking for main in -lm" >&5
+ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4114 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:4121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lm $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for wctype in -lc""... $ac_c" 1>&6
+echo "configure:4150: checking for wctype in -lc" >&5
+ac_lib_var=`echo c'_'wctype | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4158 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char wctype();
+
+int main() {
+wctype()
+; return 0; }
+EOF
+if { (eval echo configure:4169: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for wctype in -lw""... $ac_c" 1>&6
+echo "configure:4188: checking for wctype in -lw" >&5
+ac_lib_var=`echo w'_'wctype | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lw $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4196 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char wctype();
+
+int main() {
+wctype()
; return 0; }
EOF
-if { (eval echo configure:1529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:4207: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- gdb_cv_have_fpregset_t=yes
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- gdb_cv_have_fpregset_t=no
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo w | sed -e 's/^a-zA-Z0-9_/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lw $LIBS"
+else
+ echo "$ac_t""no" 1>&6
fi
-echo "$ac_t""$gdb_cv_have_fpregset_t" 1>&6
-if test $gdb_cv_have_fpregset_t = yes; then
+fi
+
+
+
+echo $ac_n "checking for long long support in compiler""... $ac_c" 1>&6
+echo "configure:4239: checking for long long support in compiler" >&5
+if eval "test \"`echo '$''{'gdb_cv_c_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4244 "configure"
+#include "confdefs.h"
+
+int main() {
+
+ extern long long foo;
+ switch (foo & 2) { case 0: return 1; }
+
+; return 0; }
+EOF
+if { (eval echo configure:4254: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_c_long_long=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_c_long_long=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_c_long_long" 1>&6
+if test $gdb_cv_c_long_long = yes; then
cat >> confdefs.h <<\EOF
-#define HAVE_FPREGSET_T 1
+#define CC_HAS_LONG_LONG 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for long long support in printf""... $ac_c" 1>&6
+echo "configure:4276: checking for long long support in printf" >&5
+if eval "test \"`echo '$''{'gdb_cv_printf_has_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gdb_cv_printf_has_long_long=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4284 "configure"
+#include "confdefs.h"
+
+int main () {
+ char buf[32];
+ long long l = 0;
+ l = (l << 16) + 0x0123;
+ l = (l << 16) + 0x4567;
+ l = (l << 16) + 0x89ab;
+ l = (l << 16) + 0xcdef;
+ sprintf (buf, "0x%016llx", l);
+ return (strcmp ("0x0123456789abcdef", buf));
+}
+EOF
+if { (eval echo configure:4298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gdb_cv_printf_has_long_long=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gdb_cv_printf_has_long_long=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test $gdb_cv_printf_has_long_long = yes; then
+ cat >> confdefs.h <<\EOF
+#define PRINTF_HAS_LONG_LONG 1
EOF
fi
+echo "$ac_t""$gdb_cv_printf_has_long_long" 1>&6
echo $ac_n "checking for long double support in compiler""... $ac_c" 1>&6
+echo "configure:4322: checking for long double support in compiler" >&5
if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1554 "configure"
+#line 4327 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() {
+int main() {
long double foo;
; return 0; }
EOF
-if { (eval echo configure:1562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4334: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_long_double=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_c_long_double=no
fi
rm -f conftest*
-
fi
echo "$ac_t""$ac_cv_c_long_double" 1>&6
@@ -1579,14 +4352,15 @@ fi
echo $ac_n "checking for long double support in printf""... $ac_c" 1>&6
+echo "configure:4356: checking for long double support in printf" >&5
if eval "test \"`echo '$''{'gdb_cv_printf_has_long_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
gdb_cv_printf_has_long_double=no
else
-cat > conftest.$ac_ext <<EOF
-#line 1590 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 4364 "configure"
#include "confdefs.h"
int main () {
@@ -1596,16 +4370,20 @@ int main () {
return (strncmp ("3.14159", buf, 7));
}
EOF
-{ (eval echo configure:1600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:4374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
gdb_cv_printf_has_long_double=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
gdb_cv_printf_has_long_double=no
fi
-fi
rm -fr conftest*
fi
+fi
+
if test $gdb_cv_printf_has_long_double = yes; then
cat >> confdefs.h <<\EOF
#define PRINTF_HAS_LONG_DOUBLE 1
@@ -1614,23 +4392,107 @@ EOF
fi
echo "$ac_t""$gdb_cv_printf_has_long_double" 1>&6
-for ac_func in valloc getpagesize
+
+echo $ac_n "checking for long double support in scanf""... $ac_c" 1>&6
+echo "configure:4398: checking for long double support in scanf" >&5
+if eval "test \"`echo '$''{'gdb_cv_scanf_has_long_double'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gdb_cv_scanf_has_long_double=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4406 "configure"
+#include "confdefs.h"
+
+int main () {
+ char *buf = "3.141592653";
+ long double f = 0;
+ sscanf (buf, "%Lg", &f);
+ return !(f > 3.14159 && f < 3.14160);
+}
+EOF
+if { (eval echo configure:4416: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gdb_cv_scanf_has_long_double=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gdb_cv_scanf_has_long_double=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test $gdb_cv_scanf_has_long_double = yes; then
+ cat >> confdefs.h <<\EOF
+#define SCANF_HAS_LONG_DOUBLE 1
+EOF
+
+fi
+echo "$ac_t""$gdb_cv_scanf_has_long_double" 1>&6
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4442: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4447 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4452: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4481: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1625 "configure"
+#line 4486 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -1643,16 +4505,18 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:4509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
@@ -1666,94 +4530,170 @@ fi
done
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_mmap'+set}'`\" = set"; then
+echo "configure:4534: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
- ac_cv_func_mmap=no
+ ac_cv_func_mmap_fixed_mapped=no
else
-cat > conftest.$ac_ext <<EOF
-#line 1677 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 4542 "configure"
#include "confdefs.h"
-/* Thanks to Mike Haertel and Jim Avera for this test. */
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
+/* This mess was copied from the GNU getpagesize.h. */
#ifndef HAVE_GETPAGESIZE
-# include <sys/param.h>
-# ifdef EXEC_PAGESIZE
-# define getpagesize() EXEC_PAGESIZE
-# else
-# ifdef NBPG
-# define getpagesize() NBPG * CLSIZE
-# ifndef CLSIZE
-# define CLSIZE 1
-# endif
-# else
-# ifdef NBPC
-# define getpagesize() NBPC
-# else
-# define getpagesize() PAGESIZE /* SVR4 */
-# endif
-# endif
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
# endif
-#endif
-#ifndef HAVE_VALLOC
-# define valloc malloc
-#endif
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
#ifdef __cplusplus
-extern "C" { void *valloc(unsigned), *malloc(unsigned); }
+extern "C" { void *malloc(unsigned); }
#else
-char *valloc(), *malloc();
+char *malloc();
#endif
int
main()
{
- char *buf1, *buf2, *buf3;
- int i = getpagesize(), j;
- int i2 = i * 2;
- int fd;
-
- buf1 = (char *)valloc(i2);
- buf2 = (char *)valloc(i);
- buf3 = (char *)malloc(i2);
- for (j = 0; j < i2; ++j)
- *(buf1 + j) = rand();
- fd = open("conftestmmap", O_CREAT | O_RDWR, 0666);
- write(fd, buf1, i2);
- mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0);
- for (j = 0; j < i; ++j)
- if (*(buf1 + j) != *(buf2 + j))
- exit(1);
- lseek(fd, (long)i, 0);
- read(fd, buf2, i); /* read into mapped memory -- file should not change */
- /* (it does in i386 SVR4.0 - Jim Avera, jima@netcom.com) */
- lseek(fd, (long)0, 0);
- read(fd, buf3, i2);
- for (j = 0; j < i2; ++j)
- if (*(buf1 + j) != *(buf3 + j))
- exit(1);
- exit(0);
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
}
EOF
-{ (eval echo configure:1746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_func_mmap=yes
+if { (eval echo configure:4682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
else
- ac_cv_func_mmap=no
-fi
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
fi
rm -fr conftest*
fi
-echo "$ac_t""$ac_cv_func_mmap" 1>&6
-if test $ac_cv_func_mmap = yes; then
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_MMAP 1
EOF
@@ -1761,9 +4701,198 @@ EOF
fi
+
+
+if test ${build} = ${host} -a ${host} = ${target} ; then
+ case ${host_os} in
+ hpux*)
+ echo $ac_n "checking for HPUX/OSF thread support""... $ac_c" 1>&6
+echo "configure:4711: checking for HPUX/OSF thread support" >&5
+ if test -f /usr/include/dce/cma_config.h ; then
+ if test "$GCC" = "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_HPUX_THREAD_SUPPORT 1
+EOF
+
+ CONFIG_OBS="${CONFIG_OJS} hpux-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} hpux-thread.c"
+ else
+ echo "$ac_t""no (suppressed because you are not using GCC)" 1>&6
+ fi
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+ ;;
+ solaris*)
+ echo $ac_n "checking for Solaris thread debugging library""... $ac_c" 1>&6
+echo "configure:4730: checking for Solaris thread debugging library" >&5
+ if test -f /usr/lib/libthread_db.so.1 ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_THREAD_DB_LIB 1
+EOF
+
+ CONFIG_OBS="${CONFIG_OBS} sol-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c"
+ echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:4740: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4748 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:4759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-ldl $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "$GCC" = "yes" ; then
+ # The GNU linker requires the -export-dynamic option to make
+ # all symbols visible in the dynamic symbol table.
+ hold_ldflags=$LDFLAGS
+ echo $ac_n "checking for the ld -export-dynamic flag""... $ac_c" 1>&6
+echo "configure:4791: checking for the ld -export-dynamic flag" >&5
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ cat > conftest.$ac_ext <<EOF
+#line 4794 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:4801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ found=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ found=no
+fi
+rm -f conftest*
+ LDFLAGS=$hold_ldflags
+ echo "$ac_t""$found" 1>&6
+ if test $found = yes; then
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} -Wl,-export-dynamic"
+ fi
+ fi
+ # Sun randomly tweaked the prototypes in <proc_service.h>
+ # at one point.
+ echo $ac_n "checking if <proc_service.h> is old""... $ac_c" 1>&6
+echo "configure:4820: checking if <proc_service.h> is old" >&5
+ if eval "test \"`echo '$''{'gdb_cv_proc_service_is_old'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 4826 "configure"
+#include "confdefs.h"
+
+ #include <proc_service.h>
+ ps_err_e ps_pdwrite
+ (struct ps_prochandle*, psaddr_t, const void*, size_t);
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:4837: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_proc_service_is_old=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_proc_service_is_old=yes
+fi
+rm -f conftest*
+
+fi
+
+ echo "$ac_t""$gdb_cv_proc_service_is_old" 1>&6
+ if test $gdb_cv_proc_service_is_old = yes; then
+ cat >> confdefs.h <<\EOF
+#define PROC_SERVICE_IS_OLD 1
+EOF
+
+ fi
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+ ;;
+ esac
+
+fi
+
ENABLE_CFLAGS=
-ENABLE_CLIBS=
-ENABLE_OBS=
+
+# Check whether --enable-tui or --disable-tui was given.
+if test "${enable_tui+set}" = set; then
+ enableval="$enable_tui"
+
+ case "${enable_tui}" in
+ yes | no) ;;
+ "") enable_tui=yes ;;
+ *)
+ { echo "configure: error: Bad value for --enable-tui: ${enableval}" 1>&2; exit 1; }
+ ;;
+ esac
+
+fi
+
+case ${enable_tui} in
+ "yes" )
+ cat >> confdefs.h <<\EOF
+#define TUI 1
+EOF
+
+ BUILD_TUI=all-tui
+ TUI_LIBRARY=tui/libtui.a
+ ;;
+ * )
+ BUILD_TUI=
+ TUI_LIBRARY=
+ ;;
+esac
+
+
# Check whether --enable-netrom or --disable-netrom was given.
if test "${enable_netrom+set}" = set; then
@@ -1777,401 +4906,629 @@ fi
if test "${enable_netrom}" = "yes"; then
- ENABLE_OBS="${ENABLE_OBS} remote-nrom.o"
+ CONFIG_OBS="${CONFIG_OBS} remote-nrom.o"
+ CONFIG_SRCS="${CONFIG_SRCS} remote-nrom.c"
fi
+# Check whether --enable-build-warnings or --disable-build-warnings was given.
+if test "${enable_build_warnings+set}" = set; then
+ enableval="$enable_build_warnings"
+ build_warnings="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations"
+case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+else
+ build_warnings=""
+fi
-# Check whether --enable-sim-powerpc or --disable-sim-powerpc was given.
-if test "${enable_sim_powerpc+set}" = set; then
- enableval="$enable_sim_powerpc"
- case "${enableval}" in
-yes) powerpc_sim=yes ;;
-no) powerpc_sim=no ;;
-*) { echo "configure: error: bad value ${enableval} given for sim-powerpc option" 1>&2; exit 1; } ;;
+if test "x${build_warnings}" != x -a "x$GCC" = xyes
+then
+ WARN_CFLAGS="${build_warnings}"
+else
+ WARN_CFLAGS=""
+fi
+
+
+MMALLOC_CFLAGS=
+MMALLOC=
+
+
+
+# Check whether --with-mmalloc or --without-mmalloc was given.
+if test "${with_mmalloc+set}" = set; then
+ withval="$with_mmalloc"
+ case "${withval}" in
+ yes) want_mmalloc=true ;;
+ no) want_mmalloc=false;;
+ *) { echo "configure: error: bad value ${withval} for GDB with-mmalloc option" 1>&2; exit 1; } ;;
esac
else
- if test x"$GCC" != x""; then powerpc_sim=yes; else powerpc_sim=no; fi
+ want_mmalloc=false
+fi
+
+if test x$want_mmalloc = xtrue; then
+ cat >> confdefs.h <<\EOF
+#define USE_MMALLOC 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define MMCHECK_FORCE 1
+EOF
+
+ MMALLOC_CFLAGS="-I$srcdir/../mmalloc"
+ MMALLOC='../mmalloc/libmmalloc.a'
+fi
+
+if test x$gdb_cv_os_cygwin = xyes; then
+ TERM_LIB='`if test -r ../libtermcap/libtermcap.a; then echo ../libtermcap/libtermcap.a; else echo -ltermcap; fi`'
+else
+ TERM_LIB=
+ echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6
+echo "configure:4974: checking for tgetent in -lncurses" >&5
+ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lncurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4982 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:4993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lncurses
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -lHcurses""... $ac_c" 1>&6
+echo "configure:5012: checking for tgetent in -lHcurses" >&5
+ac_lib_var=`echo Hcurses'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lHcurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5020 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:5031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lHcurses
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -ltermlib""... $ac_c" 1>&6
+echo "configure:5050: checking for tgetent in -ltermlib" >&5
+ac_lib_var=`echo termlib'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ltermlib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5058 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:5069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-ltermlib
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
+echo "configure:5088: checking for tgetent in -ltermcap" >&5
+ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ltermcap $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5096 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:5107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
-# target_subdir is used by the testsuite to find the target libraries.
-target_subdir=
-if test "${host}" != "${target}"; then
- target_subdir="${target_alias}/"
fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-ltermcap
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6
+echo "configure:5126: checking for tgetent in -lcurses" >&5
+ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5134 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:5145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
-configdirs="doc testsuite"
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lcurses
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -lterminfo""... $ac_c" 1>&6
+echo "configure:5164: checking for tgetent in -lterminfo" >&5
+ac_lib_var=`echo terminfo'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lterminfo $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5172 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:5183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
-# Map host cpu into the config cpu subdirectory name.
-# The default is $host_cpu.
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lterminfo
+else
+ echo "$ac_t""no" 1>&6
+fi
-case "${host_cpu}" in
+fi
-c[12]) gdb_host_cpu=convex ;;
-hppa*) gdb_host_cpu=pa ;;
-i[3456]86) gdb_host_cpu=i386 ;;
-m68*) gdb_host_cpu=m68k ;;
-m88*) gdb_host_cpu=m88k ;;
-np1) gdb_host_cpu=gould ;;
-pyramid) gdb_host_cpu=pyr ;;
-powerpc*) gdb_host_cpu=powerpc ;;
-sparc64) gdb_host_cpu=sparc ;;
-*) gdb_host_cpu=$host_cpu ;;
+fi
-esac
+fi
-# map host info into gdb names.
+fi
-case "${host}" in
+fi
-a29k-*-*) gdb_host=ultra3 ;;
-
-alpha-*-osf1*) gdb_host=alpha-osf1 ;;
-alpha-*-osf2*) gdb_host=alpha-osf2 ;;
-alpha-*-osf[3456789]*) gdb_host=alpha-osf3 ;;
-
-arm-*-*) gdb_host=arm ;;
-
-c[12]-*-*) gdb_host=convex ;;
-
-hppa*-*-bsd*) gdb_host=hppabsd ;;
-hppa*-*-hiux*) gdb_host=hppahpux ;;
-hppa*-*-hpux*) gdb_host=hppahpux ;;
-hppa*-*-osf*) gdb_host=hppaosf ;;
-
-i[3456]86-ncr-*) gdb_host=ncr3000 ;;
-i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix
-i[3456]86-sequent-sysv4*) gdb_host=ptx4 ;;
-i[3456]86-sequent-sysv*) gdb_host=ptx ;;
-i[3456]86-*-aix*) gdb_host=i386aix ;;
-i[3456]86-*-bsd*) gdb_host=i386bsd ;;
-i[3456]86-*-dgux*) gdb_host=i386dgux ;;
-i[3456]86-*-freebsd*) gdb_host=fbsd ;;
-i[3456]86-*-netbsd*) gdb_host=nbsd ;;
-i[3456]86-*-go32*) gdb_host=go32 ;;
-i[3456]86-*-linux*) gdb_host=linux ;;
-i[3456]86-*-lynxos*) gdb_host=i386lynx ;;
-i[3456]86-*-mach3*) gdb_host=i386m3 ;;
-i[3456]86-*-mach*) gdb_host=i386mach ;;
-i[3456]86-*-gnu*) gdb_host=i386gnu ;;
-i[3456]86-*-osf1mk*) gdb_host=osf1mk ;;
-i[3456]86-*-sco3.2v5*) gdb_host=i386sco5 ;;
-i[3456]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
-i[3456]86-*-sco*) gdb_host=i386sco ;;
-i[3456]86-*-solaris*) gdb_host=i386sol2 ;;
-i[3456]86-*-sunos*) gdb_host=sun386 ;;
-i[3456]86-*-sysv3.2*) gdb_host=i386v32 ;;
-i[3456]86-*-sysv32*) gdb_host=i386v32 ;;
-i[3456]86-*-sysv4*) gdb_host=i386v4 ;;
-i[3456]86-*-unixware) gdb_host=i386v4 ;;
-i[3456]86-*-sysv*) gdb_host=i386v ;;
-i[3456]86-*-isc*) gdb_host=i386v32 ;;
-i[3456]86-*-os9k) gdb_host=i386os9k ;;
-i[3456]86-*-cygwin32) gdb_host=cygwin32 ;;
-m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
-m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
-m68030-sony-*) gdb_host=news1000 ;;
-
-m68*-altos-*) gdb_host=altos ;;
-m68*-apollo*-sysv*) gdb_host=apollo68v ;;
-m68*-apollo*-bsd*) gdb_host=apollo68b ;;
-m68*-att-*) gdb_host=3b1 ;;
-m68*-bull*-sysv*) gdb_host=dpx2 ;;
-m68*-hp-bsd*) gdb_host=hp300bsd ;;
-m68*-hp-hpux*) gdb_host=hp300hpux ;;
-m68*-isi-*) gdb_host=isi ;;
-m68*-*-lynxos*) gdb_host=m68klynx ;;
-m68*-*-netbsd*) gdb_host=nbsd ;;
-m68*-*-sysv4*) gdb_host=m68kv4 ;;
-m68*-motorola-*) gdb_host=delta68 ;;
-m68*-sony-*) gdb_host=news ;;
-m68*-sun-sunos3*) gdb_host=sun3os3 ;;
-m68*-sun-sunos4*) gdb_host=sun3os4 ;;
-m68*-sun-*) gdb_host=sun3os4 ;;
-
-m88*-harris-cxux*) gdb_host=cxux ;;
-m88*-motorola-sysv4*) gdb_host=delta88v4 ;;
-m88*-motorola-sysv*) gdb_host=delta88 ;;
-m88*-*-mach3*) gdb_host=mach3 ;;
-m88*-*-*) gdb_host=m88k ;;
-
-mips-dec-mach3*) gdb_host=mach3 ;;
-mips-dec-*) gdb_host=decstation ;;
-mips-little-*) gdb_host=littlemips ;;
-mips-sgi-irix3*) gdb_host=irix3 ;;
-mips-sgi-irix4*) gdb_host=irix4 ;;
-mips-sgi-irix5*) gdb_host=irix5 ;;
-mips-sony-*) gdb_host=news-mips ;;
-mips-*-mach3*) gdb_host=mach3 ;;
-mips-*-sysv4*) gdb_host=mipsv4 ;;
-mips-*-sysv*) gdb_host=riscos ;;
-mips-*-riscos*) gdb_host=riscos ;;
-
-none-*-*) gdb_host=none ;;
-
-np1-*-*) gdb_host=np1 ;;
-
-ns32k-*-mach3*) gdb_host=mach3 ;;
-ns32k-*-netbsd*) gdb_host=nbsd ;;
-ns32k-umax-*) gdb_host=umax ;;
-ns32k-utek-sysv*) gdb_host=merlin ;;
-
-powerpc-*-aix*) gdb_host=aix ;;
-powerpcle-*-cygwin32) gdb_host=cygwin32 ;;
-pn-*-*) gdb_host=pn ;;
-
-pyramid-*-*) gdb_host=pyramid ;;
-
-romp-*-*) gdb_host=rtbsd ;;
-
-rs6000-*-lynxos*) gdb_host=rs6000lynx ;;
-rs6000-*-aix4*) gdb_host=aix4 ;;
-rs6000-*-*) gdb_host=rs6000 ;;
-
-sparc-*-lynxos*) gdb_host=sparclynx ;;
-sparc-*-netbsd*) gdb_host=nbsd ;;
-sparc-*-solaris2*) gdb_host=sun4sol2 ;;
-sparc-*-sunos4*) gdb_host=sun4os4 ;;
-sparc-*-sunos5*) gdb_host=sun4sol2 ;;
-sparc-*-*) gdb_host=sun4os4 ;;
-sparc64-*-*) gdb_host=sun4sol2 ;;
-
-tahoe-*-*) gdb_host=tahoe ;;
-
-vax-*-bsd*) gdb_host=vaxbsd ;;
-vax-*-ultrix2*) gdb_host=vaxult2 ;;
-vax-*-ultrix*) gdb_host=vaxult ;;
-
-w65-*-*) gdb_host=w65 ;;
-esac
+ if test "x$TERM_LIB" = x
+ then
+ { echo "configure: error: Could not find a term library" 1>&2; exit 1; }
+ fi
+fi
-# Map target cpu into the config cpu subdirectory name.
-# The default is $target_cpu.
-case "${target_cpu}" in
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:5227: checking for X" >&5
-alpha) gdb_target_cpu=alpha ;;
-c[12]) gdb_target_cpu=convex ;;
-hppa*) gdb_target_cpu=pa ;;
-i[3456]86) gdb_target_cpu=i386 ;;
-m68*) gdb_target_cpu=m68k ;;
-m88*) gdb_target_cpu=m88k ;;
-mips*) gdb_target_cpu=mips ;;
-np1) gdb_target_cpu=gould ;;
-powerpc*) gdb_target_cpu=powerpc ;;
-pn) gdb_target_cpu=gould ;;
-pyramid) gdb_target_cpu=pyr ;;
-sparc*) gdb_target_cpu=sparc ;;
-*) gdb_target_cpu=$target_cpu ;;
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+fi
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ # Both variables are already set.
+ have_x=yes
+ else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 5289 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5294: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5363 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:5370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11/lib \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /lib/usr/lib/X11 \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+ # Didn't find X anywhere. Cache the known absence of X.
+ ac_cv_have_x="have_x=no"
+else
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ echo "$ac_t""$have_x" 1>&6
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+
+
+
+
+
+
+
+# Begin stuff to support --enable-shared
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ case "${enableval}" in
+ yes) shared=true ;;
+ no) shared=false ;;
+ *) shared=true ;;
esac
+fi
-# map target info into gdb names.
-
-case "${target}" in
-
-a29k-*-aout*) gdb_target=a29k ;;
-a29k-*-coff*) gdb_target=a29k ;;
-a29k-*-elf*) gdb_target=a29k ;;
-a29k-*-ebmon*) gdb_target=a29k ;;
-a29k-*-kern*) gdb_target=a29k-kern ;;
-a29k-*-none*) gdb_target=a29k ;;
-a29k-*-sym1*) gdb_target=ultra3 ;;
-a29k-*-udi*) gdb_target=a29k-udi ;;
-a29k-*-vxworks*) gdb_target=vx29k ;;
-
-alpha-*-osf*) gdb_target=alpha-osf1 ;;
-
-
-arm-*-*) gdb_target=arm ;;
-
-c1-*-*) gdb_target=convex ;;
-c2-*-*) gdb_target=convex ;;
-
-h8300-*-*) gdb_target=h8300 ;;
-h8500-*-*) gdb_target=h8500 ;;
-
-sh-*-*) gdb_target=sh ;;
-
-
-hppa*-*-bsd*) gdb_target=hppabsd ;;
-hppa*-*-pro*) gdb_target=hppapro ;;
-hppa*-*-hpux*) gdb_target=hppahpux ;;
-hppa*-*-hiux*) gdb_target=hppahpux ;;
-hppa*-*-osf*) gdb_target=hppaosf ;;
-
-i[3456]86-sequent-bsd*) gdb_target=symmetry ;;
-i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
-i[3456]86-sequent-sysv*) gdb_target=ptx ;;
-i[3456]86-ncr-*) gdb_target=ncr3000 ;;
-i[3456]86-*-aout*) gdb_target=i386aout ;;
-i[3456]86-*-coff*) gdb_target=i386v ;;
-i[3456]86-*-elf*) gdb_target=i386v ;;
-i[3456]86-*-aix*) gdb_target=i386aix ;;
-i[3456]86-*-bsd*) gdb_target=i386bsd ;;
-i[3456]86-*-freebsd*) gdb_target=fbsd ;;
-i[3456]86-*-netbsd*) gdb_target=nbsd ;;
-i[3456]86-*-os9k) gdb_target=i386os9k ;;
-i[3456]86-*-go32*) gdb_target=i386aout ;;
-i[3456]86-*-lynxos*) gdb_target=i386lynx
- configdirs="${configdirs} gdbserver" ;;
-i[3456]86-*-solaris*) gdb_target=i386sol2 ;;
-i[3456]86-*-sunos*) gdb_target=sun386 ;;
-i[3456]86-*-sysv4*) gdb_target=i386v4 ;;
-i[3456]86-*-sco*) gdb_target=i386v ;;
-i[3456]86-*-sysv*) gdb_target=i386v ;;
-i[3456]86-*-linux*) gdb_target=linux
- configdirs="${configdirs} gdbserver" ;;
-i[3456]86-*-isc*) gdb_target=i386v ;;
-i[3456]86-*-mach3*) gdb_target=i386m3 ;;
-i[3456]86-*-mach*) gdb_target=i386mach ;;
-i[3456]86-*-gnu*) gdb_target=i386gnu ;;
-i[3456]86-*-netware*) gdb_target=i386nw
- configdirs="${configdirs} nlm" ;;
-i[3456]86-*-osf1mk*) gdb_target=i386mk ;;
-i[3456]86-*-cygwin32) gdb_target=cygwin32 ;;
-i960-*-bout*) gdb_target=vxworks960 ;;
-i960-nindy-coff*) gdb_target=nindy960 ;;
-i960-*-coff*) gdb_target=mon960 ;;
-i960-nindy-elf*) gdb_target=nindy960 ;;
-i960-*-elf*) gdb_target=mon960 ;;
-
-i960-*-nindy*) gdb_target=nindy960 ;;
-i960-*-vxworks*) gdb_target=vxworks960 ;;
-
-m68000-*-sunos3*) gdb_target=sun2os3 ;;
-m68000-*-sunos4*) gdb_target=sun2os4 ;;
-
-m68*-apollo*-bsd*) gdb_target=apollo68b ;;
-m68*-bull-sysv*) gdb_target=dpx2 ;;
-m68*-hp-bsd*) gdb_target=hp300bsd ;;
-m68*-hp-hpux*) gdb_target=hp300hpux ;;
-m68*-altos-*) gdb_target=altos ;;
-m68*-att-*) gdb_target=3b1 ;;
-m68*-cisco*-*) gdb_target=cisco ;;
-m68*-ericsson-*) gdb_target=es1800 ;;
-m68*-isi-*) gdb_target=isi ;;
-m68*-motorola-*) gdb_target=delta68 ;;
-m68*-netx-*) gdb_target=vxworks68 ;;
-m68*-sony-*) gdb_target=news ;;
-m68*-tandem-*) gdb_target=st2000 ;;
-m68*-rom68k-*) gdb_target=monitor ;;
-m68*-*bug-*) gdb_target=monitor ;;
-m68*-monitor-*) gdb_target=monitor ;;
-m68*-est-*) gdb_target=monitor ;;
-m68*-*-aout*) gdb_target=monitor ;;
-m68*-*-coff*) gdb_target=monitor ;;
-m68*-*-elf*) gdb_target=monitor ;;
-m68*-*-lynxos*) gdb_target=m68klynx
- configdirs="${configdirs} gdbserver" ;;
-m68*-*-netbsd*) gdb_target=nbsd ;;
-m68*-*-os68k*) gdb_target=os68k ;;
-m68*-*-sunos3*) gdb_target=sun3os3 ;;
-m68*-*-sunos4*) gdb_target=sun3os4 ;;
-m68*-*-sysv4*) gdb_target=m68kv4 ;;
-m68*-*-vxworks*) gdb_target=vxworks68 ;;
-
-m88*-harris-cxux*) gdb_target=cxux ;;
-m88*-motorola-sysv4*) gdb_target=delta88v4 ;;
-m88*-*-mach3*) gdb_target=mach3 ;;
-m88*-motorola-*) gdb_target=delta88 ;;
-m88*-*-*) gdb_target=m88k ;;
-
-mips64*-big-*) gdb_target=bigmips64 ;;
-mips*-big-*) gdb_target=bigmips ;;
-mips*-dec-mach3*) gdb_target=mach3 ;;
-mips*-dec-*) gdb_target=decstation ;;
-mips64*el-*-ecoff*) gdb_target=embedl64 ;;
-mips64*-*-ecoff*) gdb_target=embed64 ;;
-mips64*vr4300*el-*-elf*) gdb_target=vr4300el ;;
-mips64*vr4300*-*-elf*) gdb_target=vr4300 ;;
-mips64*el-*-elf*) gdb_target=embedl64 ;;
-mips64*-*-elf*) gdb_target=embed64 ;;
-mips*el-*-ecoff*) gdb_target=embedl ;;
-mips*-*-ecoff*) gdb_target=embed ;;
-mips*el-*-elf*) gdb_target=embedl ;;
-mips*-*-elf*) gdb_target=embed ;;
-mips*-little-*) gdb_target=littlemips ;;
-mips*-sgi-irix5*) gdb_target=irix5 ;;
-mips*-sgi-*) gdb_target=irix3 ;;
-mips*-sony-*) gdb_target=bigmips ;;
-mips*-*-mach3*) gdb_target=mach3 ;;
-mips*-*-sysv4*) gdb_target=mipsv4 ;;
-mips*-*-sysv*) gdb_target=bigmips ;;
-mips*-*-riscos*) gdb_target=bigmips ;;
-mips*-*-vxworks*) gdb_target=vxmips ;;
-
-none-*-*) gdb_target=none ;;
-
-np1-*-*) gdb_target=np1 ;;
-
-ns32k-*-mach3*) gdb_target=mach3 ;;
-ns32k-*-netbsd*) gdb_target=nbsd ;;
-ns32k-utek-sysv*) gdb_target=merlin ;;
-ns32k-utek-*) gdb_target=umax ;;
-
-pn-*-*) gdb_target=pn ;;
-powerpc-*-macos*) gdb_target=macos ;;
-powerpc-*-netware*) gdb_target=ppc-nw
- configdirs="${configdirs} nlm" ;;
-
-powerpc-*-aix4*) gdb_target=aix4 ;;
-powerpc-*-aix*) gdb_target=aix ;;
-powerpcle-*-cygwin32) gdb_target=cygwin32 ;;
-powerpc-*-eabi*) if test x"$powerpc_sim" = x"yes"; then
- gdb_target=ppc-sim
- else
- gdb_target=ppc-eabi
- fi ;;
-powerpcle-*-eabi*) if test x"$powerpc_sim" = x"yes"; then
- gdb_target=ppcle-sim
- else
- gdb_target=ppcle-eabi
- fi ;;
-
-pyramid-*-*) gdb_target=pyramid ;;
-
-rs6000-*-lynxos*) gdb_target=rs6000lynx ;;
-rs6000-*-aix4*) gdb_target=aix4 ;;
-rs6000-*-*) gdb_target=rs6000 ;;
-
-sparc-*-aout*) gdb_target=sparc-em ;;
-sparc-*-coff*) gdb_target=sparc-em ;;
-sparc-*-elf*) gdb_target=sparc-em ;;
-sparc-*-lynxos*) gdb_target=sparclynx
- configdirs="${configdirs} gdbserver" ;;
-sparc-*-netbsd*) gdb_target=nbsd ;;
-sparc-*-solaris2*) gdb_target=sun4sol2 ;;
-sparc-*-sunos4*) gdb_target=sun4os4 ;;
-sparc-*-sunos5*) gdb_target=sun4sol2 ;;
-sparc-*-vxworks*) gdb_target=vxsparc ;;
-sparc-*-*) gdb_target=sun4os4 ;;
-# Use sparc-em for sparclet for now.
-sparclet-*-*) gdb_target=sparc-em ;;
-sparclite*-*-*) gdb_target=sparclite ;;
-sparc64-*-solaris2*) gdb_target=sp64sol2 ;;
-sparc64-*-*) gdb_target=sp64 ;;
-
-tahoe-*-*) gdb_target=tahoe ;;
-
-vax-*-*) gdb_target=vax ;;
-
-w65-*-*) gdb_target=w65 ;;
-
-z8k-*-coff*) gdb_target=z8k ;;
+HLDFLAGS=
+HLDENV=
+# If we have shared libraries, try to set rpath reasonably.
+if test "${shared}" = "true"; then
+ case "${host}" in
+ *-*-hpux*)
+ HLDFLAGS='-Wl,+s,+b,$(libdir)'
+ ;;
+ *-*-irix5* | *-*-irix6*)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-linux*aout*)
+ ;;
+ *-*-linux* | *-pc-linux-gnu)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-solaris*)
+ HLDFLAGS='-R $(libdir)'
+ ;;
+ *-*-sysv4*)
+ HLDENV='if test -z "$${LD_RUN_PATH}"; then LD_RUN_PATH=$(libdir); else LD_RUN_PATH=$${LD_RUN_PATH}:$(libdir); fi; export LD_RUN_PATH;'
+ ;;
+ esac
+fi
+# On SunOS, if the linker supports the -rpath option, use it to
+# prevent ../bfd and ../opcodes from being included in the run time
+# search path.
+case "${host}" in
+ *-*-sunos*)
+ echo 'main () { }' > conftest.c
+ ${CC} -o conftest -Wl,-rpath= conftest.c >/dev/null 2>conftest.t
+ if grep 'unrecognized' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'No such file' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'do not mix' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'some text already loaded' conftest.t >/dev/null 2>&1; then
+ :
+ elif test "${shared}" = "true"; then
+ HLDFLAGS='-Wl,-rpath=$(libdir)'
+ else
+ HLDFLAGS='-Wl,-rpath='
+ fi
+ rm -f conftest.t conftest.c conftest
+ ;;
esac
+# End stuff to support --enable-shared
+
+# target_subdir is used by the testsuite to find the target libraries.
+target_subdir=
+if test "${host}" != "${target}"; then
+ target_subdir="${target_alias}/"
+fi
+
+
frags=
host_makefile_frag=${srcdir}/config/${gdb_host_cpu}/${gdb_host}.mh
if test ! -f ${host_makefile_frag}; then
@@ -2204,9 +5561,9 @@ if test "${target}" = "${host}"; then
nativefile=`sed -n '
s/NAT_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
' ${host_makefile_frag}`
-else
+# else
# GDBserver is only useful in a "native" enviroment
-configdirs=`echo $configdirs | sed 's/gdbserver//'`
+# configdirs=`echo $configdirs | sed 's/gdbserver//'`
fi
@@ -2240,6 +5597,102 @@ fi
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:5602: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5607 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:5618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:5635: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5640 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:5647: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:5666: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:5676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
subdirs="$configdirs"
trap '' 1 2 15
@@ -2259,11 +5712,25 @@ cat > confcache <<\EOF
# --recheck option to rerun configure.
#
EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
- sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
- >> confcache
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
if cmp -s $cache_file confcache; then
:
else
@@ -2318,7 +5785,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.8"
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -2329,7 +5796,7 @@ done
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
-trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "Makefile tui/Makefile .gdbinit:gdbinit.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
@@ -2338,9 +5805,11 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
+s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
@@ -2361,64 +5830,123 @@ s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@CC@%$CC%g
s%@CPP@%$CPP%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
s%@host_vendor@%$host_vendor%g
s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
s%@build@%$build%g
s%@build_alias@%$build_alias%g
s%@build_cpu@%$build_cpu%g
s%@build_vendor@%$build_vendor%g
s%@build_os@%$build_os%g
-s%@AR@%$AR%g
+s%@SET_MAKE@%$SET_MAKE%g
s%@RANLIB@%$RANLIB%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@AR@%$AR%g
s%@YACC@%$YACC%g
-s%@AWK@%$AWK%g
-s%@target@%$target%g
-s%@target_alias@%$target_alias%g
-s%@target_cpu@%$target_cpu%g
-s%@target_vendor@%$target_vendor%g
-s%@target_os@%$target_os%g
-s%@X_CFLAGS@%$X_CFLAGS%g
-s%@X_PRE_LIBS@%$X_PRE_LIBS%g
-s%@X_LIBS@%$X_LIBS%g
-s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
-s%@TCLHDIR@%$TCLHDIR%g
-s%@TCLLIB@%$TCLLIB%g
-s%@TKHDIR@%$TKHDIR%g
-s%@TKLIB@%$TKLIB%g
-s%@ENABLE_GDBTK@%$ENABLE_GDBTK%g
-s%@X_LDFLAGS@%$X_LDFLAGS%g
+s%@CONFIG_LDFLAGS@%$CONFIG_LDFLAGS%g
+s%@BUILD_TUI@%$BUILD_TUI%g
+s%@TUI_LIBRARY@%$TUI_LIBRARY%g
+s%@WARN_CFLAGS@%$WARN_CFLAGS%g
+s%@MMALLOC_CFLAGS@%$MMALLOC_CFLAGS%g
+s%@MMALLOC@%$MMALLOC%g
+s%@TERM_LIB@%$TERM_LIB%g
s%@ENABLE_CFLAGS@%$ENABLE_CFLAGS%g
-s%@ENABLE_CLIBS@%$ENABLE_CLIBS%g
-s%@ENABLE_OBS@%$ENABLE_OBS%g
+s%@CONFIG_OBS@%$CONFIG_OBS%g
+s%@CONFIG_DEPS@%$CONFIG_DEPS%g
+s%@CONFIG_SRCS@%$CONFIG_SRCS%g
+s%@HLDFLAGS@%$HLDFLAGS%g
+s%@HLDENV@%$HLDENV%g
s%@target_subdir@%$target_subdir%g
/@host_makefile_frag@/r $host_makefile_frag
s%@host_makefile_frag@%%g
/@target_makefile_frag@/r $target_makefile_frag
s%@target_makefile_frag@%%g
s%@frags@%$frags%g
+s%@EXEEXT@%$EXEEXT%g
s%@subdirs@%$subdirs%g
CEOF
EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
cat >> $CONFIG_STATUS <<EOF
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+CONFIG_FILES=\${CONFIG_FILES-"Makefile tui/Makefile .gdbinit:gdbinit.in"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
- # Adjust relative srcdir, etc. for subdirectories.
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
@@ -2446,6 +5974,7 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*) INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
+
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
@@ -2454,14 +5983,16 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# $configure_input" ;;
*) ac_comsub= ;;
esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
-rm -f conftest.subs
+rm -f conftest.s*
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
@@ -2482,11 +6013,17 @@ ac_eB='$%\1#\2define\3'
ac_eC=' '
ac_eD='%g'
-CONFIG_HEADERS=${CONFIG_HEADERS-"config.h:config.in"}
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
@@ -2494,7 +6031,8 @@ for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
echo creating $ac_file
rm -f conftest.frag conftest.in conftest.out
- cp $ac_given_srcdir/$ac_file_in conftest.in
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
EOF
@@ -2506,7 +6044,7 @@ rm -f conftest.vals
cat > conftest.hdr <<\EOF
s/[\\&%]/\\&/g
s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
s%ac_d%ac_u%gp
s%ac_u%ac_e%gp
EOF
@@ -2522,8 +6060,6 @@ EOF
# Break up conftest.vals because some shells have a limit on
# the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
rm -f conftest.tail
while :
@@ -2554,6 +6090,12 @@ cat >> $CONFIG_STATUS <<\EOF
echo "$ac_file is unchanged"
rm -f conftest.h
else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
rm -f $ac_file
mv conftest.h $ac_file
fi
@@ -2615,7 +6157,7 @@ EOF
cat >> $CONFIG_STATUS <<\EOF
if test "${nativefile}" = ""; then
-sed -e '/^NATDEPFILES= /s//# NATDEPFILES= /' \
+sed -e '/^NATDEPFILES[ ]*=[ ]*/s//# NATDEPFILES=/' \
< Makefile > Makefile.tem
mv -f Makefile.tem Makefile
fi
@@ -2625,14 +6167,6 @@ sed -e '/^TM_FILE[ ]*=/s,^TM_FILE[ ]*=[ ]*,&config/'"${gdb_target_cpu}"'/,
/^NAT_FILE[ ]*=/s,^NAT_FILE[ ]*=[ ]*,&config/'"${gdb_host_cpu}"'/,' <Makefile >Makefile.tmp
mv -f Makefile.tmp Makefile
-case ${srcdir} in
-.)
-;;
-*)
-grep "source ${srcdir}/.gdbinit" .gdbinit >/dev/null 2>/dev/null || \
-echo "source ${srcdir}/.gdbinit" >> .gdbinit
-esac
-
case x$CONFIG_HEADERS in
xconfig.h:config.in)
echo > stamp-h ;;
@@ -2692,13 +6226,16 @@ if test "$no_recursion" != yes; then
ac_popdir=`pwd`
cd $ac_config_dir
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
case "$srcdir" in
.) # No --srcdir option. We are building in place.
ac_sub_srcdir=$srcdir ;;
/*) # Absolute path.
ac_sub_srcdir=$srcdir/$ac_config_dir ;;
*) # Relative path.
- ac_sub_srcdir=../$srcdir/$ac_config_dir ;;
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
esac
# Check for guested configure; otherwise get Cygnus style configure.
@@ -2715,8 +6252,6 @@ if test "$no_recursion" != yes; then
if test -n "$ac_sub_configure"; then
# Make the cache file name correct relative to the subdirectory.
- # A "../" for each directory in /$ac_config_dir.
- ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
case "$cache_file" in
/*) ac_sub_cache_file=$cache_file ;;
*) # Relative path.
@@ -2742,4 +6277,3 @@ fi
exit 0
-
diff --git a/contrib/gdb/gdb/configure.host b/contrib/gdb/gdb/configure.host
new file mode 100644
index 0000000..aca63e6
--- /dev/null
+++ b/contrib/gdb/gdb/configure.host
@@ -0,0 +1,162 @@
+# Mapping of configurations into GDB host definitions. This is
+# invoked from the autoconf generated configure script.
+
+# This file sets the following shell variables:
+# gdb_host_cpu generic name of host's CPU
+# gdb_host name of GDB host definition to use
+
+# Map host cpu into the config cpu subdirectory name.
+# The default is $host_cpu.
+
+case "${host_cpu}" in
+
+alpha*) gdb_host_cpu=alpha ;;
+c[12]) gdb_host_cpu=convex ;;
+hppa*) gdb_host_cpu=pa ;;
+i[3456]86*) gdb_host_cpu=i386 ;;
+m68*) gdb_host_cpu=m68k ;;
+m88*) gdb_host_cpu=m88k ;;
+# OBSOLETE np1) gdb_host_cpu=gould ;;
+pyramid) gdb_host_cpu=pyr ;;
+powerpc*) gdb_host_cpu=powerpc ;;
+sparc64) gdb_host_cpu=sparc ;;
+*) gdb_host_cpu=$host_cpu ;;
+
+esac
+
+# map host info into gdb names.
+
+case "${host}" in
+
+a29k-*-*) gdb_host=ultra3 ;;
+
+alpha*-*-osf1*) gdb_host=alpha-osf1 ;;
+alpha*-*-osf2*) gdb_host=alpha-osf2 ;;
+alpha*-*-osf[3456789]*) gdb_host=alpha-osf3 ;;
+alpha*-*-linux*) gdb_host=alpha-linux ;;
+
+arm-*-*) gdb_host=arm ;;
+
+c[12]-*-*) gdb_host=convex ;;
+
+hppa*-*-bsd*) gdb_host=hppabsd ;;
+hppa*-*-hiux*) gdb_host=hppahpux ;;
+hppa*-*-hpux10.20) gdb_host=hpux1020 ;;
+hppa*-*-hpux11.0*) gdb_host=hpux1100 ;;
+hppa*-*-hpux*) gdb_host=hppahpux ;;
+hppa*-*-osf*) gdb_host=hppaosf ;;
+
+i[3456]86-ncr-*) gdb_host=ncr3000 ;;
+i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix
+i[3456]86-sequent-sysv4*) gdb_host=ptx4 ;;
+i[3456]86-sequent-sysv*) gdb_host=ptx ;;
+i[3456]86-*-aix*) gdb_host=i386aix ;;
+i[3456]86-*-bsd*) gdb_host=i386bsd ;;
+i[3456]86-*-dgux*) gdb_host=i386dgux ;;
+i[3456]86-*-freebsd*) gdb_host=fbsd ;;
+i[3456]86-*-netbsd*) gdb_host=nbsd ;;
+i[3456]86-*-go32*) gdb_host=go32 ;;
+i[3456]86-*-linux*) gdb_host=linux ;;
+i[3456]86-*-lynxos*) gdb_host=i386lynx ;;
+i[3456]86-*-mach3*) gdb_host=i386m3 ;;
+i[3456]86-*-mach*) gdb_host=i386mach ;;
+i[3456]86-*-gnu*) gdb_host=i386gnu ;;
+i[3456]86-*-osf1mk*) gdb_host=i386mk ;;
+i[3456]86-*-sco3.2v5*) gdb_host=i386sco5 ;;
+i[3456]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
+i[3456]86-*-sco*) gdb_host=i386sco ;;
+i[3456]86-*-solaris*) gdb_host=i386sol2 ;;
+i[3456]86-*-sunos*) gdb_host=sun386 ;;
+i[3456]86-*-sysv3.2*) gdb_host=i386v32 ;;
+i[3456]86-*-sysv32*) gdb_host=i386v32 ;;
+i[3456]86-*-sysv4.2*) gdb_host=i386v42mp ;;
+i[3456]86-*-sysv4*) gdb_host=i386v4 ;;
+i[3456]86-*-sysv5*) gdb_host=i386v42mp ;;
+i[3456]86-*-unixware2*) gdb_host=i386v42mp ;;
+i[3456]86-*-unixware*) gdb_host=i386v4 ;;
+i[3456]86-*-sysv*) gdb_host=i386v ;;
+i[3456]86-*-isc*) gdb_host=i386v32 ;;
+i[3456]86-*-cygwin*) gdb_host=cygwin ;;
+m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
+m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
+m68030-sony-*) gdb_host=news1000 ;;
+
+m68*-altos-*) gdb_host=altos ;;
+m68*-apollo*-sysv*) gdb_host=apollo68v ;;
+m68*-apollo*-bsd*) gdb_host=apollo68b ;;
+m68*-att-*) gdb_host=3b1 ;;
+m68*-bull*-sysv*) gdb_host=dpx2 ;;
+m68*-hp-bsd*) gdb_host=hp300bsd ;;
+m68*-hp-hpux*) gdb_host=hp300hpux ;;
+m68*-isi-*) gdb_host=isi ;;
+m68*-*-linux*) gdb_host=linux ;;
+m68*-*-lynxos*) gdb_host=m68klynx ;;
+m68*-*-netbsd*) gdb_host=nbsd ;;
+m68*-*-sysv4*) gdb_host=m68kv4 ;;
+m68*-motorola-*) gdb_host=delta68 ;;
+m68*-sony-*) gdb_host=news ;;
+m68*-sun-sunos3*) gdb_host=sun3os3 ;;
+m68*-sun-sunos4*) gdb_host=sun3os4 ;;
+m68*-sun-*) gdb_host=sun3os4 ;;
+
+m88*-harris-cxux*) gdb_host=cxux ;;
+m88*-motorola-sysv4*) gdb_host=delta88v4 ;;
+m88*-motorola-sysv*) gdb_host=delta88 ;;
+m88*-*-*) gdb_host=m88k ;;
+
+mips-dec-mach3*) gdb_host=mach3 ;;
+mips-dec-*) gdb_host=decstation ;;
+mips-little-*) gdb_host=littlemips ;;
+mips-sgi-irix3*) gdb_host=irix3 ;;
+mips-sgi-irix4*) gdb_host=irix4 ;;
+mips-sgi-irix5*) gdb_host=irix5 ;;
+# Close enough for now.
+mips-sgi-irix6*) gdb_host=irix5 ;;
+mips-sony-*) gdb_host=news-mips ;;
+mips-*-mach3*) gdb_host=mipsm3 ;;
+mips-*-sysv4*) gdb_host=mipsv4 ;;
+mips-*-sysv*) gdb_host=riscos ;;
+mips-*-riscos*) gdb_host=riscos ;;
+
+none-*-*) gdb_host=none ;;
+
+# OBSOLETE np1-*-*) gdb_host=np1 ;;
+
+ns32k-*-mach3*) gdb_host=ns32km3 ;;
+ns32k-*-netbsd*) gdb_host=nbsd ;;
+ns32k-umax-*) gdb_host=umax ;;
+ns32k-utek-sysv*) gdb_host=merlin ;;
+
+powerpc-*-aix*) gdb_host=aix ;;
+powerpcle-*-cygwin*) gdb_host=cygwin ;;
+powerpcle-*-solaris*) gdb_host=solaris ;;
+powerpc-*-linux*) gdb_host=linux ;;
+
+# OBSOLETE pn-*-*) gdb_host=pn ;;
+
+pyramid-*-*) gdb_host=pyramid ;;
+
+romp-*-*) gdb_host=rtbsd ;;
+
+rs6000-*-lynxos*) gdb_host=rs6000lynx ;;
+rs6000-*-aix4*) gdb_host=aix4 ;;
+rs6000-*-*) gdb_host=rs6000 ;;
+
+sparc-*-linux*) gdb_host=linux ;;
+sparc-*-lynxos*) gdb_host=sparclynx ;;
+sparc-*-netbsd*) gdb_host=nbsd ;;
+sparc-*-solaris2*) gdb_host=sun4sol2 ;;
+sparc-*-sunos4*) gdb_host=sun4os4 ;;
+sparc-*-sunos5*) gdb_host=sun4sol2 ;;
+sparc-*-*) gdb_host=sun4os4 ;;
+sparc64-*-*) gdb_host=sun4sol2 ;;
+
+strongarm-*-*) gdb_host=arm ;;
+
+tahoe-*-*) gdb_host=tahoe ;;
+
+vax-*-bsd*) gdb_host=vaxbsd ;;
+vax-*-ultrix2*) gdb_host=vaxult2 ;;
+vax-*-ultrix*) gdb_host=vaxult ;;
+
+esac
diff --git a/contrib/gdb/gdb/configure.in b/contrib/gdb/gdb/configure.in
index 0967fd1..d658118 100644
--- a/contrib/gdb/gdb/configure.in
+++ b/contrib/gdb/gdb/configure.in
@@ -1,5 +1,5 @@
dnl Autoconf configure script for GDB, the GNU debugger.
-dnl Copyright 1995, 1996 Free Software Foundation, Inc.
+dnl Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
dnl
dnl This file is part of GDB.
dnl
@@ -19,49 +19,189 @@ dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
dnl Process this file with autoconf to produce a configure script.
-AC_PREREQ(2.3)dnl
+AC_PREREQ(2.13)dnl
AC_INIT(main.c)
AC_CONFIG_HEADER(config.h:config.in)
AC_PROG_CC
AC_AIX
-AC_MINIX
AC_ISC_POSIX
+AM_PROG_CC_STDC
+
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
+AC_CANONICAL_SYSTEM
+
+dnl gdb doesn't use gettext, but bfd does. We call this to ensure we
+dnl link with the correct libraries.
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+dnl List of object files added by configure.
+
+CONFIG_OBS=
+CONFIG_DEPS=
+CONFIG_SRCS=
+
+configdirs="doc testsuite"
+
+dnl
+changequote(,)dnl
+
+. ${srcdir}/configure.host
+
+. ${srcdir}/configure.tgt
+
+dnl
+changequote([,])dnl
AC_PROG_INSTALL
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_PROG_YACC
-AC_PROG_AWK
-AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
-AC_CANONICAL_SYSTEM
AC_ARG_PROGRAM
+AC_TYPE_SIGNAL
+
AC_HEADER_STDC
-AC_CHECK_HEADERS(limits.h memory.h string.h strings.h unistd.h termios.h termio.h sgtty.h stddef.h sys/procfs.h link.h endian.h)
+
+AC_CHECK_HEADERS(ctype.h curses.h endian.h link.h \
+ memory.h objlist.h ptrace.h sgtty.h stddef.h stdlib.h \
+ string.h sys/procfs.h sys/ptrace.h sys/reg.h \
+ term.h termio.h termios.h unistd.h wait.h sys/wait.h \
+ wchar.h wctype.h asm/debugreg.h sys/debugreg.h)
AC_HEADER_STAT
-AC_CHECK_FUNCS(setpgid sbrk)
+AC_C_CONST
+
+AC_CHECK_FUNCS(setpgid sbrk sigaction isascii bzero bcopy btowc)
+AC_FUNC_ALLOCA
+
+BFD_NEED_DECLARATION(malloc)
+BFD_NEED_DECLARATION(realloc)
+BFD_NEED_DECLARATION(free)
+BFD_NEED_DECLARATION(strerror)
+BFD_NEED_DECLARATION(strdup)
+
+
+# The following save_state_t checkery is only necessary for HPUX
+# versions earlier than 10.20. When those fade from memory, this
+# could be expunged. --jsm 1999-03-22
+
+AC_MSG_CHECKING(for HPUX save_state structure)
+AC_EGREP_HEADER(save_state_t, machine/save_state.h,
+ gdb_cv_hpux_savestate=yes, gdb_cv_hpux_savestate=no)
+AC_EGREP_HEADER(ss_wide, machine/save_state.h, gdb_cv_hpux_sswide=yes,
+ gdb_cv_hpux_sswide=no)
+if test $gdb_cv_hpux_savestate = yes
+then
+ AC_DEFINE(HAVE_STRUCT_SAVE_STATE_T, 1)
+fi
+if test $gdb_cv_hpux_sswide = yes
+then
+ AC_DEFINE(HAVE_STRUCT_MEMBER_SS_WIDE, 1)
+fi
+AC_MSG_RESULT($gdb_cv_hpux_sswide)
+
+
+# If we are configured native on GNU/Linux, work around problems with
+# sys/procfs.h
+# Also detect which type of /proc is in use, such as for Unixware.
-AC_MSG_CHECKING([for gregset_t type])
-AC_CACHE_VAL(gdb_cv_have_gregset_t,
-[AC_TRY_LINK([#include <sys/procfs.h>],[gregset_t *gregsetp = 0],
-gdb_cv_have_gregset_t=yes, gdb_cv_have_gregset_t=no)])
-AC_MSG_RESULT($gdb_cv_have_gregset_t)
-if test $gdb_cv_have_gregset_t = yes; then
- AC_DEFINE(HAVE_GREGSET_T)
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ i[[3456]]86-*-linux*)
+ AC_DEFINE(START_INFERIOR_TRAPS_EXPECTED,2)
+ AC_DEFINE(sys_quotactl)
+ ;;
+ esac
+ AC_MSG_CHECKING(for directory proc entries)
+# The [gdb_host != sun4sol2] hack is because Solaris does provide the
+# multiple procfs files as of Solaris 2.6, but GDB can't use it right now.
+ if test "$ac_cv_header_sys_procfs_h" = yes -a "$gdb_host" != sun4sol2 \
+ -a -d /proc/$$ \
+ -a -f /proc/$$/ctl \
+ -a -f /proc/$$/as \
+ -a -f /proc/$$/map \
+ -a -f /proc/$$/status; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_MULTIPLE_PROC_FDS)
+ else
+ AC_MSG_RESULT(no)
+ fi
fi
-AC_MSG_CHECKING([for fpregset_t type])
-AC_CACHE_VAL(gdb_cv_have_fpregset_t,
-[AC_TRY_LINK([#include <sys/procfs.h>],[fpregset_t *fpregsetp = 0],
-gdb_cv_have_fpregset_t=yes, gdb_cv_have_fpregset_t=no)])
-AC_MSG_RESULT($gdb_cv_have_fpregset_t)
-if test $gdb_cv_have_fpregset_t = yes; then
- AC_DEFINE(HAVE_FPREGSET_T)
+if test "$ac_cv_header_sys_procfs_h" = yes; then
+ BFD_HAVE_SYS_PROCFS_TYPE(pstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prrun_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(gregset_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(fpregset_t)
+
+ dnl Check for PIOCSET ioctl entry
+
+ AC_MSG_CHECKING(for PIOCSET ioctl entry in sys/procfs.h)
+ AC_CACHE_VAL(gdb_cv_have_procfs_piocset,
+ [AC_TRY_COMPILE([#include <unistd.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+], [
+ int dummy;;
+ dummy = ioctl(0, PIOCSET, &dummy);
+ ],
+ gdb_cv_have_procfs_piocset=yes, gdb_cv_have_procfs_piocset=no)])
+ AC_MSG_RESULT($gdb_cv_have_procfs_piocset)
+ if test $gdb_cv_have_procfs_piocset = yes; then
+ AC_DEFINE(HAVE_PROCFS_PIOCSET)
+ fi
fi
+dnl See if host has libm. This is usually needed by simulators.
+AC_CHECK_LIB(m, main)
+
+dnl Solaris puts wctype in /usr/lib/libw.a before Solaris 2.6.
+dnl
+dnl A bug in GNU ld 2.9.1 causes a problem if we link in -lw
+dnl under Solaris 2.6 because it is some funky empty library.
+dnl So only link in libw if we have to.
+AC_CHECK_LIB(c, wctype,: ,AC_CHECK_LIB(w, wctype))
+
+dnl See if compiler supports "long long" type.
+
+AC_MSG_CHECKING(for long long support in compiler)
+AC_CACHE_VAL(gdb_cv_c_long_long,
+[AC_TRY_COMPILE(, [
+ extern long long foo;
+ switch (foo & 2) { case 0: return 1; }
+],
+gdb_cv_c_long_long=yes, gdb_cv_c_long_long=no)])
+AC_MSG_RESULT($gdb_cv_c_long_long)
+if test $gdb_cv_c_long_long = yes; then
+ AC_DEFINE(CC_HAS_LONG_LONG)
+fi
+
+dnl See if the compiler and runtime support printing long long
+
+AC_MSG_CHECKING(for long long support in printf)
+AC_CACHE_VAL(gdb_cv_printf_has_long_long,
+[AC_TRY_RUN([
+int main () {
+ char buf[32];
+ long long l = 0;
+ l = (l << 16) + 0x0123;
+ l = (l << 16) + 0x4567;
+ l = (l << 16) + 0x89ab;
+ l = (l << 16) + 0xcdef;
+ sprintf (buf, "0x%016llx", l);
+ return (strcmp ("0x0123456789abcdef", buf));
+}],
+gdb_cv_printf_has_long_long=yes,
+gdb_cv_printf_has_long_long=no,
+gdb_cv_printf_has_long_long=no)])
+if test $gdb_cv_printf_has_long_long = yes; then
+ AC_DEFINE(PRINTF_HAS_LONG_LONG)
+fi
+AC_MSG_RESULT($gdb_cv_printf_has_long_long)
+
dnl See if compiler supports "long double" type. Can't use AC_C_LONG_DOUBLE
dnl because autoconf complains about cross-compilation issues. However, this
dnl code uses the same variables as the macro for compatibility.
@@ -94,15 +234,125 @@ if test $gdb_cv_printf_has_long_double = yes; then
fi
AC_MSG_RESULT($gdb_cv_printf_has_long_double)
+dnl See if the compiler and runtime support scanning long doubles
+
+AC_MSG_CHECKING(for long double support in scanf)
+AC_CACHE_VAL(gdb_cv_scanf_has_long_double,
+[AC_TRY_RUN([
+int main () {
+ char *buf = "3.141592653";
+ long double f = 0;
+ sscanf (buf, "%Lg", &f);
+ return !(f > 3.14159 && f < 3.14160);
+}],
+gdb_cv_scanf_has_long_double=yes,
+gdb_cv_scanf_has_long_double=no,
+gdb_cv_scanf_has_long_double=no)])
+if test $gdb_cv_scanf_has_long_double = yes; then
+ AC_DEFINE(SCANF_HAS_LONG_DOUBLE)
+fi
+AC_MSG_RESULT($gdb_cv_scanf_has_long_double)
+
AC_FUNC_MMAP
+dnl See if thread_db library is around for Solaris thread debugging. Note that
+dnl we must explicitly test for version 1 of the library because version 0
+dnl (present on Solaris 2.4 or earlier) doesn't have the same API.
+
+dnl Note that we only want this if we are both native (host == target), and
+dnl not doing a canadian cross build (build == host).
+
+if test ${build} = ${host} -a ${host} = ${target} ; then
+ case ${host_os} in
+ hpux*)
+ AC_MSG_CHECKING(for HPUX/OSF thread support)
+ if test -f /usr/include/dce/cma_config.h ; then
+ if test "$GCC" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HPUX_THREAD_SUPPORT)
+ CONFIG_OBS="${CONFIG_OJS} hpux-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} hpux-thread.c"
+ else
+ AC_MSG_RESULT(no (suppressed because you are not using GCC))
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ solaris*)
+ AC_MSG_CHECKING(for Solaris thread debugging library)
+ if test -f /usr/lib/libthread_db.so.1 ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_THREAD_DB_LIB)
+ CONFIG_OBS="${CONFIG_OBS} sol-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c"
+ AC_CHECK_LIB(dl, dlopen)
+ if test "$GCC" = "yes" ; then
+ # The GNU linker requires the -export-dynamic option to make
+ # all symbols visible in the dynamic symbol table.
+ hold_ldflags=$LDFLAGS
+ AC_MSG_CHECKING(for the ld -export-dynamic flag)
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ AC_TRY_LINK(, [int i;], found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+ AC_MSG_RESULT($found)
+ if test $found = yes; then
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} -Wl,-export-dynamic"
+ fi
+ fi
+ # Sun randomly tweaked the prototypes in <proc_service.h>
+ # at one point.
+ AC_MSG_CHECKING(if <proc_service.h> is old)
+ AC_CACHE_VAL(gdb_cv_proc_service_is_old,[
+ AC_TRY_COMPILE([
+ #include <proc_service.h>
+ ps_err_e ps_pdwrite
+ (struct ps_prochandle*, psaddr_t, const void*, size_t);
+ ],, gdb_cv_proc_service_is_old=no,
+ gdb_cv_proc_service_is_old=yes)
+ ])
+ AC_MSG_RESULT($gdb_cv_proc_service_is_old)
+ if test $gdb_cv_proc_service_is_old = yes; then
+ AC_DEFINE(PROC_SERVICE_IS_OLD)
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ esac
+ AC_SUBST(CONFIG_LDFLAGS)
+fi
+
dnl Handle optional features that can be enabled.
ENABLE_CFLAGS=
-ENABLE_CLIBS=
-ENABLE_OBS=
+
+AC_ARG_ENABLE(tui,
+[ --enable-tui Enable full-screen terminal user interface],
+[
+ case "${enable_tui}" in
+ yes | no) ;;
+ "") enable_tui=yes ;;
+ *)
+ AC_MSG_ERROR(Bad value for --enable-tui: ${enableval})
+ ;;
+ esac
+])
+case ${enable_tui} in
+ "yes" )
+ AC_DEFINE(TUI)
+ BUILD_TUI=all-tui
+ TUI_LIBRARY=tui/libtui.a
+ ;;
+ * )
+ BUILD_TUI=
+ TUI_LIBRARY=
+ ;;
+esac
+AC_SUBST(BUILD_TUI)
+AC_SUBST(TUI_LIBRARY)
AC_ARG_ENABLE(netrom,
-[ --enable-netrom ],
+[ --enable-netrom Enable NetROM support],
[case "${enableval}" in
yes) enable_netrom=yes ;;
no) enable_netrom=no ;;
@@ -110,399 +360,146 @@ no) enable_netrom=no ;;
esac])
if test "${enable_netrom}" = "yes"; then
- ENABLE_OBS="${ENABLE_OBS} remote-nrom.o"
+ CONFIG_OBS="${CONFIG_OBS} remote-nrom.o"
+ CONFIG_SRCS="${CONFIG_SRCS} remote-nrom.c"
fi
-
-AC_ARG_ENABLE(sim-powerpc,
-[ --enable-sim-powerpc ],
-[case "${enableval}" in
-yes) powerpc_sim=yes ;;
-no) powerpc_sim=no ;;
-*) AC_MSG_ERROR(bad value ${enableval} given for sim-powerpc option) ;;
-esac],[if test x"$GCC" != x""; then powerpc_sim=yes; else powerpc_sim=no; fi])
-
-
-AC_SUBST(ENABLE_CFLAGS)
-AC_SUBST(ENABLE_CLIBS)
-AC_SUBST(ENABLE_OBS)
-
-# target_subdir is used by the testsuite to find the target libraries.
-target_subdir=
-if test "${host}" != "${target}"; then
- target_subdir="${target_alias}/"
+AC_ARG_ENABLE(build-warnings,
+[ --enable-build-warnings Enable build-time compiler warnings if gcc is used],
+[build_warnings="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations"
+case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac],[build_warnings=""])dnl
+
+if test "x${build_warnings}" != x -a "x$GCC" = xyes
+then
+ WARN_CFLAGS="${build_warnings}"
+else
+ WARN_CFLAGS=""
+fi
+AC_SUBST(WARN_CFLAGS)
+
+MMALLOC_CFLAGS=
+MMALLOC=
+AC_SUBST(MMALLOC_CFLAGS)
+AC_SUBST(MMALLOC)
+
+AC_ARG_WITH(mmalloc,
+[ --with-mmalloc Use memory mapped malloc package],
+[case "${withval}" in
+ yes) want_mmalloc=true ;;
+ no) want_mmalloc=false;;
+ *) AC_MSG_ERROR(bad value ${withval} for GDB with-mmalloc option) ;;
+esac],[want_mmalloc=false])dnl
+
+if test x$want_mmalloc = xtrue; then
+ AC_DEFINE(USE_MMALLOC)
+ AC_DEFINE(MMCHECK_FORCE)
+ MMALLOC_CFLAGS="-I$srcdir/../mmalloc"
+ MMALLOC='../mmalloc/libmmalloc.a'
fi
-AC_SUBST(target_subdir)
-
-configdirs="doc testsuite"
-dnl
-changequote(,)dnl
+dnl Figure out which term library to use.
+if test x$gdb_cv_os_cygwin = xyes; then
+ TERM_LIB='`if test -r ../libtermcap/libtermcap.a; then echo ../libtermcap/libtermcap.a; else echo -ltermcap; fi`'
+else
+ TERM_LIB=
+ AC_CHECK_LIB(ncurses, tgetent, TERM_LIB=-lncurses,
+ AC_CHECK_LIB(Hcurses, tgetent, TERM_LIB=-lHcurses,
+ AC_CHECK_LIB(termlib, tgetent, TERM_LIB=-ltermlib,
+ AC_CHECK_LIB(termcap, tgetent, TERM_LIB=-ltermcap,
+ AC_CHECK_LIB(curses, tgetent, TERM_LIB=-lcurses,
+ AC_CHECK_LIB(terminfo, tgetent, TERM_LIB=-lterminfo))))))
+
+ if test "x$TERM_LIB" = x
+ then
+ AC_MSG_ERROR(Could not find a term library, e.g. termcap or termlib!)
+ fi
+fi
+AC_SUBST(TERM_LIB)
-# Map host cpu into the config cpu subdirectory name.
-# The default is $host_cpu.
-case "${host_cpu}" in
+AC_PATH_X
-c[12]) gdb_host_cpu=convex ;;
-hppa*) gdb_host_cpu=pa ;;
-i[3456]86) gdb_host_cpu=i386 ;;
-m68*) gdb_host_cpu=m68k ;;
-m88*) gdb_host_cpu=m88k ;;
-np1) gdb_host_cpu=gould ;;
-pyramid) gdb_host_cpu=pyr ;;
-powerpc*) gdb_host_cpu=powerpc ;;
-sparc64) gdb_host_cpu=sparc ;;
-*) gdb_host_cpu=$host_cpu ;;
+AC_SUBST(ENABLE_CFLAGS)
-esac
+AC_SUBST(CONFIG_OBS)
+AC_SUBST(CONFIG_DEPS)
+AC_SUBST(CONFIG_SRCS)
-# map host info into gdb names.
+# Begin stuff to support --enable-shared
+AC_ARG_ENABLE(shared,
+[ --enable-shared Use shared libraries],
+[case "${enableval}" in
+ yes) shared=true ;;
+ no) shared=false ;;
+ *) shared=true ;;
+esac])dnl
+
+HLDFLAGS=
+HLDENV=
+# If we have shared libraries, try to set rpath reasonably.
+if test "${shared}" = "true"; then
+ case "${host}" in
+ *-*-hpux*)
+ HLDFLAGS='-Wl,+s,+b,$(libdir)'
+ ;;
+ *-*-irix5* | *-*-irix6*)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-linux*aout*)
+ ;;
+ *-*-linux* | *-pc-linux-gnu)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-solaris*)
+ HLDFLAGS='-R $(libdir)'
+ ;;
+ *-*-sysv4*)
+ HLDENV='if test -z "$${LD_RUN_PATH}"; then LD_RUN_PATH=$(libdir); else LD_RUN_PATH=$${LD_RUN_PATH}:$(libdir); fi; export LD_RUN_PATH;'
+ ;;
+ esac
+fi
+# On SunOS, if the linker supports the -rpath option, use it to
+# prevent ../bfd and ../opcodes from being included in the run time
+# search path.
case "${host}" in
-
-a29k-*-*) gdb_host=ultra3 ;;
-
-alpha-*-osf1*) gdb_host=alpha-osf1 ;;
-alpha-*-osf2*) gdb_host=alpha-osf2 ;;
-alpha-*-osf[3456789]*) gdb_host=alpha-osf3 ;;
-
-arm-*-*) gdb_host=arm ;;
-
-c[12]-*-*) gdb_host=convex ;;
-
-hppa*-*-bsd*) gdb_host=hppabsd ;;
-hppa*-*-hiux*) gdb_host=hppahpux ;;
-hppa*-*-hpux*) gdb_host=hppahpux ;;
-hppa*-*-osf*) gdb_host=hppaosf ;;
-
-i[3456]86-ncr-*) gdb_host=ncr3000 ;;
-i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix
-i[3456]86-sequent-sysv4*) gdb_host=ptx4 ;;
-i[3456]86-sequent-sysv*) gdb_host=ptx ;;
-i[3456]86-*-aix*) gdb_host=i386aix ;;
-i[3456]86-*-bsd*) gdb_host=i386bsd ;;
-i[3456]86-*-dgux*) gdb_host=i386dgux ;;
-i[3456]86-*-freebsd*) gdb_host=fbsd ;;
-i[3456]86-*-netbsd*) gdb_host=nbsd ;;
-i[3456]86-*-go32*) gdb_host=go32 ;;
-i[3456]86-*-linux*) gdb_host=linux ;;
-i[3456]86-*-lynxos*) gdb_host=i386lynx ;;
-i[3456]86-*-mach3*) gdb_host=i386m3 ;;
-i[3456]86-*-mach*) gdb_host=i386mach ;;
-i[3456]86-*-gnu*) gdb_host=i386gnu ;;
-i[3456]86-*-osf1mk*) gdb_host=osf1mk ;;
-i[3456]86-*-sco3.2v5*) gdb_host=i386sco5 ;;
-i[3456]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
-i[3456]86-*-sco*) gdb_host=i386sco ;;
-i[3456]86-*-solaris*) gdb_host=i386sol2 ;;
-i[3456]86-*-sunos*) gdb_host=sun386 ;;
-i[3456]86-*-sysv3.2*) gdb_host=i386v32 ;;
-i[3456]86-*-sysv32*) gdb_host=i386v32 ;;
-i[3456]86-*-sysv4*) gdb_host=i386v4 ;;
-i[3456]86-*-unixware) gdb_host=i386v4 ;;
-i[3456]86-*-sysv*) gdb_host=i386v ;;
-i[3456]86-*-isc*) gdb_host=i386v32 ;;
-i[3456]86-*-os9k) gdb_host=i386os9k ;;
-i[3456]86-*-cygwin32) gdb_host=cygwin32 ;;
-m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
-m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
-m68030-sony-*) gdb_host=news1000 ;;
-
-m68*-altos-*) gdb_host=altos ;;
-m68*-apollo*-sysv*) gdb_host=apollo68v ;;
-m68*-apollo*-bsd*) gdb_host=apollo68b ;;
-m68*-att-*) gdb_host=3b1 ;;
-m68*-bull*-sysv*) gdb_host=dpx2 ;;
-m68*-hp-bsd*) gdb_host=hp300bsd ;;
-m68*-hp-hpux*) gdb_host=hp300hpux ;;
-m68*-isi-*) gdb_host=isi ;;
-m68*-*-lynxos*) gdb_host=m68klynx ;;
-m68*-*-netbsd*) gdb_host=nbsd ;;
-m68*-*-sysv4*) gdb_host=m68kv4 ;;
-m68*-motorola-*) gdb_host=delta68 ;;
-m68*-sony-*) gdb_host=news ;;
-m68*-sun-sunos3*) gdb_host=sun3os3 ;;
-m68*-sun-sunos4*) gdb_host=sun3os4 ;;
-m68*-sun-*) gdb_host=sun3os4 ;;
-
-m88*-harris-cxux*) gdb_host=cxux ;;
-m88*-motorola-sysv4*) gdb_host=delta88v4 ;;
-m88*-motorola-sysv*) gdb_host=delta88 ;;
-m88*-*-mach3*) gdb_host=mach3 ;;
-m88*-*-*) gdb_host=m88k ;;
-
-mips-dec-mach3*) gdb_host=mach3 ;;
-mips-dec-*) gdb_host=decstation ;;
-mips-little-*) gdb_host=littlemips ;;
-mips-sgi-irix3*) gdb_host=irix3 ;;
-mips-sgi-irix4*) gdb_host=irix4 ;;
-mips-sgi-irix5*) gdb_host=irix5 ;;
-mips-sony-*) gdb_host=news-mips ;;
-mips-*-mach3*) gdb_host=mach3 ;;
-mips-*-sysv4*) gdb_host=mipsv4 ;;
-mips-*-sysv*) gdb_host=riscos ;;
-mips-*-riscos*) gdb_host=riscos ;;
-
-none-*-*) gdb_host=none ;;
-
-np1-*-*) gdb_host=np1 ;;
-
-ns32k-*-mach3*) gdb_host=mach3 ;;
-ns32k-*-netbsd*) gdb_host=nbsd ;;
-ns32k-umax-*) gdb_host=umax ;;
-ns32k-utek-sysv*) gdb_host=merlin ;;
-
-powerpc-*-aix*) gdb_host=aix ;;
-powerpcle-*-cygwin32) gdb_host=cygwin32 ;;
-pn-*-*) gdb_host=pn ;;
-
-pyramid-*-*) gdb_host=pyramid ;;
-
-romp-*-*) gdb_host=rtbsd ;;
-
-rs6000-*-lynxos*) gdb_host=rs6000lynx ;;
-rs6000-*-aix4*) gdb_host=aix4 ;;
-rs6000-*-*) gdb_host=rs6000 ;;
-
-sparc-*-lynxos*) gdb_host=sparclynx ;;
-sparc-*-netbsd*) gdb_host=nbsd ;;
-sparc-*-solaris2*) gdb_host=sun4sol2 ;;
-sparc-*-sunos4*) gdb_host=sun4os4 ;;
-sparc-*-sunos5*) gdb_host=sun4sol2 ;;
-sparc-*-*) gdb_host=sun4os4 ;;
-sparc64-*-*) gdb_host=sun4sol2 ;;
-
-tahoe-*-*) gdb_host=tahoe ;;
-
-vax-*-bsd*) gdb_host=vaxbsd ;;
-vax-*-ultrix2*) gdb_host=vaxult2 ;;
-vax-*-ultrix*) gdb_host=vaxult ;;
-
-w65-*-*) gdb_host=w65 ;;
-
+ *-*-sunos*)
+ echo 'main () { }' > conftest.c
+ ${CC} -o conftest -Wl,-rpath= conftest.c >/dev/null 2>conftest.t
+ if grep 'unrecognized' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'No such file' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'do not mix' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'some text already loaded' conftest.t >/dev/null 2>&1; then
+ :
+ elif test "${shared}" = "true"; then
+ HLDFLAGS='-Wl,-rpath=$(libdir)'
+ else
+ HLDFLAGS='-Wl,-rpath='
+ fi
+ rm -f conftest.t conftest.c conftest
+ ;;
esac
+AC_SUBST(HLDFLAGS)
+AC_SUBST(HLDENV)
+# End stuff to support --enable-shared
-
-# Map target cpu into the config cpu subdirectory name.
-# The default is $target_cpu.
-
-case "${target_cpu}" in
-
-alpha) gdb_target_cpu=alpha ;;
-c[12]) gdb_target_cpu=convex ;;
-hppa*) gdb_target_cpu=pa ;;
-i[3456]86) gdb_target_cpu=i386 ;;
-m68*) gdb_target_cpu=m68k ;;
-m88*) gdb_target_cpu=m88k ;;
-mips*) gdb_target_cpu=mips ;;
-np1) gdb_target_cpu=gould ;;
-powerpc*) gdb_target_cpu=powerpc ;;
-pn) gdb_target_cpu=gould ;;
-pyramid) gdb_target_cpu=pyr ;;
-sparc*) gdb_target_cpu=sparc ;;
-*) gdb_target_cpu=$target_cpu ;;
-
-esac
-
-# map target info into gdb names.
-
-case "${target}" in
-
-a29k-*-aout*) gdb_target=a29k ;;
-a29k-*-coff*) gdb_target=a29k ;;
-a29k-*-elf*) gdb_target=a29k ;;
-a29k-*-ebmon*) gdb_target=a29k ;;
-a29k-*-kern*) gdb_target=a29k-kern ;;
-a29k-*-none*) gdb_target=a29k ;;
-a29k-*-sym1*) gdb_target=ultra3 ;;
-a29k-*-udi*) gdb_target=a29k-udi ;;
-a29k-*-vxworks*) gdb_target=vx29k ;;
-
-alpha-*-osf*) gdb_target=alpha-osf1 ;;
-
-
-arm-*-*) gdb_target=arm ;;
-
-c1-*-*) gdb_target=convex ;;
-c2-*-*) gdb_target=convex ;;
-
-h8300-*-*) gdb_target=h8300 ;;
-h8500-*-*) gdb_target=h8500 ;;
-
-sh-*-*) gdb_target=sh ;;
-
-
-hppa*-*-bsd*) gdb_target=hppabsd ;;
-hppa*-*-pro*) gdb_target=hppapro ;;
-hppa*-*-hpux*) gdb_target=hppahpux ;;
-hppa*-*-hiux*) gdb_target=hppahpux ;;
-hppa*-*-osf*) gdb_target=hppaosf ;;
-
-i[3456]86-sequent-bsd*) gdb_target=symmetry ;;
-i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
-i[3456]86-sequent-sysv*) gdb_target=ptx ;;
-i[3456]86-ncr-*) gdb_target=ncr3000 ;;
-i[3456]86-*-aout*) gdb_target=i386aout ;;
-i[3456]86-*-coff*) gdb_target=i386v ;;
-i[3456]86-*-elf*) gdb_target=i386v ;;
-i[3456]86-*-aix*) gdb_target=i386aix ;;
-i[3456]86-*-bsd*) gdb_target=i386bsd ;;
-i[3456]86-*-freebsd*) gdb_target=fbsd ;;
-i[3456]86-*-netbsd*) gdb_target=nbsd ;;
-i[3456]86-*-os9k) gdb_target=i386os9k ;;
-i[3456]86-*-go32*) gdb_target=i386aout ;;
-i[3456]86-*-lynxos*) gdb_target=i386lynx
- configdirs="${configdirs} gdbserver" ;;
-i[3456]86-*-solaris*) gdb_target=i386sol2 ;;
-i[3456]86-*-sunos*) gdb_target=sun386 ;;
-i[3456]86-*-sysv4*) gdb_target=i386v4 ;;
-i[3456]86-*-sco*) gdb_target=i386v ;;
-i[3456]86-*-sysv*) gdb_target=i386v ;;
-i[3456]86-*-linux*) gdb_target=linux
- configdirs="${configdirs} gdbserver" ;;
-i[3456]86-*-isc*) gdb_target=i386v ;;
-i[3456]86-*-mach3*) gdb_target=i386m3 ;;
-i[3456]86-*-mach*) gdb_target=i386mach ;;
-i[3456]86-*-gnu*) gdb_target=i386gnu ;;
-i[3456]86-*-netware*) gdb_target=i386nw
- configdirs="${configdirs} nlm" ;;
-i[3456]86-*-osf1mk*) gdb_target=i386mk ;;
-i[3456]86-*-cygwin32) gdb_target=cygwin32 ;;
-i960-*-bout*) gdb_target=vxworks960 ;;
-i960-nindy-coff*) gdb_target=nindy960 ;;
-i960-*-coff*) gdb_target=mon960 ;;
-i960-nindy-elf*) gdb_target=nindy960 ;;
-i960-*-elf*) gdb_target=mon960 ;;
-
-i960-*-nindy*) gdb_target=nindy960 ;;
-i960-*-vxworks*) gdb_target=vxworks960 ;;
-
-m68000-*-sunos3*) gdb_target=sun2os3 ;;
-m68000-*-sunos4*) gdb_target=sun2os4 ;;
-
-m68*-apollo*-bsd*) gdb_target=apollo68b ;;
-m68*-bull-sysv*) gdb_target=dpx2 ;;
-m68*-hp-bsd*) gdb_target=hp300bsd ;;
-m68*-hp-hpux*) gdb_target=hp300hpux ;;
-m68*-altos-*) gdb_target=altos ;;
-m68*-att-*) gdb_target=3b1 ;;
-m68*-cisco*-*) gdb_target=cisco ;;
-m68*-ericsson-*) gdb_target=es1800 ;;
-m68*-isi-*) gdb_target=isi ;;
-m68*-motorola-*) gdb_target=delta68 ;;
-m68*-netx-*) gdb_target=vxworks68 ;;
-m68*-sony-*) gdb_target=news ;;
-m68*-tandem-*) gdb_target=st2000 ;;
-m68*-rom68k-*) gdb_target=monitor ;;
-m68*-*bug-*) gdb_target=monitor ;;
-m68*-monitor-*) gdb_target=monitor ;;
-m68*-est-*) gdb_target=monitor ;;
-m68*-*-aout*) gdb_target=monitor ;;
-m68*-*-coff*) gdb_target=monitor ;;
-m68*-*-elf*) gdb_target=monitor ;;
-m68*-*-lynxos*) gdb_target=m68klynx
- configdirs="${configdirs} gdbserver" ;;
-m68*-*-netbsd*) gdb_target=nbsd ;;
-m68*-*-os68k*) gdb_target=os68k ;;
-m68*-*-sunos3*) gdb_target=sun3os3 ;;
-m68*-*-sunos4*) gdb_target=sun3os4 ;;
-m68*-*-sysv4*) gdb_target=m68kv4 ;;
-m68*-*-vxworks*) gdb_target=vxworks68 ;;
-
-m88*-harris-cxux*) gdb_target=cxux ;;
-m88*-motorola-sysv4*) gdb_target=delta88v4 ;;
-m88*-*-mach3*) gdb_target=mach3 ;;
-m88*-motorola-*) gdb_target=delta88 ;;
-m88*-*-*) gdb_target=m88k ;;
-
-mips64*-big-*) gdb_target=bigmips64 ;;
-mips*-big-*) gdb_target=bigmips ;;
-mips*-dec-mach3*) gdb_target=mach3 ;;
-mips*-dec-*) gdb_target=decstation ;;
-mips64*el-*-ecoff*) gdb_target=embedl64 ;;
-mips64*-*-ecoff*) gdb_target=embed64 ;;
-mips64*vr4300*el-*-elf*) gdb_target=vr4300el ;;
-mips64*vr4300*-*-elf*) gdb_target=vr4300 ;;
-mips64*el-*-elf*) gdb_target=embedl64 ;;
-mips64*-*-elf*) gdb_target=embed64 ;;
-mips*el-*-ecoff*) gdb_target=embedl ;;
-mips*-*-ecoff*) gdb_target=embed ;;
-mips*el-*-elf*) gdb_target=embedl ;;
-mips*-*-elf*) gdb_target=embed ;;
-mips*-little-*) gdb_target=littlemips ;;
-mips*-sgi-irix5*) gdb_target=irix5 ;;
-mips*-sgi-*) gdb_target=irix3 ;;
-mips*-sony-*) gdb_target=bigmips ;;
-mips*-*-mach3*) gdb_target=mach3 ;;
-mips*-*-sysv4*) gdb_target=mipsv4 ;;
-mips*-*-sysv*) gdb_target=bigmips ;;
-mips*-*-riscos*) gdb_target=bigmips ;;
-mips*-*-vxworks*) gdb_target=vxmips ;;
-
-none-*-*) gdb_target=none ;;
-
-np1-*-*) gdb_target=np1 ;;
-
-ns32k-*-mach3*) gdb_target=mach3 ;;
-ns32k-*-netbsd*) gdb_target=nbsd ;;
-ns32k-utek-sysv*) gdb_target=merlin ;;
-ns32k-utek-*) gdb_target=umax ;;
-
-pn-*-*) gdb_target=pn ;;
-powerpc-*-macos*) gdb_target=macos ;;
-powerpc-*-netware*) gdb_target=ppc-nw
- configdirs="${configdirs} nlm" ;;
-
-powerpc-*-aix4*) gdb_target=aix4 ;;
-powerpc-*-aix*) gdb_target=aix ;;
-powerpcle-*-cygwin32) gdb_target=cygwin32 ;;
-powerpc-*-eabi*) if test x"$powerpc_sim" = x"yes"; then
- gdb_target=ppc-sim
- else
- gdb_target=ppc-eabi
- fi ;;
-powerpcle-*-eabi*) if test x"$powerpc_sim" = x"yes"; then
- gdb_target=ppcle-sim
- else
- gdb_target=ppcle-eabi
- fi ;;
-
-pyramid-*-*) gdb_target=pyramid ;;
-
-rs6000-*-lynxos*) gdb_target=rs6000lynx ;;
-rs6000-*-aix4*) gdb_target=aix4 ;;
-rs6000-*-*) gdb_target=rs6000 ;;
-
-sparc-*-aout*) gdb_target=sparc-em ;;
-sparc-*-coff*) gdb_target=sparc-em ;;
-sparc-*-elf*) gdb_target=sparc-em ;;
-sparc-*-lynxos*) gdb_target=sparclynx
- configdirs="${configdirs} gdbserver" ;;
-sparc-*-netbsd*) gdb_target=nbsd ;;
-sparc-*-solaris2*) gdb_target=sun4sol2 ;;
-sparc-*-sunos4*) gdb_target=sun4os4 ;;
-sparc-*-sunos5*) gdb_target=sun4sol2 ;;
-sparc-*-vxworks*) gdb_target=vxsparc ;;
-sparc-*-*) gdb_target=sun4os4 ;;
-# Use sparc-em for sparclet for now.
-sparclet-*-*) gdb_target=sparc-em ;;
-sparclite*-*-*) gdb_target=sparclite ;;
-sparc64-*-solaris2*) gdb_target=sp64sol2 ;;
-sparc64-*-*) gdb_target=sp64 ;;
-
-tahoe-*-*) gdb_target=tahoe ;;
-
-vax-*-*) gdb_target=vax ;;
-
-w65-*-*) gdb_target=w65 ;;
-
-z8k-*-coff*) gdb_target=z8k ;;
-
-esac
-
-dnl
-changequote([,])dnl
+# target_subdir is used by the testsuite to find the target libraries.
+target_subdir=
+if test "${host}" != "${target}"; then
+ target_subdir="${target_alias}/"
+fi
+AC_SUBST(target_subdir)
frags=
host_makefile_frag=${srcdir}/config/${gdb_host_cpu}/${gdb_host}.mh
@@ -537,9 +534,9 @@ if test "${target}" = "${host}"; then
nativefile=`sed -n '
s/NAT_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
' ${host_makefile_frag}`
-else
+# else
# GDBserver is only useful in a "native" enviroment
-configdirs=`echo $configdirs | sed 's/gdbserver//'`
+# configdirs=`echo $configdirs | sed 's/gdbserver//'`
fi
changequote([,])
@@ -573,14 +570,17 @@ fi
AC_LINK_FILES($files, $links)
+dnl Check for exe extension set on certain hosts (e.g. Win32)
+AC_EXEEXT
+
AC_CONFIG_SUBDIRS($configdirs)
-AC_OUTPUT(Makefile,
+AC_OUTPUT(Makefile tui/Makefile .gdbinit:gdbinit.in,
[
dnl Autoconf doesn't provide a mechanism for modifying definitions
dnl provided by makefile fragments.
dnl
if test "${nativefile}" = ""; then
-sed -e '/^NATDEPFILES= /s//# NATDEPFILES= /' \
+sed -e '/^NATDEPFILES[[ ]]*=[[ ]]*/s//# NATDEPFILES=/' \
< Makefile > Makefile.tem
mv -f Makefile.tem Makefile
fi
@@ -592,14 +592,6 @@ sed -e '/^TM_FILE[ ]*=/s,^TM_FILE[ ]*=[ ]*,&config/'"${gdb_target_cpu}"'/,
mv -f Makefile.tmp Makefile
changequote([,])dnl
-case ${srcdir} in
-.)
-;;
-*)
-grep "source ${srcdir}/.gdbinit" .gdbinit >/dev/null 2>/dev/null || \
-echo "source ${srcdir}/.gdbinit" >> .gdbinit
-esac
-
case x$CONFIG_HEADERS in
xconfig.h:config.in)
echo > stamp-h ;;
@@ -612,4 +604,3 @@ nativefile=$nativefile
])
exit 0
-
diff --git a/contrib/gdb/gdb/configure.tgt b/contrib/gdb/gdb/configure.tgt
new file mode 100644
index 0000000..95fc274
--- /dev/null
+++ b/contrib/gdb/gdb/configure.tgt
@@ -0,0 +1,282 @@
+# Mappings from configurations to GDB target definitions. This is
+# invoked from the autoconf generated configure script.
+
+# This file sets the following shell variables:
+# gdb_target_cpu generic name of CPU
+# gdb_target name of GDB target definition to use
+
+# This file may also modify configdirs.
+
+# Map target cpu into the config cpu subdirectory name.
+# The default is $target_cpu.
+
+case "${target_cpu}" in
+
+alpha*) gdb_target_cpu=alpha ;;
+c[12]) gdb_target_cpu=convex ;;
+hppa*) gdb_target_cpu=pa ;;
+i[3456]86*) gdb_target_cpu=i386 ;;
+m68*) gdb_target_cpu=m68k ;;
+m88*) gdb_target_cpu=m88k ;;
+mips*) gdb_target_cpu=mips ;;
+# OBSOLETE np1) gdb_target_cpu=gould ;;
+powerpc*) gdb_target_cpu=powerpc ;;
+# OBSOLETE pn) gdb_target_cpu=gould ;;
+pyramid) gdb_target_cpu=pyr ;;
+sparc*) gdb_target_cpu=sparc ;;
+thumb*) gdb_target_cpu=arm ;;
+strongarm*) gdb_target_cpu=arm ;;
+v850*) gdb_target_cpu=v850 ;;
+*) gdb_target_cpu=$target_cpu ;;
+
+esac
+
+# map target info into gdb names.
+
+case "${target}" in
+
+a29k-*-aout*) gdb_target=a29k ;;
+a29k-*-coff*) gdb_target=a29k ;;
+a29k-*-elf*) gdb_target=a29k ;;
+a29k-*-ebmon*) gdb_target=a29k ;;
+a29k-*-kern*) gdb_target=a29k-kern ;;
+a29k-*-none*) gdb_target=a29k ;;
+a29k-*-sym1*) gdb_target=ultra3 ;;
+a29k-*-udi*) gdb_target=a29k-udi ;;
+a29k-*-vxworks*) gdb_target=vx29k ;;
+
+alpha*-*-osf*) gdb_target=alpha-osf1 ;;
+alpha*-*-linux*) gdb_target=alpha-linux ;;
+
+arc-*-*) gdb_target=arc ;;
+
+arm-*-* | thumb-*-* | strongarm-*-*) gdb_target=arm
+
+ # rdi doesn't work for wingdb yet
+ case $gdb_host in
+ windows) ;;
+ *)
+ configdirs="$configdirs rdi-share"
+ CONFIG_OBS="$CONFIG_OBS remote-rdi.o rdi-share/libangsd.a"
+ ;;
+ esac
+ ;;
+
+c1-*-*) gdb_target=convex ;;
+c2-*-*) gdb_target=convex ;;
+
+d10v-*-*) gdb_target=d10v ;;
+d30v-*-*) gdb_target=d30v ;;
+
+h8300-*-*) gdb_target=h8300 ;;
+h8500-*-*) gdb_target=h8500 ;;
+
+sh-*-*) gdb_target=sh ;;
+
+fr30-*-elf*) gdb_target=fr30 ;;
+
+hppa*-*-bsd*) gdb_target=hppabsd ;;
+hppa*-*-pro*) gdb_target=hppapro ;;
+hppa*-*-hpux*) gdb_target=hppahpux ;;
+hppa*-*-hiux*) gdb_target=hppahpux ;;
+hppa*-*-osf*) gdb_target=hppaosf ;;
+
+i[3456]86-sequent-bsd*) gdb_target=symmetry ;;
+i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
+i[3456]86-sequent-sysv*) gdb_target=ptx ;;
+i[3456]86-ncr-*) gdb_target=ncr3000 ;;
+i[3456]86-*-aout*) gdb_target=i386aout ;;
+i[3456]86-*-coff*) gdb_target=i386v ;;
+i[3456]86-*-elf*) gdb_target=i386v ;;
+i[3456]86-*-aix*) gdb_target=i386aix ;;
+i[3456]86-*-bsd*) gdb_target=i386bsd ;;
+i[3456]86-*-freebsd*) gdb_target=fbsd ;;
+i[3456]86-*-netbsd*) gdb_target=nbsd ;;
+i[3456]86-*-os9k) gdb_target=i386os9k ;;
+i[3456]86-*-go32*) gdb_target=i386aout ;;
+i[3456]86-*-lynxos*) gdb_target=i386lynx
+ configdirs="${configdirs} gdbserver" ;;
+i[3456]86-*-solaris*) gdb_target=i386sol2 ;;
+i[3456]86-*-sunos*) gdb_target=sun386 ;;
+i[3456]86-*-sysv4.2MP) gdb_target=i386v42mp ;;
+i[3456]86-*-sysv4.2uw2*) gdb_target=i386v42mp ;;
+i[3456]86-*-sysv4*) gdb_target=i386v4 ;;
+i[3456]86-*-unixware2*) gdb_target=i386v42mp ;;
+i[3456]86-*-unixware*) gdb_target=i386v4 ;;
+i[3456]86-*-sco3.2v4*) gdb_target=i386sco4 ;;
+i[3456]86-*-sco3.2v5*) gdb_target=i386sco5 ;;
+i[3456]86-*-sco*) gdb_target=i386v ;;
+i[3456]86-*-sysv*) gdb_target=i386v ;;
+i[3456]86-*-linux*) gdb_target=linux
+ configdirs="${configdirs} gdbserver" ;;
+i[3456]86-pc-linux-gnu) gdb_target=linux
+ configdirs="${configdirs} gdbserver" ;;
+i[3456]86-*-isc*) gdb_target=i386v ;;
+i[3456]86-*-mach3*) gdb_target=i386m3 ;;
+i[3456]86-*-gnu*) gdb_target=i386gnu ;;
+i[3456]86-*-netware*) gdb_target=i386nw
+ configdirs="${configdirs} nlm" ;;
+i[3456]86-*-osf1mk*) gdb_target=i386mk ;;
+i[3456]86-*-cygwin*) gdb_target=cygwin ;;
+i960-*-bout*) gdb_target=vxworks960 ;;
+i960-nindy-coff*) gdb_target=nindy960 ;;
+i960-*-coff*) gdb_target=mon960 ;;
+i960-nindy-elf*) gdb_target=nindy960 ;;
+i960-*-elf*) gdb_target=mon960 ;;
+
+i960-*-nindy*) gdb_target=nindy960 ;;
+i960-*-vxworks*) gdb_target=vxworks960 ;;
+
+m32r-*-elf*) gdb_target=m32r ;;
+
+m68000-*-sunos3*) gdb_target=sun2os3 ;;
+m68000-*-sunos4*) gdb_target=sun2os4 ;;
+
+m68*-apollo*-bsd*) gdb_target=apollo68b ;;
+m68*-bull-sysv*) gdb_target=dpx2 ;;
+m68*-hp-bsd*) gdb_target=hp300bsd ;;
+m68*-hp-hpux*) gdb_target=hp300hpux ;;
+m68*-altos-*) gdb_target=altos ;;
+m68*-att-*) gdb_target=3b1 ;;
+m68*-cisco*-*) gdb_target=cisco ;;
+m68*-ericsson-*) gdb_target=es1800 ;;
+m68*-isi-*) gdb_target=isi ;;
+m68*-motorola-*) gdb_target=delta68 ;;
+m68*-netx-*) gdb_target=vxworks68 ;;
+m68*-sony-*) gdb_target=news ;;
+m68*-tandem-*) gdb_target=st2000 ;;
+m68*-rom68k-*) gdb_target=monitor ;;
+m68*-*bug-*) gdb_target=monitor ;;
+m68*-monitor-*) gdb_target=monitor ;;
+m68*-est-*) gdb_target=monitor ;;
+m68*-*-aout*) gdb_target=monitor ;;
+m68*-*-coff*) gdb_target=monitor ;;
+m68*-*-elf*) gdb_target=monitor ;;
+m68*-*-linux*) gdb_target=linux
+ configdirs="${configdirs} gdbserver" ;;
+m68*-*-lynxos*) gdb_target=m68klynx
+ configdirs="${configdirs} gdbserver" ;;
+m68*-*-netbsd*) gdb_target=nbsd ;;
+m68*-*-os68k*) gdb_target=os68k ;;
+m68*-*-sunos3*) gdb_target=sun3os3 ;;
+m68*-*-sunos4*) gdb_target=sun3os4 ;;
+m68*-*-sysv4*) gdb_target=m68kv4 ;;
+m68*-*-vxworks*) gdb_target=vxworks68 ;;
+
+m88*-harris-cxux*) gdb_target=cxux ;;
+m88*-motorola-sysv4*) gdb_target=delta88v4 ;;
+m88*-motorola-*) gdb_target=delta88 ;;
+m88*-*-*) gdb_target=m88k ;;
+
+mips64*-big-*) gdb_target=bigmips64 ;;
+mips*-big-*) gdb_target=bigmips ;;
+mips*-dec-mach3*) gdb_target=mach3 ;;
+mips*-dec-*) gdb_target=decstation ;;
+mips64*el-*-ecoff*) gdb_target=embedl64 ;;
+mips64*-*-ecoff*) gdb_target=embed64 ;;
+mips64*vr4300*el-*-elf*) gdb_target=vr4300el ;;
+mips64*vr4300*-*-elf*) gdb_target=vr4300 ;;
+mips64*vr4100*el-*-elf*) gdb_target=vr4300el ;;
+mips64*vr4100*-*-elf*) gdb_target=vr4100 ;;
+mips64*vr5000*el-*-elf*) gdb_target=vr5000el ;;
+mips64*vr5000*-*-elf*) gdb_target=vr5000
+ configdirs="${configdirs} gdbserver" ;;
+mips*tx39*el*-elf*) gdb_target=tx39l ;;
+mips*tx39*-elf*) gdb_target=tx39 ;;
+mips64*el-*-elf*) gdb_target=embedl64 ;;
+mips64*-*-elf*) gdb_target=embed64 ;;
+mips*el-*-ecoff*) gdb_target=embedl ;;
+mips*-*-ecoff*) gdb_target=embed ;;
+mips*el-*-elf*) gdb_target=embedl ;;
+mips*-*-elf*) gdb_target=embed ;;
+mips*-little-*) gdb_target=littlemips ;;
+mips*-*-lnews*) gdb_target=embedl ;;
+mips*-sgi-irix5*) gdb_target=irix5 ;;
+mips*-sgi-irix6*) gdb_target=irix5 ;;
+mips*-sgi-*) gdb_target=irix3 ;;
+mips*-sony-*) gdb_target=bigmips ;;
+mips*-*-mach3*) gdb_target=mipsm3 ;;
+mips*-*-sysv4*) gdb_target=mipsv4 ;;
+mips*-*-sysv*) gdb_target=bigmips ;;
+mips*-*-riscos*) gdb_target=bigmips ;;
+mips*-*-vxworks*) gdb_target=vxmips ;;
+
+mn10200-*-*) gdb_target=mn10200 ;;
+mn10300-*-*) gdb_target=mn10300 ;;
+
+none-*-*) gdb_target=none ;;
+
+# OBSOLETE np1-*-*) gdb_target=np1 ;;
+
+ns32k-*-mach3*) gdb_target=ns32km3 ;;
+ns32k-*-netbsd*) gdb_target=nbsd ;;
+ns32k-utek-sysv*) gdb_target=merlin ;;
+ns32k-utek-*) gdb_target=umax ;;
+
+# OBSOLETE pn-*-*) gdb_target=pn ;;
+
+powerpc-*-macos*) gdb_target=macos ;;
+powerpc-*-netware*) gdb_target=ppc-nw
+ configdirs="${configdirs} nlm" ;;
+
+powerpc-*-aix*) gdb_target=aix ;;
+powerpcle-*-cygwin*) gdb_target=cygwin ;;
+powerpcle-*-solaris*) gdb_target=solaris ;;
+powerpc-*-eabi* | powerpc-*-linux* | powerpc-*-sysv* | powerpc-*-elf*)
+ if test -f ../sim/ppc/Makefile; then
+ gdb_target=ppc-sim
+ else
+ gdb_target=ppc-eabi
+ fi ;;
+powerpcle-*-eabi* | powerpcle-*-sysv* | powerpcle-*-elf*)
+ if test -f ../sim/ppc/Makefile; then
+ gdb_target=ppcle-sim
+ else
+ gdb_target=ppcle-eabi
+ fi ;;
+
+pyramid-*-*) gdb_target=pyramid ;;
+
+rs6000-*-lynxos*) gdb_target=rs6000lynx ;;
+rs6000-*-aix4*) gdb_target=aix4 ;;
+rs6000-*-*) gdb_target=rs6000 ;;
+
+sparc-*-aout*) gdb_target=sparc-em ;;
+sparc-*-coff*) gdb_target=sparc-em ;;
+sparc-*-elf*) gdb_target=sparc-em ;;
+sparc-*-linux*) gdb_target=linux ;;
+sparc-*-lynxos*) gdb_target=sparclynx
+ configdirs="${configdirs} gdbserver" ;;
+sparc-*-netbsd*) gdb_target=nbsd ;;
+sparc-*-solaris2*) gdb_target=sun4sol2 ;;
+sparc-*-sunos4*) gdb_target=sun4os4 ;;
+sparc-*-sunos5*) gdb_target=sun4sol2 ;;
+sparc-*-vxworks*) gdb_target=vxsparc ;;
+sparc-*-*) gdb_target=sun4os4 ;;
+sparclet-*-*) gdb_target=sparclet;;
+sparclite-*-*) gdb_target=sparclite ;;
+sparc86x-*-*) gdb_target=sparclite ;;
+# It's not clear what the right solution for "v8plus" systems is yet.
+# For now, stick with sparc-sun-solaris2 since that's what config.guess
+# should return. Work is still needed to get gdb to print the 64 bit
+# regs (some of which are usable in v8plus) so sp64sol.mt hasn't been
+# deleted though presumably it should be eventually.
+#sparc64-*-solaris2*) gdb_target=sp64sol2 ;;
+sparc64-*-*) gdb_target=sp64 ;;
+
+tahoe-*-*) gdb_target=tahoe ;;
+
+
+vax-*-*) gdb_target=vax ;;
+
+fr30-*-*) gdb_target=fr30
+ ;;
+
+v850*-*-*) gdb_target=v850
+ ;;
+
+w65-*-*) gdb_target=w65 ;;
+
+z8k-*-coff*) gdb_target=z8k ;;
+
+esac
diff --git a/contrib/gdb/gdb/copying.awk b/contrib/gdb/gdb/copying.awk
index ab8efe8..4f53e92 100644
--- a/contrib/gdb/gdb/copying.awk
+++ b/contrib/gdb/gdb/copying.awk
@@ -7,11 +7,11 @@ BEGIN {
print "#include \"command.h\""
print "#include \"gdbcmd.h\""
print ""
- print "static void"
- print "show_copying_command PARAMS ((char *, int));"
+ print "static void show_copying_command PARAMS ((char *, int));"
print ""
- print "static void"
- print "show_warranty_command PARAMS ((char *, int));"
+ print "static void show_warranty_command PARAMS ((char *, int));"
+ print ""
+ print "void _initialize_copying PARAMS ((void));"
print ""
print "extern int immediate_quit;";
print "static void";
diff --git a/contrib/gdb/gdb/copying.c b/contrib/gdb/gdb/copying.c
index ffc884a..a36db1f 100644
--- a/contrib/gdb/gdb/copying.c
+++ b/contrib/gdb/gdb/copying.c
@@ -5,11 +5,11 @@
#include "command.h"
#include "gdbcmd.h"
-static void
-show_copying_command PARAMS ((char *, int));
+static void show_copying_command PARAMS ((char *, int));
-static void
-show_warranty_command PARAMS ((char *, int));
+static void show_warranty_command PARAMS ((char *, int));
+
+void _initialize_copying PARAMS ((void));
extern int immediate_quit;
static void
@@ -22,7 +22,7 @@ show_copying_command (ignore, from_tty)
printf_filtered (" Version 2, June 1991\n");
printf_filtered ("\n");
printf_filtered (" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n");
- printf_filtered (" 675 Mass Ave, Cambridge, MA 02139, USA\n");
+ printf_filtered (" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
printf_filtered (" Everyone is permitted to copy and distribute verbatim copies\n");
printf_filtered (" of this license document, but changing it is not allowed.\n");
printf_filtered ("\n");
diff --git a/contrib/gdb/gdb/core-aout.c b/contrib/gdb/gdb/core-aout.c
index 7103a9c..3c1d499 100644
--- a/contrib/gdb/gdb/core-aout.c
+++ b/contrib/gdb/gdb/core-aout.c
@@ -1,5 +1,5 @@
/* Extract registers from a "standard" core file, for GDB.
- Copyright (C) 1988-1995 Free Software Foundation, Inc.
+ Copyright (C) 1988-1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -23,6 +23,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
more machine specific. */
#include "defs.h"
+
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
+#else
+# ifdef HAVE_SYS_PTRACE_H
+# include <sys/ptrace.h>
+# endif
+#endif
+
#include <sys/types.h>
#include <sys/param.h>
#include "gdbcore.h"
@@ -35,13 +44,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/file.h>
#include "gdb_stat.h"
#include <sys/user.h>
-#ifndef NO_PTRACE_H
-# ifdef PTRACE_IN_WRONG_PLACE
-# include <ptrace.h>
-# else /* !PTRACE_IN_WRONG_PLACE */
-# include <sys/ptrace.h>
-# endif /* !PTRACE_IN_WRONG_PLACE */
-#endif /* NO_PTRACE_H */
#endif
#ifndef CORE_REGISTER_ADDR
@@ -52,6 +54,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/core.h>
#endif
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
+
+void _initialize_core_aout PARAMS ((void));
+
/* Extract the register values out of the core file and store
them where `read_register' will find them.
@@ -70,12 +76,12 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned reg_addr;
+ CORE_ADDR reg_addr;
{
- register int regno;
- register unsigned int addr;
+ int regno;
+ CORE_ADDR addr;
int bad_reg = -1;
- register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
+ CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
int numregs = ARCH_NUM_REGS;
/* If u.u_ar0 was an absolute address in the core file, relativize it now,
@@ -84,23 +90,21 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
CORE_REGISTER_ADDR to offset to the other registers. If this is a modern
core file without a upage, reg_ptr will be zero and this is all a big
NOP. */
- if (reg_ptr > (int) core_reg_size)
+ if (reg_ptr > core_reg_size)
reg_ptr -= KERNEL_U_ADDR;
for (regno = 0; regno < numregs; regno++)
{
addr = CORE_REGISTER_ADDR (regno, reg_ptr);
- if (addr >= core_reg_size) {
- if (bad_reg < 0)
- bad_reg = regno;
- } else {
- supply_register (regno, core_reg_sect + addr);
- }
+ if (addr >= core_reg_size
+ && bad_reg < 0)
+ bad_reg = regno;
+ else
+ supply_register (regno, core_reg_sect + addr);
}
+
if (bad_reg >= 0)
- {
- error ("Register %s not found in core file.", reg_names[bad_reg]);
- }
+ error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
}
@@ -109,12 +113,12 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
/* Return the address in the core dump or inferior of register REGNO.
BLOCKEND is the address of the end of the user structure. */
-unsigned int
+CORE_ADDR
register_addr (regno, blockend)
int regno;
- int blockend;
+ CORE_ADDR blockend;
{
- int addr;
+ CORE_ADDR addr;
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
diff --git a/contrib/gdb/gdb/core-regset.c b/contrib/gdb/gdb/core-regset.c
index 68b0845..d925abe 100644
--- a/contrib/gdb/gdb/core-regset.c
+++ b/contrib/gdb/gdb/core-regset.c
@@ -1,5 +1,5 @@
/* Machine independent GDB support for core files on systems using "regsets".
- Copyright 1993-1996 Free Software Foundation, Inc.
+ Copyright 1993-1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -47,6 +47,10 @@ regardless of whether or not the actual target has floating point hardware.
#include "command.h"
#include "gdbcore.h"
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
+
+void _initialize_core_regset PARAMS ((void));
+
/*
GLOBAL FUNCTION
@@ -57,7 +61,7 @@ SYNOPSIS
void fetch_core_registers (char *core_reg_sect,
unsigned core_reg_size,
- int which, unsigned in reg_addr)
+ int which, CORE_ADDR reg_addr)
DESCRIPTION
@@ -77,7 +81,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int reg_addr; /* Unused in this version */
+ CORE_ADDR reg_addr; /* Unused in this version */
{
#if defined (HAVE_GREGSET_T) && defined (HAVE_FPREGSET_T)
gregset_t gregset;
diff --git a/contrib/gdb/gdb/core-sol2.c b/contrib/gdb/gdb/core-sol2.c
index 5f43002..3c69e63 100644
--- a/contrib/gdb/gdb/core-sol2.c
+++ b/contrib/gdb/gdb/core-sol2.c
@@ -26,10 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
and sparc-nat.c to be able to read both flavours. */
#include "defs.h"
-#undef gregset_t
-#undef fpregset_t
-
#include <time.h>
+#include <sys/types.h>
#include <sys/regset.h>
#include <sys/procfs.h>
#include <fcntl.h>
@@ -41,12 +39,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "command.h"
#include "gdbcore.h"
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
+
static void
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int reg_addr; /* Unused in this version */
+ CORE_ADDR reg_addr; /* Unused in this version */
{
prgregset_t prgregset;
prfpregset_t prfpregset;
diff --git a/contrib/gdb/gdb/corefile.c b/contrib/gdb/gdb/corefile.c
index a916bf8..94e56eb 100644
--- a/contrib/gdb/gdb/corefile.c
+++ b/contrib/gdb/gdb/corefile.c
@@ -33,12 +33,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#include "dis-asm.h"
#include "language.h"
+#include "gdb_stat.h"
+#include "symfile.h"
+#include "objfiles.h"
extern char registers[];
-/* Hook for `exec_file_command' command to call. */
+/* Local function declarations. */
-void (*exec_file_display_hook) PARAMS ((char *)) = NULL;
+static void call_extra_exec_file_hooks PARAMS ((char *filename));
+
+/* You can have any number of hooks for `exec_file_command' command to call.
+ If there's only one hook, it is set in exec_file_display hook.
+ If there are two or more hooks, they are set in exec_file_extra_hooks[],
+ and exec_file_display_hook is set to a function that calls all of them.
+ This extra complexity is needed to preserve compatibility with
+ old code that assumed that only one hook could be set, and which called
+ exec_file_display_hook directly. */
+
+typedef void (*hook_type) PARAMS ((char *));
+
+hook_type exec_file_display_hook; /* the original hook */
+static hook_type *exec_file_extra_hooks; /* array of additional hooks */
+static int exec_file_hook_count = 0; /* size of array */
/* Binary file diddling handle for the core file. */
@@ -61,12 +78,47 @@ core_file_command (filename, from_tty)
if (!filename)
(t->to_detach) (filename, from_tty);
else
- (t->to_open) (filename, from_tty);
+ {
+ /* Yes, we were given the path of a core file. Do we already
+ have a symbol file? If not, can we determine it from the
+ core file? If we can, do so.
+ */
+#ifdef HPUXHPPA
+ if (symfile_objfile == NULL)
+ {
+ char * symfile;
+ symfile = t->to_core_file_to_sym_file (filename);
+ if (symfile)
+ {
+ char * symfile_copy = strdup (symfile);
+
+ make_cleanup (free, symfile_copy);
+ symbol_file_command (symfile_copy, from_tty);
+ }
+ else
+ warning ("Unknown symbols for '%s'; use the 'symbol-file' command.", filename);
+ }
+#endif
+ (t->to_open) (filename, from_tty);
+ }
else
error ("GDB can't read core files on this machine.");
}
+/* If there are two or more functions that wish to hook into exec_file_command,
+ * this function will call all of the hook functions. */
+
+static void
+call_extra_exec_file_hooks (filename)
+ char *filename;
+{
+ int i;
+
+ for (i = 0; i < exec_file_hook_count; i++)
+ (*exec_file_extra_hooks[i])(filename);
+}
+
/* Call this to specify the hook for exec_file_command to call back.
This is called from the x-window display code. */
@@ -74,7 +126,33 @@ void
specify_exec_file_hook (hook)
void (*hook) PARAMS ((char *));
{
- exec_file_display_hook = hook;
+ hook_type *new_array;
+
+ if (exec_file_display_hook != NULL)
+ {
+ /* There's already a hook installed. Arrange to have both it
+ * and the subsequent hooks called. */
+ if (exec_file_hook_count == 0)
+ {
+ /* If this is the first extra hook, initialize the hook array. */
+ exec_file_extra_hooks = (hook_type *) xmalloc (sizeof(hook_type));
+ exec_file_extra_hooks[0] = exec_file_display_hook;
+ exec_file_display_hook = call_extra_exec_file_hooks;
+ exec_file_hook_count = 1;
+ }
+
+ /* Grow the hook array by one and add the new hook to the end.
+ Yes, it's inefficient to grow it by one each time but since
+ this is hardly ever called it's not a big deal. */
+ exec_file_hook_count++;
+ new_array =
+ (hook_type *) xrealloc (exec_file_extra_hooks,
+ exec_file_hook_count * sizeof(hook_type));
+ exec_file_extra_hooks = new_array;
+ exec_file_extra_hooks[exec_file_hook_count - 1] = hook;
+ }
+ else
+ exec_file_display_hook = hook;
}
/* The exec file must be closed before running an inferior.
@@ -84,7 +162,7 @@ specify_exec_file_hook (hook)
void
close_exec_file ()
{
-#ifdef FIXME
+#if 0 /* FIXME */
if (exec_bfd)
bfd_tempclose (exec_bfd);
#endif
@@ -93,9 +171,27 @@ close_exec_file ()
void
reopen_exec_file ()
{
-#ifdef FIXME
+#if 0 /* FIXME */
if (exec_bfd)
bfd_reopen (exec_bfd);
+#else
+ char *filename;
+ int res;
+ struct stat st;
+ long mtime;
+
+ /* Don't do anything if the current target isn't exec. */
+ if (exec_bfd == NULL || strcmp (target_shortname, "exec") != 0)
+ return;
+
+ /* If the timestamp of the exec file has changed, reopen it. */
+ filename = strdup (bfd_get_filename (exec_bfd));
+ make_cleanup (free, filename);
+ mtime = bfd_get_mtime(exec_bfd);
+ res = stat (filename, &st);
+
+ if (mtime && mtime != st.st_mtime)
+ exec_file_command (filename, 0);
#endif
}
@@ -172,6 +268,19 @@ read_memory (memaddr, myaddr, len)
memory_error (status, memaddr);
}
+void
+read_memory_section (memaddr, myaddr, len, bfd_section)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ asection *bfd_section;
+{
+ int status;
+ status = target_read_memory_section (memaddr, myaddr, len, bfd_section);
+ if (status != 0)
+ memory_error (status, memaddr);
+}
+
/* Like target_read_memory, but slightly different parameters. */
int
@@ -230,16 +339,47 @@ read_memory_integer (memaddr, len)
return extract_signed_integer (buf, len);
}
-unsigned LONGEST
+ULONGEST
read_memory_unsigned_integer (memaddr, len)
CORE_ADDR memaddr;
int len;
{
- char buf[sizeof (unsigned LONGEST)];
+ char buf[sizeof (ULONGEST)];
read_memory (memaddr, buf, len);
return extract_unsigned_integer (buf, len);
}
+
+void
+read_memory_string (memaddr, buffer, max_len)
+ CORE_ADDR memaddr;
+ char * buffer;
+ int max_len;
+{
+ register char * cp;
+ register int i;
+ int cnt;
+
+ cp = buffer;
+ while (1)
+ {
+ if (cp - buffer >= max_len)
+ {
+ buffer[max_len - 1] = '\0';
+ break;
+ }
+ cnt = max_len - (cp - buffer);
+ if (cnt > 8)
+ cnt = 8;
+ read_memory (memaddr + (int) (cp - buffer), cp, cnt);
+ for (i = 0; i < cnt && *cp; i++, cp++)
+ ; /* null body */
+
+ if (i < cnt && !*cp)
+ break;
+ }
+}
+
#if 0
/* Enable after 4.12. It is not tested. */
diff --git a/contrib/gdb/gdb/corelow.c b/contrib/gdb/gdb/corelow.c
index 48bc184..e635257 100644
--- a/contrib/gdb/gdb/corelow.c
+++ b/contrib/gdb/gdb/corelow.c
@@ -1,5 +1,5 @@
/* Core dump and executable file functions below target vector, for GDB.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
+#include <unistd.h>
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "symtab.h"
@@ -30,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "target.h"
#include "gdbcore.h"
-#include "thread.h"
+#include "gdbthread.h"
/* List of all available core_fns. On gdb startup, each core file register
reader calls add_core_fns() to register information on each core format it
@@ -41,7 +42,7 @@ static struct core_fns *core_file_fns = NULL;
static void core_files_info PARAMS ((struct target_ops *));
#ifdef SOLIB_ADD
-static int solib_add_stub PARAMS ((char *));
+static int solib_add_stub PARAMS ((PTR));
#endif
static void core_open PARAMS ((char *, int));
@@ -52,6 +53,20 @@ static void core_close PARAMS ((int));
static void get_core_registers PARAMS ((int));
+static void add_to_thread_list PARAMS ((bfd *, asection *, PTR));
+
+static int ignore PARAMS ((CORE_ADDR, char *));
+
+static char *core_file_to_sym_file PARAMS ((char *));
+
+static int core_file_thread_alive PARAMS ((int tid));
+
+static void init_core_ops PARAMS ((void));
+
+void _initialize_corelow PARAMS ((void));
+
+struct target_ops core_ops;
+
/* Link a new core_fns into the global core_file_fns list. Called on gdb
startup by the _initialize routine in each core file register reader, to
register information about each format the the reader is prepared to
@@ -76,10 +91,10 @@ core_close (quitting)
{
char *name;
- inferior_pid = 0; /* Avoid confusion from thread stuff */
-
if (core_bfd)
{
+ inferior_pid = 0; /* Avoid confusion from thread stuff */
+
name = bfd_get_filename (core_bfd);
if (!bfd_close (core_bfd))
warning ("cannot close \"%s\": %s",
@@ -104,7 +119,7 @@ core_close (quitting)
static int
solib_add_stub (from_ttyp)
- char *from_ttyp;
+ PTR from_ttyp;
{
SOLIB_ADD (NULL, *(int *)from_ttyp, &current_target);
re_enable_breakpoints_in_shlibs ();
@@ -133,7 +148,8 @@ add_to_thread_list (abfd, asect, reg_sect_arg)
/* Warning, Will Robinson, looking at BFD private data! */
- if (asect->filepos == reg_sect->filepos) /* Did we find .reg? */
+ if (reg_sect != NULL
+ && asect->filepos == reg_sect->filepos) /* Did we find .reg? */
inferior_pid = thread_id; /* Yes, make it current */
}
@@ -184,7 +200,7 @@ core_open (filename, from_tty)
/* FIXME: should be checking for errors from bfd_close (for one thing,
on error it does not free all the storage associated with the
bfd). */
- make_cleanup (bfd_close, temp_bfd);
+ make_cleanup ((make_cleanup_func) bfd_close, temp_bfd);
error ("\"%s\" is not a core dump: %s",
filename, bfd_errmsg (bfd_get_error ()));
}
@@ -194,7 +210,7 @@ core_open (filename, from_tty)
discard_cleanups (old_chain); /* Don't free filename any more */
unpush_target (&core_ops);
core_bfd = temp_bfd;
- old_chain = make_cleanup (core_close, core_bfd);
+ old_chain = make_cleanup ((make_cleanup_func) core_close, core_bfd);
validate_files ();
@@ -273,9 +289,9 @@ get_core_registers (regno)
sec_ptr reg_sec;
unsigned size;
char *the_regs;
- char secname[10];
+ char secname[30];
enum bfd_flavour our_flavour = bfd_get_flavour (core_bfd);
- struct core_fns *cf;
+ struct core_fns *cf = NULL;
if (core_file_fns == NULL)
{
@@ -351,6 +367,69 @@ cant:
registers_fetched ();
}
+static char *
+core_file_to_sym_file (core)
+ char * core;
+{
+ CONST char * failing_command;
+ char * p;
+ char * temp;
+ bfd * temp_bfd;
+ int scratch_chan;
+
+ if (! core)
+ error ("No core file specified.");
+
+ core = tilde_expand (core);
+ if (core[0] != '/')
+ {
+ temp = concat (current_directory, "/", core, NULL);
+ core = temp;
+ }
+
+ scratch_chan = open (core, write_files ? O_RDWR : O_RDONLY, 0);
+ if (scratch_chan < 0)
+ perror_with_name (core);
+
+ temp_bfd = bfd_fdopenr (core, gnutarget, scratch_chan);
+ if (temp_bfd == NULL)
+ perror_with_name (core);
+
+ if (!bfd_check_format (temp_bfd, bfd_core))
+ {
+ /* Do it after the err msg */
+ /* FIXME: should be checking for errors from bfd_close (for one thing,
+ on error it does not free all the storage associated with the
+ bfd). */
+ make_cleanup ((make_cleanup_func) bfd_close, temp_bfd);
+ error ("\"%s\" is not a core dump: %s",
+ core, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Find the data section */
+ if (build_section_table (temp_bfd, &core_ops.to_sections,
+ &core_ops.to_sections_end))
+ error ("\"%s\": Can't find sections: %s",
+ bfd_get_filename (temp_bfd), bfd_errmsg (bfd_get_error ()));
+
+ failing_command = bfd_core_file_failing_command (temp_bfd);
+
+ bfd_close (temp_bfd);
+
+ /* If we found a filename, remember that it is probably saved
+ relative to the executable that created it. If working directory
+ isn't there now, we may not be able to find the executable. Rather
+ than trying to be sauve about finding it, just check if the file
+ exists where we are now. If not, then punt and tell our client
+ we couldn't find the sym file.
+ */
+ p = (char *) failing_command;
+ if ((p != NULL) && (access (p, F_OK) != 0))
+ p = NULL;
+
+ return p;
+}
+
static void
core_files_info (t)
struct target_ops *t;
@@ -369,51 +448,64 @@ ignore (addr, contents)
return 0;
}
-struct target_ops core_ops = {
- "core", /* to_shortname */
- "Local core dump file", /* to_longname */
- "Use a core file as a target. Specify the filename of the core file.", /* to_doc */
- core_open, /* to_open */
- core_close, /* to_close */
- find_default_attach, /* to_attach */
- core_detach, /* to_detach */
- 0, /* to_resume */
- 0, /* to_wait */
- get_core_registers, /* to_fetch_registers */
- 0, /* to_store_registers */
- 0, /* to_prepare_to_store */
- xfer_memory, /* to_xfer_memory */
- core_files_info, /* to_files_info */
- ignore, /* to_insert_breakpoint */
- ignore, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- 0, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- find_default_create_inferior, /* to_create_inferior */
- 0, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- core_stratum, /* to_stratum */
- 0, /* to_next */
- 0, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 0, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC, /* to_magic */
-};
+
+/* Okay, let's be honest: threads gleaned from a core file aren't
+ exactly lively, are they? On the other hand, if we don't claim
+ that each & every one is alive, then we don't get any of them
+ to appear in an "info thread" command, which is quite a useful
+ behaviour.
+ */
+static int
+core_file_thread_alive (tid)
+ int tid;
+{
+ return 1;
+}
+
+/* Fill in core_ops with its defined operations and properties. */
+
+static void
+init_core_ops ()
+{
+ core_ops.to_shortname = "core";
+ core_ops.to_longname = "Local core dump file";
+ core_ops.to_doc =
+ "Use a core file as a target. Specify the filename of the core file.";
+ core_ops.to_open = core_open;
+ core_ops.to_close = core_close;
+ core_ops.to_attach = find_default_attach;
+ core_ops.to_require_attach = find_default_require_attach;
+ core_ops.to_detach = core_detach;
+ core_ops.to_require_detach = find_default_require_detach;
+ core_ops.to_fetch_registers = get_core_registers;
+ core_ops.to_xfer_memory = xfer_memory;
+ core_ops.to_files_info = core_files_info;
+ core_ops.to_insert_breakpoint = ignore;
+ core_ops.to_remove_breakpoint = ignore;
+ core_ops.to_create_inferior = find_default_create_inferior;
+ core_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ core_ops.to_thread_alive = core_file_thread_alive;
+ core_ops.to_core_file_to_sym_file = core_file_to_sym_file;
+ core_ops.to_stratum = core_stratum;
+ core_ops.to_has_memory = 1;
+ core_ops.to_has_stack = 1;
+ core_ops.to_has_registers = 1;
+ core_ops.to_magic = OPS_MAGIC;
+}
+
+/* non-zero if we should not do the add_target call in
+ _initialize_corelow; not initialized (i.e., bss) so that
+ the target can initialize it (i.e., data) if appropriate.
+ This needs to be set at compile time because we don't know
+ for sure whether the target's initialize routine is called
+ before us or after us. */
+int coreops_suppress_target;
void
-_initialize_corelow()
+_initialize_corelow ()
{
- add_target (&core_ops);
+ init_core_ops ();
+
+ if (!coreops_suppress_target)
+ add_target (&core_ops);
}
diff --git a/contrib/gdb/gdb/cp-valprint.c b/contrib/gdb/gdb/cp-valprint.c
index 48f4905..eeeb79e 100644
--- a/contrib/gdb/gdb/cp-valprint.c
+++ b/contrib/gdb/gdb/cp-valprint.c
@@ -30,11 +30,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "annotate.h"
#include "gdb_string.h"
#include "c-lang.h"
+#include "target.h"
+
+/* Indication of presence of HP-compiled object files */
+extern int hp_som_som_object_present; /* defined in symtab.c */
+
int vtblprint; /* Controls printing of vtbl's */
int objectprint; /* Controls looking up an object's derived type
using what we find in its vtables. */
-static int static_field_print; /* Controls printing of static fields. */
+int static_field_print; /* Controls printing of static fields. */
static struct obstack dont_print_vb_obstack;
static struct obstack dont_print_statmem_obstack;
@@ -44,9 +49,14 @@ cp_print_static_field PARAMS ((struct type *, value_ptr, GDB_FILE *, int, int,
enum val_prettyprint));
static void
-cp_print_value PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *,
+cp_print_value PARAMS ((struct type *, struct type *, char *, int, CORE_ADDR, GDB_FILE *,
int, int, enum val_prettyprint, struct type **));
+static void
+cp_print_hpacc_virtual_table_entries PARAMS ((struct type *, int *, value_ptr, GDB_FILE *,
+ int, int, enum val_prettyprint));
+
+
void
cp_print_class_method (valaddr, type, stream)
char *valaddr;
@@ -86,6 +96,8 @@ cp_print_class_method (valaddr, type, stream)
QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
{
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (domain, i, j);
kind = "virtual ";
goto common;
}
@@ -97,6 +109,12 @@ cp_print_class_method (valaddr, type, stream)
sym = find_pc_function (addr);
if (sym == 0)
{
+ /* 1997-08-01 Currently unsupported with HP aCC */
+ if (hp_som_som_object_present)
+ {
+ fputs_filtered ("?? <not supported with HP aCC>", stream);
+ return;
+ }
error ("invalid pointer to member function");
}
len = TYPE_NFN_FIELDS (domain);
@@ -120,21 +138,19 @@ cp_print_class_method (valaddr, type, stream)
common:
if (i < len)
{
+ char *demangled_name;
+
fprintf_filtered (stream, "&");
- c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
- fprintf_unfiltered (stream, kind);
- if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
- && is_cplus_marker (TYPE_FN_FIELD_PHYSNAME (f, j)[1]))
- {
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
- TYPE_FN_FIELDLIST_NAME (domain, i),
- 0, stream);
- }
+ fprintf_filtered (stream, kind);
+ demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ fprintf_filtered (stream, "<badly mangled name %s>",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
else
{
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
- TYPE_FN_FIELDLIST_NAME (domain, i),
- 0, stream);
+ fputs_filtered (demangled_name, stream);
+ free (demangled_name);
}
}
else
@@ -152,6 +168,13 @@ static const char vtbl_ptr_name_old[] =
const char vtbl_ptr_name[] =
{ '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
+/* HP aCC uses different names */
+const char hpacc_vtbl_ptr_name[] =
+ { '_', '_', 'v', 'f', 'p', 0 };
+const char hpacc_vtbl_ptr_type_name[] =
+ { '_', '_', 'v', 'f', 't', 'y', 'p', 0 };
+
+
/* Return truth value for assertion that TYPE is of the type
"pointer to virtual function". */
@@ -197,14 +220,19 @@ cp_is_vtbl_member(type)
TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
same meanings as in cp_print_value and c_val_print.
+ 2nd argument REAL_TYPE is used to carry over the type of the derived
+ class across the recursion to base classes.
+
DONT_PRINT is an array of baseclass types that we
should not print, or zero if called from top level. */
void
-cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
+cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format, recurse, pretty,
dont_print_vb, dont_print_statmem)
struct type *type;
+ struct type *real_type;
char *valaddr;
+ int offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -216,6 +244,7 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
int i, len, n_baseclasses;
struct obstack tmp_obstack;
char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
+ int fields_seen = 0;
CHECK_TYPEDEF (type);
@@ -223,18 +252,26 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
len = TYPE_NFIELDS (type);
n_baseclasses = TYPE_N_BASECLASSES (type);
- /* Print out baseclasses such that we don't print
+ /* First, print out baseclasses such that we don't print
duplicates of virtual baseclasses. */
+
if (n_baseclasses > 0)
- cp_print_value (type, valaddr, address, stream,
+ cp_print_value (type, real_type, valaddr, offset, address, stream,
format, recurse+1, pretty, dont_print_vb);
- if (!len && n_baseclasses == 1)
+ /* Second, print out data fields */
+
+ /* If there are no data fields, or if the only field is the
+ * vtbl pointer, skip this part */
+ if ((len == n_baseclasses) ||
+ ((len - n_baseclasses == 1) &&
+ TYPE_HAS_VTABLE(type) &&
+ STREQN(TYPE_FIELD_NAME (type, n_baseclasses), hpacc_vtbl_ptr_name, 5)) ||
+ !len)
fprintf_filtered (stream, "<No data fields>");
else
{
extern int inspect_it;
- int fields_seen = 0;
if (dont_print_statmem == 0)
{
@@ -250,6 +287,11 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
/* If requested, skip printing of static fields. */
if (!static_field_print && TYPE_FIELD_STATIC (type, i))
continue;
+
+ /* If a vtable pointer appears, we'll print it out later */
+ if (TYPE_HAS_VTABLE(type) && STREQN(TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5))
+ continue;
+
if (fields_seen)
fprintf_filtered (stream, ", ");
else if (n_baseclasses > 0)
@@ -301,7 +343,9 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
language_cplus,
DMGL_PARAMS | DMGL_ANSI);
annotate_field_name_end ();
- fputs_filtered (" = ", stream);
+ /* do not print leading '=' in case of anonymous unions */
+ if (strcmp (TYPE_FIELD_NAME (type, i), ""))
+ fputs_filtered (" = ", stream);
annotate_field_value ();
}
@@ -318,9 +362,9 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
else
{
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
- unpack_field_as_long (type, valaddr, i));
+ unpack_field_as_long (type, valaddr + offset, i));
- val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
+ val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0, 0,
stream, format, 0, recurse + 1, pretty);
}
}
@@ -332,26 +376,20 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
}
else if (TYPE_FIELD_STATIC (type, i))
{
- value_ptr v;
- char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, i);
- struct symbol *sym =
- lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
- if (sym == NULL)
+ value_ptr v = value_static_field (type, i);
+ if (v == NULL)
fputs_filtered ("<optimized out>", stream);
else
- {
- v = value_at (TYPE_FIELD_TYPE (type, i),
- (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
- cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
- stream, format, recurse + 1,
- pretty);
- }
+ cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
+ stream, format, recurse + 1,
+ pretty);
}
else
{
val_print (TYPE_FIELD_TYPE (type, i),
- valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
- 0, stream, format, 0, recurse + 1, pretty);
+ valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
+ address + TYPE_FIELD_BITPOS (type, i) / 8,
+ stream, format, 0, recurse + 1, pretty);
}
}
annotate_field_end ();
@@ -370,7 +408,81 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
fprintf_filtered (stream, "\n");
print_spaces_filtered (2 * recurse, stream);
}
- }
+ } /* if there are data fields */
+ /* Now print out the virtual table pointer if there is one */
+ if (TYPE_HAS_VTABLE(type) && STREQN(TYPE_FIELD_NAME (type, n_baseclasses), hpacc_vtbl_ptr_name, 5))
+ {
+ value_ptr v;
+ /* First get the virtual table pointer and print it out*/
+
+#if 0
+ fputs_filtered ("__vfp = ", stream);
+#endif
+
+ fputs_filtered (", Virtual table at ", stream);
+
+ /* pai: FIXME 32x64 problem? */
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+ v = value_from_longest (lookup_pointer_type (builtin_type_unsigned_long),
+ * (unsigned long *) (valaddr + offset));
+
+ val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ fields_seen = 1;
+
+ if (vtblprint)
+ {
+ /* Print out function pointers in vtable. */
+
+ /* FIXME: then-clause is for non-RRBC layout of virtual
+ * table. The RRBC case in the else-clause is yet to be
+ * implemented. The if (1) below should be changed to a
+ * test for whether the executable we have was compiled
+ * with a version of HP aCC that doesn't have RRBC
+ * support. */
+
+ if (1)
+ {
+ /* no RRBC support; function pointers embedded directly in vtable */
+
+ int vfuncs = count_virtual_fns (real_type);
+
+ fputs_filtered (" {", stream);
+
+ /* FIXME : doesn't work at present */
+#if 0
+ fprintf_filtered (stream, "%d entr%s: ", vfuncs, vfuncs == 1 ? "y" : "ies");
+#else
+ fputs_filtered ("not implemented", stream);
+
+
+#endif
+
+ /* recursive function that prints all virtual function entries */
+#if 0
+ cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v, stream, format, recurse, pretty);
+#endif
+ fputs_filtered ("}", stream);
+ } /* non-RRBC case */
+ else
+ {
+ /* FIXME -- seem comments above */
+ /* RRBC support present; function pointers are found
+ * by indirection through the class segment entries. */
+
+
+ } /* RRBC case */
+ } /* if vtblprint */
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+
+ } /* if vtable exists */
+
fprintf_filtered (stream, "}");
}
@@ -378,10 +490,12 @@ cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
baseclasses. */
static void
-cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
+cp_print_value (type, real_type, valaddr, offset, address, stream, format, recurse, pretty,
dont_print_vb)
struct type *type;
+ struct type *real_type;
char *valaddr;
+ int offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -407,8 +521,10 @@ cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
for (i = 0; i < n_baseclasses; i++)
{
int boffset;
+ int skip;
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
char *basename = TYPE_NAME (baseclass);
+ char *base_valaddr;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
@@ -425,8 +541,41 @@ cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
}
- boffset = baseclass_offset (type, i , valaddr, address);
+ if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ /* Assume HP/Taligent runtime convention */
+ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
+ valaddr, offset, &boffset, &skip);
+ if (skip >= 0)
+ error ("Virtual base class offset not found from vtable while printing");
+ base_valaddr = valaddr;
+ }
+ else
+ {
+ boffset = baseclass_offset (type, i , valaddr + offset, address + offset);
+ skip = ((boffset == -1) || (boffset+offset) < 0 ) ? 1 : -1;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ if (boffset != -1 && ((boffset+offset) < 0 || (boffset+offset) >= TYPE_LENGTH (type)))
+ {
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (address + boffset, base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
+ skip = 1;
+ }
+ else
+ base_valaddr = valaddr;
+ }
+ else
+ base_valaddr = valaddr;
+ }
+ /* now do the printing */
if (pretty)
{
fprintf_filtered (stream, "\n");
@@ -437,10 +586,12 @@ cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
baseclass name. */
fputs_filtered (basename ? basename : "", stream);
fputs_filtered ("> = ", stream);
- if (boffset == -1)
+
+
+ if (skip >= 1)
fprintf_filtered (stream, "<invalid address>");
else
- cp_print_value_fields (baseclass, valaddr + boffset, address + boffset,
+ cp_print_value_fields (baseclass, real_type, base_valaddr, offset + boffset, address,
stream, format, recurse, pretty,
(struct type **) obstack_base (&dont_print_vb_obstack),
0);
@@ -503,11 +654,11 @@ cp_print_static_field (type, val, stream, format, recurse, pretty)
sizeof (CORE_ADDR));
CHECK_TYPEDEF (type);
- cp_print_value_fields (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
+ cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
stream, format, recurse, pretty, NULL, 1);
return;
}
- val_print (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
+ val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
stream, format, 0, recurse, pretty);
}
@@ -526,7 +677,16 @@ cp_print_class_member (valaddr, domain, stream, prefix)
int bits = 0;
register unsigned int i;
unsigned len = TYPE_NFIELDS (domain);
+
/* @@ Make VAL into bit offset */
+
+ /* Note: HP aCC generates offsets that are the real byte offsets added
+ to a constant bias 0x20000000 (1 << 29). This constant bias gets
+ shifted out in the code below -- joyous happenstance! */
+
+ /* Note: HP cfront uses a constant bias of 1; if we support this
+ compiler ever, we will have to adjust the computation below */
+
LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
{
@@ -566,6 +726,72 @@ cp_print_class_member (valaddr, domain, stream, prefix)
fprintf_filtered (stream, "%d", val >> 3);
}
+
+/* This function prints out virtual table entries for a class; it
+ * recurses on the base classes to find all virtual functions
+ * available in a class.
+ *
+ * pai/1997-05-21 Note: As the name suggests, it's currently
+ * implemented for HP aCC runtime only. g++ objects are handled
+ * differently and I have made no attempt to fold that logic in
+ * here. The runtime layout is different for the two cases. Also,
+ * this currently has only the code for non-RRBC layouts generated by
+ * the HP aCC compiler; RRBC code is stubbed out and will have to be
+ * added later. */
+
+
+static void
+cp_print_hpacc_virtual_table_entries (type, vfuncs, v, stream, format, recurse, pretty)
+ struct type * type;
+ int * vfuncs;
+ value_ptr v;
+ GDB_FILE *stream;
+ int format;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ int fn, oi;
+
+ /* pai: FIXME this function doesn't work. It should handle a given
+ * virtual function only once (latest redefinition in class hierarchy)
+ */
+
+ /* Recursion on other classes that can share the same vtable */
+ struct type * pbc = primary_base_class (type);
+ if (pbc)
+ cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format, recurse, pretty);
+
+ /* Now deal with vfuncs declared in this class */
+ for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++)
+ for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++)
+ if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi))
+ {
+ char * vf_name;
+
+ /* virtual function offset */
+ int vx = TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi) - 1;
+
+ /* Get the address of the vfunction entry */
+ value_ptr vf = value_copy (v);
+ if (VALUE_LAZY (vf))
+ (void) value_fetch_lazy (vf);
+ vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx); /* adjust by offset */
+ vf = value_ind (vf); /* get the entry */
+ VALUE_TYPE (vf) = VALUE_TYPE (v); /* make it a pointer */
+
+ /* print out the entry */
+ val_print (VALUE_TYPE (vf), VALUE_CONTENTS (vf), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ vf_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi),
+ DMGL_ARM); /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
+ fprintf_filtered (stream, " %s", vf_name);
+ if (--(*vfuncs) > 0)
+ fputs_filtered (", ", stream);
+ }
+}
+
+
+
void
_initialize_cp_valprint ()
{
diff --git a/contrib/gdb/gdb/cpu32bug-rom.c b/contrib/gdb/gdb/cpu32bug-rom.c
index 43f76f6..758c8ca 100644
--- a/contrib/gdb/gdb/cpu32bug-rom.c
+++ b/contrib/gdb/gdb/cpu32bug-rom.c
@@ -92,61 +92,56 @@ static struct target_ops cpu32bug_ops;
static char *cpu32bug_inits[] = {"\r", NULL};
-static struct monitor_ops cpu32bug_cmds =
+static struct monitor_ops cpu32bug_cmds ;
+
+static void
+init_cpu32bug_cmds(void)
{
- MO_CLR_BREAK_USES_ADDR,
- cpu32bug_inits, /* Init strings */
- "g\r", /* continue command */
- "t\r", /* single step */
- NULL, /* interrupt command */
- "br %x\r", /* set a breakpoint */
- "nobr %x\r", /* clear a breakpoint */
- "nobr\r", /* clear all breakpoints */
- "bf %x:%x %x;b\r", /* fill (start count val) */
- {
- "ms %x %02x\r", /* setmem.cmdb (addr, value) */
- "ms %x %04x\r", /* setmem.cmdw (addr, value) */
- "ms %x %08x\r", /* setmem.cmdl (addr, value) */
- NULL, /* setmem.cmdll (addr, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL, /* setreg.term_cmd */
- },
- {
- "md %x:%x;b\r", /* getmem.cmdb (addr, len) */
- "md %x:%x;b\r", /* getmem.cmdw (addr, len) */
- "md %x:%x;b\r", /* getmem.cmdl (addr, len) */
- NULL, /* getmem.cmdll (addr, len) */
- " ", /* getmem.resp_delim */
- NULL, /* getmem.term */
- NULL, /* getmem.term_cmd */
- },
- {
- "rs %s %x\r", /* setreg.cmd (name, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL /* setreg.term_cmd */
- },
- {
- "rs %s\r", /* getreg.cmd (name) */
- "=", /* getreg.resp_delim */
- NULL, /* getreg.term */
- NULL /* getreg.term_cmd */
- },
- "rd\r", /* dump_registers */
- "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)", /* register_pattern */
- cpu32bug_supply_register, /* supply_register */
- NULL, /* load_routine (defaults to SRECs) */
- "lo\r", /* download command */
- "lo\r\n", /* load response */
- "CPU32Bug>", /* monitor command prompt */
- "\r", /* end-of-line terminator */
- NULL, /* optional command terminator */
- &cpu32bug_ops, /* target operations */
- SERIAL_1_STOPBITS, /* number of stop bits */
- cpu32bug_regnames, /* registers names */
- MONITOR_OPS_MAGIC /* magic */
- };
+ cpu32bug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
+ cpu32bug_cmds.init = cpu32bug_inits; /* Init strings */
+ cpu32bug_cmds.cont = "g\r"; /* continue command */
+ cpu32bug_cmds.step = "t\r"; /* single step */
+ cpu32bug_cmds.stop = NULL; /* interrupt command */
+ cpu32bug_cmds.set_break = "br %x\r"; /* set a breakpoint */
+ cpu32bug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
+ cpu32bug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
+ cpu32bug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
+ cpu32bug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
+ cpu32bug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
+ cpu32bug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
+ cpu32bug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ cpu32bug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ cpu32bug_cmds.setmem.term = NULL; /* setreg.term */
+ cpu32bug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ cpu32bug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
+ cpu32bug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
+ cpu32bug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
+ cpu32bug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ cpu32bug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
+ cpu32bug_cmds.getmem.term = NULL; /* getmem.term */
+ cpu32bug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ cpu32bug_cmds.setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */
+ cpu32bug_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ cpu32bug_cmds.setreg.term = NULL; /* setreg.term */
+ cpu32bug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ cpu32bug_cmds.getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */
+ cpu32bug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ cpu32bug_cmds.getreg.term = NULL; /* getreg.term */
+ cpu32bug_cmds.getreg.term_cmd = NULL ; /* getreg.term_cmd */
+ cpu32bug_cmds.dump_registers = "rd\r"; /* dump_registers */
+ cpu32bug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ cpu32bug_cmds.supply_register = cpu32bug_supply_register; /* supply_register */
+ cpu32bug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ cpu32bug_cmds.load = "lo\r"; /* download command */
+ cpu32bug_cmds.loadresp = "\n"; /* load response */
+ cpu32bug_cmds.prompt = "CPU32Bug>"; /* monitor command prompt */
+ cpu32bug_cmds.line_term = "\r"; /* end-of-line terminator */
+ cpu32bug_cmds.cmd_end = NULL; /* optional command terminator */
+ cpu32bug_cmds.target = &cpu32bug_ops; /* target operations */
+ cpu32bug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ cpu32bug_cmds.regnames = cpu32bug_regnames; /* registers names */
+ cpu32bug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+}; /* init_cpu32bug_cmds */
static void
cpu32bug_open(args, from_tty)
@@ -159,6 +154,7 @@ cpu32bug_open(args, from_tty)
void
_initialize_cpu32bug_rom ()
{
+ init_cpu32bug_cmds() ;
init_monitor_ops (&cpu32bug_ops);
cpu32bug_ops.to_shortname = "cpu32bug";
diff --git a/contrib/gdb/gdb/cxux-nat.c b/contrib/gdb/gdb/cxux-nat.c
index 2ed1430..2c4b6f1 100644
--- a/contrib/gdb/gdb/cxux-nat.c
+++ b/contrib/gdb/gdb/cxux-nat.c
@@ -368,7 +368,7 @@ add_shared_symbol_files ()
return;
}
- objfile = symbol_file_add (LIBC_FILE, 0, 0, 0, 0, 1);
+ objfile = symbol_file_add (LIBC_FILE, 0, 0, 0, 0, 1, 0, 0);
minsym = lookup_minimal_symbol (LINKS_MAP_POINTER, objfile);
ld_map = (struct link_map *)
@@ -384,7 +384,7 @@ add_shared_symbol_files ()
if (target_read_string ((CORE_ADDR)lms.l_name, &path_name,
PATH_MAX, &local_errno))
{
- symbol_file_add (path_name, 1, lms.l_addr, 0, 0, 0);
+ symbol_file_add (path_name, 1, lms.l_addr, 0, 0, 0, 0, 0);
free(path_name);
}
}
diff --git a/contrib/gdb/gdb/dbxread.c b/contrib/gdb/gdb/dbxread.c
index 2bc60be..0749412 100644
--- a/contrib/gdb/gdb/dbxread.c
+++ b/contrib/gdb/gdb/dbxread.c
@@ -1,5 +1,5 @@
/* Read dbx symbol tables and convert to internal format, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -41,10 +41,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif
#include "obstack.h"
-#include <sys/param.h>
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
#include "gdb_stat.h"
#include <ctype.h>
#include "symtab.h"
@@ -66,6 +62,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */
+/* This macro returns the size field of a minimal symbol, which is normally
+ stored in the "info" field. The macro can be overridden for specific
+ targets (e.g. MIPS16) that use the info field for other purposes. */
+#ifndef MSYMBOL_SIZE
+#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym))
+#endif
+
+
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab. */
@@ -105,18 +109,12 @@ struct symloc {
#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
-/* Macro to determine which symbols to ignore when reading the first symbol
- of a file. Some machines override this definition. */
-#ifndef IGNORE_SYMBOL
-/* This code is used on Ultrix systems. Ignore it */
-#define IGNORE_SYMBOL(type) (type == (int)N_NSYMS)
-#endif
-
/* Remember what we deduced to be the source language of this psymtab. */
static enum language psymtab_language = language_unknown;
/* Nonzero means give verbose info on gdb action. From main.c. */
+
extern int info_verbose;
/* The BFD for this file -- implicit parameter to next_symbol_text. */
@@ -129,28 +127,31 @@ static bfd *symfile_bfd;
static unsigned symbol_size;
-/* This is the offset of the symbol table in the executable file */
+/* This is the offset of the symbol table in the executable file. */
+
static unsigned symbol_table_offset;
-/* This is the offset of the string table in the executable file */
+/* This is the offset of the string table in the executable file. */
+
static unsigned string_table_offset;
/* For elf+stab executables, the n_strx field is not a simple index
- into the string table. Instead, each .o file has a base offset
- in the string table, and the associated symbols contain offsets
- from this base. The following two variables contain the base
- offset for the current and next .o files. */
+ into the string table. Instead, each .o file has a base offset in
+ the string table, and the associated symbols contain offsets from
+ this base. The following two variables contain the base offset for
+ the current and next .o files. */
+
static unsigned int file_string_table_offset;
static unsigned int next_file_string_table_offset;
-/* .o and NLM files contain unrelocated addresses which are based at 0. When
- non-zero, this flag disables some of the special cases for Solaris elf+stab
- text addresses at location 0. */
+/* .o and NLM files contain unrelocated addresses which are based at
+ 0. When non-zero, this flag disables some of the special cases for
+ Solaris elf+stab text addresses at location 0. */
static int symfile_relocatable = 0;
- /* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are relative
- to the function start address. */
+/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are
+ relative to the function start address. */
static int block_address_function_relative = 0;
@@ -159,8 +160,14 @@ static int block_address_function_relative = 0;
what address the program is actually going to be loaded at, so we
need to make guesses based on the symbols (which *are* relocated to
reflect the address it will be loaded at). */
+
static CORE_ADDR lowest_text_address;
+/* Non-zero if there is any line number info in the objfile. Prevents
+ end_psymtab from discarding an otherwise empty psymtab. */
+
+static int has_line_numbers;
+
/* Complaints about the symbols we have encountered. */
struct complaint lbrac_complaint =
@@ -186,6 +193,9 @@ struct complaint lbrac_mismatch_complaint =
struct complaint repeated_header_complaint =
{"\"repeated\" header file %s not previously seen, at symtab pos %d", 0, 0};
+
+struct complaint unclaimed_bincl_complaint =
+ {"N_BINCL %s not in entries for any file, at symtab pos %d", 0, 0};
/* During initial symbol readin, we need to have a structure to keep
track of which psymtabs have which bincls in them. This structure
@@ -206,6 +216,9 @@ static int bincls_allocated;
/* Local function prototypes */
+static void
+process_now PARAMS ((struct objfile *));
+
static void
free_header_files PARAMS ((void));
@@ -276,24 +289,11 @@ add_this_object_header_file PARAMS ((int));
static void
free_header_files ()
{
- register int i;
-
- if (header_files != NULL)
- {
- for (i = 0; i < n_header_files; i++)
- {
- free (header_files[i].name);
- }
- free ((PTR)header_files);
- header_files = NULL;
- n_header_files = 0;
- }
if (this_object_header_files)
{
free ((PTR)this_object_header_files);
this_object_header_files = NULL;
}
- n_allocated_header_files = 0;
n_allocated_this_object_header_files = 0;
}
@@ -302,11 +302,6 @@ free_header_files ()
static void
init_header_files ()
{
- n_header_files = 0;
- n_allocated_header_files = 10;
- header_files = (struct header_file *)
- xmalloc (10 * sizeof (struct header_file));
-
n_allocated_this_object_header_files = 10;
this_object_header_files = (int *) xmalloc (10 * sizeof (int));
}
@@ -339,10 +334,10 @@ add_old_header_file (name, instance)
char *name;
int instance;
{
- register struct header_file *p = header_files;
+ register struct header_file *p = HEADER_FILES (current_objfile);
register int i;
- for (i = 0; i < n_header_files; i++)
+ for (i = 0; i < N_HEADER_FILES (current_objfile); i++)
if (STREQ (p[i].name, name) && instance == p[i].instance)
{
add_this_object_header_file (i);
@@ -368,26 +363,40 @@ add_new_header_file (name, instance)
int instance;
{
register int i;
+ register struct header_file *hfile;
/* Make sure there is room for one more header file. */
- if (n_header_files == n_allocated_header_files)
+ i = N_ALLOCATED_HEADER_FILES (current_objfile);
+
+ if (N_HEADER_FILES (current_objfile) == i)
{
- n_allocated_header_files *= 2;
- header_files = (struct header_file *)
- xrealloc ((char *) header_files,
- (n_allocated_header_files * sizeof (struct header_file)));
+ if (i == 0)
+ {
+ N_ALLOCATED_HEADER_FILES (current_objfile) = 10;
+ HEADER_FILES (current_objfile) = (struct header_file *)
+ xmalloc (10 * sizeof (struct header_file));
+ }
+ else
+ {
+ i *= 2;
+ N_ALLOCATED_HEADER_FILES (current_objfile) = i;
+ HEADER_FILES (current_objfile) = (struct header_file *)
+ xrealloc ((char *) HEADER_FILES (current_objfile),
+ (i * sizeof (struct header_file)));
+ }
}
/* Create an entry for this header file. */
- i = n_header_files++;
- header_files[i].name = savestring (name, strlen(name));
- header_files[i].instance = instance;
- header_files[i].length = 10;
- header_files[i].vector
+ i = N_HEADER_FILES (current_objfile)++;
+ hfile = HEADER_FILES (current_objfile) + i;
+ hfile->name = savestring (name, strlen(name));
+ hfile->instance = instance;
+ hfile->length = 10;
+ hfile->vector
= (struct type **) xmalloc (10 * sizeof (struct type *));
- memset (header_files[i].vector, 0, 10 * sizeof (struct type *));
+ memset (hfile->vector, 0, 10 * sizeof (struct type *));
add_this_object_header_file (i);
}
@@ -397,7 +406,7 @@ static struct type **
explicit_lookup_type (real_filenum, index)
int real_filenum, index;
{
- register struct header_file *f = &header_files[real_filenum];
+ register struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum];
if (index >= f->length)
{
@@ -420,29 +429,35 @@ record_minimal_symbol (name, address, type, objfile)
{
enum minimal_symbol_type ms_type;
int section;
+ asection *bfd_section;
switch (type)
{
case N_TEXT | N_EXT:
ms_type = mst_text;
section = SECT_OFF_TEXT;
+ bfd_section = DBX_TEXT_SECTION (objfile);
break;
case N_DATA | N_EXT:
ms_type = mst_data;
section = SECT_OFF_DATA;
+ bfd_section = DBX_DATA_SECTION (objfile);
break;
case N_BSS | N_EXT:
ms_type = mst_bss;
section = SECT_OFF_BSS;
+ bfd_section = DBX_BSS_SECTION (objfile);
break;
case N_ABS | N_EXT:
ms_type = mst_abs;
section = -1;
+ bfd_section = NULL;
break;
#ifdef N_SETV
case N_SETV | N_EXT:
ms_type = mst_data;
section = SECT_OFF_DATA;
+ bfd_section = DBX_DATA_SECTION (objfile);
break;
case N_SETV:
/* I don't think this type actually exists; since a N_SETV is the result
@@ -450,6 +465,7 @@ record_minimal_symbol (name, address, type, objfile)
file local. */
ms_type = mst_file_data;
section = SECT_OFF_DATA;
+ bfd_section = DBX_DATA_SECTION (objfile);
break;
#endif
case N_TEXT:
@@ -458,6 +474,7 @@ record_minimal_symbol (name, address, type, objfile)
case N_FN_SEQ:
ms_type = mst_file_text;
section = SECT_OFF_TEXT;
+ bfd_section = DBX_TEXT_SECTION (objfile);
break;
case N_DATA:
ms_type = mst_file_data;
@@ -478,14 +495,17 @@ record_minimal_symbol (name, address, type, objfile)
ms_type = mst_data;
}
section = SECT_OFF_DATA;
+ bfd_section = DBX_DATA_SECTION (objfile);
break;
case N_BSS:
ms_type = mst_file_bss;
section = SECT_OFF_BSS;
+ bfd_section = DBX_BSS_SECTION (objfile);
break;
default:
ms_type = mst_unknown;
section = -1;
+ bfd_section = NULL;
break;
}
@@ -494,12 +514,7 @@ record_minimal_symbol (name, address, type, objfile)
lowest_text_address = address;
prim_record_minimal_symbol_and_info
- (obsavestring (name, strlen (name), &objfile -> symbol_obstack),
- address,
- ms_type,
- NULL,
- section,
- objfile);
+ (name, address, ms_type, NULL, section, bfd_section, objfile);
}
/* Scan and build partial symbols for a symbol file.
@@ -524,29 +539,26 @@ dbx_symfile_read (objfile, section_offsets, mainline)
val = strlen (objfile->name);
+ sym_bfd = objfile->obfd;
+
/* .o and .nlm files are relocatables with text, data and bss segs based at
0. This flag disables special (Solaris stabs-in-elf only) fixups for
- symbols with a value of 0. XXX - This is a Krock. Solaris stabs-in-elf
- should be fixed to determine pst->textlow without using this text seg of
- 0 fixup crap. */
+ symbols with a value of 0. */
- if (strcmp (&objfile->name[val-2], ".o") == 0
- || strcmp (&objfile->name[val-4], ".nlm") == 0)
- symfile_relocatable = 1;
+ symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
/* This is true for Solaris (and all other systems which put stabs
in sections, hopefully, since it would be silly to do things
differently from Solaris), and false for SunOS4 and other a.out
file formats. */
block_address_function_relative =
- ((0 == strncmp (bfd_get_target (objfile->obfd), "elf", 3))
- || (0 == strncmp (bfd_get_target (objfile->obfd), "som", 3))
- || (0 == strncmp (bfd_get_target (objfile->obfd), "coff", 4))
- || (0 == strncmp (bfd_get_target (objfile->obfd), "pe", 2))
- || (0 == strncmp (bfd_get_target (objfile->obfd), "nlm", 3)));
+ ((0 == strncmp (bfd_get_target (sym_bfd), "elf", 3))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "som", 3))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "coff", 4))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "pe", 2))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "nlm", 3)));
- sym_bfd = objfile->obfd;
- val = bfd_seek (objfile->obfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
+ val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
if (val < 0)
perror_with_name (objfile->name);
@@ -559,11 +571,11 @@ dbx_symfile_read (objfile, section_offsets, mainline)
symbol_size = DBX_SYMBOL_SIZE (objfile);
symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
- pending_blocks = 0;
- back_to = make_cleanup (really_free_pendings, 0);
+ free_pending_blocks ();
+ back_to = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
init_minimal_symbol_collection ();
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
/* Now that the symbol table data of the executable file are all in core,
process them and define symbols accordingly. */
@@ -624,8 +636,13 @@ dbx_symfile_init (objfile)
unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
/* Allocate struct to keep track of the symfile */
- objfile->sym_stab_info = (PTR)
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
+ memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+
+ DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
+ DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data");
+ DBX_BSS_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".bss");
/* FIXME POKING INSIDE BFD DATA STRUCTURES */
#define STRING_TABLE_OFFSET (sym_bfd->origin + obj_str_filepos (sym_bfd))
@@ -732,6 +749,18 @@ dbx_symfile_finish (objfile)
{
if (objfile->sym_stab_info != NULL)
{
+ if (HEADER_FILES (objfile) != NULL)
+ {
+ register int i = N_HEADER_FILES (objfile);
+ register struct header_file *hfiles = HEADER_FILES (objfile);
+
+ while (--i >= 0)
+ {
+ free (hfiles [i].name);
+ free (hfiles [i].vector);
+ }
+ free ((PTR) hfiles);
+ }
mfree (objfile -> md, objfile->sym_stab_info);
}
free_header_files ();
@@ -739,10 +768,113 @@ dbx_symfile_finish (objfile)
/* Buffer for reading the symbol table entries. */
-static struct internal_nlist symbuf[4096];
+static struct external_nlist symbuf[4096];
static int symbuf_idx;
static int symbuf_end;
+/* cont_elem is used for continuing information in cfront.
+ It saves information about which types need to be fixed up and
+ completed after all the stabs are read. */
+struct cont_elem
+ {
+ /* sym and stabsstring for continuing information in cfront */
+ struct symbol * sym;
+ char * stabs;
+ /* state dependancies (statics that must be preserved) */
+ int sym_idx;
+ int sym_end;
+ int symnum;
+ int (*func) PARAMS ((struct objfile *, struct symbol *, char *));
+ /* other state dependancies include:
+ (assumption is that these will not change since process_now FIXME!!)
+ stringtab_global
+ n_stabs
+ objfile
+ symfile_bfd */
+};
+
+static struct cont_elem *cont_list = 0;
+static int cont_limit = 0;
+static int cont_count = 0;
+
+/* Arrange for function F to be called with arguments SYM and P later
+ in the stabs reading process. */
+void
+process_later (sym, p, f)
+ struct symbol *sym;
+ char *p;
+ int (*f) PARAMS ((struct objfile *, struct symbol *, char *));
+{
+
+ /* Allocate more space for the deferred list. */
+ if (cont_count >= cont_limit - 1)
+ {
+ cont_limit += 32; /* chunk size */
+
+ cont_list
+ = (struct cont_elem *) xrealloc (cont_list,
+ (cont_limit
+ * sizeof (struct cont_elem)));
+ if (!cont_list)
+ error ("Virtual memory exhausted\n");
+ }
+
+ /* Save state variables so we can process these stabs later. */
+ cont_list[cont_count].sym_idx = symbuf_idx;
+ cont_list[cont_count].sym_end = symbuf_end;
+ cont_list[cont_count].symnum = symnum;
+ cont_list[cont_count].sym = sym;
+ cont_list[cont_count].stabs = p;
+ cont_list[cont_count].func = f;
+ cont_count++;
+}
+
+/* Call deferred funtions in CONT_LIST. */
+
+static void
+process_now (objfile)
+ struct objfile *objfile;
+{
+ int i;
+ int save_symbuf_idx;
+ int save_symbuf_end;
+ int save_symnum;
+ struct symbol *sym;
+ char *stabs;
+ int err;
+ int (*func) PARAMS ((struct objfile *, struct symbol *, char *));
+
+ /* Save the state of our caller, we'll want to restore it before
+ returning. */
+ save_symbuf_idx = symbuf_idx;
+ save_symbuf_end = symbuf_end;
+ save_symnum = symnum;
+
+ /* Iterate over all the deferred stabs. */
+ for (i = 0; i < cont_count; i++)
+ {
+ /* Restore the state for this deferred stab. */
+ symbuf_idx = cont_list[i].sym_idx;
+ symbuf_end = cont_list[i].sym_end;
+ symnum = cont_list[i].symnum;
+ sym = cont_list[i].sym;
+ stabs = cont_list[i].stabs;
+ func = cont_list[i].func;
+
+ /* Call the function to handle this deferrd stab. */
+ err = (*func) (objfile, sym, stabs);
+ if (err)
+ error ("Internal error: unable to resolve stab.\n");
+ }
+
+ /* Restore our caller's state. */
+ symbuf_idx = save_symbuf_idx;
+ symbuf_end = save_symbuf_end;
+ symnum = save_symnum;
+ cont_count = 0;
+}
+
+
/* Name of last function encountered. Used in Solaris to approximate
object file boundaries. */
static char *last_function_name;
@@ -816,6 +948,14 @@ fill_symbuf (sym_bfd)
(unsigned char *)&(symp)->n_value); \
}
+#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
+ { \
+ (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
+ (intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx); \
+ (intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc); \
+ (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value); \
+ }
+
/* Invariant: The symbol pointed to by symbuf_idx is the first one
that hasn't been swapped. Swap the symbol at the same time
that symbuf_idx is incremented. */
@@ -829,13 +969,18 @@ static char *
dbx_next_symbol_text (objfile)
struct objfile *objfile;
{
+ struct internal_nlist nlist;
+
if (symbuf_idx == symbuf_end)
fill_symbuf (symfile_bfd);
+
symnum++;
- SWAP_SYMBOL(&symbuf[symbuf_idx], symfile_bfd);
+ INTERNALIZE_SYMBOL(nlist, &symbuf[symbuf_idx], symfile_bfd);
OBJSTAT (objfile, n_stabs++);
- return symbuf[symbuf_idx++].n_strx + stringtab_global
- + file_string_table_offset;
+
+ symbuf_idx++;
+
+ return nlist.n_strx + stringtab_global + file_string_table_offset;
}
/* Initialize the list of bincls to contain none and have some
@@ -1040,11 +1185,8 @@ read_dbx_dynamic_symtab (section_offsets, objfile)
}
name = (char *) bfd_asymbol_name (*rel->sym_ptr_ptr);
- prim_record_minimal_symbol
- (obsavestring (name, strlen (name), &objfile -> symbol_obstack),
- address,
- mst_solib_trampoline,
- objfile);
+ prim_record_minimal_symbol (name, address, mst_solib_trampoline,
+ objfile);
}
do_cleanups (back_to);
@@ -1064,7 +1206,9 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
CORE_ADDR text_addr;
int text_size;
{
- register struct internal_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */
+ register struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */
+ struct internal_nlist nlist;
+
register char *namestring;
int nsl;
int past_first_source_file = 0;
@@ -1072,6 +1216,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
CORE_ADDR last_function_start = 0;
struct cleanup *back_to;
bfd *abfd;
+ int textlow_not_set;
/* Current partial symtab */
struct partial_symtab *pst;
@@ -1107,7 +1252,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
/* Init bincl list */
init_bincl_list (20, objfile);
- back_to = make_cleanup (free_bincl_list, objfile);
+ back_to = make_cleanup ((make_cleanup_func) free_bincl_list, objfile);
last_source_file = NULL;
@@ -1117,6 +1262,8 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
abfd = objfile->obfd;
symbuf_end = symbuf_idx = 0;
next_symbol_text_func = dbx_next_symbol_text;
+ textlow_not_set = 1;
+ has_line_numbers = 0;
for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
{
@@ -1129,9 +1276,13 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
/*
* Special case to speed up readin.
*/
- if (bufp->n_type == (unsigned char)N_SLINE) continue;
+ if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
+ {
+ has_line_numbers = 1;
+ continue;
+ }
- SWAP_SYMBOL (bufp, abfd);
+ INTERNALIZE_SYMBOL (nlist, bufp, abfd);
OBJSTAT (objfile, n_stabs++);
/* Ok. There is a lot of code duplicated in the rest of this
@@ -1146,27 +1297,28 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
I've imbedded it in the following macro.
*/
-/* Set namestring based on bufp. If the string table index is invalid,
+/* Set namestring based on nlist. If the string table index is invalid,
give a fake name, and print a single error message per symbol file read,
rather than abort the symbol reading or flood the user with messages. */
/*FIXME: Too many adds and indirections in here for the inner loop. */
#define SET_NAMESTRING()\
- if (((unsigned)bufp->n_strx + file_string_table_offset) >= \
+ if (((unsigned)CUR_SYMBOL_STRX + file_string_table_offset) >= \
DBX_STRINGTAB_SIZE (objfile)) { \
complain (&string_table_offset_complaint, symnum); \
namestring = "<bad string table offset>"; \
} else \
- namestring = bufp->n_strx + file_string_table_offset + \
+ namestring = CUR_SYMBOL_STRX + file_string_table_offset + \
DBX_STRINGTAB (objfile)
-#define CUR_SYMBOL_TYPE bufp->n_type
-#define CUR_SYMBOL_VALUE bufp->n_value
+#define CUR_SYMBOL_TYPE nlist.n_type
+#define CUR_SYMBOL_VALUE nlist.n_value
+#define CUR_SYMBOL_STRX nlist.n_strx
#define DBXREAD_ONLY
#define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms)\
start_psymtab(ofile, secoff, fname, low, symoff, global_syms, static_syms)
-#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)\
- end_psymtab(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)
+#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set)\
+ end_psymtab(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set)
#include "partial-stab.h"
}
@@ -1175,22 +1327,26 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
if (DBX_SYMCOUNT (objfile) > 0 /* We have some syms */
/*FIXME, does this have a bug at start address 0? */
&& last_o_file_start
- && objfile -> ei.entry_point < bufp->n_value
+ && objfile -> ei.entry_point < nlist.n_value
&& objfile -> ei.entry_point >= last_o_file_start)
{
objfile -> ei.entry_file_lowpc = last_o_file_start;
- objfile -> ei.entry_file_highpc = bufp->n_value;
+ objfile -> ei.entry_file_highpc = nlist.n_value;
}
if (pst)
{
+ /* Don't set pst->texthigh lower than it already is. */
+ CORE_ADDR text_end =
+ (lowest_text_address == (CORE_ADDR)-1
+ ? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
+ : lowest_text_address)
+ + text_size;
+
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- (lowest_text_address == (CORE_ADDR)-1
- ? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
- : lowest_text_address)
- + text_size,
- dependency_list, dependencies_used);
+ text_end > pst->texthigh ? text_end : pst->texthigh,
+ dependency_list, dependencies_used, textlow_not_set);
}
do_cleanups (back_to);
@@ -1247,7 +1403,7 @@ start_psymtab (objfile, section_offsets,
struct partial_symtab *
end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
- capping_text, dependency_list, number_dependencies)
+ capping_text, dependency_list, number_dependencies, textlow_not_set)
struct partial_symtab *pst;
char **include_list;
int num_includes;
@@ -1255,12 +1411,13 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
CORE_ADDR capping_text;
struct partial_symtab **dependency_list;
int number_dependencies;
+ int textlow_not_set;
{
int i;
struct objfile *objfile = pst -> objfile;
if (capping_symbol_offset != -1)
- LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst);
+ LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst);
pst->texthigh = capping_text;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
@@ -1269,8 +1426,8 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
we have to do some tricks to fill in texthigh and textlow.
The first trick is in partial-stab.h: if we see a static
or global function, and the textlow for the current pst
- is still 0, then we use that function's address for
- the textlow of the pst. */
+ is not set (ie: textlow_not_set), then we use that function's
+ address for the textlow of the pst. */
/* Now, to fill in texthigh, we remember the last function seen
in the .o file (also in partial-stab.h). Also, there's a hack in
@@ -1279,52 +1436,61 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
a reliable texthigh by taking the address plus size of the
last function in the file. */
- if (pst->texthigh == 0 && last_function_name) {
- char *p;
- int n;
- struct minimal_symbol *minsym;
-
- p = strchr (last_function_name, ':');
- if (p == NULL)
- p = last_function_name;
- n = p - last_function_name;
- p = alloca (n + 1);
- strncpy (p, last_function_name, n);
- p[n] = 0;
+ if (pst->texthigh == 0 && last_function_name)
+ {
+ char *p;
+ int n;
+ struct minimal_symbol *minsym;
+
+ p = strchr (last_function_name, ':');
+ if (p == NULL)
+ p = last_function_name;
+ n = p - last_function_name;
+ p = alloca (n + 2);
+ strncpy (p, last_function_name, n);
+ p[n] = 0;
- minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ if (minsym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal symbol name,
+ try again with an appended underscore if the minimal symbol
+ was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ }
- if (minsym)
- pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) +
- (long) MSYMBOL_INFO (minsym);
+ if (minsym)
+ pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
- last_function_name = NULL;
- }
+ last_function_name = NULL;
+ }
/* this test will be true if the last .o file is only data */
- if (pst->textlow == 0)
- /* This loses if the text section really starts at address zero
- (generally true when we are debugging a .o file, for example).
- That is why this whole thing is inside SOFUN_ADDRESS_MAYBE_MISSING. */
+ if (textlow_not_set)
pst->textlow = pst->texthigh;
+ else
+ {
+ struct partial_symtab *p1;
- /* If we know our own starting text address, then walk through all other
- psymtabs for this objfile, and if any didn't know their ending text
- address, set it to our starting address. Take care to not set our
- own ending address to our starting address, nor to set addresses on
- `dependency' files that have both textlow and texthigh zero. */
- if (pst->textlow) {
- struct partial_symtab *p1;
-
- ALL_OBJFILE_PSYMTABS (objfile, p1) {
- if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst) {
- p1->texthigh = pst->textlow;
- /* if this file has only data, then make textlow match texthigh */
- if (p1->textlow == 0)
- p1->textlow = p1->texthigh;
- }
+ /* If we know our own starting text address, then walk through all other
+ psymtabs for this objfile, and if any didn't know their ending text
+ address, set it to our starting address. Take care to not set our
+ own ending address to our starting address, nor to set addresses on
+ `dependency' files that have both textlow and texthigh zero. */
+
+ ALL_OBJFILE_PSYMTABS (objfile, p1)
+ {
+ if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
+ {
+ p1->texthigh = pst->textlow;
+ /* if this file has only data, then make textlow match texthigh */
+ if (p1->textlow == 0)
+ p1->textlow = p1->texthigh;
+ }
+ }
}
- }
/* End of kludge for patching Solaris textlow and texthigh. */
#endif /* SOFUN_ADDRESS_MAYBE_MISSING. */
@@ -1388,7 +1554,8 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
if (num_includes == 0
&& number_dependencies == 0
&& pst->n_global_syms == 0
- && pst->n_static_syms == 0)
+ && pst->n_static_syms == 0
+ && has_line_numbers == 0)
{
/* Throw away this psymtab, it's empty. We can't deallocate it, since
it is on the obstack, but we can forget to chain it on the list. */
@@ -1397,21 +1564,8 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
is wrong, in that a psymtab with N_SLINE entries but nothing else
is not empty, but we don't realize that. Fixing that without slowing
things down might be tricky. */
- struct partial_symtab *prev_pst;
- /* First, snip it out of the psymtab chain */
-
- if (pst->objfile->psymtabs == pst)
- pst->objfile->psymtabs = pst->next;
- else
- for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
- if (prev_pst->next == pst)
- prev_pst->next = pst->next;
-
- /* Next, put it on a free list for recycling */
-
- pst->next = pst->objfile->free_psymtabs;
- pst->objfile->free_psymtabs = pst;
+ discard_psymtab (pst);
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *)NULL;
@@ -1459,7 +1613,7 @@ dbx_psymtab_to_symtab_1 (pst)
/* Init stuff necessary for reading in symbols */
stabsread_init ();
buildsym_init ();
- old_chain = make_cleanup (really_free_pendings, 0);
+ old_chain = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
file_string_table_offset = FILE_STRING_OFFSET (pst);
symbol_size = SYMBOL_SIZE (pst);
@@ -1526,7 +1680,8 @@ read_ofile_symtab (pst)
struct partial_symtab *pst;
{
register char *namestring;
- register struct internal_nlist *bufp;
+ register struct external_nlist *bufp;
+ struct internal_nlist nlist;
unsigned char type;
unsigned max_symnum;
register bfd *abfd;
@@ -1565,13 +1720,13 @@ read_ofile_symtab (pst)
bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR);
fill_symbuf (abfd);
bufp = &symbuf[symbuf_idx++];
- SWAP_SYMBOL (bufp, abfd);
+ INTERNALIZE_SYMBOL (nlist, bufp, abfd);
OBJSTAT (objfile, n_stabs++);
SET_NAMESTRING ();
processing_gcc_compilation = 0;
- if (bufp->n_type == N_TEXT)
+ if (nlist.n_type == N_TEXT)
{
const char *tempstring = namestring;
@@ -1608,7 +1763,7 @@ read_ofile_symtab (pst)
if (symbuf_idx == symbuf_end)
fill_symbuf (abfd);
bufp = &symbuf[symbuf_idx];
- if (bufp->n_type != (unsigned char)N_SO)
+ if (bfd_h_get_8 (abfd, bufp->e_type) != N_SO)
error("First symbol in segment of executable not a source symbol");
max_symnum = sym_size / symbol_size;
@@ -1621,15 +1776,15 @@ read_ofile_symtab (pst)
if (symbuf_idx == symbuf_end)
fill_symbuf(abfd);
bufp = &symbuf[symbuf_idx++];
- SWAP_SYMBOL (bufp, abfd);
+ INTERNALIZE_SYMBOL (nlist, bufp, abfd);
OBJSTAT (objfile, n_stabs++);
- type = bufp->n_type;
+ type = bfd_h_get_8 (abfd, bufp->e_type);
SET_NAMESTRING ();
if (type & N_STAB) {
- process_one_symbol (type, bufp->n_desc, bufp->n_value,
+ process_one_symbol (type, nlist.n_desc, nlist.n_value,
namestring, section_offsets, objfile);
}
/* We skip checking for a new .o or -l file; that should never
@@ -1683,6 +1838,11 @@ read_ofile_symtab (pst)
last_source_start_addr = text_offset;
pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT);
+
+ /* Process items which we had to "process_later" due to dependancies
+ on other stabs. */
+ process_now (objfile);
+
end_stabs ();
}
@@ -1746,9 +1906,9 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (last_source_file == NULL && type != (unsigned char)N_SO)
{
- /* Ignore any symbols which appear before an N_SO symbol. Currently
- no one puts symbols there, but we should deal gracefully with the
- case. A complain()t might be in order (if !IGNORE_SYMBOL (type)),
+ /* Ignore any symbols which appear before an N_SO symbol.
+ Currently no one puts symbols there, but we should deal
+ gracefully with the case. A complain()t might be in order,
but this should not be an error (). */
return;
}
@@ -1758,7 +1918,7 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
case N_FUN:
case N_FNAME:
- if (! strcmp (name, ""))
+ if (*name == '\000')
{
/* This N_FUN marks the end of a function. This closes off the
current block. */
@@ -1767,13 +1927,22 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
/* Make a block for the local symbols within. */
finish_block (new->name, &local_symbols, new->old_blocks,
- function_start_offset, function_start_offset + valu,
+ new->start_addr, new->start_addr + valu,
objfile);
+
+ /* May be switching to an assembler file which may not be using
+ block relative stabs, so reset the offset. */
+ if (block_address_function_relative)
+ function_start_offset = 0;
+
break;
}
/* Relocate for dynamic loading */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+#ifdef SMASH_TEXT_ADDRESS
+ SMASH_TEXT_ADDRESS (valu);
+#endif
goto define_a_symbol;
case N_LBRAC:
@@ -1784,10 +1953,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (n_opt_found && desc == 1)
break;
-#if defined(BLOCK_ADDRESS_ABSOLUTE)
- /* Relocate for dynamic loading (?). */
- valu += function_start_offset;
-#else
if (block_address_function_relative)
/* Relocate for Sun ELF acc fn-relative syms. */
valu += function_start_offset;
@@ -1795,7 +1960,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
/* On most machines, the block addresses are relative to the
N_SO, the linker did not relocate them (sigh). */
valu += last_source_start_addr;
-#endif
#ifdef SUN_FIXED_LBRAC_BUG
if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address) {
@@ -1815,10 +1979,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (n_opt_found && desc == 1)
break;
-#if defined(BLOCK_ADDRESS_ABSOLUTE)
- /* Relocate for dynamic loading (?). */
- valu += function_start_offset;
-#else
if (block_address_function_relative)
/* Relocate for Sun ELF acc fn-relative syms. */
valu += function_start_offset;
@@ -1826,7 +1986,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
/* On most machines, the block addresses are relative to the
N_SO, the linker did not relocate them (sigh). */
valu += last_source_start_addr;
-#endif
new = pop_context();
if (desc != new->depth)
@@ -1932,8 +2091,12 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (*name == '\000')
break;
+ if (block_address_function_relative)
+ function_start_offset = 0;
+
start_stabs ();
start_symtab (name, NULL, valu);
+ record_debugformat ("stabs");
break;
case N_SOL:
@@ -1964,8 +2127,10 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
/* This type of "symbol" really just records
one line-number -- core-address correspondence.
Enter it in the line list for this symbol table. */
+
/* Relocate for dynamic loading and for ELF acc fn-relative syms. */
valu += function_start_offset;
+
#ifdef SUN_FIXED_LBRAC_BUG
last_pc_address = valu; /* Save for SunOS bug circumcision */
#endif
@@ -2110,12 +2275,22 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (p == NULL)
p = name;
n = p - name;
- p = alloca (n + 1);
+ p = alloca (n + 2);
strncpy (p, name, n);
p[n] = 0;
msym = lookup_minimal_symbol (p, last_source_file,
objfile);
+ if (msym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal
+ symbol name, try again with an appended underscore
+ if the minimal symbol was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, last_source_file,
+ objfile);
+ }
if (msym)
valu = SYMBOL_VALUE_ADDRESS (msym);
}
@@ -2231,9 +2406,37 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
file's symbols at once. */
case N_ENDM: /* Solaris 2: End of module */
case N_MAIN: /* Name of main routine. */
+ case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
break;
}
+ /* '#' is a GNU C extension to allow one symbol to refer to another
+ related symbol.
+
+ Generally this is used so that an alias can refer to its main
+ symbol. */
+ if (name[0] == '#')
+ {
+ /* Initialize symbol reference names and determine if this is
+ a definition. If symbol reference is being defined, go
+ ahead and add it. Otherwise, just return sym. */
+
+ char *s = name;
+ int refnum;
+
+ /* If this stab defines a new reference ID that is not on the
+ reference list, then put it on the reference list.
+
+ We go ahead and advance NAME past the reference, even though
+ it is not strictly necessary at this time. */
+ refnum = symbol_reference_defined (&s);
+ if (refnum >= 0)
+ if (!ref_search (refnum))
+ ref_add (refnum, 0, name, valu);
+ name = s;
+ }
+
+
previous_stab_code = type;
}
@@ -2283,7 +2486,7 @@ coffstab_build_psymtabs (objfile, section_offsets, mainline,
/* There is already a dbx_symfile_info allocated by our caller.
It might even contain some info from the coff symtab to help us. */
- info = (struct dbx_symfile_info *) objfile->sym_stab_info;
+ info = objfile->sym_stab_info;
DBX_TEXT_ADDR (objfile) = textaddr;
DBX_TEXT_SIZE (objfile) = textsize;
@@ -2384,7 +2587,7 @@ elfstab_build_psymtabs (objfile, section_offsets, mainline,
/* There is already a dbx_symfile_info allocated by our caller.
It might even contain some info from the ELF symtab to help us. */
- info = (struct dbx_symfile_info *) objfile->sym_stab_info;
+ info = objfile->sym_stab_info;
text_sect = bfd_get_section_by_name (sym_bfd, ".text");
if (!text_sect)
@@ -2471,8 +2674,9 @@ stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
error ("stabsect_build_psymtabs: Found stabs (%s), but not string section (%s)",
stab_name, stabstr_name);
- objfile->sym_stab_info = (PTR) xmalloc (sizeof (struct dbx_symfile_info));
- memset (DBX_SYMFILE_INFO (objfile), 0, sizeof (struct dbx_symfile_info));
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmalloc (sizeof (struct dbx_symfile_info));
+ memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
text_sect = bfd_get_section_by_name (sym_bfd, text_name);
if (!text_sect)
@@ -2515,29 +2719,6 @@ stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
dbx_symfile_read (objfile, section_offsets, 0);
}
-/* Parse the user's idea of an offset for dynamic linking, into our idea
- of how to represent it for fast symbol reading. */
-
-static struct section_offsets *
-dbx_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets)
- + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- ANOFFSET (section_offsets, i) = addr;
-
- return section_offsets;
-}
-
static struct sym_fns aout_sym_fns =
{
bfd_target_aout_flavour,
@@ -2545,7 +2726,8 @@ static struct sym_fns aout_sym_fns =
dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
- dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ default_symfile_offsets,
+ /* sym_offsets: parse user's offsets to internal form */
NULL /* next: pointer to next struct sym_fns */
};
diff --git a/contrib/gdb/gdb/dcache.c b/contrib/gdb/gdb/dcache.c
index 9f44e96..a97a940 100644
--- a/contrib/gdb/gdb/dcache.c
+++ b/contrib/gdb/gdb/dcache.c
@@ -1,7 +1,7 @@
/* Caching code. Typically used by remote back ends for
caching remote memory.
- Copyright 1992, 1993, 1995 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1995, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -23,7 +23,7 @@
#include "dcache.h"
#include "gdbcmd.h"
#include "gdb_string.h"
-
+#include "gdbcore.h"
/*
The data cache could lead to incorrect results because it doesn't know
@@ -111,7 +111,7 @@
struct dcache_block
{
struct dcache_block *p; /* next in list */
- unsigned int addr; /* Address for which data is recorded. */
+ CORE_ADDR addr; /* Address for which data is recorded. */
char data[LINE_SIZE]; /* bytes at given address */
unsigned char state[LINE_SIZE]; /* what state the data is in */
@@ -148,12 +148,30 @@ struct dcache_struct
int cache_has_stuff;
} ;
+static int dcache_poke_byte PARAMS ((DCACHE *dcache, CORE_ADDR addr,
+ char *ptr));
+
+static int dcache_peek_byte PARAMS ((DCACHE *dcache, CORE_ADDR addr,
+ char *ptr));
+
+static struct dcache_block *dcache_hit PARAMS ((DCACHE *dcache,
+ CORE_ADDR addr));
+
+static int dcache_write_line PARAMS ((DCACHE *dcache,struct dcache_block *db));
+
+static struct dcache_block *dcache_alloc PARAMS ((DCACHE *dcache));
+
+static int dcache_writeback PARAMS ((DCACHE *dcache));
+
+static void dcache_info PARAMS ((char *exp, int tty));
+
+void _initialize_dcache PARAMS ((void));
+
int remote_dcache = 0;
DCACHE *last_cache; /* Used by info dcache */
-
/* Free all the data cache blocks, thus discarding all cached data. */
void
@@ -186,11 +204,11 @@ dcache_flush (dcache)
/* If addr is present in the dcache, return the address of the block
containing it. */
-static
-struct dcache_block *
+
+static struct dcache_block *
dcache_hit (dcache, addr)
DCACHE *dcache;
- unsigned int addr;
+ CORE_ADDR addr;
{
register struct dcache_block *db;
@@ -261,8 +279,8 @@ dcache_write_line (dcache, db)
prevents errors from creeping in if a memory retrieval is
interrupted (which used to put garbage blocks in the valid
list...). */
-static
-struct dcache_block *
+
+static struct dcache_block *
dcache_alloc (dcache)
DCACHE *dcache;
{
@@ -302,7 +320,7 @@ dcache_alloc (dcache)
Returns 0 on error. */
-int
+static int
dcache_peek_byte (dcache, addr, ptr)
DCACHE *dcache;
CORE_ADDR addr;
@@ -321,7 +339,7 @@ dcache_peek_byte (dcache, addr, ptr)
else
db = dcache_alloc (dcache);
immediate_quit++;
- db->addr = MASK (addr);
+ db->addr = MASK (addr);
while (done < LINE_SIZE)
{
int try =
@@ -342,28 +360,6 @@ dcache_peek_byte (dcache, addr, ptr)
return ok;
}
-/* Using the data cache DCACHE return the contents of the word at
- address ADDR in the remote machine.
-
- Returns 0 on error. */
-
-int
-dcache_peek (dcache, addr, data)
- DCACHE *dcache;
- CORE_ADDR addr;
- int *data;
-{
- char *dp = (char *) data;
- int i;
- for (i = 0; i < (int) sizeof (int); i++)
- {
- if (!dcache_peek_byte (dcache, addr + i, dp + i))
- return 0;
- }
- return 1;
-}
-
-
/* Writeback any dirty lines to the remote. */
static int
dcache_writeback (dcache)
@@ -391,7 +387,10 @@ dcache_fetch (dcache, addr)
CORE_ADDR addr;
{
int res;
- dcache_peek (dcache, addr, &res);
+
+ if (dcache_xfer_memory (dcache, addr, (char *)&res, sizeof res, 0) != sizeof res)
+ memory_error (EIO, addr);
+
return res;
}
@@ -400,7 +399,7 @@ dcache_fetch (dcache, addr)
Return zero on write error.
*/
-int
+static int
dcache_poke_byte (dcache, addr, ptr)
DCACHE *dcache;
CORE_ADDR addr;
@@ -431,15 +430,10 @@ dcache_poke (dcache, addr, data)
CORE_ADDR addr;
int data;
{
- char *dp = (char *) (&data);
- int i;
- for (i = 0; i < (int) sizeof (int); i++)
- {
- if (!dcache_poke_byte (dcache, addr + i, dp + i))
- return 0;
- }
- dcache_writeback (dcache);
- return 1;
+ if (dcache_xfer_memory (dcache, addr, (char *)&data, sizeof data, 1) != sizeof data)
+ return 0;
+
+ return dcache_writeback (dcache);
}
@@ -485,8 +479,8 @@ dcache_xfer_memory (dcache, memaddr, myaddr, len, should_write)
if (remote_dcache)
{
- int (*xfunc) ()
- = should_write ? dcache_poke_byte : dcache_peek_byte;
+ int (*xfunc) PARAMS ((DCACHE *dcache, CORE_ADDR addr, char *ptr));
+ xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
for (i = 0; i < len; i++)
{
@@ -498,8 +492,8 @@ dcache_xfer_memory (dcache, memaddr, myaddr, len, should_write)
}
else
{
- int (*xfunc) ()
- = should_write ? dcache->write_memory : dcache->read_memory;
+ memxferfunc xfunc;
+ xfunc = should_write ? dcache->write_memory : dcache->read_memory;
if (dcache->cache_has_stuff)
dcache_flush (dcache);
diff --git a/contrib/gdb/gdb/defs.h b/contrib/gdb/gdb/defs.h
index a1d181f..c0552a1 100644
--- a/contrib/gdb/gdb/defs.h
+++ b/contrib/gdb/gdb/defs.h
@@ -1,5 +1,5 @@
/* Basic, host-specific, and target-specific definitions for GDB.
- Copyright (C) 1986, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright (C) 1986, 89, 91, 92, 93, 94, 95, 96, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -24,6 +24,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h" /* Generated by configure */
#include <stdio.h>
#include <errno.h> /* System call error return status */
+#include <limits.h>
+
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#else
+# include <sys/types.h> /* for size_t */
+#endif
/* Just in case they're not defined in stdio.h. */
@@ -52,7 +59,7 @@ extern char *strsignal PARAMS ((int));
#include "progress.h"
-#ifndef NO_MMALLOC
+#ifdef USE_MMALLOC
#include "mmalloc.h"
#endif
@@ -67,8 +74,12 @@ extern char *strsignal PARAMS ((int));
typedef bfd_vma CORE_ADDR;
+#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
+#endif
/* Gdb does *lots* of string compares. Use macros to speed them up by
avoiding function calls if the first characters are not the same. */
@@ -84,17 +95,39 @@ typedef bfd_vma CORE_ADDR;
/* Check if a character is one of the commonly used C++ marker characters. */
extern int is_cplus_marker PARAMS ((int));
+/* use tui interface if non-zero */
+extern int tui_version;
+
+#if defined(TUI)
+/* all invocations of TUIDO should have two sets of parens */
+#define TUIDO(x) tuiDo x
+#else
+#define TUIDO(x)
+#endif
+
+/* enable xdb commands if set */
+extern int xdb_commands;
+
+/* enable dbx commands if set */
+extern int dbx_commands;
+
extern int quit_flag;
extern int immediate_quit;
extern int sevenbit_strings;
extern void quit PARAMS ((void));
+#ifdef QUIT
+/* do twice to force compiler warning */
+#define QUIT_FIXME "FIXME"
+#define QUIT_FIXME "ignoring redefinition of QUIT"
+#else
#define QUIT { \
if (quit_flag) quit (); \
if (interactive_hook) interactive_hook (); \
PROGRESS (1); \
}
+#endif
/* Command classes are top-level categories into which commands are broken
down for "help" purposes.
@@ -108,9 +141,9 @@ enum command_class
all_classes = -2, all_commands = -1,
/* Classes of commands */
no_class = -1, class_run = 0, class_vars, class_stack,
- class_files, class_support, class_info, class_breakpoint,
+ class_files, class_support, class_info, class_breakpoint, class_trace,
class_alias, class_obscure, class_user, class_maintenance,
- class_pseudo
+ class_pseudo, class_tui, class_xdb
};
/* Languages represented in the symbol table and elsewhere.
@@ -124,6 +157,7 @@ enum language
language_auto, /* Placeholder for automatic setting */
language_c, /* C */
language_cplus, /* C++ */
+ language_java, /* Java */
language_chill, /* Chill */
language_fortran, /* Fortran */
language_m2, /* Modula-2 */
@@ -131,6 +165,13 @@ enum language
language_scm /* Scheme / Guile */
};
+enum precision_type
+{
+ single_precision,
+ double_precision,
+ unspecified_precision
+};
+
/* the cleanup list records things that have to be undone
if an error happens (descriptors to be closed, memory to be freed, etc.)
Each link in the chain records a function to call and an
@@ -207,6 +248,8 @@ extern char *chill_demangle PARAMS ((const char *));
/* From utils.c */
+extern void notice_quit PARAMS ((void));
+
extern int strcmp_iw PARAMS ((const char *, const char *));
extern char *safe_strerror PARAMS ((int));
@@ -218,36 +261,61 @@ extern void init_malloc PARAMS ((void *));
extern void request_quit PARAMS ((int));
extern void do_cleanups PARAMS ((struct cleanup *));
+extern void do_final_cleanups PARAMS ((struct cleanup *));
+extern void do_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
+extern void do_run_cleanups PARAMS ((struct cleanup *));
extern void discard_cleanups PARAMS ((struct cleanup *));
+extern void discard_final_cleanups PARAMS ((struct cleanup *));
+extern void discard_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
+
+typedef void (*make_cleanup_func) PARAMS ((void *));
-/* The bare make_cleanup function is one of those rare beasts that
- takes almost any type of function as the first arg and anything that
- will fit in a "void *" as the second arg.
+extern struct cleanup *make_cleanup PARAMS ((make_cleanup_func, void *));
- Should be, once all calls and called-functions are cleaned up:
-extern struct cleanup *
-make_cleanup PARAMS ((void (*function) (void *), void *));
+extern struct cleanup *make_final_cleanup PARAMS ((make_cleanup_func, void *));
- Until then, lint and/or various type-checking compiler options will
- complain about make_cleanup calls. It'd be wrong to just cast things,
- since the type actually passed when the function is called would be
- wrong. */
+extern struct cleanup *make_my_cleanup PARAMS ((struct cleanup **,
+ make_cleanup_func, void *));
-extern struct cleanup *make_cleanup ();
+extern struct cleanup *make_run_cleanup PARAMS ((make_cleanup_func, void *));
extern struct cleanup *save_cleanups PARAMS ((void));
+extern struct cleanup *save_final_cleanups PARAMS ((void));
+extern struct cleanup *save_my_cleanups PARAMS ((struct cleanup **));
extern void restore_cleanups PARAMS ((struct cleanup *));
+extern void restore_final_cleanups PARAMS ((struct cleanup *));
+extern void restore_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
extern void free_current_contents PARAMS ((char **));
-extern void null_cleanup PARAMS ((char **));
+extern void null_cleanup PARAMS ((PTR));
extern int myread PARAMS ((int, char *, int));
extern int query PARAMS((char *, ...))
ATTR_FORMAT(printf, 1, 2);
+
+#if !defined (USE_MMALLOC)
+extern PTR mmalloc PARAMS ((PTR, size_t));
+extern PTR mrealloc PARAMS ((PTR, PTR, size_t));
+extern void mfree PARAMS ((PTR, PTR));
+#endif
+
+/* From demangle.c */
+
+extern void set_demangling_style PARAMS ((char *));
+
+/* From tm.h */
+
+struct type;
+typedef int (use_struct_convention_fn) PARAMS ((int gcc_p, struct type *value_type));
+extern use_struct_convention_fn generic_use_struct_convention;
+
+typedef unsigned char *(breakpoint_from_pc_fn) PARAMS ((CORE_ADDR *pcptr, int *lenptr));
+
+
/* Annotation stuff. */
@@ -259,9 +327,41 @@ extern void wrap_here PARAMS ((char *));
extern void reinitialize_more_filter PARAMS ((void));
+/* new */
+enum streamtype
+{
+ afile,
+ astring
+};
+
+/* new */
+typedef struct tui_stream
+{
+ enum streamtype ts_streamtype;
+ FILE *ts_filestream;
+ char *ts_strbuf;
+ int ts_buflen;
+} GDB_FILE;
+
+extern GDB_FILE *gdb_stdout;
+extern GDB_FILE *gdb_stderr;
+
+#if 0
typedef FILE GDB_FILE;
#define gdb_stdout stdout
#define gdb_stderr stderr
+#endif
+
+#if defined(TUI)
+#include "tui.h"
+#include "tuiCommand.h"
+#include "tuiData.h"
+#include "tuiIO.h"
+#include "tuiLayout.h"
+#include "tuiWin.h"
+#endif
+
+extern void gdb_fclose PARAMS ((GDB_FILE **));
extern void gdb_flush PARAMS ((GDB_FILE *));
@@ -271,6 +371,8 @@ extern void fputs_filtered PARAMS ((const char *, GDB_FILE *));
extern void fputs_unfiltered PARAMS ((const char *, GDB_FILE *));
+extern int fputc_filtered PARAMS ((int c, GDB_FILE *));
+
extern int fputc_unfiltered PARAMS ((int c, GDB_FILE *));
extern int putchar_unfiltered PARAMS ((int c));
@@ -279,16 +381,18 @@ extern void puts_filtered PARAMS ((const char *));
extern void puts_unfiltered PARAMS ((const char *));
+extern void puts_debug PARAMS ((char *prefix, char *string, char *suffix));
+
extern void vprintf_filtered PARAMS ((const char *, va_list))
ATTR_FORMAT(printf, 1, 0);
-extern void vfprintf_filtered PARAMS ((FILE *, const char *, va_list))
+extern void vfprintf_filtered PARAMS ((GDB_FILE *, const char *, va_list))
ATTR_FORMAT(printf, 2, 0);
-extern void fprintf_filtered PARAMS ((FILE *, const char *, ...))
+extern void fprintf_filtered PARAMS ((GDB_FILE *, const char *, ...))
ATTR_FORMAT(printf, 2, 3);
-extern void fprintfi_filtered PARAMS ((int, FILE *, const char *, ...))
+extern void fprintfi_filtered PARAMS ((int, GDB_FILE *, const char *, ...))
ATTR_FORMAT(printf, 3, 4);
extern void printf_filtered PARAMS ((const char *, ...))
@@ -300,15 +404,25 @@ extern void printfi_filtered PARAMS ((int, const char *, ...))
extern void vprintf_unfiltered PARAMS ((const char *, va_list))
ATTR_FORMAT(printf, 1, 0);
-extern void vfprintf_unfiltered PARAMS ((FILE *, const char *, va_list))
+extern void vfprintf_unfiltered PARAMS ((GDB_FILE *, const char *, va_list))
ATTR_FORMAT(printf, 2, 0);
-extern void fprintf_unfiltered PARAMS ((FILE *, const char *, ...))
+extern void fprintf_unfiltered PARAMS ((GDB_FILE *, const char *, ...))
ATTR_FORMAT(printf, 2, 3);
extern void printf_unfiltered PARAMS ((const char *, ...))
ATTR_FORMAT(printf, 1, 2);
+extern int gdb_file_isatty PARAMS ((GDB_FILE *));
+
+extern GDB_FILE *gdb_file_init_astring PARAMS ((int));
+
+extern void gdb_file_deallocate PARAMS ((GDB_FILE **));
+
+extern char *gdb_file_get_strbuf PARAMS ((GDB_FILE *));
+
+extern void gdb_file_adjust_strbuf PARAMS ((int, GDB_FILE *));
+
extern void print_spaces PARAMS ((int, GDB_FILE *));
extern void print_spaces_filtered PARAMS ((int, GDB_FILE *));
@@ -319,10 +433,20 @@ extern void gdb_printchar PARAMS ((int, GDB_FILE *, int));
extern void gdb_print_address PARAMS ((void *, GDB_FILE *));
+typedef bfd_vma t_addr;
+typedef bfd_vma t_reg;
+extern char* paddr PARAMS ((t_addr addr));
+
+extern char* preg PARAMS ((t_reg reg));
+
+extern char* paddr_nz PARAMS ((t_addr addr));
+
+extern char* preg_nz PARAMS ((t_reg reg));
+
extern void fprintf_symbol_filtered PARAMS ((GDB_FILE *, char *,
enum language, int));
-extern void perror_with_name PARAMS ((char *));
+extern NORETURN void perror_with_name PARAMS ((char *)) ATTR_NORETURN;
extern void print_sys_errmsg PARAMS ((char *, int));
@@ -365,6 +489,8 @@ extern void print_address PARAMS ((CORE_ADDR, GDB_FILE *));
extern int openp PARAMS ((char *, int, char *, int, int, char **));
+extern int source_full_path_of PARAMS ((char *, char **));
+
extern void mod_path PARAMS ((char *, char **));
extern void directory_command PARAMS ((char *, int));
@@ -413,7 +539,7 @@ struct command_line
struct command_line **body_list;
};
-extern struct command_line *read_command_lines PARAMS ((void));
+extern struct command_line *read_command_lines PARAMS ((char *, int));
extern void free_command_lines PARAMS ((struct command_line **));
@@ -462,23 +588,21 @@ enum val_prettyprint
#include "fopen-same.h"
#endif
+/* Microsoft C can't deal with const pointers */
+
+#ifdef _MSC_VER
+#define CONST_PTR
+#else
+#define CONST_PTR const
+#endif
+
/*
- * Allow things in gdb to be declared "const". If compiling ANSI, it
- * just works. If compiling with gcc but non-ansi, redefine to __const__.
- * If non-ansi, non-gcc, then eliminate "const" entirely, making those
+ * Allow things in gdb to be declared "volatile". If compiling ANSI, it
+ * just works. If compiling with gcc but non-ansi, redefine to __volatile__.
+ * If non-ansi, non-gcc, then eliminate "volatile" entirely, making those
* objects be read-write rather than read-only.
*/
-#ifndef const
-#ifndef __STDC__
-# ifdef __GNUC__
-# define const __const__
-# else
-# define const /*nothing*/
-# endif /* GNUC */
-#endif /* STDC */
-#endif /* const */
-
#ifndef volatile
#ifndef __STDC__
# ifdef __GNUC__
@@ -489,7 +613,8 @@ enum val_prettyprint
#endif /* STDC */
#endif /* volatile */
-/* Defaults for system-wide constants (if not defined by xm.h, we fake it). */
+/* Defaults for system-wide constants (if not defined by xm.h, we fake it).
+ FIXME: Assumes 2's complement arithmetic */
#if !defined (UINT_MAX)
#define UINT_MAX ((unsigned int)(~0)) /* 0xFFFFFFFF for 32-bits */
@@ -500,7 +625,7 @@ enum val_prettyprint
#endif
#if !defined (INT_MIN)
-#define INT_MIN (-INT_MAX - 1) /* 0x80000000 for 32-bits */
+#define INT_MIN ((int)((int) ~0 ^ INT_MAX)) /* 0x80000000 for 32-bits */
#endif
#if !defined (ULONG_MAX)
@@ -511,46 +636,36 @@ enum val_prettyprint
#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */
#endif
+#ifndef LONGEST
+
#ifdef BFD64
/* This is to make sure that LONGEST is at least as big as CORE_ADDR. */
#define LONGEST BFD_HOST_64_BIT
+#define ULONGEST BFD_HOST_U_64_BIT
#else /* No BFD64 */
-/* If all compilers for this host support "long long" and we want to
- use it for LONGEST (the performance hit is about 10% on a testsuite
- run based on one DECstation test), then the xm.h file can define
- CC_HAS_LONG_LONG.
-
- Using GCC 1.39 on BSDI with long long causes about 700 new
- testsuite failures. Using long long for LONGEST on the DECstation
- causes 3 new FAILs in the testsuite and many heuristic fencepost
- warnings. These are not investigated, but a first guess would be
- that the BSDI problems are GCC bugs in long long support and the
- latter are GDB bugs. */
-
-#ifndef CC_HAS_LONG_LONG
-# if defined (__GNUC__) && defined (FORCE_LONG_LONG)
-# define CC_HAS_LONG_LONG 1
-# endif
-#endif
-
-/* LONGEST should not be a typedef, because "unsigned LONGEST" needs to work.
- CC_HAS_LONG_LONG is defined if the host compiler supports "long long"
- variables and we wish to make use of that support. */
-
-#ifndef LONGEST
# ifdef CC_HAS_LONG_LONG
# define LONGEST long long
+# define ULONGEST unsigned long long
# else
-# define LONGEST long
+/* BFD_HOST_64_BIT is defined for some hosts that don't have long long
+ (e.g. i386-windows) so try it. */
+# ifdef BFD_HOST_64_BIT
+# define LONGEST BFD_HOST_64_BIT
+# define ULONGEST BFD_HOST_U_64_BIT
+# else
+# define LONGEST long
+# define ULONGEST unsigned long
+# endif
# endif
-#endif
#endif /* No BFD64 */
+#endif /* ! LONGEST */
+
/* Convert a LONGEST to an int. This is used in contexts (e.g. number of
arguments to a function, number in a value history, register number, etc.)
where the value must not be larger than can fit in an int. */
@@ -568,13 +683,23 @@ extern char *strsave PARAMS ((const char *));
extern char *mstrsave PARAMS ((void *, const char *));
+#ifdef _MSC_VER /* FIXME; was long, but this causes compile errors in msvc if already defined */
+extern PTR xmmalloc PARAMS ((PTR, size_t));
+
+extern PTR xmrealloc PARAMS ((PTR, PTR, size_t));
+#else
extern PTR xmmalloc PARAMS ((PTR, long));
extern PTR xmrealloc PARAMS ((PTR, PTR, long));
+#endif
extern int parse_escape PARAMS ((char **));
-extern char *reg_names[];
+/* compat - handle old targets that just define REGISTER_NAMES */
+#ifndef REGISTER_NAME
+extern char *gdb_register_names[];
+#define REGISTER_NAME(i) gdb_register_names[i]
+#endif
/* Message to be printed before the error message, when an error occurs. */
@@ -588,7 +713,7 @@ extern char *quit_pre_print;
extern char *warning_pre_print;
-extern NORETURN void error PARAMS((char *, ...)) ATTR_NORETURN;
+extern NORETURN void error PARAMS((const char *, ...)) ATTR_NORETURN;
extern void error_begin PARAMS ((void));
@@ -613,12 +738,12 @@ typedef int return_mask;
extern NORETURN void
return_to_top_level PARAMS ((enum return_reason)) ATTR_NORETURN;
-extern int
-catch_errors PARAMS ((int (*) (char *), void *, char *, return_mask));
+typedef int (catch_errors_ftype) PARAMS ((PTR));
+extern int catch_errors PARAMS ((catch_errors_ftype *, PTR, char *, return_mask));
extern void warning_begin PARAMS ((void));
-extern void warning PARAMS ((char *, ...))
+extern void warning PARAMS ((const char *, ...))
ATTR_FORMAT(printf, 1, 2);
/* Global functions from other, non-gdb GNU thingies.
@@ -631,10 +756,24 @@ extern char *getenv PARAMS ((const char *));
/* From other system libraries */
-#ifdef __STDC__
+#ifdef HAVE_STDDEF_H
#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#if defined(_MSC_VER) && !defined(__cplusplus)
+/* msvc defines these in stdlib.h for c code */
+#undef min
+#undef max
+#endif
#include <stdlib.h>
#endif
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#endif
/* We take the address of fclose later, but some stdio's forget
@@ -643,64 +782,51 @@ extern char *getenv PARAMS ((const char *));
somewhere. */
#ifndef FCLOSE_PROVIDED
-extern int fclose ();
+extern int fclose PARAMS ((FILE *));
#endif
#ifndef atof
-extern double atof ();
+extern double atof PARAMS ((const char *)); /* X3.159-1989 4.10.1.1 */
#endif
#ifndef MALLOC_INCOMPATIBLE
+#ifdef NEED_DECLARATION_MALLOC
extern PTR malloc ();
-
-extern PTR realloc ();
-
-extern void free ();
-
-#endif /* MALLOC_INCOMPATIBLE */
-
-#ifndef __WIN32__
-
-#ifndef strchr
-extern char *strchr ();
-#endif
-
-#ifndef strrchr
-extern char *strrchr ();
-#endif
-
-#ifndef strstr
-extern char *strstr ();
#endif
-#ifndef strtok
-extern char *strtok ();
+#ifdef NEED_DECLARATION_REALLOC
+extern PTR realloc ();
#endif
-#ifndef strerror
-extern char *strerror ();
+#ifdef NEED_DECLARATION_FREE
+extern void free ();
#endif
-#endif /* !__WIN32__ */
+#endif /* MALLOC_INCOMPATIBLE */
/* Various possibilities for alloca. */
#ifndef alloca
# ifdef __GNUC__
# define alloca __builtin_alloca
# else /* Not GNU C */
-# ifdef sparc
-# include <alloca.h> /* NOTE: Doesn't declare alloca() */
-# endif
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
/* We need to be careful not to declare this in a way which conflicts with
bison. Bison never declares it as char *, but under various circumstances
(like __hpux) we need to use void *. */
-# if defined (__STDC__) || defined (__hpux)
+# if defined (__STDC__) || defined (__hpux)
extern void *alloca ();
-# else /* Don't use void *. */
+# else /* Don't use void *. */
extern char *alloca ();
-# endif /* Don't use void *. */
+# endif /* Don't use void *. */
+# endif /* Not _AIX */
+# endif /* Not HAVE_ALLOCA_H */
# endif /* Not GNU C */
#endif /* alloca not defined */
@@ -718,18 +844,10 @@ extern char *strerror ();
#define LITTLE_ENDIAN 1234
#endif
-/* Target-system-dependent parameters for GDB. */
+/* Dynamic target-system-dependent parameters for GDB. */
+#include "gdbarch.h"
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-/* The target endianness is selectable at runtime. Define
- TARGET_BYTE_ORDER to be a variable. The user can use the `set
- endian' command to change it. */
-#undef TARGET_BYTE_ORDER
-#define TARGET_BYTE_ORDER target_byte_order
-extern int target_byte_order;
-#endif
-
-extern void set_endian_from_file PARAMS ((bfd *));
+/* Static target-system-dependent parameters for GDB. */
/* Number of bits in a char or unsigned char for the target machine.
Just like CHAR_BIT in <limits.h> but describes the target machine. */
@@ -793,38 +911,71 @@ extern void set_endian_from_file PARAMS ((bfd *));
from byte/word byte order. */
#if !defined (BITS_BIG_ENDIAN)
-#ifndef TARGET_BYTE_ORDER_SELECTABLE
-
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-#define BITS_BIG_ENDIAN 1
-#endif /* Big endian. */
-
-#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
-#define BITS_BIG_ENDIAN 0
-#endif /* Little endian. */
-
-#else /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
#define BITS_BIG_ENDIAN (TARGET_BYTE_ORDER == BIG_ENDIAN)
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-#endif /* BITS_BIG_ENDIAN not defined. */
+#endif
/* In findvar.c. */
extern LONGEST extract_signed_integer PARAMS ((void *, int));
-extern unsigned LONGEST extract_unsigned_integer PARAMS ((void *, int));
+extern ULONGEST extract_unsigned_integer PARAMS ((void *, int));
extern int extract_long_unsigned_integer PARAMS ((void *, int, LONGEST *));
extern CORE_ADDR extract_address PARAMS ((void *, int));
-extern void store_signed_integer PARAMS ((void *, int, LONGEST));
+extern void store_signed_integer PARAMS ((PTR, int, LONGEST));
+
+extern void store_unsigned_integer PARAMS ((PTR, int, ULONGEST));
-extern void store_unsigned_integer PARAMS ((void *, int, unsigned LONGEST));
+extern void store_address PARAMS ((PTR, int, LONGEST));
-extern void store_address PARAMS ((void *, int, CORE_ADDR));
+/* Setup definitions for host and target floating point formats. We need to
+ consider the format for `float', `double', and `long double' for both target
+ and host. We need to do this so that we know what kind of conversions need
+ to be done when converting target numbers to and from the hosts DOUBLEST
+ data type. */
+
+/* This is used to indicate that we don't know the format of the floating point
+ number. Typically, this is useful for native ports, where the actual format
+ is irrelevant, since no conversions will be taking place. */
+
+extern const struct floatformat floatformat_unknown;
+
+#if HOST_BYTE_ORDER == BIG_ENDIAN
+# ifndef HOST_FLOAT_FORMAT
+# define HOST_FLOAT_FORMAT &floatformat_ieee_single_big
+# endif
+# ifndef HOST_DOUBLE_FORMAT
+# define HOST_DOUBLE_FORMAT &floatformat_ieee_double_big
+# endif
+#else /* LITTLE_ENDIAN */
+# ifndef HOST_FLOAT_FORMAT
+# define HOST_FLOAT_FORMAT &floatformat_ieee_single_little
+# endif
+# ifndef HOST_DOUBLE_FORMAT
+# define HOST_DOUBLE_FORMAT &floatformat_ieee_double_little
+# endif
+#endif
+
+#ifndef HOST_LONG_DOUBLE_FORMAT
+#define HOST_LONG_DOUBLE_FORMAT &floatformat_unknown
+#endif
+
+#ifndef TARGET_FLOAT_FORMAT
+#define TARGET_FLOAT_FORMAT (TARGET_BYTE_ORDER == BIG_ENDIAN \
+ ? &floatformat_ieee_single_big \
+ : &floatformat_ieee_single_little)
+#endif
+#ifndef TARGET_DOUBLE_FORMAT
+#define TARGET_DOUBLE_FORMAT (TARGET_BYTE_ORDER == BIG_ENDIAN \
+ ? &floatformat_ieee_double_big \
+ : &floatformat_ieee_double_little)
+#endif
+
+#ifndef TARGET_LONG_DOUBLE_FORMAT
+# define TARGET_LONG_DOUBLE_FORMAT &floatformat_unknown
+#endif
/* Use `long double' if the host compiler supports it. (Note that this is not
necessarily any longer than `double'. On SunOS/gcc, it's the same as
@@ -835,13 +986,16 @@ extern void store_address PARAMS ((void *, int, CORE_ADDR));
host's `long double'. In general, we'll probably reduce the precision of
any such values and print a warning. */
-
#ifdef HAVE_LONG_DOUBLE
typedef long double DOUBLEST;
#else
typedef double DOUBLEST;
#endif
+extern void floatformat_to_doublest PARAMS ((const struct floatformat *,
+ char *, DOUBLEST *));
+extern void floatformat_from_doublest PARAMS ((const struct floatformat *,
+ DOUBLEST *, char *));
extern DOUBLEST extract_floating PARAMS ((void *, int));
extern void store_floating PARAMS ((void *, int, DOUBLEST));
@@ -863,7 +1017,7 @@ extern void store_floating PARAMS ((void *, int, DOUBLEST));
extern CORE_ADDR push_bytes PARAMS ((CORE_ADDR, char *, int));
-extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST));
+extern CORE_ADDR push_word PARAMS ((CORE_ADDR, ULONGEST));
/* Some parts of gdb might be considered optional, in the sense that they
are not essential for being able to build a working, usable debugger
@@ -884,19 +1038,6 @@ extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST));
extern int watchdog;
#endif
-#include "dis-asm.h" /* Get defs for disassemble_info */
-
-extern int dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr,
- int len, disassemble_info *info));
-
-extern void dis_asm_memory_error PARAMS ((int status, bfd_vma memaddr,
- disassemble_info *info));
-
-extern void dis_asm_print_address PARAMS ((bfd_vma addr,
- disassemble_info *info));
-
-extern int (*tm_print_insn) PARAMS ((bfd_vma, disassemble_info*));
-
/* Hooks for alternate command interfaces. */
#ifdef __STDC__
@@ -904,30 +1045,38 @@ struct target_waitstatus;
struct cmd_list_element;
#endif
-extern void (*init_ui_hook) PARAMS ((void));
+extern void (*init_ui_hook) PARAMS ((char *argv0));
extern void (*command_loop_hook) PARAMS ((void));
extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer,
- FILE *stream));
+ GDB_FILE *stream));
extern void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s,
int line, int stopline,
int noerror));
-extern int (*query_hook) PARAMS (());
-extern void (*flush_hook) PARAMS ((FILE *stream));
+extern struct frame_info *parse_frame_specification PARAMS ((char *frame_exp));
+extern int (*query_hook) PARAMS ((const char *, va_list));
+extern void (*warning_hook) PARAMS ((const char *, va_list));
+extern void (*flush_hook) PARAMS ((GDB_FILE *stream));
extern void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b));
extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
extern void (*modify_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
extern void (*target_output_hook) PARAMS ((char *));
extern void (*interactive_hook) PARAMS ((void));
extern void (*registers_changed_hook) PARAMS ((void));
-
+extern void (*readline_begin_hook) PARAMS ((char *, ...));
+extern char * (*readline_hook) PARAMS ((char *));
+extern void (*readline_end_hook) PARAMS ((void));
+extern void (*register_changed_hook) PARAMS ((int regno));
+extern void (*memory_changed_hook) PARAMS ((CORE_ADDR addr, int len));
+extern void (*context_hook) PARAMS ((int));
extern int (*target_wait_hook) PARAMS ((int pid,
struct target_waitstatus *status));
extern void (*call_command_hook) PARAMS ((struct cmd_list_element *c,
char *cmd, int from_tty));
-extern NORETURN void (*error_hook) PARAMS (()) ATTR_NORETURN;
+extern NORETURN void (*error_hook) PARAMS ((void)) ATTR_NORETURN;
+extern void (*error_begin_hook) PARAMS ((void));
/* Inhibit window interface if non-zero. */
@@ -943,7 +1092,7 @@ extern int use_windows;
#endif
#ifndef SLASH_P
-#if defined(__GO32__)||defined(__WIN32__)
+#if defined(__GO32__)||defined(_WIN32)
#define SLASH_P(X) ((X)=='\\')
#else
#define SLASH_P(X) ((X)=='/')
@@ -951,7 +1100,7 @@ extern int use_windows;
#endif
#ifndef SLASH_CHAR
-#if defined(__GO32__)||defined(__WIN32__)
+#if defined(__GO32__)||defined(_WIN32)
#define SLASH_CHAR '\\'
#else
#define SLASH_CHAR '/'
@@ -959,7 +1108,7 @@ extern int use_windows;
#endif
#ifndef SLASH_STRING
-#if defined(__GO32__)||defined(__WIN32__)
+#if defined(__GO32__)||defined(_WIN32)
#define SLASH_STRING "\\"
#else
#define SLASH_STRING "/"
@@ -970,4 +1119,21 @@ extern int use_windows;
#define ROOTED_P(X) (SLASH_P((X)[0]))
#endif
+/* On some systems, PIDGET is defined to extract the inferior pid from
+ an internal pid that has the thread id and pid in seperate bit
+ fields. If not defined, then just use the entire internal pid as
+ the actual pid. */
+
+#ifndef PIDGET
+#define PIDGET(pid) (pid)
+#endif
+
+/* If under Cygwin, provide backwards compatibility with older
+ Cygwin compilers that don't define the current cpp define. */
+#ifdef __CYGWIN32__
+#ifndef __CYGWIN__
+#define __CYGWIN__
+#endif
+#endif
+
#endif /* #ifndef DEFS_H */
diff --git a/contrib/gdb/gdb/demangle.c b/contrib/gdb/gdb/demangle.c
index bb3f092..669d9ab 100644
--- a/contrib/gdb/gdb/demangle.c
+++ b/contrib/gdb/gdb/demangle.c
@@ -1,26 +1,26 @@
/* Basic C++ demangling support for GDB.
- Copyright 1991, 1992, 1996 Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1996, 1999 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
-This file is part of GDB.
+ This file is part of GDB.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This file contains support code for C++ demangling that is common
- to a styles of demangling, and GDB specific. */
+ to a styles of demangling, and GDB specific. */
#include "defs.h"
#include "command.h"
@@ -31,54 +31,85 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Select the default C++ demangling style to use. The default is "auto",
which allows gdb to attempt to pick an appropriate demangling style for
the executable it has loaded. It can be set to a specific style ("gnu",
- "lucid", "arm", etc.) in which case gdb will never attempt to do auto
+ "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto
selection of the style unless you do an explicit "set demangle auto".
To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in
the appropriate target configuration file. */
#ifndef DEFAULT_DEMANGLING_STYLE
-# define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
+#define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
#endif
-/* String name for the current demangling style. Set by the "set demangling"
- command, printed as part of the output by the "show demangling" command. */
+/* String name for the current demangling style. Set by the
+ "set demangle-style" command, printed as part of the output by the
+ "show demangle-style" command. */
static char *current_demangling_style_string;
/* List of supported demangling styles. Contains the name of the style as
seen by the user, and the enum value that corresponds to that style. */
-
+
static const struct demangler
+ {
+ char *demangling_style_name;
+ enum demangling_styles demangling_style;
+ char *demangling_style_doc;
+ }
+demanglers[] =
{
- char *demangling_style_name;
- enum demangling_styles demangling_style;
- char *demangling_style_doc;
-} demanglers [] =
-{
- {AUTO_DEMANGLING_STYLE_STRING,
- auto_demangling,
- "Automatic selection based on executable"},
- {GNU_DEMANGLING_STYLE_STRING,
- gnu_demangling,
- "GNU (g++) style demangling"},
- {LUCID_DEMANGLING_STYLE_STRING,
- lucid_demangling,
- "Lucid (lcc) style demangling"},
- {ARM_DEMANGLING_STYLE_STRING,
- arm_demangling,
- "ARM style demangling"},
- {NULL, unknown_demangling, NULL}
+ {
+ AUTO_DEMANGLING_STYLE_STRING,
+ auto_demangling,
+ "Automatic selection based on executable"
+ }
+ ,
+ {
+ GNU_DEMANGLING_STYLE_STRING,
+ gnu_demangling,
+ "GNU (g++) style demangling"
+ }
+ ,
+ {
+ LUCID_DEMANGLING_STYLE_STRING,
+ lucid_demangling,
+ "Lucid (lcc) style demangling"
+ }
+ ,
+ {
+ ARM_DEMANGLING_STYLE_STRING,
+ arm_demangling,
+ "ARM style demangling"
+ }
+ ,
+ {
+ HP_DEMANGLING_STYLE_STRING,
+ hp_demangling,
+ "HP (aCC) style demangling"
+ }
+ ,
+ {
+ EDG_DEMANGLING_STYLE_STRING,
+ edg_demangling,
+ "EDG style demangling"
+ }
+ ,
+ {
+ NULL, unknown_demangling, NULL
+ }
};
-/* set current demangling style. called by the "set demangling" command
- after it has updated the current_demangling_style_string to match
- what the user has entered.
+static void
+set_demangling_command PARAMS ((char *, int, struct cmd_list_element *));
+
+/* Set current demangling style. Called by the "set demangle-style"
+ command after it has updated the current_demangling_style_string to
+ match what the user has entered.
- if the user has entered a string that matches a known demangling style
+ If the user has entered a string that matches a known demangling style
name in the demanglers[] array then just leave the string alone and update
the current_demangling_style enum value to match.
- if the user has entered a string that doesn't match, including an empty
+ If the user has entered a string that doesn't match, including an empty
string, then print a list of the currently known styles and restore
the current_demangling_style_string to match the current_demangling_style
enum value.
@@ -95,16 +126,16 @@ set_demangling_command (ignore, from_tty, c)
const struct demangler *dem;
/* First just try to match whatever style name the user supplied with
- one of the known ones. Don't bother special casing for an empty
- name, we just treat it as any other style name that doesn't match.
- If we match, update the current demangling style enum. */
+ one of the known ones. Don't bother special casing for an empty
+ name, we just treat it as any other style name that doesn't match.
+ If we match, update the current demangling style enum. */
- for (dem = demanglers; dem -> demangling_style_name != NULL; dem++)
+ for (dem = demanglers; dem->demangling_style_name != NULL; dem++)
{
if (STREQ (current_demangling_style_string,
- dem -> demangling_style_name))
+ dem->demangling_style_name))
{
- current_demangling_style = dem -> demangling_style;
+ current_demangling_style = dem->demangling_style;
break;
}
}
@@ -113,24 +144,24 @@ set_demangling_command (ignore, from_tty, c)
style name and supply a list of valid ones. FIXME: This should
probably be done with some sort of completion and with help. */
- if (dem -> demangling_style_name == NULL)
+ if (dem->demangling_style_name == NULL)
{
if (*current_demangling_style_string != '\0')
{
printf_unfiltered ("Unknown demangling style `%s'.\n",
- current_demangling_style_string);
+ current_demangling_style_string);
}
printf_unfiltered ("The currently understood settings are:\n\n");
- for (dem = demanglers; dem -> demangling_style_name != NULL; dem++)
+ for (dem = demanglers; dem->demangling_style_name != NULL; dem++)
{
- printf_unfiltered ("%-10s %s\n", dem -> demangling_style_name,
- dem -> demangling_style_doc);
- if (dem -> demangling_style == current_demangling_style)
+ printf_unfiltered ("%-10s %s\n", dem->demangling_style_name,
+ dem->demangling_style_doc);
+ if (dem->demangling_style == current_demangling_style)
{
free (current_demangling_style_string);
current_demangling_style_string =
- savestring (dem -> demangling_style_name,
- strlen (dem -> demangling_style_name));
+ savestring (dem->demangling_style_name,
+ strlen (dem->demangling_style_name));
}
}
if (current_demangling_style == unknown_demangling)
@@ -148,7 +179,7 @@ set_demangling_command (ignore, from_tty, c)
}
}
-/* Fake a "set demangling" command. */
+/* Fake a "set demangle-style" command. */
void
set_demangling_style (style)
@@ -159,7 +190,7 @@ set_demangling_style (style)
free (current_demangling_style_string);
}
current_demangling_style_string = savestring (style, strlen (style));
- set_demangling_command ((char *) NULL, 0);
+ set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
}
/* In order to allow a single demangler executable to demangle strings
@@ -178,7 +209,7 @@ set_demangling_style (style)
ensuring that it is the character that terminates the gcc<n>_compiled
marker symbol (FIXME). */
-static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
+static char cplus_markers[] = {CPLUS_MARKER, '.', '$', '\0'};
int
is_cplus_marker (c)
@@ -190,17 +221,17 @@ is_cplus_marker (c)
void
_initialize_demangler ()
{
- struct cmd_list_element *set, *show;
+ struct cmd_list_element *set, *show;
- set = add_set_cmd ("demangle-style", class_support, var_string_noescape,
- (char *) &current_demangling_style_string,
- "Set the current C++ demangling style.\n\
+ set = add_set_cmd ("demangle-style", class_support, var_string_noescape,
+ (char *) &current_demangling_style_string,
+ "Set the current C++ demangling style.\n\
Use `set demangle-style' without arguments for a list of demangling styles.",
- &setlist);
- show = add_show_from_set (set, &showlist);
- set -> function.sfunc = set_demangling_command;
+ &setlist);
+ show = add_show_from_set (set, &showlist);
+ set->function.sfunc = set_demangling_command;
- /* Set the default demangling style chosen at compilation time. */
- set_demangling_style (DEFAULT_DEMANGLING_STYLE);
- set_cplus_marker_for_demangling (CPLUS_MARKER);
+ /* Set the default demangling style chosen at compilation time. */
+ set_demangling_style (DEFAULT_DEMANGLING_STYLE);
+ set_cplus_marker_for_demangling (CPLUS_MARKER);
}
diff --git a/contrib/gdb/gdb/dink32-rom.c b/contrib/gdb/gdb/dink32-rom.c
new file mode 100644
index 0000000..c0c2e51
--- /dev/null
+++ b/contrib/gdb/gdb/dink32-rom.c
@@ -0,0 +1,198 @@
+/* Remote debugging interface for DINK32 (PowerPC) ROM monitor for
+ GDB, the GNU debugger.
+ Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+
+static void dink32_open PARAMS ((char *args, int from_tty));
+
+static void
+dink32_supply_register (regname, regnamelen, val, vallen)
+ char *regname;
+ int regnamelen;
+ char *val;
+ int vallen;
+{
+ int regno = 0, base = 0;
+
+ if (regnamelen < 2 || regnamelen > 4)
+ return;
+
+ switch (regname[0])
+ {
+ case 'R':
+ if (regname[1] < '0' || regname[1] > '9')
+ return;
+ if (regnamelen == 2)
+ regno = regname[1] - '0';
+ else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9')
+ regno = (regname[1] - '0') * 10 + (regname[2] - '0');
+ else
+ return;
+ break;
+ case 'F':
+ if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9')
+ return;
+ if (regnamelen == 3)
+ regno = 32 + regname[2] - '0';
+ else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9')
+ regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0');
+ else
+ return;
+ break;
+ case 'I':
+ if (regnamelen != 2 || regname[1] != 'P')
+ return;
+ regno = 64;
+ break;
+ case 'M':
+ if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R')
+ return;
+ regno = 65;
+ break;
+ case 'C':
+ if (regnamelen != 2 || regname[1] != 'R')
+ return;
+ regno = 66;
+ break;
+ case 'S':
+ if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R')
+ return;
+ else if (regname[3] == '8')
+ regno = 67;
+ else if (regname[3] == '9')
+ regno = 68;
+ else if (regname[3] == '1')
+ regno = 69;
+ else if (regname[3] == '0')
+ regno = 70;
+ else
+ return;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+static void
+dink32_load (monops, filename, from_tty)
+ struct monitor_ops *monops;
+ char *filename;
+ int from_tty;
+{
+ extern int inferior_pid;
+
+ generic_load (filename, from_tty);
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_pid = 0; /* No process now */
+}
+
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. */
+
+static char *dink32_regnames[NUM_REGS] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+
+ "srr0", "msr", "cr", "lr", "ctr", "xer", "xer"
+};
+
+static struct target_ops dink32_ops;
+
+static char *dink32_inits[] = {"\r", NULL};
+
+static struct monitor_ops dink32_cmds;
+
+static void
+dink32_open (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ monitor_open (args, &dink32_cmds, from_tty);
+}
+
+void
+_initialize_dink32_rom ()
+{
+ dink32_cmds.flags = MO_HEX_PREFIX | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR | MO_HANDLE_NL | MO_32_REGS_PAIRED | MO_SETREG_INTERACTIVE | MO_SETMEM_INTERACTIVE | MO_GETMEM_16_BOUNDARY | MO_CLR_BREAK_1_BASED | MO_SREC_ACK | MO_SREC_ACK_ROTATE;
+ dink32_cmds.init = dink32_inits;
+ dink32_cmds.cont = "go +\r";
+ dink32_cmds.step = "tr +\r";
+ dink32_cmds.set_break = "bp 0x%x\r";
+ dink32_cmds.clr_break = "bp %d\r";
+#if 0 /* Would need to follow strict alignment rules.. */
+ dink32_cmds.fill = "mf %x %x %x\r";
+#endif
+ dink32_cmds.setmem.cmdb = "mm -b %x\r";
+ dink32_cmds.setmem.cmdw = "mm -w %x\r";
+ dink32_cmds.setmem.cmdl = "mm %x\r";
+ dink32_cmds.setmem.term = " ? ";
+ dink32_cmds.getmem.cmdb = "md %x\r";
+ dink32_cmds.getmem.resp_delim = " ";
+ dink32_cmds.setreg.cmd = "rm %s\r";
+ dink32_cmds.setreg.term = " ? ";
+ dink32_cmds.getreg.cmd = "rd %s\r";
+ dink32_cmds.getreg.resp_delim = ": ";
+ dink32_cmds.dump_registers = "rd r\r";
+ dink32_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)";
+ dink32_cmds.supply_register = dink32_supply_register;
+ /* S-record download, via "keyboard port". */
+ dink32_cmds.load = "dl -k\r";
+ dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r";
+#if 0 /* slow load routine not needed if S-records work... */
+ dink32_cmds.load_routine = dink32_load;
+#endif
+ dink32_cmds.prompt = "DINK32_603 >>";
+ dink32_cmds.line_term = "\r";
+ dink32_cmds.target = &dink32_ops;
+ dink32_cmds.stopbits = SERIAL_1_STOPBITS;
+ dink32_cmds.regnames = dink32_regnames;
+ dink32_cmds.magic = MONITOR_OPS_MAGIC;
+
+ init_monitor_ops (&dink32_ops);
+
+ dink32_ops.to_shortname = "dink32";
+ dink32_ops.to_longname = "DINK32 monitor";
+ dink32_ops.to_doc = "Debug using the DINK32 monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ dink32_ops.to_open = dink32_open;
+
+ add_target (&dink32_ops);
+}
diff --git a/contrib/gdb/gdb/doc/ChangeLog b/contrib/gdb/gdb/doc/ChangeLog
index 42e8393..1e03a80 100644
--- a/contrib/gdb/gdb/doc/ChangeLog
+++ b/contrib/gdb/gdb/doc/ChangeLog
@@ -1,3 +1,265 @@
+Thu Feb 11 18:00:59 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Update the credits.
+
+Mon Feb 8 17:33:57 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Fix mistakes noticed in printout of last
+ draft, add Alpha to discussion of heuristic fence post.
+
+Fri Feb 5 17:20:00 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo, remote.texi: Many changes; update to Seventh
+ Edition, merge some HP changes into mainline, describe some
+ previously undocumented features, describe more of the target
+ commands available, eliminate obsolete section on renamed
+ commands.
+ * all-cfg.texi, HPPA-cfg.texi: Remove some obsolete conditionals.
+
+Wed Jan 20 17:47:45 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Make many HPPA conditionals unconditional,
+ including catchpoint description, since now on for all configs.
+ * all-cfg.texi: @clear HPPA, since is mainly for very HP-specific
+ specializations.
+
+Thu Jan 14 17:10:12 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (GDBvn.texi): Fix match expression to work with
+ current format of VERSION in gdb/Makefile.in.
+ * gdb.texinfo: Fix node ref to match new readline.
+
+Wed Jan 13 10:38:40 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * gdb.texinfo: Changes made as part of a project to merge in
+ changes made by HP. Documentation makes extensive use of
+ @ifclear HPPA and @ifset HPPA. The HP manual omits doumentation
+ on remote debugging. There are differences in documentation
+ (HP vs. non-HP) on C++ support (aCC vs. gnu gcc++). Also,
+ the HP manual discusses catchpoints, hardware watchpoints, and
+ some HPUX specific limitations for shared library support.
+
+ There are also a number of @node changes.
+
+1999-01-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdbint.texinfo (Formatting): Disambiguate a sentence.
+ (C Usage): Same.
+
+Wed Jan 6 11:55:34 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Edith Epstein
+ <eepstein@cygnus.com> as part of a project to merge in changes
+ made by HP.
+
+ * HPPA-cfg.texi: new file.
+
+ * all-cfg.texi: set HPPA for HP PA-RISC targets.
+
+ * refcard.tex: change documentation about catch.
+ removed info catch.
+
+Mon Jan 4 18:29:18 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Expand on GDB's coding standards,
+ specify the use of arg names with prototypes.
+
+1998-12-14 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * gdb.texinfo: Fix tipo.
+
+Sun Dec 13 10:27:59 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo: Document TARGET_BYTE_ORDER_DEFAULT and
+ TARGET_BYTE_ORDER_SELECTABLE_P.
+
+Thu Dec 10 16:07:09 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (FRAME_FIND_SAVED_REGS): Document.
+
+1998-12-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * agentexpr.texi: New file.
+
+Wed Dec 9 21:13:57 1998 Andrew Cagney <cagney@chook>
+
+ * gdbint.texinfo (REGISTER_NAME): Replace REGISTER_NAMES.
+
+1998-12-03 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * remote.texi: Changed wording that implied that the GDB remote
+ protocol caches register values instead of GDB itself.
+
+Tue Dec 1 17:45:43 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Add some info about symbol readers.
+ (CHILL_PRODUCER, etc): Comment out descriptions, not useful.
+ (IN_SOLIB_CALL_TRAMPOLINE): Rename info from IN_SOLIB_TRAMPOLINE.
+ (IN_SOLIB_RETURN_TRAMPOLINE): Describe.
+ (KERNEL_DEBUGGING, MIPSEL): No info about these, remove.
+
+Mon Nov 30 11:32:21 1998 Andrew Cagney <cagney@chook>
+
+ * gdbint.texinfo (FRAME_CHAIN_VALID_ALTERNATE):
+
+Sat Nov 28 13:45:53 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (INNER_THAN): Update, now takes parameters.
+
+Fri Nov 27 12:39:45 1998 Andrew Cagney <cagney@chook>
+
+ * gdbint.texinfo (NO_SINGLE_STEP): Replace with
+ SOFTWARE_SINGLE_STEP_P and SOFTWARE_SINGLE_STEP.
+
+Wed Oct 14 10:02:40 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo: Fix minor typos.
+
+Wed Sep 30 18:03:19 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Complete overhaul. Group descriptions more
+ logically, add more info on generic algorithms, remove much
+ obsolete and/or wrong material.
+
+Fri Jul 24 17:51:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (Method Type Descriptor): Expand and correct.
+
+Mon May 4 10:37:12 1998 Brian Youmans (3diff@gnu.org)
+
+ * refcard.tex: Copyright, address updates.
+
+Tue Apr 21 18:09:56 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo (EDITION, DATE): Update and change to use ordinals
+ for the edition instead of confusing GDB-version-like numbers.
+
+Mon Apr 13 14:05:00 1998 Fred Fish <fnf@cygnus.com>
+
+ * gdb.texinfo (hbreak, watch): Fix typo, "date" -> "data".
+
+Thu Apr 2 16:52:44 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * LRS: Reformat a bit to keep text under 80 columns.
+
+Thu Apr 2 16:10:36 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Add some credits, mention bug monitor.
+ * remote.texi: Mention mips monitor targets.
+ * gdbint.texinfo: Describe SP_REGNUM, STEP_SKIPS_DELAY.
+
+Mon Feb 2 17:13:03 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Remove obsolete mentions of pinsn.c and opcode.h
+ files, finish sorting of host vs target vs native macros, describe
+ some more of them.
+
+Tue Jan 13 16:44:50 1998 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (Host Conditionals): Document change from
+ using NO_MMALLOC to it's inverse, USE_MMALLOC.
+
+Mon Nov 24 13:55:21 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (Host Conditionals): Document
+ PRINTF_HAS_LONG_DOUBLE, SCANF_HAS_LONG_DOUBLE, HAVE_LONG_DOUBLE.
+
+Fri Jul 4 14:52:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbint.texinfo (Host Conditionals): Add CRLF_SOURCE_LINES.
+ Document LSEEK_NOT_LINEAR.
+
+Tue Mar 25 14:44:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (Stab Section Basics): Make it clear that only
+ some versions of the GNU linker remove the leading N_UNDF symbol.
+
+Thu Feb 27 17:45:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (String Field): Document type number pairs here,
+ instead of in the Sun specific section.
+ (Include Files): The GNU linker supports the N_BINCL
+ optimization. Clarify the N_BINCL value, and what it is used
+ for.
+ (Procedures): Document N_FUN with an empty string to mark the end
+ of a function.
+ (Typedefs): Mention that Sun compilers may use N_GSYM for a type.
+ (Sun Differences): Remove this node, as the information is now
+ elsewhere in the main document.
+ (Stab Section Basics): Mention that the GNU linker may optimize
+ stabs and remove the leading N_UNDF symbol.
+
+Mon Dec 9 12:23:32 1996 Roland Pesch <roland@wrs.com>
+
+ * gdb.texinfo, refcard.tex: Restore author credit
+
+Wed Oct 2 22:01:36 1996 Fred Fish <fnf@fishfood.ninemoons.com>
+
+ * gdbint.texinfo (SIGTRAMP_START, SIGTRAMP_END): Update
+ documentation to account for START and END macros taking
+ one arg.
+
+Thu Aug 22 17:59:03 1996 Fred Fish <fnf@cygnus.com>
+
+ From: Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
+ * gdb.texinfo (Frames): Fix typo.
+
+Tue Jul 23 10:06:20 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (NO_SINGLE_STEP): Document that single_step takes
+ a target_signal as arg type, not a pid.
+
+Fri Jul 12 11:10:05 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * gdb.texinfo: Document `set assembly-language'.
+
+Thu Jul 11 13:50:28 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.texi: Update list of stubs in the GDB distribution.
+
+Fri Jul 5 15:38:54 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (NO_MMCHECK): Renamed from NO_MMALLOC_CHECK.
+ Also document that some systems can use mmalloc but must define
+ this if their C runtime allocates memory that is later freed.
+ (MMCHECK_FORCE): Document new macro.
+
+Fri Jun 28 22:17:10 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * remote.texi: Add documentation for target Sparclet.
+
+Mon Jun 24 18:12:22 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (srcdir, VPATH, prefix, infodir, INSTALL,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf set values.
+ * configure.in: Rewritten for autoconf.
+ * configure: New.
+
+Mon Jun 17 10:43:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (DVIPS): New define, set to dvips.
+ (dvi): Add stabs.dvi.
+ (ps): New target.
+ (all-doc): Depend on info, dvi, and ps targets.
+ (STAGESTUFF): Add *.ps and *.dvi files.
+ (clean-info, clean-dvi): Remove.
+ (mostlyclean): Does not depend upon clean-info or clean-dvi,
+ rules completely rewritten.
+ (maintainer-clean): Remove clean-info and clean-dvi
+ dependencies and put their actions in the rules.
+ (gdb.ps): New target
+ (gdb.dvi, gdbgui.dvi, gdbint.dvi, stabs.dvi): Remove
+ intermediate TeX files, whether they have 2 or 3 character
+ extensions.
+ (gdbint.ps): Add target and rules.
+ (gdb-internals): Delete unused target.
+ (Makefile): Depends upon config.status also.
+
+Sat Mar 30 15:46:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (CC_HAS_LONG_LONG): Clarify when/how this is
+ set.
+
Sat Mar 16 15:10:20 1996 Fred Fish <fnf@cygnus.com>
From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
@@ -27,6 +289,11 @@ Fri Dec 8 21:08:44 1995 Fred Fish <fnf@cygnus.com>
* gdbint.texinfo (Releases): Change gdb.tar.Z to gdb.tar.gz.
Fix typo.
+Fri Dec 1 11:07:50 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (Releases): Make "gdb.tar.gz" rather than
+ "gdb.tar.Z".
+
Wed Sep 20 13:14:10 1995 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (maintainer-clean): New target, synonym for
diff --git a/contrib/gdb/gdb/doc/GDBvn.texi b/contrib/gdb/gdb/doc/GDBvn.texi
index f90e24d..fd722bd 100644
--- a/contrib/gdb/gdb/doc/GDBvn.texi
+++ b/contrib/gdb/gdb/doc/GDBvn.texi
@@ -1 +1 @@
-@set GDBVN 4.16
+@set GDBVN 4.18
diff --git a/contrib/gdb/gdb/doc/HPPA-cfg.texi b/contrib/gdb/gdb/doc/HPPA-cfg.texi
new file mode 100644
index 0000000..88a138c
--- /dev/null
+++ b/contrib/gdb/gdb/doc/HPPA-cfg.texi
@@ -0,0 +1,114 @@
+@c GDB MANUAL configuration file.
+@c Copyright (c) 1993 Free Software Foundation, Inc.
+@c
+@c NOTE: While the GDB manual is configurable (by changing these
+@c switches), its configuration is ***NOT*** automatically tied in to
+@c source configuration---because the authors expect that, save in
+@c unusual cases, the most inclusive form of the manual is appropriate
+@c no matter how the program itself is configured.
+@c
+@c The only automatically-varying variable is the GDB version number,
+@c which the Makefile rewrites based on the VERSION variable from
+@c `../Makefile.in'.
+@c
+@c GDB version number is recorded in the variable GDBVN
+@include GDBvn.texi
+@c
+@c ----------------------------------------------------------------------
+@c PLATFORM FLAGS:
+@clear GENERIC
+@c
+@c HP PA-RISC target:
+@set HPPA
+@c
+@c Hitachi H8/300 target:
+@clear H8
+@c Hitachi H8/300 target ONLY:
+@clear H8EXCLUSIVE
+@c
+@c remote MIPS target:
+@clear MIPS
+@c
+@c SPARC target:
+@clear SPARC
+@c
+@c AMD 29000 target:
+@clear AMD29K
+@c
+@c Intel 960 target:
+@clear I960
+@c
+@c Tandem ST2000 (phone switch) target:
+@clear ST2000
+@c
+@c Zilog 8000 target:
+@clear Z8K
+@c
+@c Wind River Systems VxWorks environment:
+@clear VXWORKS
+@c
+@c ----------------------------------------------------------------------
+@c DOC FEATURE FLAGS:
+@c
+@c Bare-board target?
+@clear BARETARGET
+@c
+@c Restrict languages discussed to C?
+@c This is backward. As time permits, change this to language-specific
+@c switches for what to include.
+@clear CONLY
+@c Discuss Fortran?
+@clear FORTRAN
+@c
+@c Discuss Modula 2?
+@clear MOD2
+@c
+@c Specifically for host machine running DOS?
+@clear DOSHOST
+@c
+@c Talk about CPU simulator targets?
+@clear SIMS
+@c
+@c Remote serial line settings of interest?
+@set SERIAL
+@c
+@c Discuss features requiring Posix or similar OS environment?
+@set POSIX
+@c
+@c Discuss remote serial debugging stub?
+@clear REMOTESTUB
+@c
+@c Discuss gdbserver?
+@set GDBSERVER
+@c
+@c Discuss gdbserve.nlm?
+@set GDBSERVE
+@c
+@c Refrain from discussing how to configure sw and format doc?
+@clear PRECONFIGURED
+@c
+@c Refrain from referring to unfree publications?
+@set FSFDOC
+@c
+@c ----------------------------------------------------------------------
+@c STRINGS:
+@c
+@c Name of GDB program. Used also for (gdb) prompt string.
+@set GDBP gdb
+@c
+@c Name of GDB product. Used in running text.
+@set GDBN GDB
+@c
+@c Name of target.
+@set TARGET HP 9000 Systems
+@c
+@c Name of host. Should not be used in generic configs, but generic
+@c value may catch some flubs.
+@set HOST machine specific
+@c
+@c Name of GCC product
+@set NGCC GCC
+@c
+@c Name of GCC program
+@set GCC gcc
+
diff --git a/contrib/gdb/gdb/doc/LRS b/contrib/gdb/gdb/doc/LRS
new file mode 100644
index 0000000..7e25d43
--- /dev/null
+++ b/contrib/gdb/gdb/doc/LRS
@@ -0,0 +1,197 @@
+What's LRS?
+===========
+
+LRS, or Live Range Splitting is an optimization technique which allows
+a user variable to reside in different locations during different parts
+of a function.
+
+For example, a variable might reside in the stack for part of a function
+and in a register during a loop and in a different register during
+another loop.
+
+Clearly, if a variable may reside in different locations, then the
+compiler must describe to the debugger where the variable resides for
+any given part of the function.
+
+This document describes the debug format for encoding these extensions
+in stabs.
+
+Since these extensions are gcc specific, these additional symbols and
+stabs can be disabled by the gcc command option -gstabs.
+
+
+GNU extensions for LRS under stabs:
+===================================
+
+
+range symbols:
+-------------
+
+ A range symbol will be used to mark the beginning or end of a
+ live range (the range which describes where a symbol is active,
+ or live). These symbols will later be referenced in the stabs for
+ debug purposes. For simplicity, we'll use the terms "range_start"
+ and "range_end" to identify the range symbols which mark the beginning
+ and end of a live range respectively.
+
+ Any text symbol which would normally appear in the symbol table
+ (eg. a function name) can be used as range symbol. If an address
+ is needed to delimit a live range and does not match any of the
+ values of symbols which would normally appear in the symbol table,
+ a new symbol will be added to the table whose value is that address.
+
+ The three new symbol types described below have been added for this
+ purpose.
+
+ For efficiency, the compiler should use existing symbols as range
+ symbols whenever possible; this reduces the number of additional
+ symbols which need to be added to the symbol table.
+
+
+New debug symbol type for defining ranges:
+------------------------------------------
+
+ range_off - contains PC function offset for start/end of a live range.
+ Its location is relative to the function start and therefore
+ eliminates the need for additional relocation.
+
+ This symbol has a values in the text section, and does not have a name.
+
+ NOTE: the following may not be needed but are included here just
+ in case.
+ range - contains PC value of beginning or end of a live range
+ (relocs required).
+
+ NOTE: the following will be required if we desire LRS debugging
+ to work with old style a.out stabs.
+ range_abs - contains absolute PC value of start/end of a live
+ range. The range_abs debug symbol is provided for
+ completeness, in case there is a need to describe addresses
+ in ROM, etc.
+
+
+Live range:
+-----------
+
+ The compiler and debugger view a variable with multiple homes as
+ a primary symbol and aliases for that symbol. The primary symbol
+ describes the default home of the variable while aliases describe
+ alternate homes for the variable.
+
+ A live range defines the interval of instructions beginning with
+ range_start and ending at range_end-1, and is used to specify a
+ range of instructions where an alias is active or "live". So,
+ the actual end of the range will be one less than the value of the
+ range_end symbol.
+
+ Ranges do not have to be nested. Eg. Two ranges may intersect while
+ each range contains subranges which are not in the other range.
+
+ There does not have to be a 1-1 mapping from range_start to
+ range_end symbols. Eg. Two range_starts can share the same
+ range_end, while one symbol's range_start can be another symbol's
+ range_end.
+
+ When a variable's storage class changes (eg. from stack to register,
+ or from one register to another), a new symbol entry will be
+ added to the symbol table with stabs describing the new type,
+ and appropriate live ranges refering to the variable's initial
+ symbol index.
+
+ For variables which are defined in the source but optimized away,
+ a symbol should be emitted with the live range l(0,0).
+
+ Live ranges for aliases of a particular variable should always
+ be disjoint. Overlapping ranges for aliases of the same variable
+ will be treated as an error by the debugger, and the overlapping
+ range will be ignored.
+
+ If no live range information is given, the live range will be assumed to
+ span the symbol's entire lexical scope.
+
+
+New stabs string identifiers:
+-----------------------------
+
+ "id" in "#id" in the following section refers to a numeric value.
+
+ New stab syntax for live range: l(<ref_from>,<ref_to>)
+
+ <ref_from> - "#id" where #id identifies the text symbol (range symbol) to
+ use as the start of live range (range_start). The value for
+ the referenced text symbol is the starting address of the
+ live range.
+
+ <ref_to> - "#id" where #id identifies the text symbol (range symbol) to
+ use as the end of live range (range_end). The value for
+ the referenced text symbol is ONE BYTE PAST the ending
+ address of the live range.
+
+
+ New stab syntax for identifying symbols.
+
+ <def> - "#id="
+
+ Uses:
+ <def><name>:<typedef1>...
+ When used in front of a symbol name, "#id=" defines a
+ unique reference number for this symbol. The reference
+ number can be used later when defining aliases for this
+ symbol.
+ <def>
+ When used as the entire stab string, "#id=" identifies this
+ nameless symbol as being the symbol for which "#id" refers to.
+
+
+ <ref> - "#id" where "#id" refers to the symbol for which the string
+ "#id=" identifies.
+ Uses:
+ <ref>:<typedef2>;<liverange>;<liverange>...
+ Defines an alias for the symbol identified by the reference
+ number ID.
+ l(<ref1>,<ref2>)
+ When used within a live range, "#id" refers to the text
+ symbol identified by "#id=" to use as the range symbol.
+
+ <liverange> - "l(<ref_from>,<ref_to>)" - specifies a live range for a
+ symbol. Multiple "l" specifiers can be combined to represent
+ mutiple live ranges, separated by semicolons.
+
+
+
+
+Example:
+========
+
+Consider a program of the form:
+
+ void foo(){
+ int a = ...;
+ ...
+ while (b--)
+ c += a;
+ ..
+ d = a;
+ ..
+ }
+
+Assume that "a" lives in the stack at offset -8, except for inside the
+loop where "a" resides in register "r5".
+
+The way to describe this is to create a stab for the variable "a" which
+describes "a" as living in the stack and an alias for the variable "a"
+which describes it as living in register "r5" in the loop.
+
+Let's assume that "#1" and "#2" are symbols which bound the area where
+"a" lives in a register.
+
+The stabs to describe "a" and its alias would look like this:
+
+ .stabs "#3=a:1",128,0,8,-8
+ .stabs "#3:r1;l(#1,#2)",64,0,0,5
+
+
+This design implies that the debugger will keep a chain of aliases for
+any given variable with aliases and that chain will be searched first
+to find out if an alias is active. If no alias is active, then the
+debugger will assume that the main variable is active.
diff --git a/contrib/gdb/gdb/doc/Makefile.in b/contrib/gdb/gdb/doc/Makefile.in
index 385b444..4bcd62e 100644
--- a/contrib/gdb/gdb/doc/Makefile.in
+++ b/contrib/gdb/gdb/doc/Makefile.in
@@ -1,4 +1,4 @@
-##Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+##Copyright (C) 1991, 1992, 1999 Free Software Foundation, Inc.
# Makefile for GDB documentation.
# This file is part of GDB.
@@ -17,17 +17,18 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-srcdir = .
+srcdir = @srcdir@
+VPATH = @srcdir@
-prefix = /usr/local
+prefix = @prefix@
-infodir = $(prefix)/info
+infodir = @infodir@
-SHELL = /bin/sh
+SHELL = @SHELL@
-INSTALL = install -c
-INSTALL_PROGRAM = $(INSTALL)
-INSTALL_DATA = $(INSTALL)
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
# main GDB source directory
gdbdir = $(srcdir)/..
@@ -74,6 +75,9 @@ TEX = tex
# auxiliary program for sorting Texinfo indices
TEXINDEX = texindex
+# Program to generate Postscript files from DVI files.
+DVIPS = dvips
+
# Main GDB manual's source files
SFILES_INCLUDED = gdb-cfg.texi $(srcdir)/remote.texi
@@ -88,15 +92,16 @@ SFILES_DOC = $(SFILES_LOCAL) \
all install:
info: gdb.info gdbint.info stabs.info
-dvi: gdb.dvi refcard.dvi gdbint.dvi
-all-doc: gdb.info gdb.dvi refcard.dvi gdb-internals gdbint.dvi
+dvi: gdb.dvi gdbint.dvi stabs.dvi refcard.dvi
+ps: gdb.ps gdbint.ps stabs.ps refcard.ps
+all-doc: info dvi ps
install-info: info
for i in *.info* ; do \
$(INSTALL_DATA) $$i $(infodir)/$$i ; \
done
-STAGESTUFF = *.info* gdb-all.texi GDBvn.texi
+STAGESTUFF = *.info* gdb-all.texi GDBvn.texi *.ps *.dvi
# Copy the object files from a particular stage into a subdirectory.
stage1: force
@@ -128,17 +133,13 @@ de-stage3: force
-(cd stage3 ; mv -f * ..)
-rmdir stage3
-clean-info:
- rm -f gdb.info* gdbint.info* stabs.info*
-
-clean-dvi:
- rm -f gdb.dvi gdbint.dvi stabs.dvi sedref.dvi
-
-mostlyclean: clean-info clean-dvi
- rm -f gdb.?? gdb.??? gdb.mm gdb.ms gdb.me
- rm -f links2roff
- rm -f refcard.ps lrefcard.ps refcard.log sedref.* *~
- rm -f gdbint.?? gdbint.??? stabs.?? stabs.???
+# The "least clean" level of cleaning. Get rid of files which are
+# automatically generated files that are just intermediate files,
+#
+mostlyclean:
+ rm -f gdb.mm gdb.ms gdb.me links2roff
+ rm -f *.aux *.cp* *.fn* *.ky* *.log *.pg* *.toc *.tp* *.vr*
+ rm -f sedref.dvi sedref.tex tmp.sed
clean: mostlyclean
rm -f rluser.texinfo inc-hist.texi gdb-cfg.texi
@@ -146,10 +147,12 @@ clean: mostlyclean
distclean: clean
rm -f Makefile config.status
-# GDBvn.texi and refcard.dvi are distributed, so they should not be
-# removed by "clean" or "distclean".
-maintainer-clean realclean: distclean clean-dvi clean-info
- rm -f GDBvn.texi refcard.dvi
+# GDBvn.texi, the dvi files, the info files, and the postscript files,
+# are all part of the distribution, so it should not be removed by
+# "clean" or "distclean". Use maintainer-clean to remove them.
+
+maintainer-clean realclean: distclean
+ rm -f GDBvn.texi *.info* *.dvi *.ps
# GDB QUICK REFERENCE (dvi output)
refcard.dvi : refcard.tex $(REFEDITS)
@@ -166,11 +169,11 @@ refcard.dvi : refcard.tex $(REFEDITS)
rm -f sedref.log sedref.tex tmp.sed
refcard.ps : refcard.dvi
- dvips -t landscape refcard.dvi -o
+ $(DVIPS) -t landscape -o $@ $?
# File to record current GDB version number (copied from main dir Makefile.in)
GDBvn.texi : ${gdbdir}/Makefile.in
- echo "@set GDBVN `sed <$(srcdir)/../Makefile.in -n 's/VERSION = //p'`" > ./GDBvn.new
+ echo "@set GDBVN `sed <$(srcdir)/../Makefile.in -n 's/^VERSION *= *//p'`" > ./GDBvn.new
mv GDBvn.new GDBvn.texi
# Updated atomically
@@ -204,7 +207,11 @@ gdb.dvi: ${SFILES_DOC}
$(SET_TEXINPUTS) $(TEX) gdb.texinfo
$(TEXINDEX) gdb.??
$(SET_TEXINPUTS) $(TEX) gdb.texinfo
- rm -f gdb.?? gdb.log gdb.aux gdb.toc gdb.??s
+ rm -f gdb.aux gdb.cp* gdb.fn* gdb.ky* gdb.log gdb.pg* gdb.toc \
+ gdb.tp* gdb.vr*
+
+gdb.ps: gdb.dvi
+ $(DVIPS) -o $@ $?
# GDB MANUAL: info file
# We're using texinfo2, and older makeinfo's may not be able to
@@ -302,11 +309,13 @@ gdbint.dvi : gdbint.texinfo
$(SET_TEXINPUTS) $(TEX) gdbint.texinfo
$(TEXINDEX) gdbint.??
$(SET_TEXINPUTS) $(TEX) gdbint.texinfo
- rm -f gdbint.?? gdbint.aux gdbint.cps gdbint.fns gdbint.kys \
- gdbint.log gdbint.pgs gdbint.toc gdbint.tps gdbint.vrs
+ rm -f gdbint.aux gdbint.cp* gdbint.fn* gdbint.ky* \
+ gdbint.log gdbint.pg* gdbint.toc gdbint.tp* gdbint.vr*
+
+gdbint.ps : gdbint.dvi
+ $(DVIPS) -o $@ $?
# GDB INTERNALS MANUAL: info file
-gdb-internals: gdbint.info
gdbint.info: gdbint.texinfo
$(MAKEINFO) -o gdbint.info $(srcdir)/gdbint.texinfo
@@ -319,13 +328,13 @@ stabs.dvi : stabs.texinfo
$(SET_TEXINPUTS) $(TEX) stabs.texinfo
$(TEXINDEX) stabs.??
$(SET_TEXINPUTS) $(TEX) stabs.texinfo
- rm -f stabs.?? stabs.aux stabs.cps stabs.fns stabs.kys \
- stabs.log stabs.pgs stabs.toc stabs.tps stabs.vrs
+ rm -f stabs.aux stabs.cp* stabs.fn* stabs.ky* \
+ stabs.log stabs.pg* stabs.toc stabs.tp* stabs.vr*
stabs.ps: stabs.dvi
- dvips -o stabs.ps stabs
+ $(DVIPS) -o $@ $?
force:
-Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+Makefile: Makefile.in $(host_makefile_frag) $(target_makefile_frag) config.status
$(SHELL) ./config.status
diff --git a/contrib/gdb/gdb/doc/agentexpr.texi b/contrib/gdb/gdb/doc/agentexpr.texi
new file mode 100644
index 0000000..8484aa2
--- /dev/null
+++ b/contrib/gdb/gdb/doc/agentexpr.texi
@@ -0,0 +1,839 @@
+\input texinfo
+@c %**start of header
+@setfilename agentexpr.info
+@settitle GDB Agent Expressions
+@setchapternewpage off
+@c %**end of header
+
+Revision: $Id: agentexpr.texi,v 1.2 1998/12/09 21:23:46 jimb Exp $
+
+@node The GDB Agent Expression Mechanism
+@chapter The GDB Agent Expression Mechanism
+
+In some applications, it is not feasable for the debugger to interrupt
+the program's execution long enough for the developer to learn anything
+helpful about its behavior. If the program's correctness depends on its
+real-time behavior, delays introduced by a debugger might cause the
+program to fail, even when the code itself is correct. It is useful to
+be able to observe the program's behavior without interrupting it.
+
+Using GDB's @code{trace} and @code{collect} commands, the user can
+specify locations in the program, and arbitrary expressions to evaluate
+when those locations are reached. Later, using the @code{tfind}
+command, she can examine the values those expressions had when the
+program hit the trace points. The expressions may also denote objects
+in memory --- structures or arrays, for example --- whose values GDB
+should record; while visiting a particular tracepoint, the user may
+inspect those objects as if they were in memory at that moment.
+However, because GDB records these values without interacting with the
+user, it can do so quickly and unobtrusively, hopefully not disturbing
+the program's behavior.
+
+When GDB is debugging a remote target, the GDB @dfn{agent} code running
+on the target computes the values of the expressions itself. To avoid
+having a full symbolic expression evaluator on the agent, GDB translates
+expressions in the source language into a simpler bytecode language, and
+then sends the bytecode to the agent; the agent then executes the
+bytecode, and records the values for GDB to retrieve later.
+
+The bytecode language is simple; there are forty-odd opcodes, the bulk
+of which are the usual vocabulary of C operands (addition, subtraction,
+shifts, and so on) and various sizes of literals and memory reference
+operations. The bytecode interpreter operates strictly on machine-level
+values --- various sizes of integers and floating point numbers --- and
+requires no information about types or symbols; thus, the interpreter's
+internal data structures are simple, and each bytecode requires only a
+few native machine instructions to implement it. The interpreter is
+small, and strict limits on the memory and time required to evaluate an
+expression are easy to determine, making it suitable for use by the
+debugging agent in real-time applications.
+
+@menu
+* General Bytecode Design:: Overview of the interpreter.
+* Bytecode Descriptions:: What each one does.
+* Using Agent Expressions:: How agent expressions fit into the big picture.
+* Varying Target Capabilities:: How to discover what the target can do.
+* Tracing on Symmetrix:: Special info for implementation on EMC's
+ boxes.
+* Rationale:: Why we did it this way.
+@end menu
+
+
+@c @node Rationale
+@c @section Rationale
+
+
+@node General Bytecode Design
+@section General Bytecode Design
+
+The agent represents bytecode expressions as an array of bytes. Each
+instruction is one byte long (thus the term @dfn{bytecode}). Some
+instructions are followed by operand bytes; for example, the @code{goto}
+instruction is followed by a destination for the jump.
+
+The bytecode interpreter is a stack-based machine; most instructions pop
+their operands off the stack, perform some operation, and push the
+result back on the stack for the next instruction to consume. Each
+element of the stack may contain either a integer or a floating point
+value; these values are as many bits wide as the largest integer that
+can be directly manipulated in the source language. Stack elements
+carry no record of their type; bytecode could push a value as an
+integer, then pop it as a floating point value. However, GDB will not
+generate code which does this. In C, one might define the type of a
+stack element as follows:
+@example
+union agent_val @{
+ LONGEST l;
+ DOUBLEST d;
+@};
+@end example
+@noindent
+where @code{LONGEST} and @code{DOUBLEST} are @code{typedef} names for
+the largest integer and floating point types on the machine.
+
+By the time the bytecode interpreter reaches the end of the expression,
+the value of the expression should be the only value left on the stack.
+For tracing applications, @code{trace} bytecodes in the expression will
+have recorded the necessary data, and the value on the stack may be
+discarded. For other applications, like conditional breakpoints, the
+value may be useful.
+
+Separate from the stack, the interpreter has two registers:
+@table @code
+@item pc
+The address of the next bytecode to execute.
+
+@item start
+The address of the start of the bytecode expression, necessary for
+interpreting the @code{goto} and @code{if_goto} instructions.
+
+@end table
+@noindent
+Neither of these registers is directly visible to the bytecode language
+itself, but they are useful for defining the meanings of the bytecode
+operations.
+
+There are no instructions to perform side effects on the running
+program, or call the program's functions; we assume that these
+expressions are only used for unobtrusive debugging, not for patching
+the running code.
+
+Most bytecode instructions do not distinguish between the various sizes
+of values, and operate on full-width values; the upper bits of the
+values are simply ignored, since they do not usually make a difference
+to the value computed. The exceptions to this rule are:
+@table @asis
+
+@item memory reference instructions (@code{ref}@var{n})
+There are distinct instructions to fetch different word sizes from
+memory. Once on the stack, however, the values are treated as full-size
+integers. They may need to be sign-extended; the @code{ext} instruction
+exists for this purpose.
+
+@item the sign-extension instruction (@code{ext} @var{n})
+These clearly need to know which portion of their operand is to be
+extended to occupy the full length of the word.
+
+@end table
+
+If the interpreter is unable to evaluate an expression completely for
+some reason (a memory location is inaccessible, or a divisor is zero,
+for example), we say that interpretation ``terminates with an error''.
+This means that the problem is reported back to the interpreter's caller
+in some helpful way. In general, code using agent expressions should
+assume that they may attempt to divide by zero, fetch arbitrary memory
+locations, and misbehave in other ways.
+
+Even complicated C expressions compile to a few bytecode instructions;
+for example, the expression @code{x + y * z} would typically produce
+code like the following, assuming that @code{x} and @code{y} live in
+registers, and @code{z} is a global variable holding a 32-bit
+@code{int}:
+@example
+reg 1
+reg 2
+const32 @i{address of z}
+ref32
+ext 32
+mul
+add
+end
+@end example
+
+In detail, these mean:
+@table @code
+
+@item reg 1
+Push the value of register 1 (presumably holding @code{x}) onto the
+stack.
+
+@item reg 2
+Push the value of register 2 (holding @code{y}).
+
+@item const32 @i{address of z}
+Push the address of @code{z} onto the stack.
+
+@item ref32
+Fetch a 32-bit word from the address at the top of the stack; replace
+the address on the stack with the value. Thus, we replace the address
+of @code{z} with @code{z}'s value.
+
+@item ext 32
+Sign-extend the value on the top of the stack from 32 bits to full
+length. This is necessary because @code{z} is a signed integer.
+
+@item mul
+Pop the top two numbers on the stack, multiply them, and push their
+product. Now the top of the stack contains the value of the expression
+@code{y * z}.
+
+@item add
+Pop the top two numbers, add them, and push the sum. Now the top of the
+stack contains the value of @code{x + y * z}.
+
+@item end
+Stop executing; the value left on the stack top is the value to be
+recorded.
+
+@end table
+
+
+@node Bytecode Descriptions
+@section Bytecode Descriptions
+
+Each bytecode description has the following form:
+
+@table @asis
+
+@item @code{add} (0x02): @var{a} @var{b} @result{} @var{a+b}
+
+Pop the top two stack items, @var{a} and @var{b}, as integers; push
+their sum, as an integer.
+
+@end table
+
+In this example, @code{add} is the name of the bytecode, and
+@code{(0x02)} is the one-byte value used to encode the bytecode, in
+hexidecimal. The phrase ``@var{a} @var{b} @result{} @var{a+b}'' shows
+the stack before and after the bytecode executes. Beforehand, the stack
+must contain at least two values, @var{a} and @var{b}; since the top of
+the stack is to the right, @var{b} is on the top of the stack, and
+@var{a} is underneath it. After execution, the bytecode will have
+popped @var{a} and @var{b} from the stack, and replaced them with a
+single value, @var{a+b}. There may be other values on the stack below
+those shown, but the bytecode affects only those shown.
+
+Here is another example:
+
+@table @asis
+
+@item @code{const8} (0x22) @var{n}: @result{} @var{n}
+Push the 8-bit integer constant @var{n} on the stack, without sign
+extension.
+
+@end table
+
+In this example, the bytecode @code{const8} takes an operand @var{n}
+directly from the bytecode stream; the operand follows the @code{const8}
+bytecode itself. We write any such operands immediately after the name
+of the bytecode, before the colon, and describe the exact encoding of
+the operand in the bytecode stream in the body of the bytecode
+description.
+
+For the @code{const8} bytecode, there are no stack items given before
+the @result{}; this simply means that the bytecode consumes no values
+from the stack. If a bytecode consumes no values, or produces no
+values, the list on either side of the @result{} may be empty.
+
+If a value is written as @var{a}, @var{b}, or @var{n}, then the bytecode
+treats it as an integer. If a value is written is @var{addr}, then the
+bytecode treats it as an address.
+
+We do not fully describe the floating point operations here; although
+this design can be extended in a clean way to handle floating point
+values, they are not of immediate interest to the customer, so we avoid
+describing them, to save time.
+
+
+@table @asis
+
+@item @code{float} (0x01): @result{}
+
+Prefix for floating-point bytecodes. Not implemented yet.
+
+@item @code{add} (0x02): @var{a} @var{b} @result{} @var{a+b}
+Pop two integers from the stack, and push their sum, as an integer.
+
+@item @code{sub} (0x03): @var{a} @var{b} @result{} @var{a-b}
+Pop two integers from the stack, subtract the top value from the
+next-to-top value, and push the difference.
+
+@item @code{mul} (0x04): @var{a} @var{b} @result{} @var{a*b}
+Pop two integers from the stack, multiply them, and push the product on
+the stack. Note that, when one multiplies two @var{n}-bit numbers
+yielding another @var{n}-bit number, it is irrelevant whether the
+numbers are signed or not; the results are the same.
+
+@item @code{div_signed} (0x05): @var{a} @var{b} @result{} @var{a/b}
+Pop two signed integers from the stack; divide the next-to-top value by
+the top value, and push the quotient. If the divisor is zero, terminate
+with an error.
+
+@item @code{div_unsigned} (0x06): @var{a} @var{b} @result{} @var{a/b}
+Pop two unsigned integers from the stack; divide the next-to-top value
+by the top value, and push the quotient. If the divisor is zero,
+terminate with an error.
+
+@item @code{rem_signed} (0x07): @var{a} @var{b} @result{} @var{a modulo b}
+Pop two signed integers from the stack; divide the next-to-top value by
+the top value, and push the remainder. If the divisor is zero,
+terminate with an error.
+
+@item @code{rem_unsigned} (0x08): @var{a} @var{b} @result{} @var{a modulo b}
+Pop two unsigned integers from the stack; divide the next-to-top value
+by the top value, and push the remainder. If the divisor is zero,
+terminate with an error.
+
+@item @code{lsh} (0x09): @var{a} @var{b} @result{} @var{a<<b}
+Pop two integers from the stack; let @var{a} be the next-to-top value,
+and @var{b} be the top value. Shift @var{a} left by @var{b} bits, and
+push the result.
+
+@item @code{rsh_signed} (0x0a): @var{a} @var{b} @result{} @var{@code{(signed)}a>>b}
+Pop two integers from the stack; let @var{a} be the next-to-top value,
+and @var{b} be the top value. Shift @var{a} right by @var{b} bits,
+inserting copies of the top bit at the high end, and push the result.
+
+@item @code{rsh_unsigned} (0x0b): @var{a} @var{b} @result{} @var{a>>b}
+Pop two integers from the stack; let @var{a} be the next-to-top value,
+and @var{b} be the top value. Shift @var{a} right by @var{b} bits,
+inserting zero bits at the high end, and push the result.
+
+@item @code{log_not} (0x0e): @var{a} @result{} @var{!a}
+Pop an integer from the stack; if it is zero, push the value one;
+otherwise, push the value zero.
+
+@item @code{bit_and} (0x0f): @var{a} @var{b} @result{} @var{a&b}
+Pop two integers from the stack, and push their bitwise @code{and}.
+
+@item @code{bit_or} (0x10): @var{a} @var{b} @result{} @var{a|b}
+Pop two integers from the stack, and push their bitwise @code{or}.
+
+@item @code{bit_xor} (0x11): @var{a} @var{b} @result{} @var{a^b}
+Pop two integers from the stack, and push their bitwise
+exclusive-@code{or}.
+
+@item @code{bit_not} (0x12): @var{a} @result{} @var{~a}
+Pop an integer from the stack, and push its bitwise complement.
+
+@item @code{equal} (0x13): @var{a} @var{b} @result{} @var{a=b}
+Pop two integers from the stack; if they are equal, push the value one;
+otherwise, push the value zero.
+
+@item @code{less_signed} (0x14): @var{a} @var{b} @result{} @var{a<b}
+Pop two signed integers from the stack; if the next-to-top value is less
+than the top value, push the value one; otherwise, push the value zero.
+
+@item @code{less_unsigned} (0x15): @var{a} @var{b} @result{} @var{a<b}
+Pop two unsigned integers from the stack; if the next-to-top value is less
+than the top value, push the value one; otherwise, push the value zero.
+
+@item @code{ext} (0x16) @var{n}: @var{a} @result{} @var{a}, sign-extended from @var{n} bits
+Pop an unsigned value from the stack; treating it as an @var{n}-bit
+twos-complement value, extend it to full length. This means that all
+bits to the left of bit @var{n-1} (where the least significant bit is bit
+0) are set to the value of bit @var{n-1}. Note that @var{n} may be
+larger than or equal to the width of the stack elements of the bytecode
+engine; in this case, the bytecode should have no effect.
+
+The number of source bits to preserve, @var{n}, is encoded as a single
+byte unsigned integer following the @code{ext} bytecode.
+
+@item @code{zero_ext} (0x2a) @var{n}: @var{a} @result{} @var{a}, zero-extended from @var{n} bits
+Pop an unsigned value from the stack; zero all but the bottom @var{n}
+bits. This means that all bits to the left of bit @var{n-1} (where the
+least significant bit is bit 0) are set to the value of bit @var{n-1}.
+
+The number of source bits to preserve, @var{n}, is encoded as a single
+byte unsigned integer following the @code{zero_ext} bytecode.
+
+@item @code{ref8} (0x17): @var{addr} @result{} @var{a}
+@itemx @code{ref16} (0x18): @var{addr} @result{} @var{a}
+@itemx @code{ref32} (0x19): @var{addr} @result{} @var{a}
+@itemx @code{ref64} (0x1a): @var{addr} @result{} @var{a}
+Pop an address @var{addr} from the stack. For bytecode
+@code{ref}@var{n}, fetch an @var{n}-bit value from @var{addr}, using the
+natural target endianness. Push the fetched value as an unsigned
+integer.
+
+Note that @var{addr} may not be aligned in any particular way; the
+@code{ref@var{n}} bytecodes should operate correctly for any address.
+
+If attempting to access memory at @var{addr} would cause a processor
+exception of some sort, terminate with an error.
+
+@item @code{ref_float} (0x1b): @var{addr} @result{} @var{d}
+@itemx @code{ref_double} (0x1c): @var{addr} @result{} @var{d}
+@itemx @code{ref_long_double} (0x1d): @var{addr} @result{} @var{d}
+@itemx @code{l_to_d} (0x1e): @var{a} @result{} @var{d}
+@itemx @code{d_to_l} (0x1f): @var{d} @result{} @var{a}
+Not implemented yet.
+
+@item @code{dup} (0x28): @var{a} => @var{a} @var{a}
+Push another copy of the stack's top element.
+
+@item @code{swap} (0x2b): @var{a} @var{b} => @var{b} @var{a}
+Exchange the top two items on the stack.
+
+@item @code{pop} (0x29): @var{a} =>
+Discard the top value on the stack.
+
+@item @code{if_goto} (0x20) @var{offset}: @var{a} @result{}
+Pop an integer off the stack; if it is non-zero, branch to the given
+offset in the bytecode string. Otherwise, continue to the next
+instruction in the bytecode stream. In other words, if @var{a} is
+non-zero, set the @code{pc} register to @code{start} + @var{offset}.
+Thus, an offset of zero denotes the beginning of the expression.
+
+The @var{offset} is stored as a sixteen-bit unsigned value, stored
+immediately following the @code{if_goto} bytecode. It is always stored
+most signficant byte first, regardless of the target's normal
+endianness. The offset is not guaranteed to fall at any particular
+alignment within the bytecode stream; thus, on machines where fetching a
+16-bit on an unaligned address raises an exception, you should fetch the
+offset one byte at a time.
+
+@item @code{goto} (0x21) @var{offset}: @result{}
+Branch unconditionally to @var{offset}; in other words, set the
+@code{pc} register to @code{start} + @var{offset}.
+
+The offset is stored in the same way as for the @code{if_goto} bytecode.
+
+@item @code{const8} (0x22) @var{n}: @result{} @var{n}
+@itemx @code{const16} (0x23) @var{n}: @result{} @var{n}
+@itemx @code{const32} (0x24) @var{n}: @result{} @var{n}
+@itemx @code{const64} (0x25) @var{n}: @result{} @var{n}
+Push the integer constant @var{n} on the stack, without sign extension.
+To produce a small negative value, push a small twos-complement value,
+and then sign-extend it using the @code{ext} bytecode.
+
+The constant @var{n} is stored in the appropriate number of bytes
+following the @code{const}@var{b} bytecode. The constant @var{n} is
+always stored most significant byte first, regardless of the target's
+normal endianness. The constant is not guaranteed to fall at any
+particular alignment within the bytecode stream; thus, on machines where
+fetching a 16-bit on an unaligned address raises an exception, you
+should fetch @var{n} one byte at a time.
+
+@item @code{reg} (0x26) @var{n}: @result{} @var{a}
+Push the value of register number @var{n}, without sign extension. The
+registers are numbered following GDB's conventions.
+
+The register number @var{n} is encoded as a 16-bit unsigned integer
+immediately following the @code{reg} bytecode. It is always stored most
+signficant byte first, regardless of the target's normal endianness.
+The register number is not guaranteed to fall at any particular
+alignment within the bytecode stream; thus, on machines where fetching a
+16-bit on an unaligned address raises an exception, you should fetch the
+register number one byte at a time.
+
+@item @code{trace} (0x0c): @var{addr} @var{size} @result{}
+Record the contents of the @var{size} bytes at @var{addr} in a trace
+buffer, for later retrieval by GDB.
+
+@item @code{trace_quick} (0x0d) @var{size}: @var{addr} @result{} @var{addr}
+Record the contents of the @var{size} bytes at @var{addr} in a trace
+buffer, for later retrieval by GDB. @var{size} is a single byte
+unsigned integer following the @code{trace} opcode.
+
+This bytecode is equivalent to the sequence @code{dup const8 @var{size}
+trace}, but we provide it anyway to save space in bytecode strings.
+
+@item @code{trace16} (0x30) @var{size}: @var{addr} @result{} @var{addr}
+Identical to trace_quick, except that @var{size} is a 16-bit big-endian
+unsigned integer, not a single byte. This should probably have been
+named @code{trace_quick16}, for consistency.
+
+@item @code{end} (0x27): @result{}
+Stop executing bytecode; the result should be the top element of the
+stack. If the purpose of the expression was to compute an lvalue or a
+range of memory, then the next-to-top of the stack is the lvalue's
+address, and the top of the stack is the lvalue's size, in bytes.
+
+@end table
+
+
+@node Using Agent Expressions
+@section Using Agent Expressions
+
+Here is a sketch of a full non-stop debugging cycle, showing how agent
+expressions fit into the process.
+
+@itemize @bullet
+
+@item
+The user selects trace points in the program's code at which GDB should
+collect data.
+
+@item
+The user specifies expressions to evaluate at each trace point. These
+expressions may denote objects in memory, in which case those objects'
+contents are recorded as the program runs, or computed values, in which
+case the values themselves are recorded.
+
+@item
+GDB transmits the tracepoints and their associated expressions to the
+GDB agent, running on the debugging target.
+
+@item
+The agent arranges to be notified when a trace point is hit. Note that,
+on some systems, the target operating system is completely responsible
+for collecting the data; see @ref{Tracing on Symmetrix}.
+
+@item
+When execution on the target reaches a trace point, the agent evaluates
+the expressions associated with that trace point, and records the
+resulting values and memory ranges.
+
+@item
+Later, when the user selects a given trace event and inspects the
+objects and expression values recorded, GDB talks to the agent to
+retrieve recorded data as necessary to meet the user's requests. If the
+user asks to see an object whose contents have not been recorded, GDB
+reports an error.
+
+@end itemize
+
+
+@node Varying Target Capabilities
+@section Varying Target Capabilities
+
+Some targets don't support floating-point, and some would rather not
+have to deal with @code{long long} operations. Also, different targets
+will have different stack sizes, and different bytecode buffer lengths.
+
+Thus, GDB needs a way to ask the target about itself. We haven't worked
+out the details yet, but in general, GDB should be able to send the
+target a packet asking it to describe itself. The reply should be a
+packet whose length is explicit, so we can add new information to the
+packet in future revisions of the agent, without confusing old versions
+of GDB, and it should contain a version number. It should contain at
+least the following information:
+
+@itemize @bullet
+
+@item
+whether floating point is supported
+
+@item
+whether @code{long long} is supported
+
+@item
+maximum acceptable size of bytecode stack
+
+@item
+maximum acceptable length of bytecode expressions
+
+@item
+which registers are actually available for collection
+
+@item
+whether the target supports disabled tracepoints
+
+@end itemize
+
+
+
+@node Tracing on Symmetrix
+@section Tracing on Symmetrix
+
+This section documents the API used by the GDB agent to collect data on
+Symmetrix systems.
+
+Cygnus originally implemented these tracing features to help EMC
+Corporation debug their Symmetrix high-availability disk drives. The
+Symmetrix application code already includes substantial tracing
+facilities; the GDB agent for the Symmetrix system uses those facilities
+for its own data collection, via the API described here.
+
+@deftypefn Function DTC_RESPONSE adbg_find_memory_in_frame (FRAME_DEF *@var{frame}, char *@var{address}, char **@var{buffer}, unsigned int *@var{size})
+Search the trace frame @var{frame} for memory saved from @var{address}.
+If the memory is available, provide the address of the buffer holding
+it; otherwise, provide the address of the next saved area.
+
+@itemize @bullet
+
+@item
+If the memory at @var{address} was saved in @var{frame}, set
+@code{*@var{buffer}} to point to the buffer in which that memory was
+saved, set @code{*@var{size}} to the number of bytes from @var{address}
+that are saved at @code{*@var{buffer}}, and return
+@code{OK_TARGET_RESPONSE}. (Clearly, in this case, the function will
+always set @code{*@var{size}} to a value greater than zero.)
+
+@item
+If @var{frame} does not record any memory at @var{address}, set
+@code{*@var{size}} to the distance from @var{address} to the start of
+the saved region with the lowest address higher than @var{address}. If
+there is no memory saved from any higher address, set @code{*@var{size}}
+to zero. Return @code{NOT_FOUND_TARGET_RESPONSE}.
+@end itemize
+
+These two possibilities allow the caller to either retrieve the data, or
+walk the address space to the next saved area.
+@end deftypefn
+
+This function allows the GDB agent to map the regions of memory saved in
+a particular frame, and retrieve their contents efficiently.
+
+This function also provides a clean interface between the GDB agent and
+the Symmetrix tracing structures, making it easier to adapt the GDB
+agent to future versions of the Symmetrix system, and vice versa. This
+function searches all data saved in @var{frame}, whether the data is
+there at the request of a bytecode expression, or because it falls in
+one of the format's memory ranges, or because it was saved from the top
+of the stack. EMC can arbitrarily change and enhance the tracing
+mechanism, but as long as this function works properly, all collected
+memory is visible to GDB.
+
+The function itself is straightforward to implement. A single pass over
+the trace frame's stack area, memory ranges, and expression blocks can
+yield the address of the buffer (if the requested address was saved),
+and also note the address of the next higher range of memory, to be
+returned when the search fails.
+
+As an example, suppose the trace frame @code{f} has saved sixteen bytes
+from address @code{0x8000} in a buffer at @code{0x1000}, and thirty-two
+bytes from address @code{0xc000} in a buffer at @code{0x1010}. Here are
+some sample calls, and the effect each would have:
+
+@table @code
+
+@item adbg_find_memory_in_frame (f, (char*) 0x8000, &buffer, &size)
+This would set @code{buffer} to @code{0x1000}, set @code{size} to
+sixteen, and return @code{OK_TARGET_RESPONSE}, since @code{f} saves
+sixteen bytes from @code{0x8000} at @code{0x1000}.
+
+@item adbg_find_memory_in_frame (f, (char *) 0x8004, &buffer, &size)
+This would set @code{buffer} to @code{0x1004}, set @code{size} to
+twelve, and return @code{OK_TARGET_RESPONSE}, since @file{f} saves the
+twelve bytes from @code{0x8004} starting four bytes into the buffer at
+@code{0x1000}. This shows that request addresses may fall in the middle
+of saved areas; the function should return the address and size of the
+remainder of the buffer.
+
+@item adbg_find_memory_in_frame (f, (char *) 0x8100, &buffer, &size)
+This would set @code{size} to @code{0x3f00} and return
+@code{NOT_FOUND_TARGET_RESPONSE}, since there is no memory saved in
+@code{f} from the address @code{0x8100}, and the next memory available
+is at @code{0x8100 + 0x3f00}, or @code{0xc000}. This shows that request
+addresses may fall outside of all saved memory ranges; the function
+should indicate the next saved area, if any.
+
+@item adbg_find_memory_in_frame (f, (char *) 0x7000, &buffer, &size)
+This would set @code{size} to @code{0x1000} and return
+@code{NOT_FOUND_TARGET_RESPONSE}, since the next saved memory is at
+@code{0x7000 + 0x1000}, or @code{0x8000}.
+
+@item adbg_find_memory_in_frame (f, (char *) 0xf000, &buffer, &size)
+This would set @code{size} to zero, and return
+@code{NOT_FOUND_TARGET_RESPONSE}. This shows how the function tells the
+caller that no further memory ranges have been saved.
+
+@end table
+
+As another example, here is a function which will print out the
+addresses of all memory saved in the trace frame @code{frame} on the
+Symmetrix INLINES console:
+@example
+void
+print_frame_addresses (FRAME_DEF *frame)
+@{
+ char *addr;
+ char *buffer;
+ unsigned long size;
+
+ addr = 0;
+ for (;;)
+ @{
+ /* Either find out how much memory we have here, or discover
+ where the next saved region is. */
+ if (adbg_find_memory_in_frame (frame, addr, &buffer, &size)
+ == OK_TARGET_RESPONSE)
+ printp ("saved %x to %x\n", addr, addr + size);
+ if (size == 0)
+ break;
+ addr += size;
+ @}
+@}
+@end example
+
+Note that there is not necessarily any connection between the order in
+which the data is saved in the trace frame, and the order in which
+@code{adbg_find_memory_in_frame} will return those memory ranges. The
+code above will always print the saved memory regions in order of
+increasing address, while the underlying frame structure might store the
+data in a random order.
+
+[[This section should cover the rest of the Symmetrix functions the stub
+relies upon, too.]]
+
+@node Rationale
+@section Rationale
+
+Some of the design decisions apparent above are arguable.
+
+@table @b
+
+@item What about stack overflow/underflow?
+GDB should be able to query the target to discover its stack size.
+Given that information, GDB can determine at translation time whether a
+given expression will overflow the stack. But this spec isn't about
+what kinds of error-checking GDB ought to do.
+
+@item Why are you doing everything in LONGEST?
+
+Speed isn't important, but agent code size is; using LONGEST brings in a
+bunch of support code to do things like division, etc. So this is a
+serious concern.
+
+First, note that you don't need different bytecodes for different
+operand sizes. You can generate code without @emph{knowing} how big the
+stack elements actually are on the target. If the target only supports
+32-bit ints, and you don't send any 64-bit bytecodes, everything just
+works. The observation here is that the MIPS and the Alpha have only
+fixed-size registers, and you can still get C's semantics even though
+most instructions only operate on full-sized words. You just need to
+make sure everything is properly sign-extended at the right times. So
+there is no need for 32- and 64-bit variants of the bytecodes. Just
+implement everything using the largest size you support.
+
+GDB should certainly check to see what sizes the target supports, so the
+user can get an error earlier, rather than later. But this information
+is not necessary for correctness.
+
+
+@item Why don't you have @code{>} or @code{<=} operators?
+I want to keep the interpreter small, and we don't need them. We can
+combine the @code{less_} opcodes with @code{log_not}, and swap the order
+of the operands, yielding all four asymmetrical comparison operators.
+For example, @code{(x <= y)} is @code{! (x > y)}, which is @code{! (y <
+x)}.
+
+@item Why do you have @code{log_not}?
+@itemx Why do you have @code{ext}?
+@itemx Why do you have @code{zero_ext}?
+These are all easily synthesized from other instructions, but I expect
+them to be used frequently, and they're simple, so I include them to
+keep bytecode strings short.
+
+@code{log_not} is equivalent to @code{const8 0 equal}; it's used in half
+the relational operators.
+
+@code{ext @var{n}} is equivalent to @code{const8 @var{s-n} lsh const8
+@var{s-n} rsh_signed}, where @var{s} is the size of the stack elements;
+it follows @code{ref@var{m}} and @var{reg} bytecodes when the value
+should be signed. See the next bulleted item.
+
+@code{zero_ext @var{n}} is equivalent to @code{const@var{m} @var{mask}
+log_and}; it's used whenever we push the value of a register, because we
+can't assume the upper bits of the register aren't garbage.
+
+@item Why not have sign-extending variants of the @code{ref} operators?
+Because that would double the number of @code{ref} operators, and we
+need the @code{ext} bytecode anyway for accessing bitfields.
+
+@item Why not have constant-address variants of the @code{ref} operators?
+Because that would double the number of @code{ref} operators again, and
+@code{const32 @var{address} ref32} is only one byte longer.
+
+@item Why do the @code{ref@var{n}} operators have to support unaligned fetches?
+GDB will generate bytecode that fetches multi-byte values at unaligned
+addresses whenever the executable's debugging information tells it to.
+Furthermore, GDB does not know the value the pointer will have when GDB
+generates the bytecode, so it cannot determine whether a particular
+fetch will be aligned or not.
+
+In particular, structure bitfields may be several bytes long, but follow
+no alignment rules; members of packed structures are not necessarily
+aligned either.
+
+In general, there are many cases where unaligned references occur in
+correct C code, either at the programmer's explicit request, or at the
+compiler's discretion. Thus, it is simpler to make the GDB agent
+bytecodes work correctly in all circumstances than to make GDB guess in
+each case whether the compiler did the usual thing.
+
+@item Why are there no side-effecting operators?
+Because our current client doesn't want them? That's a cheap answer. I
+think the real answer is that I'm afraid of implementing function
+calls. We should re-visit this issue after the present contract is
+delivered.
+
+@item Why aren't the @code{goto} ops PC-relative?
+The interpreter has the base address around anyway for PC bounds
+checking, and it seemed simpler.
+
+@item Why is there only one offset size for the @code{goto} ops?
+Offsets are currently sixteen bits. I'm not happy with this situation
+either:
+
+Suppose we have multiple branch ops with different offset sizes. As I
+generate code left-to-right, all my jumps are forward jumps (there are
+no loops in expressions), so I never know the target when I emit the
+jump opcode. Thus, I have to either always assume the largest offset
+size, or do jump relaxation on the code after I generate it, which seems
+like a big waste of time.
+
+I can imagine a reasonable expression being longer than 256 bytes. I
+can't imagine one being longer than 64k. Thus, we need 16-bit offsets.
+This kind of reasoning is so bogus, but relaxation is pathetic.
+
+The other approach would be to generate code right-to-left. Then I'd
+always know my offset size. That might be fun.
+
+@item Where is the function call bytecode?
+
+When we add side-effects, we should add this.
+
+@item Why does the @code{reg} bytecode take a 16-bit register number?
+
+Intel's IA64-architecture, Merced, has 128 general-purpose registers,
+and 128 floating-point registers, and I'm sure it has some random
+control registers.
+
+@item Why do we need @code{trace} and @code{trace_quick}?
+Because GDB needs to record all the memory contents and registers an
+expression touches. If the user wants to evaluate an expression
+@code{x->y->z}, the agent must record the values of @code{x} and
+@code{x->y} as well as the value of @code{x->y->z}.
+
+@item Don't the @code{trace} bytecodes make the interpreter less general?
+They do mean that the interpreter contains special-purpose code, but
+that doesn't mean the interpreter can only be used for that purpose. If
+an expression doesn't use the @code{trace} bytecodes, they don't get in
+its way.
+
+@item Why doesn't @code{trace_quick} consume its arguments the way everything else does?
+In general, you do want your operators to consume their arguments; it's
+consistent, and generally reduces the amount of stack rearrangement
+necessary. However, @code{trace_quick} is a kludge to save space; it
+only exists so we needn't write @code{dup const8 @var{SIZE} trace}
+before every memory reference. Therefore, it's okay for it not to
+consume its arguments; it's meant for a specific context in which we
+know exactly what it should do with the stack. If we're going to have a
+kludge, it should be an effective kludge.
+
+@item Why does @code{trace16} exist?
+That opcode was added by the customer that contracted Cygnus for the
+data tracing work. I personally think it is unnecessary; objects that
+large will be quite rare, so it is okay to use @code{dup const16
+@var{size} trace} in those cases.
+
+Whatever we decide to do with @code{trace16}, we should at least leave
+opcode 0x30 reserved, to remain compatible with the customer who added
+it.
+
+@end table
+
+@bye
diff --git a/contrib/gdb/gdb/doc/all-cfg.texi b/contrib/gdb/gdb/doc/all-cfg.texi
index 5b549c2..74d8090 100644
--- a/contrib/gdb/gdb/doc/all-cfg.texi
+++ b/contrib/gdb/gdb/doc/all-cfg.texi
@@ -18,6 +18,9 @@
@c PLATFORM FLAGS:
@set GENERIC
@c
+@c HP PA-RISC target ONLY:
+@clear HPPA
+@c
@c Hitachi H8/300 target:
@set H8
@c Hitachi H8/300 target ONLY:
@@ -28,6 +31,7 @@
@c
@c SPARC target:
@set SPARC
+@set SPARCLET
@c
@c AMD 29000 target:
@set AMD29K
@@ -41,18 +45,12 @@
@c Zilog 8000 target:
@set Z8K
@c
-@c Lucid "Energize" environment:
-@clear LUCID
-@c
@c Wind River Systems VxWorks environment:
@set VXWORKS
@c
@c ----------------------------------------------------------------------
@c DOC FEATURE FLAGS:
@c
-@c Include change-from-old?
-@set NOVEL
-@c
@c Bare-board target?
@clear BARETARGET
@c
@@ -72,9 +70,6 @@
@c Talk about CPU simulator targets?
@set SIMS
@c
-@c Is manual stand-alone, or part of an agglomeration, with overall GPL?
-@clear AGGLOMERATION
-@c
@c Remote serial line settings of interest?
@set SERIAL
@c
@@ -105,9 +100,6 @@
@c Name of GDB product. Used in running text.
@set GDBN GDB
@c
-@c Name of GDB initialization file.
-@set GDBINIT .gdbinit
-@c
@c Name of host. Should not be used in generic configs, but generic
@c value may catch some flubs.
@set HOST machine specific
diff --git a/contrib/gdb/gdb/doc/configure b/contrib/gdb/gdb/doc/configure
new file mode 100644
index 0000000..8c5591ce
--- /dev/null
+++ b/contrib/gdb/gdb/doc/configure
@@ -0,0 +1,862 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.2
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.2"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=refcard.tex
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:556: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.2"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/contrib/gdb/gdb/doc/configure.in b/contrib/gdb/gdb/doc/configure.in
index 1d2b47e..460efc2 100644
--- a/contrib/gdb/gdb/doc/configure.in
+++ b/contrib/gdb/gdb/doc/configure.in
@@ -1,7 +1,4 @@
-srcname="GDB doc"
-srctrigger=gdb.texinfo
-# per-host:
-# per-target:
-
-files=""
-links=""
+AC_PREREQ(2.12.1)
+AC_INIT(refcard.tex)
+AC_PROG_INSTALL
+AC_OUTPUT(Makefile)
diff --git a/contrib/gdb/gdb/doc/gdb.texinfo b/contrib/gdb/gdb/doc/gdb.texinfo
index 89bfa83..fc920bb 100644
--- a/contrib/gdb/gdb/doc/gdb.texinfo
+++ b/contrib/gdb/gdb/doc/gdb.texinfo
@@ -1,5 +1,5 @@
\input texinfo @c -*-texinfo-*-
-@c Copyright 1988 1989 1990 1991 1992 1993 1994 1995
+@c Copyright 1988-1999
@c Free Software Foundation, Inc.
@c
@c %**start of header
@@ -15,7 +15,6 @@
@ifclear GENERIC
@settitle Debugging with @value{GDBN} (@value{TARGET})
@end ifclear
-@clear RENAMED
@setchapternewpage odd
@c %**end of header
@@ -31,14 +30,10 @@
@syncodeindex vr cp
@c !!set GDB manual's edition---not the same as GDB version!
-@set EDITION 4.12
+@set EDITION Seventh
@c !!set GDB manual's revision date
-@set DATE January 1994
-
-@c GDB CHANGELOG CONSULTED BETWEEN:
-@c Fri Oct 11 23:27:06 1991 John Gilmore (gnu at cygnus.com)
-@c Sat Dec 22 02:51:40 1990 John Gilmore (gnu at cygint)
+@set DATE February 1999
@c THIS MANUAL REQUIRES TEXINFO-2 macros and info-makers to format properly.
@@ -57,12 +52,11 @@ END-INFO-DIR-ENTRY
This file documents the @sc{gnu} debugger @value{GDBN}.
-This is Edition @value{EDITION}, @value{DATE},
+This is the @value{EDITION} Edition, @value{DATE},
of @cite{Debugging with @value{GDBN}: the @sc{gnu} Source-Level Debugger}
for @value{GDBN} Version @value{GDBVN}.
-Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
-Free Software Foundation, Inc.
+Copyright (C) 1988-1999 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -91,28 +85,45 @@ into another language, under the above conditions for modified versions.
@subtitle (@value{TARGET})
@end ifclear
@sp 1
-@subtitle Edition @value{EDITION}, for @value{GDBN} version @value{GDBVN}
+@ifclear HPPA
+@subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN}
+@subtitle @value{DATE}
+@author Richard M. Stallman and Roland H. Pesch
+@end ifclear
+@ifset HPPA
+@subtitle Edition @value{EDITION}, for @value{HPVER} (based on @value{GDBN} @value{GDBVN})
@subtitle @value{DATE}
-@author Richard M. Stallman and Cygnus Support
+@author Richard M. Stallman and Roland H. Pesch (modified by HP)
+@end ifset
@page
+@ifclear HPPA
@tex
{\parskip=0pt
\hfill (Send bugs and comments on @value{GDBN} to bug-gdb\@prep.ai.mit.edu.)\par
\hfill {\it Debugging with @value{GDBN}}\par
\hfill \TeX{}info \texinfoversion\par
-\hfill doc\@cygnus.com\par
}
@end tex
+@end ifclear
+@ifset HPPA
+@tex
+{\parskip=0pt
+\hfill {\it Debugging with @value{GDBN}}\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+@end ifset
@vskip 0pt plus 1filll
-Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
-Free Software Foundation, Inc.
+Copyright @copyright{} 1988-1999 Free Software Foundation, Inc.
@sp 2
+@ifclear HPPA
Published by the Free Software Foundation @*
59 Temple Place - Suite 330, @*
Boston, MA 02111-1307 USA @*
Printed copies are available for $20 each. @*
ISBN 1-882114-11-6 @*
+@end ifclear
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -129,14 +140,15 @@ into another language, under the above conditions for modified versions.
@page
@ifinfo
-@node Top
+@node Top, Summary, (dir), (dir)
@top Debugging with @value{GDBN}
This file describes @value{GDBN}, the @sc{gnu} symbolic debugger.
-This is Edition @value{EDITION}, @value{DATE}, for @value{GDBN} Version
+This is the @value{EDITION} Edition, @value{DATE}, for @value{GDBN} Version
@value{GDBVN}.
+Copyright (C) 1988-1999 Free Software Foundation, Inc.
@menu
* Summary:: Summary of @value{GDBN}
@ifclear BARETARGET
@@ -153,10 +165,10 @@ This is Edition @value{EDITION}, @value{DATE}, for @value{GDBN} Version
@ifclear CONLY
* Languages:: Using @value{GDBN} with different languages
@end ifclear
+
@ifset CONLY
* C:: C language support
@end ifset
-@c remnant makeinfo bug, blank line needed after two end-ifs?
* Symbols:: Examining the symbol table
* Altering:: Altering execution
@@ -169,21 +181,269 @@ This is Edition @value{EDITION}, @value{DATE}, for @value{GDBN} Version
@end ifclear
* GDB Bugs:: Reporting bugs in @value{GDBN}
-* Command Line Editing:: Facilities of the readline library
-* Using History Interactively::
-@c @ifset NOVEL
-@c * Renamed Commands::
-@c @end ifset
+
@ifclear PRECONFIGURED
+@ifclear HPPA
* Formatting Documentation:: How to format and print @value{GDBN} documentation
-* Installing GDB:: Installing GDB
@end ifclear
+@end ifclear
+
+* Command Line Editing:: Command Line Editing
+* Using History Interactively:: Using History Interactively
+* Installing GDB:: Installing GDB
* Index:: Index
+
+ --- The Detailed Node Listing ---
+
+Summary of @value{GDBN}
+
+* Free Software:: Freely redistributable software
+* Contributors:: Contributors to GDB
+
+Getting In and Out of @value{GDBN}
+
+* Invoking GDB:: How to start @value{GDBN}
+* Quitting GDB:: How to quit @value{GDBN}
+* Shell Commands:: How to use shell commands inside @value{GDBN}
+
+Invoking @value{GDBN}
+
+* File Options:: Choosing files
+* Mode Options:: Choosing modes
+
+@value{GDBN} Commands
+
+* Command Syntax:: How to give commands to @value{GDBN}
+* Completion:: Command completion
+* Help:: How to ask @value{GDBN} for help
+
+Running Programs Under @value{GDBN}
+
+* Compilation:: Compiling for debugging
+* Starting:: Starting your program
+@ifclear BARETARGET
+* Arguments:: Your program's arguments
+* Environment:: Your program's environment
+@end ifclear
+
+* Working Directory:: Your program's working directory
+* Input/Output:: Your program's input and output
+* Attach:: Debugging an already-running process
+* Kill Process:: Killing the child process
+@ifclear HPPA
+* Process Information:: Additional process information
+@end ifclear
+
+* Threads:: Debugging programs with multiple threads
+* Processes:: Debugging programs with multiple processes
+
+Stopping and Continuing
+
+* Breakpoints:: Breakpoints, watchpoints, and catchpoints
+* Continuing and Stepping:: Resuming execution
+@ifset POSIX
+* Signals:: Signals
+@end ifset
+@ifclear BARETARGET
+* Thread Stops:: Stopping and starting multi-thread programs
+@end ifclear
+
+Breakpoints and watchpoints
+
+* Set Breaks:: Setting breakpoints
+* Set Watchpoints:: Setting watchpoints
+* Set Catchpoints:: Setting catchpoints
+* Delete Breaks:: Deleting breakpoints
+* Disabling:: Disabling breakpoints
+* Conditions:: Break conditions
+* Break Commands:: Breakpoint command lists
+@ifclear CONLY
+* Breakpoint Menus:: Breakpoint menus
+@end ifclear
+
+Examining the Stack
+
+* Frames:: Stack frames
+* Backtrace:: Backtraces
+* Selection:: Selecting a frame
+* Frame Info:: Information on a frame
+* Alpha/MIPS Stack:: Alpha and MIPS machines and the function stack
+
+Examining Source Files
+
+* List:: Printing source lines
+@ifclear DOSHOST
+* Search:: Searching source files
+@end ifclear
+* Source Path:: Specifying source directories
+* Machine Code:: Source and machine code
+
+Examining Data
+
+* Expressions:: Expressions
+* Variables:: Program variables
+* Arrays:: Artificial arrays
+* Output Formats:: Output formats
+* Memory:: Examining memory
+* Auto Display:: Automatic display
+* Print Settings:: Print settings
+* Value History:: Value history
+* Convenience Vars:: Convenience variables
+* Registers:: Registers
+@ifclear HAVE-FLOAT
+* Floating Point Hardware:: Floating point hardware
+@end ifclear
+
+Using @value{GDBN} with Different Languages
+
+* Setting:: Switching between source languages
+* Show:: Displaying the language
+@ifset MOD2
+* Checks:: Type and range checks
+@end ifset
+
+* Support:: Supported languages
+
+Switching between source languages
+
+* Filenames:: Filename extensions and languages.
+* Manually:: Setting the working language manually
+* Automatically:: Having @value{GDBN} infer the source language
+
+@ifset MOD2
+Type and range checking
+
+* Type Checking:: An overview of type checking
+* Range Checking:: An overview of range checking
+@end ifset
+
+Supported languages
+
+@ifset MOD2
+* C:: C and C++
+
+C Language Support
+
+* C Operators:: C operators
+
+C Language Support
+@end ifset
+
+* C Operators:: C and C++ operators
+* C Constants:: C and C++ constants
+* Cplus expressions:: C++ expressions
+* C Defaults:: Default settings for C and C++
+@ifset MOD2
+* C Checks:: C and C++ type and range checks
+@end ifset
+* Debugging C:: @value{GDBN} and C
+* Debugging C plus plus:: @value{GDBN} features for C++
+
+@ifset MOD2
+Modula-2
+
+* M2 Operators:: Built-in operators
+* Built-In Func/Proc:: Built-in functions and procedures
+* M2 Constants:: Modula-2 constants
+* M2 Defaults:: Default settings for Modula-2
+* Deviations:: Deviations from standard Modula-2
+* M2 Checks:: Modula-2 type and range checks
+* M2 Scope:: The scope operators @code{::} and @code{.}
+* GDB/M2:: @value{GDBN} and Modula-2
+@end ifset
+
+Altering Execution
+
+* Assignment:: Assignment to variables
+* Jumping:: Continuing at a different address
+@ifclear BARETARGET
+* Signaling:: Giving your program a signal
+@end ifclear
+* Returning:: Returning from a function
+* Calling:: Calling your program's functions
+* Patching:: Patching your program
+
+@value{GDBN} Files
+
+* Files:: Commands to specify files
+* Symbol Errors:: Errors reading symbol files
+
+Specifying a Debugging Target
+
+* Active Targets:: Active targets
+* Target Commands:: Commands for managing targets
+@ifclear HPPA
+* Byte Order:: Choosing target byte order
+* Remote:: Remote debugging
+
+Remote debugging
+@end ifclear
+
+@ifset REMOTESTUB
+* Remote Serial:: @value{GDBN} remote serial protocol
+@end ifset
+
+@ifset I960
+* i960-Nindy Remote:: @value{GDBN} with a remote i960 (Nindy)
+@end ifset
+
+@ifset AMD29K
+* UDI29K Remote:: The UDI protocol for AMD29K
+* EB29K Remote:: The EBMON protocol for AMD29K
+@end ifset
+
+@ifset VXWORKS
+* VxWorks Remote:: @value{GDBN} and VxWorks
+@end ifset
+
+@ifset ST2000
+* ST2000 Remote:: @value{GDBN} with a Tandem ST2000
+@end ifset
+
+@ifset H8
+* Hitachi Remote:: @value{GDBN} and Hitachi Microprocessors
+@end ifset
+
+@ifset MIPS
+* MIPS Remote:: @value{GDBN} and MIPS boards
+@end ifset
+
+@ifset SIMS
+* Simulator:: Simulated CPU target
+@end ifset
+
+Controlling @value{GDBN}
+
+* Prompt:: Prompt
+* Editing:: Command editing
+* History:: Command history
+* Screen Size:: Screen size
+* Numbers:: Numbers
+* Messages/Warnings:: Optional warnings and messages
+
+Canned Sequences of Commands
+
+* Define:: User-defined commands
+* Hooks:: User-defined command hooks
+* Command Files:: Command files
+* Output:: Commands for controlled output
+
+Reporting Bugs in @value{GDBN}
+
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+
+Installing @value{GDBN}
+
+* Separate Objdir:: Compiling @value{GDBN} in another directory
+* Config Names:: Specifying names for hosts and targets
+* Configure Options:: Summary of options for configure
@end menu
+
@end ifinfo
-@node Summary
+@node Summary, Sample Session, Top, Top
@unnumbered Summary of @value{GDBN}
The purpose of a debugger such as @value{GDBN} is to allow you to see what is
@@ -224,8 +484,8 @@ see @ref{Modula-2,,Modula-2}. There is no further documentation on Chill yet.
Debugging Pascal programs which use sets, subranges, file variables, or nested
functions does not currently work. @value{GDBN} does not support
entering expressions, printing values, or similar features using Pascal syntax.
-
@end ifset
+
@ifset FORTRAN
@cindex Fortran
@value{GDBN} can be used to debug programs written in Fortran, although
@@ -235,12 +495,21 @@ some variables with a trailing underscore.
@end ifset
@end ifclear
+@ifset HPPA
+This version of the manual documents HP Wildebeest (WDB) Version 0.75,
+implemented on HP 9000 systems running Release 10.20, 10.30, or 11.0 of
+the HP-UX operating system. HP WDB 0.75 can be used to debug code
+generated by the HP ANSI C and HP ANSI C++ compilers as well as the
+@sc{gnu} C and C++ compilers. It does not support the debugging of
+Fortran, Modula-2, or Chill programs.
+@end ifset
+
@menu
* Free Software:: Freely redistributable software
* Contributors:: Contributors to GDB
@end menu
-@node Free Software
+@node Free Software, Contributors, Summary, Summary
@unnumberedsec Free software
@value{GDBN} is @dfn{free software}, protected by the @sc{gnu}
@@ -256,16 +525,16 @@ Fundamentally, the General Public License is a license which says that
you have these freedoms and that you cannot take these freedoms away
from anyone else.
-@node Contributors
+@node Contributors, , Free Software, Summary
@unnumberedsec Contributors to GDB
-Richard Stallman was the original author of GDB, and of many other @sc{gnu}
-programs. Many others have contributed to its development. This
-section attempts to credit major contributors. One of the virtues of
-free software is that everyone is free to contribute to it; with
+Richard Stallman was the original author of GDB, and of many other
+@sc{gnu} programs. Many others have contributed to its development.
+This section attempts to credit major contributors. One of the virtues
+of free software is that everyone is free to contribute to it; with
regret, we cannot actually acknowledge everyone here. The file
-@file{ChangeLog} in the @value{GDBN} distribution approximates a blow-by-blow
-account.
+@file{ChangeLog} in the @value{GDBN} distribution approximates a
+blow-by-blow account.
Changes much prior to version 2.0 are lost in the mists of time.
@@ -275,17 +544,17 @@ or your friends (or enemies, to be evenhanded) have been unfairly
omitted from this list, we would like to add your names!
@end quotation
-So that they may not regard their long labor as thankless, we
-particularly thank those who shepherded GDB through major releases:
-Stan Shebs (release 4.14),
-Fred Fish (releases 4.13, 4.12, 4.11, 4.10, and 4.9),
-Stu Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4),
+So that they may not regard their many labors as thankless, we
+particularly thank those who shepherded @value{GDBN} through major
+releases:
+Jim Blandy (release 4.18);
+Jason Molenda (release 4.17);
+Stan Shebs (release 4.14);
+Fred Fish (releases 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, and 4.9);
+Stu Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4);
John Gilmore (releases 4.3, 4.2, 4.1, 4.0, and 3.9);
Jim Kingdon (releases 3.5, 3.4, and 3.3);
and Randy Smith (releases 3.2, 3.1, and 3.0).
-As major maintainer of @value{GDBN} for some period, each
-contributed significantly to the structure, stability, and capabilities
-of the entire debugger.
Richard Stallman, assisted at various times by Peter TerMaat, Chris
Hanson, and Richard Mlynarik, handled releases through 2.8.
@@ -304,6 +573,8 @@ Henkel-Wallace, Rich Pixley, Steve Chamberlain, and John Gilmore.
David Johnson wrote the original COFF support; Pace Willison did
the original support for encapsulated COFF.
+Brent Benson of Harris Computer Systems contributed DWARF 2 support.
+
Adam de Boor and Bradley Davis contributed the ISI Optimum V support.
Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS
support.
@@ -323,15 +594,18 @@ Tim Tucker contributed support for the Gould NP1 and Gould Powernode.
Pace Willison contributed Intel 386 support.
Jay Vosburgh contributed Symmetry support.
+Andreas Schwab contributed M68K Linux support.
+
Rich Schaefer and Peter Schauer helped with support of SunOS shared
libraries.
-Jay Fenlason and Roland McGrath ensured that @value{GDBN} and GAS agree about
-several machine instruction sets.
+Jay Fenlason and Roland McGrath ensured that @value{GDBN} and GAS agree
+about several machine instruction sets.
-Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped
-develop remote debugging. Intel Corporation and Wind River Systems
-contributed remote debugging modules for their products.
+Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped develop
+remote debugging. Intel Corporation, Wind River Systems, AMD, and ARM
+contributed remote debugging modules for the i960, VxWorks, A29K UDI,
+and RDI targets, respectively.
Brian Fox is the author of the readline libraries providing
command-line editing and command history.
@@ -348,18 +622,56 @@ He also enhanced the command-completion support to cover C++ overloaded
symbols.
@end ifclear
-Hitachi America, Ltd. sponsored the support for Hitachi microprocessors.
+Hitachi America, Ltd. sponsored the support for H8/300, H8/500, and
+Super-H processors.
+
+NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx processors.
+
+Mitsubishi sponsored the support for D10V, D30V, and M32R/D processors.
+
+Toshiba sponsored the support for the TX39 Mips processor.
+
+Matsushita sponsored the support for the MN10200 and MN10300 processors.
+
+Fujitsu sponsored the support for SPARClite and FR30 processors
Kung Hsu, Jeff Law, and Rick Sladkey added support for hardware
watchpoints.
+Michael Snyder added support for tracepoints.
+
Stu Grossman wrote gdbserver.
Jim Kingdon, Peter Schauer, Ian Taylor, and Stu Grossman made
nearly innumerable bug fixes and cleanups throughout GDB.
+The following people at the Hewlett-Packard Company contributed
+support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0
+(narrow mode), HP's implementation of kernel threads, HP's aC++
+compiler, and the terminal user interface: Ben Krepp, Richard Title,
+John Bishop, Susan Macchia, Kathy Mann, Satish Pai, India Paul, Steve
+Rehrauer, and Elena Zannoni. Kim Haase provided HP-specific
+information in this manual.
+
+Cygnus Solutions has sponsored GDB maintenance and much of its
+development since 1991. Cygnus engineers who have worked on GDB
+fulltime include Mark Alexander, Jim Blandy, Per Bothner, Edith Epstein,
+Chris Faylor, Fred Fish, Martin Hunt, Jim Ingham, John Gilmore, Stu
+Grossman, Kung Hsu, Jim Kingdon, John Metzler, Fernando Nasser, Geoffrey
+Noer, Dawn Perchik, Rich Pixley, Zdenek Radouch, Keith Seitz, Stan
+Shebs, David Taylor, and Elena Zannoni. In addition, Dave Brolley, Ian
+Carmichael, Steve Chamberlain, Nick Clifton, JT Conklin, Stan Cox, DJ
+Delorie, Ulrich Drepper, Frank Eigler, Doug Evans, Sean Fagan, David
+Henkel-Wallace, Richard Henderson, Jeff Holcomb, Jeff Law, Jim Lemke,
+Tom Lord, Bob Manson, Michael Meissner, Jason Merrill, Catherine Moore,
+Drew Moseley, Ken Raeburn, Gavin Romig-Koch, Rob Savoye, Jamie Smith,
+Mike Stump, Ian Taylor, Angela Thomas, Michael Tiemann, Tom Tromey, Ron
+Unrau, Jim Wilson, and David Zuhn have made contributions both large
+and small.
+
+
@ifclear BARETARGET
-@node Sample Session
+@node Sample Session, Invocation, Summary, Top
@chapter A Sample @value{GDBN} Session
You can use this manual at your leisure to read all about @value{GDBN}.
@@ -406,6 +718,7 @@ m4: End of input: 0: fatal error: EOF in string
@noindent
Let us use @value{GDBN} to try to see what is going on.
+@ifclear HPPA
@smallexample
$ @b{@value{GDBP} m4}
@c FIXME: this falsifies the exact text played out, to permit smallbook
@@ -416,9 +729,24 @@ $ @b{@value{GDBP} m4}
There is absolutely no warranty for @value{GDBN}; type "show warranty"
for details.
-@value{GDBN} @value{GDBVN}, Copyright 1995 Free Software Foundation, Inc...
+@value{GDBN} @value{GDBVN}, Copyright 1999 Free Software Foundation, Inc...
+(@value{GDBP})
+@end smallexample
+@end ifclear
+@ifset HPPA
+@smallexample
+$ @b{@value{GDBP} m4}
+Wildebeest is free software and you are welcome to distribute copies of
+it under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for Wildebeest; type "show warranty"
+for details.
+
+Hewlett-Packard Wildebeest 0.75 (based on GDB 4.16)
+(built for PA-RISC 1.1 or 2.0, HP-UX 10.20)
+Copyright 1996, 1997 Free Software Foundation, Inc.
(@value{GDBP})
@end smallexample
+@end ifset
@noindent
@value{GDBN} reads only enough symbol data to know where to find the
@@ -630,7 +958,7 @@ session with the @value{GDBN} @code{quit} command.
@end smallexample
@end ifclear
-@node Invocation
+@node Invocation, Commands, Sample Session, Top
@chapter Getting In and Out of @value{GDBN}
This chapter discusses how to start @value{GDBN}, and how to get out of it.
@@ -644,11 +972,11 @@ type @kbd{quit} or @kbd{C-d} to exit.
@menu
* Invoking GDB:: How to start @value{GDBN}
-* Quitting GDB:: How to quit @value{GDBN}
+* Quitting GDB:: How to quit @value{GDBN}
* Shell Commands:: How to use shell commands inside @value{GDBN}
@end menu
-@node Invoking GDB
+@node Invoking GDB, Quitting GDB, Invocation, Invocation
@section Invoking @value{GDBN}
@ifset H8EXCLUSIVE
@@ -696,17 +1024,19 @@ to debug a running process:
would attach @value{GDBN} to process @code{1234} (unless you also have a file
named @file{1234}; @value{GDBN} does check for a core file first).
+@ifclear HPPA
Taking advantage of the second command-line argument requires a fairly
complete operating system; when you use @value{GDBN} as a remote debugger
attached to a bare board, there may not be any notion of ``process'',
and there is often no way to get a core dump.
@end ifclear
+@end ifclear
You can run @code{gdb} without printing the front material, which describes
@value{GDBN}'s non-warranty, by specifying @code{-silent}:
@smallexample
-@value{GDBP} @var{-silent}
+@value{GDBP} -silent
@end smallexample
@noindent
@@ -753,6 +1083,9 @@ in sequential order. The order makes a difference when the
@ifset MIPS
* MIPS Remote:: @value{GDBN} and MIPS boards
@end ifset
+@ifset SPARCLET
+* Sparclet Remote:: @value{GDBN} and Sparclet boards
+@end ifset
@ifset SIMS
* Simulator:: Simulated CPU target
@end ifset
@@ -764,8 +1097,10 @@ in sequential order. The order makes a difference when the
@end menu
@ifclear GENERIC
+@ifclear HPPA
@include remote.texi
@end ifclear
+@end ifclear
@node File Options
@subsection Choosing files
@@ -833,6 +1168,7 @@ Files,, Command files}.
Add @var{directory} to the path to search for source files.
@ifclear BARETARGET
+@ifclear HPPA
@item -m
@itemx -mapped
@emph{Warning: this option depends on operating system facilities that are not
@@ -850,27 +1186,32 @@ The @file{.syms} file is specific to the host machine where @value{GDBN}
is run. It holds an exact image of the internal @value{GDBN} symbol
table. It cannot be shared across multiple host platforms.
@end ifclear
+@end ifclear
+@ifclear HPPA
@item -r
@itemx -readnow
Read each symbol file's entire symbol table immediately, rather than
the default, which is to read it incrementally as it is needed.
This makes startup slower, but makes future operations faster.
+@end ifclear
@end table
@ifclear BARETARGET
+@ifclear HPPA
The @code{-mapped} and @code{-readnow} options are typically combined in
order to build a @file{.syms} file that contains complete symbol
-information. (@xref{Files,,Commands to specify files}, for information
-
-a @file{.syms} file for future use is:
+information. (@xref{Files,,Commands to specify files}, for
+information on @file{.syms} files.) A simple GDB invocation to do
+nothing but build a @file{.syms} file for future use is:
@example
gdb -batch -nx -mapped -readnow programname
@end example
@end ifclear
+@end ifclear
-@node Mode Options
+@node Mode Options, , File Options, Invoking GDB
@subsection Choosing modes
You can run @value{GDBN} in various alternative modes---for example, in
@@ -880,9 +1221,9 @@ batch mode or quiet mode.
@item -nx
@itemx -n
Do not execute commands from any initialization files (normally called
-@file{@value{GDBINIT}}). Normally, the commands in these files are
-executed after all the command options and arguments have been
-processed. @xref{Command Files,,Command files}.
+@file{.gdbinit}, or @file{gdb.ini} on PCs). Normally, the commands in
+these files are executed after all the command options and arguments
+have been processed. @xref{Command Files,,Command files}.
@item -quiet
@itemx -q
@@ -912,16 +1253,6 @@ terminates) is not issued when running in batch mode.
Run @value{GDBN} using @var{directory} as its working directory,
instead of the current directory.
-@ifset LUCID
-@item -context @var{authentication}
-When the Energize programming system starts up @value{GDBN}, it uses this
-option to trigger an alternate mode of interaction.
-@var{authentication} is a pair of numeric codes that identify @value{GDBN}
-as a client in the Energize environment. Avoid this option when you run
-@value{GDBN} directly from the command line. See @ref{Energize,,Using
-@value{GDBN} with Energize} for more discussion of using @value{GDBN} with Energize.
-@end ifset
-
@ifclear DOSHOST
@item -fullname
@itemx -f
@@ -936,17 +1267,34 @@ a signal to display the source code for the frame.
@end ifclear
@ifset SERIAL
+@ifclear HPPA
@item -b @var{bps}
Set the line speed (baud rate or bits per second) of any serial
interface used by @value{GDBN} for remote debugging.
+@end ifclear
@item -tty @var{device}
Run using @var{device} for your program's standard input and output.
@c FIXME: kingdon thinks there is more to -tty. Investigate.
@end ifset
+
+@ifset HPPA
+@item -tui
+Use a Terminal User Interface. For information, use your Web browser to
+read the file @file{TUI.html}, which is usually installed in the
+directory @code{/opt/langtools/wdb/doc} on HP-UX systems. Do not use
+this option if you run @value{GDBN} from Emacs (see @pxref{Emacs, ,Using
+@value{GDBN} under @sc{gnu} Emacs}).
+
+@item -xdb
+Run in XDB compatibility mode, allowing the use of certain XDB commands.
+For information, see the file @file{xdb_trans.html}, which is usually
+installed in the directory @code{/opt/langtools/wdb/doc} on HP-UX
+systems.
+@end ifset
@end table
-@node Quitting GDB
+@node Quitting GDB, Shell Commands, Invoking GDB, Invocation
@section Quitting @value{GDBN}
@cindex exiting @value{GDBN}
@cindex leaving @value{GDBN}
@@ -974,7 +1322,7 @@ device, you can release it with the @code{detach} command
(@pxref{Attach, ,Debugging an already-running process}).
@end ifclear
-@node Shell Commands
+@node Shell Commands, , Quitting GDB, Invocation
@section Shell commands
If you need to execute occasional shell commands during your
@@ -985,7 +1333,7 @@ just use the @code{shell} command.
@kindex shell
@cindex shell escape
@item shell @var{command string}
-Invoke a the standard shell to execute @var{command string}.
+Invoke a standard shell to execute @var{command string}.
@ifclear DOSHOST
If it exists, the environment variable @code{SHELL} determines which
shell to run. Otherwise @value{GDBN} uses @code{/bin/sh}.
@@ -1004,7 +1352,7 @@ Execute the @code{make} program with the specified
arguments. This is equivalent to @samp{shell make @var{make-args}}.
@end table
-@node Commands
+@node Commands, Running, Invocation, Top
@chapter @value{GDBN} Commands
You can abbreviate a @value{GDBN} command to the first few letters of the command
@@ -1019,7 +1367,7 @@ show you the alternatives available, if there is more than one possibility).
* Help:: How to ask @value{GDBN} for help
@end menu
-@node Command Syntax
+@node Command Syntax, Completion, Commands, Commands
@section Command syntax
A @value{GDBN} command is a single line of input. There is no limit on
@@ -1062,7 +1410,7 @@ Any text from a @kbd{#} to the end of the line is a comment; it does
nothing. This is useful mainly in command files (@pxref{Command
Files,,Command files}).
-@node Completion
+@node Completion, Help, Command Syntax, Commands
@section Command completion
@cindex completion
@@ -1178,10 +1526,15 @@ place:
In general, @value{GDBN} can tell that a quote is needed (and inserts it) if
you have not yet started typing the argument list when you ask for
completion on an overloaded symbol.
+
+For more information about overloaded functions, @pxref{Cplus
+expressions, ,C++ expressions}. You can use the command @code{set
+overload-resolution off} to disable overload resolution;
+@pxref{Debugging C plus plus, ,@value{GDBN} features for C++}.
@end ifclear
-@node Help
+@node Help, , Completion, Commands
@section Getting help
@cindex online documentation
@kindex help
@@ -1259,9 +1612,11 @@ complete i
@noindent results in:
@smallexample
+@group
info
inspect
ignore
+@end group
@end smallexample
@noindent This is intended for use by @sc{gnu} Emacs.
@@ -1288,7 +1643,7 @@ You can get a complete list of the @code{info} sub-commands with
@kindex set
@item set
-You can assign the result of an expresson to an environment variable with
+You can assign the result of an expression to an environment variable with
@code{set}. For example, you can set the @value{GDBN} prompt to a $-sign with
@code{set prompt $}.
@@ -1334,7 +1689,7 @@ Display information about permission for copying @value{GDBN}.
Display the @sc{gnu} ``NO WARRANTY'' statement.
@end table
-@node Running
+@node Running, Stopping, Commands, Top
@chapter Running Programs Under @value{GDBN}
When you run a program under @value{GDBN}, you must first generate
@@ -1351,17 +1706,21 @@ already running process, or kill a child process.
@ifclear BARETARGET
* Arguments:: Your program's arguments
* Environment:: Your program's environment
+@end ifclear
+
* Working Directory:: Your program's working directory
* Input/Output:: Your program's input and output
* Attach:: Debugging an already-running process
* Kill Process:: Killing the child process
+@ifclear HPPA
* Process Information:: Additional process information
-* Threads:: Debugging programs with multiple threads
-* Processes:: Debugging programs with multiple processes
@end ifclear
+
+* Threads:: Debugging programs with multiple threads
+* Processes:: Debugging programs with multiple processes
@end menu
-@node Compilation
+@node Compilation, Starting, Running, Running
@section Compiling for debugging
In order to debug a program effectively, you need to generate
@@ -1377,7 +1736,13 @@ Many C compilers are unable to handle the @samp{-g} and @samp{-O}
options together. Using those compilers, you cannot generate optimized
executables containing debugging information.
+@ifclear HPPA
@value{NGCC}, the @sc{gnu} C compiler, supports @samp{-g} with or without
+@end ifclear
+@ifset HPPA
+The HP ANSI C and C++ compilers, as well as @value{NGCC}, the @sc{gnu} C
+compiler, support @samp{-g} with or without
+@end ifset
@samp{-O}, making it possible to debug optimized code. We recommend
that you @emph{always} use @samp{-g} whenever you compile a program.
You may think your program is correct, but there is no sense in pushing
@@ -1402,7 +1767,7 @@ Older versions of the @sc{gnu} C compiler permitted a variant option
format; if your @sc{gnu} C compiler has this option, do not use it.
@need 2000
-@node Starting
+@node Starting, Arguments, Compilation, Running
@section Starting your program
@cindex starting
@cindex running
@@ -1441,9 +1806,10 @@ Specify the arguments to give your program as the arguments of the
@code{run} command. If a shell is available on your target, the shell
is used to pass the arguments, so that you may use normal conventions
(such as wildcard expansion or variable substitution) in describing
-the arguments. In Unix systems, you can control which shell is used
-with the @code{SHELL} environment variable. @xref{Arguments, ,Your
-program's arguments}.
+the arguments.
+In Unix systems, you can control which shell is used with the
+@code{SHELL} environment variable.
+@xref{Arguments, ,Your program's arguments}.
@item The @emph{environment.}
Your program normally inherits its environment from @value{GDBN}, but you can
@@ -1483,16 +1849,17 @@ table, and reads it again. When it does this, @value{GDBN} tries to retain
your current breakpoints.
@ifclear BARETARGET
-@node Arguments
+@node Arguments, Environment, Starting, Running
@section Your program's arguments
@cindex arguments (to your program)
The arguments to your program can be specified by the arguments of the
-@code{run} command. They are passed to a shell, which expands wildcard
-characters and performs redirection of I/O, and thence to your program.
-Your @code{SHELL} environment variable (if it exists) specifies what
-shell @value{GDBN} uses. If you do not define @code{SHELL},
-@value{GDBN} uses @code{/bin/sh}.
+@code{run} command.
+They are passed to a shell, which expands wildcard characters and
+performs redirection of I/O, and thence to your program. Your
+@code{SHELL} environment variable (if it exists) specifies what shell
+@value{GDBN} uses. If you do not define @code{SHELL}, @value{GDBN} uses
+@code{/bin/sh}.
@code{run} with no arguments uses the same arguments used by the previous
@code{run}, or those set by the @code{set args} command.
@@ -1511,7 +1878,7 @@ it again without arguments.
Show the arguments to give your program when it is started.
@end table
-@node Environment
+@node Environment, Working Directory, Arguments, Running
@section Your program's environment
@cindex environment (of your program)
@@ -1592,7 +1959,7 @@ your program. You may wish to move setting of environment variables to
files that are only run when you sign on, such as @file{.login} or
@file{.profile}.
-@node Working Directory
+@node Working Directory, Input/Output, Environment, Running
@section Your program's working directory
@cindex working directory (of your program)
@@ -1616,7 +1983,7 @@ Set the @value{GDBN} working directory to @var{directory}.
Print the @value{GDBN} working directory.
@end table
-@node Input/Output
+@node Input/Output, Attach, Working Directory, Running
@section Your program's input and output
@cindex redirection
@@ -1670,7 +2037,7 @@ When you use the @code{tty} command or redirect input in the @code{run}
command, only the input @emph{for your program} is affected. The input
for @value{GDBN} still comes from your terminal.
-@node Attach
+@node Attach, Kill Process, Input/Output, Running
@section Debugging an already-running process
@kindex attach
@cindex attach
@@ -1692,14 +2059,23 @@ which supports processes; for example, @code{attach} does not work for
programs on bare-board targets that lack an operating system. You must
also have permission to send the process a signal.
-When using @code{attach}, you should first use the @code{file} command
-to specify the program running in the process and load its symbol table.
-@xref{Files, ,Commands to Specify Files}.
+When you use @code{attach}, the debugger finds the program running in
+the process first by looking in the current working directory, then (if
+the program is not found) by using the source file search path
+(@pxref{Source Path, ,Specifying source directories}). You can also use
+the @code{file} command to load the program. @xref{Files, ,Commands to
+Specify Files}.
The first thing @value{GDBN} does after arranging to debug the specified
process is to stop it. You can examine and modify an attached process
with all the @value{GDBN} commands that are ordinarily available when you start
+@ifclear HPPA
processes with @code{run}. You can insert breakpoints; you can step and
+@end ifclear
+@ifset HPPA
+processes with @code{run}. You can insert breakpoints (except in shared
+libraries); you can step and
+@end ifset
continue; you can modify storage. If you would rather the process
continue running, you may use the @code{continue} command after
attaching @value{GDBN} to the process.
@@ -1723,9 +2099,14 @@ control whether or not you need to confirm by using the @code{set
confirm} command (@pxref{Messages/Warnings, ,Optional warnings and
messages}).
-@node Kill Process
-@c @group
+@ifset HPPA
+@node Kill Process, Threads, Attach, Running
+@section Killing the child process
+@end ifset
+@ifclear HPPA
+@node Kill Process, Process Information, Attach, Running
@section Killing the child process
+@end ifclear
@table @code
@kindex kill
@@ -1736,7 +2117,6 @@ Kill the child process in which your program is running under @value{GDBN}.
This command is useful if you wish to debug a core dump instead of a
running process. @value{GDBN} ignores any core dump file while your program
is running.
-@c @end group
On some operating systems, a program cannot be executed outside @value{GDBN}
while you have breakpoints set on it inside @value{GDBN}. You can use the
@@ -1750,7 +2130,8 @@ next type @code{run}, @value{GDBN} notices that the file has changed, and
reads the symbol table again (while trying to preserve your current
breakpoint settings).
-@node Process Information
+@ifclear HPPA
+@node Process Information, Threads, Kill Process, Running
@section Additional process information
@kindex /proc
@@ -1791,20 +2172,27 @@ received.
@item info proc all
Show all the above information about the process.
@end table
+@end ifclear
-@node Threads
+@ifset HPPA
+@node Threads, Processes, Kill Process, Running
@section Debugging programs with multiple threads
+@end ifset
+@ifclear HPPA
+@node Threads, Processes, Process Information, Running
+@section Debugging programs with multiple threads
+@end ifclear
@cindex threads of execution
@cindex multiple threads
@cindex switching threads
-In some operating systems, a single program may have more than one
-@dfn{thread} of execution. The precise semantics of threads differ from
-one operating system to another, but in general the threads of a single
-program are akin to multiple processes---except that they share one
-address space (that is, they can all examine and modify the same
-variables). On the other hand, each thread has its own registers and
-execution stack, and perhaps private memory.
+In some operating systems, such as HP-UX and Solaris, a single program
+may have more than one @dfn{thread} of execution. The precise semantics
+of threads differ from one operating system to another, but in general
+the threads of a single program are akin to multiple processes---except
+that they share one address space (that is, they can all examine and
+modify the same variables). On the other hand, each thread has its own
+registers and execution stack, and perhaps private memory.
@value{GDBN} provides these facilities for debugging multi-thread
programs:
@@ -1818,6 +2206,7 @@ a command to apply a command to a list of threads
@item thread-specific breakpoints
@end itemize
+@ifclear HPPA
@quotation
@emph{Warning:} These facilities are not yet available on every
@value{GDBN} configuration where the operating system supports threads.
@@ -1835,6 +2224,7 @@ see the IDs of currently known threads.
@c FIXME to implementors: how hard would it be to say "sorry, this GDB
@c doesn't support threads"?
@end quotation
+@end ifclear
@cindex focus of debugging
@cindex current thread
@@ -1844,6 +2234,7 @@ control, one thread in particular is always the focus of debugging.
This thread is called the @dfn{current thread}. Debugging commands show
program information from the perspective of the current thread.
+@ifclear HPPA
@kindex New @var{systag}
@cindex thread identifier (system)
@c FIXME-implementors!! It would be more helpful if the [New...] message
@@ -1906,6 +2297,62 @@ For example,
* 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8)
at threadtest.c:68
@end smallexample
+@end ifclear
+@ifset HPPA
+
+@cindex thread number
+@cindex thread identifier (GDB)
+For debugging purposes, @value{GDBN} associates its own thread
+number---a small integer assigned in thread-creation order---with each
+thread in your program.
+
+@kindex New @var{systag}
+@cindex thread identifier (system)
+@c FIXME-implementors!! It would be more helpful if the [New...] message
+@c included GDB's numeric thread handle, so you could just go to that
+@c thread without first checking `info threads'.
+Whenever @value{GDBN} detects a new thread in your program, it displays
+both @value{GDBN}'s thread number and the target system's identification for the thread with a message in the
+form @samp{[New @var{systag}]}. @var{systag} is a thread identifier
+whose form varies depending on the particular system. For example, on
+HP-UX, you see
+
+@example
+[New thread 2 (system thread 26594)]
+@end example
+
+@noindent
+when @value{GDBN} notices a new thread.
+
+@table @code
+@kindex info threads
+@item info threads
+Display a summary of all threads currently in your
+program. @value{GDBN} displays for each thread (in this order):
+
+@enumerate
+@item the thread number assigned by @value{GDBN}
+
+@item the target system's thread identifier (@var{systag})
+
+@item the current stack frame summary for that thread
+@end enumerate
+
+@noindent
+An asterisk @samp{*} to the left of the @value{GDBN} thread number
+indicates the current thread.
+
+For example,
+@end table
+@c end table here to get a little more width for example
+
+@example
+(@value{GDBP}) info threads
+ * 3 system thread 26607 worker (wptr=0x7b09c318 "@@") at quicksort.c:137
+ 2 system thread 26606 0x7b0030d8 in __ksleep () from /usr/lib/libc.2
+ 1 system thread 27905 0x7b003498 in _brk () from /usr/lib/libc.2
+@end example
+@end ifset
@table @code
@kindex thread @var{threadno}
@@ -1919,7 +2366,12 @@ you selected, and its current stack frame summary:
@smallexample
@c FIXME!! This example made up; find a @value{GDBN} w/threads and get real one
(@value{GDBP}) thread 2
+@ifclear HPPA
[Switching to process 35 thread 23]
+@end ifclear
+@ifset HPPA
+[Switching to thread 2 (system thread 26594)]
+@end ifset
0x34e5 in sigpause ()
@end smallexample
@@ -1955,7 +2407,8 @@ programs with multiple threads.
watchpoints in programs with multiple threads.
@end ifclear
-@node Processes
+@ifclear HPPA
+@node Processes, , Threads, Running
@section Debugging programs with multiple processes
@cindex fork, debugging programs which call
@@ -1978,8 +2431,68 @@ get its process ID. Then tell @value{GDBN} (a new invocation of
@value{GDBN} if you are also debugging the parent process) to attach to
the child process (see @ref{Attach}). From that point on you can debug
the child process just like any other process which you attached to.
+@end ifclear
+@ifset HPPA
+@node Processes, , Threads, Running
+@section Debugging programs with multiple processes
-@node Stopping
+@cindex fork, debugging programs which call
+@cindex multiple processes
+@cindex processes, multiple
+
+@value{GDBN} provides support for debugging programs that create
+additional processes using the @code{fork} or @code{vfork} function.
+
+By default, when a program forks, @value{GDBN} will continue to debug
+the parent process and the child process will run unimpeded.
+
+If you want to follow the child process instead of the parent process,
+use the command @w{@code{set follow-fork-mode}}.
+
+@table @code
+@kindex set follow-fork-mode
+@item set follow-fork-mode @var{mode}
+Set the debugger response to a program call of @code{fork} or
+@code{vfork}. A call to @code{fork} or @code{vfork} creates a new
+process. The @var{mode} can be:
+
+@table @code
+@item parent
+The original process is debugged after a fork. The child process runs
+unimpeded.
+
+@item child
+The new process is debugged after a fork. The parent process runs
+unimpeded.
+
+@item ask
+The debugger will ask for one of the above choices.
+@end table
+
+@item show follow-fork-mode
+Display the current debugger response to a fork or vfork call.
+@end table
+
+If you ask to debug a child process and a @code{vfork} is followed by an
+@code{exec}, @value{GDBN} executes the new target up to the first
+breakpoint in the new target. If you have a breakpoint set on
+@code{main} in your original program, the breakpoint will also be set on
+the child process's @code{main}.
+
+When a child process is spawned by @code{vfork}, you cannot debug the
+child or parent until an @code{exec} call completes.
+
+If you issue a @code{run} command to @value{GDBN} after an @code{exec}
+call executes, the new target restarts. To restart the parent process,
+use the @code{file} command with the parent executable name as its
+argument.
+
+You can use the @code{catch} command to make @value{GDBN} stop whenever
+a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set
+Catchpoints, ,Setting catchpoints}.
+@end ifset
+
+@node Stopping, Stack, Running, Top
@chapter Stopping and Continuing
The principal purposes of using a debugger are so that you can stop your
@@ -2010,51 +2523,36 @@ and why it stopped.
@end table
@menu
-@ifclear CONLY
-* Breakpoints:: Breakpoints, watchpoints, and exceptions
-@end ifclear
-@ifset CONLY
-* Breakpoints:: Breakpoints and watchpoints
-@end ifset
-@c Remnant makeinfo bug requires blank line after *successful* end-if in menu:
-
+* Breakpoints:: Breakpoints, watchpoints, and catchpoints
* Continuing and Stepping:: Resuming execution
@ifset POSIX
* Signals:: Signals
@end ifset
+
@ifclear BARETARGET
-* Thread Stops:: Stopping and starting multi-thread programs
+* Thread Stops:: Stopping and starting multi-thread programs
@end ifclear
+
@end menu
-@c makeinfo node-defaulting requires adjacency of @node and sectioning cmds
-@c ...hence distribute @node Breakpoints over two possible @if expansions.
-@c
-@ifclear CONLY
-@node Breakpoints
-@section Breakpoints, watchpoints, and exceptions
-@end ifclear
-@ifset CONLY
-@node Breakpoints
-@section Breakpoints and watchpoints
-@end ifset
+@node Breakpoints, Continuing and Stepping, Stopping, Stopping
+@section Breakpoints, watchpoints, and catchpoints
@cindex breakpoints
A @dfn{breakpoint} makes your program stop whenever a certain point in
-the program is reached. For each breakpoint, you can add
-conditions to control in finer detail whether your program stops.
-You can set breakpoints with the @code{break} command and its variants
-(@pxref{Set Breaks, ,Setting breakpoints}), to specify the place where
-your program should stop by line number, function name or exact address
-in the program.
-@ifclear CONLY
-In languages with exception handling (such as @sc{gnu} C++), you can also set
-breakpoints where an exception is raised (@pxref{Exception Handling,,
-Breakpoints and exceptions}).
-@end ifclear
+the program is reached. For each breakpoint, you can add conditions to
+control in finer detail whether your program stops. You can set
+breakpoints with the @code{break} command and its variants (@pxref{Set
+Breaks, ,Setting breakpoints}), to specify the place where your program
+should stop by line number, function name or exact address in the
+program.
-In SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can now set
-breakpoints in shared libraries before the executable is run.
+In HP-UX, SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can set
+breakpoints in shared libraries before the executable is run. There is
+a minor limitation on HP-UX systems: you must wait until the executable
+is run in order to set breakpoints in shared library routines that are
+not called directly by the program (for example, routines that are
+arguments in a @code{pthread_create} call).
@cindex watchpoints
@cindex memory tracing
@@ -2071,22 +2569,30 @@ You can arrange to have values from your program displayed automatically
whenever @value{GDBN} stops at a breakpoint. @xref{Auto Display,,
Automatic display}.
+@cindex catchpoints
+@cindex breakpoint on events
+A @dfn{catchpoint} is another special breakpoint that stops your program
+when a certain kind of event occurs, such as the throwing of a C++
+exception or the loading of a library. As with watchpoints, you use a
+different command to set a catchpoint (@pxref{Set Catchpoints, ,Setting
+catchpoints}), but aside from that, you can manage a catchpoint like any
+other breakpoint. (To stop when your program receives a signal, use the
+@code{handle} command; @pxref{Signals, ,Signals}.)
+
@cindex breakpoint numbers
@cindex numbers for breakpoints
-@value{GDBN} assigns a number to each breakpoint or watchpoint when you
-create it; these numbers are successive integers starting with one. In
-many of the commands for controlling various features of breakpoints you
-use the breakpoint number to say which breakpoint you want to change.
-Each breakpoint may be @dfn{enabled} or @dfn{disabled}; if disabled, it has
-no effect on your program until you enable it again.
+@value{GDBN} assigns a number to each breakpoint, watchpoint, or
+catchpoint when you create it; these numbers are successive integers
+starting with one. In many of the commands for controlling various
+features of breakpoints you use the breakpoint number to say which
+breakpoint you want to change. Each breakpoint may be @dfn{enabled} or
+@dfn{disabled}; if disabled, it has no effect on your program until you
+enable it again.
@menu
* Set Breaks:: Setting breakpoints
* Set Watchpoints:: Setting watchpoints
-@ifclear CONLY
-* Exception Handling:: Breakpoints and exceptions
-@end ifclear
-
+* Set Catchpoints:: Setting catchpoints
* Delete Breaks:: Deleting breakpoints
* Disabling:: Disabling breakpoints
* Conditions:: Break conditions
@@ -2094,12 +2600,13 @@ no effect on your program until you enable it again.
@ifclear CONLY
* Breakpoint Menus:: Breakpoint menus
@end ifclear
+
@c @ifclear BARETARGET
@c * Error in Breakpoints:: ``Cannot insert breakpoints''
@c @end ifclear
@end menu
-@node Set Breaks
+@node Set Breaks, Set Watchpoints, Breakpoints, Breakpoints
@subsection Setting breakpoints
@c FIXME LMB what does GDB do if no code on line of breakpt?
@@ -2186,6 +2693,7 @@ same as for the @code{break} command, and the breakpoint is set in the same
way, but the breakpoint is automatically deleted after the first time your
program stops there. @xref{Disabling, ,Disabling breakpoints}.
+@ifclear HPPA
@kindex hbreak
@item hbreak @var{args}
Set a hardware-assisted breakpoint. @var{args} are the same as for the
@@ -2195,10 +2703,10 @@ have this support. The main purpose of this is EPROM/ROM code
debugging, so you can set a breakpoint at an instruction without
changing the instruction. This can be used with the new trap-generation
provided by SPARClite DSU. DSU will generate traps when a program accesses
-some date or instruction address that is assigned to the debug registers.
+some data or instruction address that is assigned to the debug registers.
However the hardware breakpoint registers can only take two data breakpoints,
and @value{GDBN} will reject this command if more than two are used.
-Delete or disable usused hardware breakpoints before setting
+Delete or disable unused hardware breakpoints before setting
new ones. @xref{Conditions, ,Break conditions}.
@kindex thbreak
@@ -2211,6 +2719,7 @@ first time your program stops there. Also, like the @code{hbreak}
command, the breakpoint requires hardware support and some target hardware
may not have this support. @xref{Disabling, ,Disabling breakpoints}.
Also @xref{Conditions, ,Break conditions}.
+@end ifclear
@kindex rbreak
@cindex regular expression
@@ -2235,13 +2744,13 @@ classes.
@item info breakpoints @r{[}@var{n}@r{]}
@itemx info break @r{[}@var{n}@r{]}
@itemx info watchpoints @r{[}@var{n}@r{]}
-Print a table of all breakpoints and watchpoints set and not
-deleted, with the following columns for each breakpoint:
+Print a table of all breakpoints, watchpoints, and catchpoints set and
+not deleted, with the following columns for each breakpoint:
@table @emph
@item Breakpoint Numbers
@item Type
-Breakpoint or watchpoint.
+Breakpoint, watchpoint, or catchpoint.
@item Disposition
Whether the breakpoint is marked to be disabled or deleted when hit.
@item Enabled or Disabled
@@ -2267,12 +2776,12 @@ the @code{x} command are set to the address of the last breakpoint
listed (@pxref{Memory, ,Examining memory}).
@noindent
-@code{info break} now displays a count of the number of times the
-breakpoint has been hit. This is especially useful in conjunction with
-the @code{ignore} command. You can ignore a large number of breakpoint
-hits, look at the breakpoint info to see how many times the
-breakpoint was hit, and then run again, ignoring one less than that
-number. This will get you quickly to the last hit of that breakpoint.
+@code{info break} displays a count of the number of times the breakpoint
+has been hit. This is especially useful in conjunction with the
+@code{ignore} command. You can ignore a large number of breakpoint
+hits, look at the breakpoint info to see how many times the breakpoint
+was hit, and then run again, ignoring one less than that number. This
+will get you quickly to the last hit of that breakpoint.
@end table
@value{GDBN} allows you to set any number of breakpoints at the same place in
@@ -2318,50 +2827,45 @@ Temporary internal breakpoint used by the @value{GDBN} @code{until} command.
@item finish
Temporary internal breakpoint used by the @value{GDBN} @code{finish} command.
-@end table
+@ifset HPPA
+@item shlib events
+Shared library events.
+@end ifset
+@end table
@end table
-@node Set Watchpoints
+@node Set Watchpoints, Set Catchpoints, Set Breaks, Breakpoints
@subsection Setting watchpoints
-@cindex setting watchpoints
+@cindex setting watchpoints
+@cindex software watchpoints
+@cindex hardware watchpoints
You can use a watchpoint to stop execution whenever the value of an
-expression changes, without having to predict a particular place
-where this may happen.
-
-Watchpoints currently execute two orders of magnitude more slowly than
-other breakpoints, but this can be well worth it to catch errors where
-you have no clue what part of your program is the culprit.
-
-@c FIXME - did Stan mean to @ignore this out?
-@ignore
-Some processors provide special hardware to support watchpoint
-evaluation; @value{GDBN} will use such hardware if it is available,
-and if the support code has been added for that configuration.
-@end ignore
+expression changes, without having to predict a particular place where
+this may happen.
+
+Depending on your system, watchpoints may be implemented in software or
+hardware. GDB does software watchpointing by single-stepping your
+program and testing the variable's value each time, which is hundreds of
+times slower than normal execution. (But this may still be worth it, to
+catch errors where you have no clue what part of your program is the
+culprit.)
+
+On some systems, such as HP-UX and Linux, GDB includes support for
+hardware watchpoints, which do not slow down the running of your
+program.
@table @code
@kindex watch
@item watch @var{expr}
Set a watchpoint for an expression. @value{GDBN} will break when @var{expr}
is written into by the program and its value changes.
-This can be used with the new trap-generation provided by
-SPARClite DSU. DSU will generate traps when a program accesses
-some date or instruction address that is assigned to the debug registers.
-For the data addresses, DSU facilitates the @code{watch} command.
-However the hardware breakpoint registers can only take two data watchpoints,
-and both watchpoints must be the same kind. For example, you can set two
-watchpoints with @code{watch} commands, two with @code{rwatch}
-commands, @strong{or} two with @code{awatch} commands, but you cannot set one
-watchpoint with one command and the other with a different command.
-@value{GBDN} will reject the command if you try to mix watchpoints.
-Delete or disable unused watchpoint commands before setting new ones.
@kindex rwatch
@item rwatch @var{expr}
-Set a watchpoint that will break when watch @var{args} is read by the program.
+Set a watchpoint that will break when watch @var{expr} is read by the program.
If you use both watchpoints, both must be set with the @code{rwatch}
command.
@@ -2373,15 +2877,47 @@ by the program. If you use both watchpoints, both must be set with the
@kindex info watchpoints
@item info watchpoints
-This command prints a list of watchpoints and breakpoints; it is the
-same as @code{info break}.
+This command prints a list of watchpoints, breakpoints, and catchpoints;
+it is the same as @code{info break}.
@end table
+@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
+watchpoints execute very quickly, and the debugger reports a change in
+value at the exact instruction where the change occurs. If @value{GDBN}
+cannot set a hardware watchpoint, it sets a software watchpoint, which
+executes more slowly and reports the change in value at the next
+statement, not the instruction, after the change occurs.
+
+When you issue the @code{watch} command, @value{GDBN} reports
+
+@example
+Hardware watchpoint @var{num}: @var{expr}
+@end example
+
+@noindent
+if it was able to set a hardware watchpoint.
+
+The SPARClite DSU will generate traps when a program accesses
+some data or instruction address that is assigned to the debug registers.
+For the data addresses, DSU facilitates the @code{watch} command.
+However the hardware breakpoint registers can only take two data watchpoints,
+and both watchpoints must be the same kind. For example, you can set two
+watchpoints with @code{watch} commands, two with @code{rwatch}
+commands, @strong{or} two with @code{awatch} commands, but you cannot set one
+watchpoint with one command and the other with a different command.
+@value{GDBN} will reject the command if you try to mix watchpoints.
+Delete or disable unused watchpoint commands before setting new ones.
+
+If you call a function interactively using @code{print} or @code{call},
+any watchpoints you have set will be inactive until GDB reaches another
+kind of breakpoint or the call completes.
+
@ifclear BARETARGET
@quotation
@cindex watchpoints and threads
@cindex threads and watchpoints
-@emph{Warning:} in multi-thread programs, watchpoints have only limited
+@ifclear HPPA
+@emph{Warning:} In multi-thread programs, watchpoints have only limited
usefulness. With the current watchpoint implementation, @value{GDBN}
can only watch the value of an expression @emph{in a single thread}. If
you are confident that the expression can only change due to the current
@@ -2389,40 +2925,90 @@ thread's activity (and if you are also confident that no other thread
can become current), then you can use watchpoints as usual. However,
@value{GDBN} may not notice when a non-current thread's activity changes
the expression.
+@end ifclear
+@ifset HPPA
+@emph{Warning:} In multi-thread programs, software watchpoints have only
+limited usefulness. If @value{GDBN} creates a software watchpoint, it
+can only watch the value of an expression @emph{in a single thread}. If
+you are confident that the expression can only change due to the current
+thread's activity (and if you are also confident that no other thread
+can become current), then you can use software watchpoints as usual.
+However, @value{GDBN} may not notice when a non-current thread's
+activity changes the expression. (Hardware watchpoints, in contrast,
+watch an expression in all threads.)
+@end ifset
@end quotation
@end ifclear
-@ifclear CONLY
-@node Exception Handling
-@subsection Breakpoints and exceptions
+@node Set Catchpoints, Delete Breaks, Set Watchpoints, Breakpoints
+@subsection Setting catchpoints
+@cindex catchpoints
@cindex exception handlers
+@cindex event handling
-Some languages, such as @sc{gnu} C++, implement exception handling. You can
-use @value{GDBN} to examine what caused your program to raise an exception,
-and to list the exceptions your program is prepared to handle at a
-given point in time.
+You can use @dfn{catchpoints} to cause the debugger to stop for certain
+kinds of program events, such as C++ exceptions or the loading of a
+shared library. Use the @code{catch} command to set a catchpoint.
@table @code
@kindex catch
-@item catch @var{exceptions}
-You can set breakpoints at active exception handlers by using the
-@code{catch} command. @var{exceptions} is a list of names of exceptions
-to catch.
+@item catch @var{event}
+Stop when @var{event} occurs. @var{event} can be any of the following:
+@table @code
+@item throw
+@kindex catch throw
+The throwing of a C++ exception.
+
+@item catch
+@kindex catch catch
+The catching of a C++ exception.
+
+@item exec
+@kindex catch exec
+A call to @code{exec}. This is currently only available for HP-UX.
+
+@item fork
+@kindex catch fork
+A call to @code{fork}. This is currently only available for HP-UX.
+
+@item vfork
+@kindex catch vfork
+A call to @code{vfork}. This is currently only available for HP-UX.
+
+@item load
+@itemx load @var{libname}
+@kindex catch load
+The dynamic loading of any shared library, or the loading of the library
+@var{libname}. This is currently only available for HP-UX.
+
+@item unload
+@itemx unload @var{libname}
+@kindex catch unload
+The unloading of any dynamically loaded shared library, or the unloading
+of the library @var{libname}. This is currently only available for HP-UX.
@end table
-You can use @code{info catch} to list active exception handlers.
-@xref{Frame Info, ,Information about a frame}.
+@item tcatch @var{event}
+Set a catchpoint that is enabled only for one stop. The catchpoint is
+automatically deleted after the first time the event is caught.
-There are currently some limitations to exception handling in @value{GDBN}:
+@end table
+
+Use the @code{info break} command to list the current catchpoints.
+
+There are currently some limitations to C++ exception handling
+(@code{catch throw} and @code{catch catch}) in @value{GDBN}:
@itemize @bullet
@item
If you call a function interactively, @value{GDBN} normally returns
control to you when the function has finished executing. If the call
raises an exception, however, the call may bypass the mechanism that
-returns control to you and cause your program to simply continue
-running until it hits a breakpoint, catches a signal that @value{GDBN} is
-listening for, or exits.
+returns control to you and cause your program either to abort or to
+simply continue running until it hits a breakpoint, catches a signal
+that @value{GDBN} is listening for, or exits. This is the case even if
+you set a catchpoint for the exception; catchpoints on exceptions are
+disabled within interactive calls.
@item
You cannot raise an exception interactively.
@@ -2460,30 +3046,30 @@ that depends on the value of @var{id}, you can stop your program when
a specific exception is raised. You can use multiple conditional
breakpoints to stop your program when any of a number of exceptions are
raised.
-@end ifclear
-@node Delete Breaks
+
+@node Delete Breaks, Disabling, Set Catchpoints, Breakpoints
@subsection Deleting breakpoints
-@cindex clearing breakpoints, watchpoints
-@cindex deleting breakpoints, watchpoints
-It is often necessary to eliminate a breakpoint or watchpoint once it
-has done its job and you no longer want your program to stop there. This
-is called @dfn{deleting} the breakpoint. A breakpoint that has been
-deleted no longer exists; it is forgotten.
+@cindex clearing breakpoints, watchpoints, catchpoints
+@cindex deleting breakpoints, watchpoints, catchpoints
+It is often necessary to eliminate a breakpoint, watchpoint, or
+catchpoint once it has done its job and you no longer want your program
+to stop there. This is called @dfn{deleting} the breakpoint. A
+breakpoint that has been deleted no longer exists; it is forgotten.
With the @code{clear} command you can delete breakpoints according to
where they are in your program. With the @code{delete} command you can
-delete individual breakpoints or watchpoints by specifying their
-breakpoint numbers.
+delete individual breakpoints, watchpoints, or catchpoints by specifying
+their breakpoint numbers.
It is not necessary to delete a breakpoint to proceed past it. @value{GDBN}
automatically ignores breakpoints on the first instruction to be executed
when you continue execution without changing the execution address.
@table @code
-@item clear
@kindex clear
+@item clear
Delete any breakpoints at the next instruction to be executed in the
selected stack frame (@pxref{Selection, ,Selecting a frame}). When
the innermost frame is selected, this is a good way to delete a
@@ -2501,30 +3087,30 @@ Delete any breakpoints set at or within the code of the specified line.
@kindex delete
@kindex d
@item delete @r{[}breakpoints@r{]} @r{[}@var{bnums}@dots{}@r{]}
-Delete the breakpoints or watchpoints of the numbers specified as
-arguments. If no argument is specified, delete all breakpoints (@value{GDBN}
-asks confirmation, unless you have @code{set confirm off}). You
-can abbreviate this command as @code{d}.
+Delete the breakpoints, watchpoints, or catchpoints of the numbers
+specified as arguments. If no argument is specified, delete all
+breakpoints (@value{GDBN} asks confirmation, unless you have @code{set
+confirm off}). You can abbreviate this command as @code{d}.
@end table
-@node Disabling
+@node Disabling, Conditions, Delete Breaks, Breakpoints
@subsection Disabling breakpoints
@kindex disable breakpoints
@kindex enable breakpoints
-Rather than deleting a breakpoint or watchpoint, you might prefer to
-@dfn{disable} it. This makes the breakpoint inoperative as if it had
-been deleted, but remembers the information on the breakpoint so that
-you can @dfn{enable} it again later.
+Rather than deleting a breakpoint, watchpoint, or catchpoint, you might
+prefer to @dfn{disable} it. This makes the breakpoint inoperative as if
+it had been deleted, but remembers the information on the breakpoint so
+that you can @dfn{enable} it again later.
-You disable and enable breakpoints and watchpoints with the
-@code{enable} and @code{disable} commands, optionally specifying one or
-more breakpoint numbers as arguments. Use @code{info break} or
-@code{info watch} to print a list of breakpoints or watchpoints if you
-do not know which numbers to use.
+You disable and enable breakpoints, watchpoints, and catchpoints with
+the @code{enable} and @code{disable} commands, optionally specifying one
+or more breakpoint numbers as arguments. Use @code{info break} or
+@code{info watch} to print a list of breakpoints, watchpoints, and
+catchpoints if you do not know which numbers to use.
-A breakpoint or watchpoint can have any of four different states of
-enablement:
+A breakpoint, watchpoint, or catchpoint can have any of four different
+states of enablement:
@itemize @bullet
@item
@@ -2541,8 +3127,8 @@ Enabled for deletion. The breakpoint stops your program, but
immediately after it does so it is deleted permanently.
@end itemize
-You can use the following commands to enable or disable breakpoints and
-watchpoints:
+You can use the following commands to enable or disable breakpoints,
+watchpoints, and catchpoints:
@table @code
@kindex disable breakpoints
@@ -2578,7 +3164,7 @@ breakpoint of its own, but it does not change the state of your other
breakpoints; see @ref{Continuing and Stepping, ,Continuing and
stepping}.)
-@node Conditions
+@node Conditions, Break Commands, Disabling, Breakpoints
@subsection Break conditions
@cindex conditional breakpoints
@cindex breakpoint conditions
@@ -2618,20 +3204,31 @@ purpose of performing side effects when a breakpoint is reached
Break conditions can be specified when a breakpoint is set, by using
@samp{if} in the arguments to the @code{break} command. @xref{Set
Breaks, ,Setting breakpoints}. They can also be changed at any time
-with the @code{condition} command. The @code{watch} command does not
-recognize the @code{if} keyword; @code{condition} is the only way to
-impose a further condition on a watchpoint.
+with the @code{condition} command.
+@ifclear HPPA
+@c The watch command now seems to recognize the if keyword.
+@c catch doesn't, though.
+The @code{watch} command does not recognize the @code{if} keyword;
+@code{condition} is the only way to impose a further condition on a
+watchpoint.
+@end ifclear
+@ifset HPPA
+You can also use the @code{if} keyword with the @code{watch} command.
+The @code{catch} command does not recognize the @code{if} keyword;
+@code{condition} is the only way to impose a further condition on a
+catchpoint.
+@end ifset
@table @code
@kindex condition
@item condition @var{bnum} @var{expression}
-Specify @var{expression} as the break condition for breakpoint or
-watchpoint number @var{bnum}. After you set a condition, breakpoint
-@var{bnum} stops your program only if the value of @var{expression} is
-true (nonzero, in C). When you use @code{condition}, @value{GDBN}
-checks @var{expression} immediately for syntactic correctness, and to
-determine whether symbols in it have referents in the context of your
-breakpoint.
+Specify @var{expression} as the break condition for breakpoint,
+watchpoint, or catchpoint number @var{bnum}. After you set a condition,
+breakpoint @var{bnum} stops your program only if the value of
+@var{expression} is true (nonzero, in C). When you use
+@code{condition}, @value{GDBN} checks @var{expression} immediately for
+syntactic correctness, and to determine whether symbols in it have
+referents in the context of your breakpoint.
@c FIXME so what does GDB do if there is no referent? Moreover, what
@c about watchpoints?
@value{GDBN} does
@@ -2681,14 +3278,17 @@ is decremented each time. @xref{Convenience Vars, ,Convenience
variables}.
@end table
-@node Break Commands
+Ignore counts apply to breakpoints, watchpoints, and catchpoints.
+
+
+@node Break Commands, Breakpoint Menus, Conditions, Breakpoints
@subsection Breakpoint command lists
@cindex breakpoint commands
-You can give any breakpoint (or watchpoint) a series of commands to
-execute when your program stops due to that breakpoint. For example, you
-might want to print the values of certain expressions, or enable other
-breakpoints.
+You can give any breakpoint (or watchpoint or catchpoint) a series of
+commands to execute when your program stops due to that breakpoint. For
+example, you might want to print the values of certain expressions, or
+enable other breakpoints.
@table @code
@kindex commands
@@ -2704,8 +3304,8 @@ To remove all commands from a breakpoint, type @code{commands} and
follow it immediately with @code{end}; that is, give no commands.
With no @var{bnum} argument, @code{commands} refers to the last
-breakpoint or watchpoint set (not to the breakpoint most recently
-encountered).
+breakpoint, watchpoint, or catchpoint set (not to the breakpoint most
+recently encountered).
@end table
Pressing @key{RET} as a means of repeating the last @value{GDBN} command is
@@ -2763,7 +3363,7 @@ end
@end example
@ifclear CONLY
-@node Breakpoint Menus
+@node Breakpoint Menus, , Break Commands, Breakpoints
@subsection Breakpoint menus
@cindex overloading
@cindex symbol overloading
@@ -2788,6 +3388,7 @@ We choose three particular definitions of that function name:
@c FIXME! This is likely to change to show arg type lists, at least
@smallexample
+@group
(@value{GDBP}) b String::after
[0] cancel
[1] all
@@ -2805,6 +3406,7 @@ Multiple breakpoints were set.
Use the "delete" command to delete unwanted
breakpoints.
(@value{GDBP})
+@end group
@end smallexample
@end ifclear
@@ -2838,7 +3440,7 @@ Use the "delete" command to delete unwanted
@c @end enumerate
@c @end ifclear
-@node Continuing and Stepping
+@node Continuing and Stepping, Signals, Breakpoints, Stopping
@section Continuing and stepping
@cindex stepping
@@ -2886,17 +3488,11 @@ calling function; or @code{jump} (@pxref{Jumping, ,Continuing at a
different address}) to go to an arbitrary location in your program.
A typical technique for using stepping is to set a breakpoint
-@ifclear CONLY
-(@pxref{Breakpoints, ,Breakpoints; watchpoints; and exceptions})
-@end ifclear
-@ifset CONLY
-(@pxref{Breakpoints, ,Breakpoints and watchpoints})
-@end ifset
-at the
-beginning of the function or the section of your program where a
-problem is believed to lie, run your program until it stops at that
-breakpoint, and then step through the suspect area, examining the
-variables that are interesting, until you see the problem happen.
+(@pxref{Breakpoints, ,Breakpoints; watchpoints; and catchpoints}) at the
+beginning of the function or the section of your program where a problem
+is believed to lie, run your program until it stops at that breakpoint,
+and then step through the suspect area, examining the variables that are
+interesting, until you see the problem happen.
@table @code
@kindex step
@@ -2961,7 +3557,7 @@ An argument @var{count} is a repeat count, as for @code{step}.
The @code{next} command now only stops at the first instruction of a
source line. This prevents the multiple stops that used to occur in
-swtch statements, for loops, etc.
+switch statements, for loops, etc.
@kindex finish
@item finish
@@ -2972,9 +3568,9 @@ Contrast this with the @code{return} command (@pxref{Returning,
,Returning from a function}).
@kindex until
-@itemx u
@kindex u
@item until
+@itemx u
Continue running until a source line past the current line, in the
current stack frame, is reached. This command is used to avoid single
stepping through a loop more than once. It is like the @code{next}
@@ -3050,7 +3646,7 @@ An argument is a repeat count, as in @code{next}.
@end table
@ifset POSIX
-@node Signals
+@node Signals, Thread Stops, Continuing and Stepping, Stopping
@section Signals
@cindex signals
@@ -3146,7 +3742,7 @@ program a signal}.
@end ifset
@ifclear BARETARGET
-@node Thread Stops
+@node Thread Stops, , Signals, Stopping
@section Stopping and starting multi-thread programs
When your program has multiple threads (@pxref{Threads,, Debugging
@@ -3208,9 +3804,32 @@ You might even find your program stopped in another thread after
continuing or even single-stepping. This happens whenever some other
thread runs into a breakpoint, a signal, or an exception before the
first thread completes whatever you requested.
+
+On some OSes, you can lock the OS scheduler and thus allow only a single
+thread to run.
+
+@table @code
+@item set scheduler-locking @var{mode}
+Set the scheduler locking mode. If it is @code{off}, then there is no
+locking and any thread may run at any time. If @code{on}, then only the
+current thread may run when the inferior is resumed. The @code{step}
+mode optimizes for single-stepping. It stops other threads from
+``seizing the prompt'' by preempting the current thread while you are
+stepping. Other threads will only rarely (or never) get a chance to run
+when you step. They are more likely to run when you ``next'' over a
+function call, and they are completely free to run when you use commands
+like ``continue'', ``until'', or ``finish''. However, unless another
+thread hits a breakpoint during its timeslice, they will never steal the
+GDB prompt away from the thread that you are debugging.
+
+@item show scheduler-locking
+Display the current scheduler locking mode.
+@end table
+
@end ifclear
-@node Stack
+
+@node Stack, Source, Stopping, Top
@chapter Examining the Stack
When your program has stopped, the first thing you need to know is where it
@@ -3246,12 +3865,11 @@ currently executing frame and describes it briefly, similar to the
* Backtrace:: Backtraces
* Selection:: Selecting a frame
* Frame Info:: Information on a frame
-@ifset MIPS
-* MIPS Stack:: MIPS machines and the function stack
-@end ifset
+* Alpha/MIPS Stack:: Alpha and MIPS machines and the function stack
+
@end menu
-@node Frames
+@node Frames, Backtrace, Stack, Stack
@section Stack frames
@cindex frame
@@ -3307,7 +3925,7 @@ no provision for frameless functions elsewhere in the stack.
@item frame @var{args}
The @code{frame} command allows you to move from one stack frame to another,
and to print the stack frame you select. @var{args} may be either the
-address of the frame of the stack frame number. Without an argument,
+address of the frame or the stack frame number. Without an argument,
@code{frame} prints the current stack frame.
@kindex select-frame
@@ -3317,9 +3935,12 @@ to another without printing the frame. This is the silent version of
@code{frame}.
@end table
-@node Backtrace
+@node Backtrace, Selection, Frames, Stack
@section Backtraces
+@cindex backtraces
+@cindex tracebacks
+@cindex stack traces
A backtrace is a summary of how your program got where it is. It shows one
line per frame, for many frames, starting with the currently executing
frame (frame zero), followed by its caller (frame one), and on up the
@@ -3377,7 +3998,7 @@ The display for frame zero does not begin with a program counter
value, indicating that your program has stopped at the beginning of the
code for line @code{993} of @code{builtin.c}.
-@node Selection
+@node Selection, Frame Info, Backtrace, Stack
@section Selecting a frame
Most commands for examining the stack and other data in your program work on
@@ -3404,6 +4025,7 @@ addition, this can be useful when your program has multiple stacks and
switches between them.
@ifclear H8EXCLUSIVE
+@ifclear HPPA
On the SPARC architecture, @code{frame} needs two addresses to
select an arbitrary frame: a frame pointer and a stack pointer.
@@ -3416,6 +4038,7 @@ pointer, a program counter, and a memory stack pointer.
@c SETUP_ARBITRARY_FRAME in the tm-*.h files. The above is up to date
@c as of 27 Jan 1994.
@end ifclear
+@end ifclear
@kindex up
@item up @var{n}
@@ -3465,7 +4088,7 @@ in @value{GDBN} command scripts, where the output might be unnecessary and
distracting.
@end table
-@node Frame Info
+@node Frame Info, Alpha/MIPS Stack, Selection, Stack
@section Information about a frame
There are several other commands to print information about the selected
@@ -3527,6 +4150,7 @@ line. These are all variables (declared either static or automatic)
accessible at the point of execution of the selected frame.
@ifclear CONLY
+@ifclear HPPA
@kindex info catch
@cindex catch exceptions
@cindex exception handlers
@@ -3535,19 +4159,21 @@ Print a list of all the exception handlers that are active in the
current stack frame at the current point of execution. To see other
exception handlers, visit the associated frame (using the @code{up},
@code{down}, or @code{frame} commands); then type @code{info catch}.
-@xref{Exception Handling, ,Breakpoints and exceptions}.
+@xref{Set Catchpoints, , Setting catchpoints}.
+@end ifclear
@end ifclear
@end table
-@ifset MIPS
-@node MIPS Stack
-@section MIPS machines and the function stack
+@node Alpha/MIPS Stack, , Frame Info, Stack
+@section MIPS/Alpha machines and the function stack
+@cindex stack on Alpha
@cindex stack on MIPS
+@cindex Alpha stack
@cindex MIPS stack
-MIPS based computers use an unusual stack frame, which sometimes
-requires @value{GDBN} to search backward in the object code to find the
-beginning of a function.
+Alpha- and MIPS-based computers use an unusual stack frame, which
+sometimes requires @value{GDBN} to search backward in the object code to
+find the beginning of a function.
@cindex response time, MIPS debugging
To improve response time (especially for embedded applications, where
@@ -3556,7 +4182,7 @@ you may want to limit the size of this search, using one of these
commands:
@table @code
-@cindex @code{heuristic-fence-post} (MIPS)
+@cindex @code{heuristic-fence-post} (Alpha,MIPS)
@item set heuristic-fence-post @var{limit}
Restrict @value{GDBN} to examining at most @var{limit} bytes in its search
for the beginning of a function. A value of @var{0} (the default)
@@ -3570,10 +4196,10 @@ Display the current limit.
@noindent
These commands are available @emph{only} when @value{GDBN} is configured
-for debugging programs on MIPS processors.
-@end ifset
+for debugging programs on Alpha or MIPS processors.
+
-@node Source
+@node Source, Data, Stack, Top
@chapter Examining Source Files
@value{GDBN} can print parts of your program's source, since the debugging
@@ -3600,7 +4226,7 @@ Emacs facilities to view source; @pxref{Emacs, ,Using @value{GDBN} under @sc{gnu
* Machine Code:: Source and machine code
@end menu
-@node List
+@node List, Search, Source, Source
@section Printing source lines
@kindex list
@@ -3718,7 +4344,7 @@ Specifies the line containing the program address @var{address}.
@end table
@ifclear DOSHOST
-@node Search
+@node Search, Source Path, List, Source
@section Searching source files
@cindex searching
@kindex reverse-search
@@ -3745,7 +4371,7 @@ this command as @code{rev}.
@end table
@end ifclear
-@node Source Path
+@node Source Path, Machine Code, Search, Source
@section Specifying source directories
@cindex source path
@@ -3825,7 +4451,7 @@ directories you want in the source path. You can add all the
directories in one command.
@end enumerate
-@node Machine Code
+@node Machine Code, , Source Path, Source
@section Source and machine code
You can use the command @code{info line} to map source lines to program
@@ -3885,22 +4511,20 @@ surrounding this value. Two arguments specify a range of addresses
@end table
@ifclear H8EXCLUSIVE
-We can use @code{disassemble} to inspect the object code
-range shown in the last @code{info line} example (the example
-shows SPARC machine instructions):
-
+The following example shows the disassembly of a range of addresses of
+HP PA-RISC 2.0 code:
@smallexample
-(@value{GDBP}) disas 0x63e4 0x6404
-Dump of assembler code from 0x63e4 to 0x6404:
-0x63e4 <builtin_init+5340>: ble 0x63f8 <builtin_init+5360>
-0x63e8 <builtin_init+5344>: sethi %hi(0x4c00), %o0
-0x63ec <builtin_init+5348>: ld [%i1+4], %o0
-0x63f0 <builtin_init+5352>: b 0x63fc <builtin_init+5364>
-0x63f4 <builtin_init+5356>: ld [%o0+4], %o0
-0x63f8 <builtin_init+5360>: or %o0, 0x1a4, %o0
-0x63fc <builtin_init+5364>: call 0x9288 <path_search>
-0x6400 <builtin_init+5368>: nop
+(@value{GDBP}) disas 0x32c4 0x32e4
+Dump of assembler code from 0x32c4 to 0x32e4:
+0x32c4 <main+204>: addil 0,dp
+0x32c8 <main+208>: ldw 0x22c(sr0,r1),r26
+0x32cc <main+212>: ldil 0x3000,r31
+0x32d0 <main+216>: ble 0x3f8(sr4,r31)
+0x32d4 <main+220>: ldo 0(r31),rp
+0x32d8 <main+224>: addil -0x800,dp
+0x32dc <main+228>: ldo 0x588(r1),r26
+0x32e0 <main+232>: ldil 0x3000,r31
End of assembler dump.
@end smallexample
@end ifclear
@@ -3926,7 +4550,26 @@ to 0x808c:
@end smallexample
@end ifset
-@node Data
+Some architectures have more than one commonly-used set of instruction
+mnemonics or other syntax.
+
+@table @code
+@kindex set assembly-language
+@cindex assembly instructions
+@cindex instructions, assembly
+@cindex machine instructions
+@cindex listing machine instructions
+@item set assembly-language @var{instruction-set}
+Select the instruction set to use when disassembling the
+program via the @code{disassemble} or @code{x/i} commands.
+
+Currently this command is only defined for the Intel x86 family. You
+can set @var{instruction-set} to either @code{i386} or @code{i8086}.
+The default is @code{i386}.
+@end table
+
+
+@node Data, Languages, Source, Top
@chapter Examining Data
@cindex printing data
@@ -3986,9 +4629,10 @@ command rather than @code{print}. @xref{Symbols, ,Examining the Symbol Table}.
@ifclear HAVE-FLOAT
* Floating Point Hardware:: Floating point hardware
@end ifclear
+
@end menu
-@node Expressions
+@node Expressions, Variables, Data, Data
@section Expressions
@cindex expressions
@@ -4043,7 +4687,7 @@ a cast). This construct is allowed regardless of what kind of data is
normally supposed to reside at @var{addr}.
@end table
-@node Variables
+@node Variables, Arrays, Expressions, Data
@section Program variables
The most common kind of expression to use is the name of a variable
@@ -4054,7 +4698,7 @@ Variables in expressions are understood in the selected stack frame
@itemize @bullet
@item
-global (or static)
+global (or file-static)
@end itemize
@noindent or
@@ -4139,7 +4783,11 @@ also takes more than one machine instruction to destroy a stack frame;
after you begin stepping through that group of instructions, local
variable definitions may be gone.
-@node Arrays
+This may also happen when the compiler does significant optimizations.
+To be sure of always seeing accurate values, turn off all optimization
+when compiling.
+
+@node Arrays, Output Formats, Variables, Data
@section Artificial arrays
@cindex artificial array
@@ -4211,7 +4859,7 @@ p dtab[$i++]->fv
@dots{}
@end example
-@node Output Formats
+@node Output Formats, Memory, Arrays, Data
@section Output formats
@cindex formatted output
@@ -4280,7 +4928,7 @@ To reprint the last value in the value history with a different format,
you can use the @code{print} command with just a format and no
expression. For example, @samp{p/x} reprints the last value in hex.
-@node Memory
+@node Memory, Auto Display, Output Formats, Data
@section Examining memory
You can use the command @code{x} (for ``examine'') to examine memory in
@@ -4385,7 +5033,7 @@ If the @code{x} command has a repeat count, the address and contents saved
are from the last memory unit printed; this is not the same as the last
address printed if several units were printed on the last line of output.
-@node Auto Display
+@node Auto Display, Print Settings, Memory, Data
@section Automatic display
@cindex automatic display
@cindex display of expressions
@@ -4481,7 +5129,7 @@ there is no variable @code{last_char}---the display is disabled
automatically. The next time your program stops where @code{last_char}
is meaningful, you can enable the display expression once again.
-@node Print Settings
+@node Print Settings, Value History, Auto Display, Data
@section Print settings
@cindex format options
@@ -4777,7 +5425,12 @@ Allow @value{GDBN} to choose a decoding style by inspecting your program.
@item gnu
Decode based on the @sc{gnu} C++ compiler (@code{g++}) encoding algorithm.
+@ifclear HPPA
This is the default.
+@end ifclear
+
+@item hp
+Decode based on the HP ANSI C++ (@code{aCC}) encoding algorithm.
@item lucid
Decode based on the Lucid C++ compiler (@code{lcc}) encoding algorithm.
@@ -4788,9 +5441,8 @@ Decode using the algorithm in the @cite{C++ Annotated Reference Manual}.
debugging @code{cfront}-generated executables. @value{GDBN} would
require further enhancement to permit that.
-@item foo
-Show the list of formats.
@end table
+If you omit @var{style}, you will see a list of possible formats.
@kindex show demangle-style
@item show demangle-style
@@ -4823,10 +5475,15 @@ Do not print static members when displaying a C++ object.
@item show print static-members
Show whether C++ static members are printed, or not.
+@c These don't work with HP ANSI C++ yet.
@kindex set print vtbl
@item set print vtbl
@itemx set print vtbl on
Pretty print C++ virtual function tables. The default is off.
+@ifset HPPA
+(The @code{vtbl} commands do not work on programs compiled with the HP
+ANSI C++ compiler (@code{aCC}).)
+@end ifset
@item set print vtbl off
Do not pretty print C++ virtual function tables.
@@ -4837,7 +5494,7 @@ Show whether C++ virtual function tables are pretty printed, or not.
@end table
@end ifclear
-@node Value History
+@node Value History, Convenience Vars, Print Settings, Data
@section Value history
@cindex value history
@@ -4914,7 +5571,7 @@ values are available, @code{show values +} produces no display.
Pressing @key{RET} to repeat @code{show values @var{n}} has exactly the
same effect as @samp{show values +}.
-@node Convenience Vars
+@node Convenience Vars, Registers, Value History, Data
@section Convenience variables
@cindex convenience variables
@@ -4995,7 +5652,13 @@ The variable @code{$_exitcode} is automatically set to the exit code when
the program being debugged terminates.
@end table
-@node Registers
+@ifset HPPA
+If you refer to a function or variable name that begins with a dollar
+sign, @value{GDBN} searches for a user or system name first, before it
+searches for a convenience variable.
+@end ifset
+
+@node Registers, Floating Point Hardware, Convenience Vars, Data
@section Registers
@cindex registers
@@ -5117,7 +5780,7 @@ processors.
@end ifset
@ifclear HAVE-FLOAT
-@node Floating Point Hardware
+@node Floating Point Hardware, , Registers, Data
@section Floating point hardware
@cindex floating point
@@ -5135,7 +5798,7 @@ the ARM and x86 machines.
@end ifclear
@ifclear CONLY
-@node Languages
+@node Languages, Symbols, Data, Top
@chapter Using @value{GDBN} with Different Languages
@cindex languages
@@ -5166,7 +5829,7 @@ language}.
* Support:: Supported languages
@end menu
-@node Setting
+@node Setting, Show, Languages, Languages
@section Switching between source languages
There are two ways to control the working language---either have @value{GDBN}
@@ -5198,33 +5861,40 @@ program, and will display that source code, not the generated C code.
* Automatically:: Having @value{GDBN} infer the source language
@end menu
-@node Filenames
+@node Filenames, Manually, Setting, Setting
@subsection List of filename extensions and languages
If a source file name ends in one of the following extensions, then
@value{GDBN} infers that its language is the one indicated.
@table @file
-@ifset MOD2
-@item .mod
-Modula-2 source file
-@end ifset
@item .c
C source file
@item .C
@itemx .cc
-@itemx .cxx
-@itemx .cpp
@itemx .cp
+@itemx .cpp
+@itemx .cxx
@itemx .c++
C++ source file
+@item .f
+@itemx .F
+Fortran source file
+
+@ifclear HPPA
@item .ch
@itemx .c186
@itemx .c286
CHILL source file.
+@end ifclear
+
+@ifset MOD2
+@item .mod
+Modula-2 source file
+@end ifset
@item .s
@itemx .S
@@ -5232,7 +5902,10 @@ Assembler source file. This actually behaves almost like C, but
@value{GDBN} does not skip over function prologues when stepping.
@end table
-@node Manually
+In addition, you may set the language associated with a filename
+extension. @xref{Show, , Displaying the language}.
+
+@node Manually, Automatically, Filenames, Setting
@subsection Setting the working language
If you allow @value{GDBN} to set the language automatically,
@@ -5251,6 +5924,13 @@ a language, such as
@end ifset
For a list of the supported languages, type @samp{set language}.
+@ifclear MOD2
+Setting the language manually prevents @value{GDBN} from updating the
+working language automatically. For example, if you used the @code{c}
+setting to debug a C++ program, names might not be demangled properly,
+overload resolution would not work, user-defined operators might not be
+interpreted correctly, and so on.
+@end ifclear
@ifset MOD2
Setting the language manually prevents @value{GDBN} from updating the working
language automatically. This can lead to confusion if you try
@@ -5271,7 +5951,7 @@ printed would be the value of @code{a}. In Modula-2, this means to compare
@code{a} to the result of @code{b+c}, yielding a @code{BOOLEAN} value.
@end ifset
-@node Automatically
+@node Automatically, , Manually, Setting
@subsection Having @value{GDBN} infer the source language
To have @value{GDBN} set the working language automatically, use
@@ -5290,8 +5970,14 @@ written in one source language can be used by a main program written in
a different source language. Using @samp{set language auto} in this
case frees you from having to set the working language manually.
-@node Show
+@ifset MOD2
+@node Show, Checks, Setting, Languages
+@section Displaying the language
+@end ifset
+@ifclear MOD2
+@node Show, Support, Setting, Languages
@section Displaying the language
+@end ifclear
The following commands help you find out which language is the
working language, and also what language source files were written in.
@@ -5317,8 +6003,23 @@ Display the source language of this source file.
information listed here.
@end table
+In unusual circumstances, you may have source files with extensions
+not in the standard list. You can then set the extension associated
+with a language explicitly:
+
+@kindex set extension-language
+@kindex info extensions
+@table @code
+@item set extension-language @var{.ext} @var{language}
+Set source files with extension @var{.ext} to be assumed to be in
+the source language @var{language}.
+
+@item info extensions
+List all the filename extensions and the associated languages.
+@end table
+
@ifset MOD2
-@node Checks
+@node Checks, Support, Show, Languages
@section Type and range checking
@quotation
@@ -5351,7 +6052,7 @@ for the default settings of supported languages.
@cindex type checking
@cindex checks, type
-@node Type Checking
+@node Type Checking, Range Checking, Checks, Checks
@subsection An overview of type checking
Some languages, such as Modula-2, are strongly typed, meaning that the
@@ -5422,7 +6123,7 @@ is setting it automatically.
@cindex range checking
@cindex checks, range
-@node Range Checking
+@node Range Checking, , Type Checking, Checks
@subsection An overview of range checking
In some languages (such as Modula-2), it is an error to exceed the
@@ -5482,14 +6183,20 @@ being set automatically by @value{GDBN}.
@end table
@end ifset
-@node Support
+@ifset MOD2
+@node Support, , Checks, Languages
+@section Supported languages
+@end ifset
+@ifclear MOD2
+@node Support, , Show, Languages
@section Supported languages
+@end ifclear
@ifset MOD2
-@value{GDBN} 4 supports C, C++, and Modula-2.
+@value{GDBN} supports C, C++, Fortran, Chill, assembly, and Modula-2.
@end ifset
@ifclear MOD2
-@value{GDBN} 4 supports C, and C++.
+@value{GDBN} supports C, C++, Fortran, Chill, and assembly.
@end ifclear
Some @value{GDBN} features may be used in expressions regardless of the
language you use: the @value{GDBN} @code{@@} and @code{::} operators,
@@ -5511,50 +6218,70 @@ language reference or tutorial.
* Modula-2:: Modula-2
@end menu
-@node C
+@node C, Modula-2, , Support
@subsection C and C++
@cindex C and C++
@cindex expressions in C or C++
+@end ifset
Since C and C++ are so closely related, many features of @value{GDBN} apply
to both languages. Whenever this is the case, we discuss those languages
together.
-@end ifset
+
@ifclear MOD2
@c Cancel this below, under same condition, at end of this chapter!
@raisesections
@end ifclear
+@ifclear HPPA
@cindex C++
@kindex g++
@cindex @sc{gnu} C++
-The C++ debugging facilities are jointly implemented by the @sc{gnu} C++
+The C++ debugging facilities are jointly implemented by the C++
compiler and @value{GDBN}. Therefore, to debug your C++ code
-effectively, you must compile your C++ programs with the @sc{gnu} C++
-compiler, @code{g++}.
+effectively, you must compile your C++ programs with a supported
+C++ compiler, such as @sc{gnu} @code{g++}, or the HP ANSI C++
+compiler (@code{aCC}).
-For best results when debugging C++ programs, use the stabs debugging
+For best results when using @sc{gnu} C++, use the stabs debugging
format. You can select that format explicitly with the @code{g++}
command-line options @samp{-gstabs} or @samp{-gstabs+}. See
-@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu} CC,
-gcc.info, Using @sc{gnu} CC}, for more information.
+@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu}
+CC, gcc.info, Using @sc{gnu} CC}, for more information.
+@end ifclear
+@ifset HPPA
+@cindex C++
+@kindex g++
+@cindex @sc{gnu} C++
+You can use @value{GDBN} to debug C programs compiled with either the HP
+C compiler (@code{cc}) or the GNU C compiler (@code{gcc}), and to debug
+programs compiled with either the HP ANSI C++ compiler (@code{aCC}) or
+the @sc{gnu} C++ compiler (@code{g++}).
+
+If you compile with the @sc{gnu} C++ compiler, use the stabs debugging
+format for best results when debugging. You can select that format
+explicitly with the @code{g++} command-line options @samp{-gstabs} or
+@samp{-gstabs+}. See @ref{Debugging Options,,Options for Debugging Your
+Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more
+information.
+@end ifset
@end ifclear
+
@ifset CONLY
-@node C
+@node C, Symbols, Data, Top
@chapter C Language Support
@cindex C language
@cindex expressions in C
Information specific to the C language is built into @value{GDBN} so that you
-can use C expressions while degugging. This also permits @value{GDBN} to
+can use C expressions while debugging. This also permits @value{GDBN} to
output values in a manner consistent with C conventions.
@menu
* C Operators:: C operators
-* C Constants:: C constants
-* Debugging C:: @value{GDBN} and C
@end menu
@end ifset
+
@ifclear CONLY
@menu
* C Operators:: C and C++ operators
@@ -5566,18 +6293,18 @@ output values in a manner consistent with C conventions.
@end ifset
* Debugging C:: @value{GDBN} and C
-* Debugging C plus plus:: Special features for C++
+* Debugging C plus plus:: @value{GDBN} features for C++
@end menu
@end ifclear
@ifclear CONLY
@cindex C and C++ operators
-@node C Operators
+@node C Operators, C Constants, , C
@subsubsection C and C++ operators
@end ifclear
@ifset CONLY
@cindex C operators
-@node C Operators
+@node C Operators, C Constants, C, C
@section C operators
@end ifset
@@ -5591,8 +6318,14 @@ For the purposes of C and C++, the following definitions hold:
@itemize @bullet
@item
+@ifclear HPPA
@emph{Integral types} include @code{int} with any of its storage-class
specifiers; @code{char}; and @code{enum}.
+@end ifclear
+@ifset HPPA
+@emph{Integral types} include @code{int} with any of its storage-class
+specifiers; @code{char}; @code{enum}; and, for C++, @code{bool}.
+@end ifset
@item
@emph{Floating-point types} include @code{float} and @code{double}.
@@ -5710,6 +6443,11 @@ Structure member, and pointer-to-structure member. For convenience,
pointer based on the stored type information.
Defined on @code{struct} and @code{union} data.
+@ifset HPPA
+@item .*@r{, }->*
+Dereferences of pointers to members.
+@end ifset
+
@item []
Array indexing. @code{@var{a}[@var{i}]} is defined as
@code{*(@var{a}+@var{i})}. Same precedence as @code{->}.
@@ -5735,17 +6473,33 @@ Same precedence as @code{::}, above.
@end ifclear
@end table
+@ifset HPPA
+If an operator is redefined in the user code, @value{GDBN} usually
+attempts to invoke the redefined version instead of using the operator's
+predefined meaning.
+@end ifset
+
@ifclear CONLY
-@cindex C and C++ constants
-@node C Constants
+@menu
+* C Constants::
+@end menu
+
+@ifset MOD2
+@node C Constants, Cplus expressions, C Operators, C
@subsubsection C and C++ constants
+@end ifset
+@ifclear MOD2
+@node C Constants, Cplus expressions, C Operators, Support
+@subsubsection C and C++ constants
+@end ifclear
+@cindex C and C++ constants
@value{GDBN} allows you to express the constants of C and C++ in the
following ways:
@end ifclear
@ifset CONLY
@cindex C constants
-@node C Constants
+@node C Constants, Debugging C, C Operators, C
@section C constants
@value{GDBN} allows you to express the constants of C in the
@@ -5797,13 +6551,29 @@ and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers.
@end itemize
@ifclear CONLY
-@node Cplus expressions
+@menu
+* Cplus expressions::
+* C Defaults::
+@ifset MOD2
+* C Checks::
+@end ifset
+
+* Debugging C::
+@end menu
+
+@ifset MOD2
+@node Cplus expressions, C Defaults, C Constants, C
+@subsubsection C++ expressions
+@end ifset
+@ifclear MOD2
+@node Cplus expressions, C Defaults, C Constants, Support
@subsubsection C++ expressions
+@end ifclear
@cindex expressions in C++
-@value{GDBN} expression handling has a number of extensions to
-interpret a significant subset of C++ expressions.
+@value{GDBN} expression handling can interpret most C++ expressions.
+@ifclear HPPA
@cindex C++ support, not in @sc{coff}
@cindex @sc{coff} versus C++
@cindex C++ and object formats
@@ -5816,18 +6586,18 @@ interpret a significant subset of C++ expressions.
@c FIXME!! GDB may eventually be able to debug C++ using DWARF; check
@c periodically whether this has happened...
@quotation
-@emph{Warning:} @value{GDBN} can only debug C++ code if you compile with
-the @sc{gnu} C++ compiler. Moreover, C++ debugging depends on the use of
+@emph{Warning:} @value{GDBN} can only debug C++ code if you use the
+proper compiler. Typically, C++ debugging depends on the use of
additional debugging information in the symbol table, and thus requires
-special support. @value{GDBN} has this support @emph{only} with the
-stabs debug format. In particular, if your compiler generates a.out,
-MIPS @sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions
-to the symbol table, these facilities are all available. (With @sc{gnu} CC,
+special support. In particular, if your compiler generates a.out, MIPS
+@sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions to the
+symbol table, these facilities are all available. (With @sc{gnu} CC,
you can use the @samp{-gstabs} option to request stabs debugging
extensions explicitly.) Where the object code format is standard
@sc{coff} or @sc{dwarf} in @sc{elf}, on the other hand, most of the C++
support in @value{GDBN} does @emph{not} work.
@end quotation
+@end ifclear
@enumerate
@@ -5847,6 +6617,7 @@ expressions have the same namespace available as the member function;
that is, @value{GDBN} allows implicit references to the class instance
pointer @code{this} following the same rules as C++.
+@ifclear HPPA
@cindex call overloaded functions
@cindex type conversions in C++
@item
@@ -5855,6 +6626,38 @@ call to the right definition, with one restriction---you must use
arguments of the type required by the function that you want to call.
@value{GDBN} does not perform conversions requiring constructors or
user-defined type operators.
+@end ifclear
+@ifset HPPA
+@cindex call overloaded functions
+@cindex overloaded functions
+@cindex type conversions in C++
+@item
+You can call overloaded functions; @value{GDBN} resolves the function
+call to the right definition, with some restrictions. GDB does not
+perform overload resolution involving user-defined type conversions,
+calls to constructors, or instantiations of templates that do not exist
+in the program. It also cannot handle ellipsis argument lists or
+default arguments.
+
+It does perform integral conversions and promotions, floating-point
+promotions, arithmetic conversions, pointer conversions, conversions of
+class objects to base classes, and standard conversions such as those of
+functions or arrays to pointers; it requires an exact match on the
+number of function arguments.
+
+Overload resolution is always performed, unless you have specified
+@code{set overload-resolution off}. @xref{Debugging C plus plus,
+,@value{GDBN} features for C++}.
+
+You must specify@code{set overload-resolution off} in order to use an
+explicit function signature to call an overloaded function, as in
+@smallexample
+p 'foo(char,int)'('x', 13)
+@end smallexample
+The @value{GDBN} command-completion facility can simplify this;
+@pxref{Completion, ,Command completion}.
+
+@end ifset
@cindex reference declarations
@item
@@ -5878,27 +6681,41 @@ resolving name scope by reference to source files, in both C and C++
debugging (@pxref{Variables, ,Program variables}).
@end enumerate
-@node C Defaults
+@ifset HPPA
+In addition, @value{GDBN} supports calling virtual functions correctly,
+printing out virtual bases of objects, calling functions in a base
+subobject, casting objects, and invoking user-defined operators.
+@end ifset
+
+@ifset MOD2
+@node C Defaults, C Checks, Cplus expressions, C
@subsubsection C and C++ defaults
+@end ifset
+@ifclear MOD2
+@node C Defaults, Debugging C, Cplus expressions, Support
+@subsubsection C and C++ defaults
+@end ifclear
@cindex C and C++ defaults
+@ifclear HPPA
If you allow @value{GDBN} to set type and range checking automatically, they
both default to @code{off} whenever the working language changes to
C or C++. This happens regardless of whether you or @value{GDBN}
selects the working language.
+@end ifclear
-If you allow @value{GDBN} to set the language automatically, it recognizes
-source files whose names end with @file{.c}, @file{.C}, or @file{.cc}, and
-when @value{GDBN} enters code compiled from one of these files,
-it sets the working language to C or C++.
-@xref{Automatically, ,Having @value{GDBN} infer the source language}, for
-further details.
+If you allow @value{GDBN} to set the language automatically, it
+recognizes source files whose names end with @file{.c}, @file{.C}, or
+@file{.cc}, etc, and when @value{GDBN} enters code compiled from one of
+these files, it sets the working language to C or C++.
+@xref{Automatically, ,Having @value{GDBN} infer the source language},
+for further details.
@ifset MOD2
@c Type checking is (a) primarily motivated by Modula-2, and (b)
@c unimplemented. If (b) changes, it might make sense to let this node
@c appear even if Mod-2 does not, but meanwhile ignore it. roland 16jul93.
-@node C Checks
+@node C Checks, Debugging C, C Defaults, C Constants
@subsubsection C and C++ type and range checks
@cindex C and C++ checks
@@ -5932,11 +6749,17 @@ that is not itself an array.
@end ifclear
@ifclear CONLY
-@node Debugging C
+@ifset MOD2
+@node Debugging C, Debugging C plus plus, C Checks, C
+@subsubsection @value{GDBN} and C
+@end ifset
+@ifclear MOD2
+@node Debugging C, Debugging C plus plus, C Defaults, Support
@subsubsection @value{GDBN} and C
@end ifclear
+@end ifclear
@ifset CONLY
-@node Debugging C
+@node Debugging C, , C Constants, C
@section @value{GDBN} and C
@end ifset
@@ -5954,8 +6777,18 @@ with pointers and a memory allocation function. @xref{Expressions,
,Expressions}.
@ifclear CONLY
-@node Debugging C plus plus
+@menu
+* Debugging C plus plus::
+@end menu
+
+@ifset MOD2
+@node Debugging C plus plus, , Debugging C, C
+@subsubsection @value{GDBN} features for C++
+@end ifset
+@ifclear MOD2
+@node Debugging C plus plus, , Debugging C, Support
@subsubsection @value{GDBN} features for C++
+@end ifclear
@cindex commands for C++
Some @value{GDBN} commands are particularly useful with C++, and some are
@@ -5976,10 +6809,10 @@ classes.
@xref{Set Breaks, ,Setting breakpoints}.
@cindex C++ exception handling
-@item catch @var{exceptions}
-@itemx info catch
-Debug C++ exception handling using these commands. @xref{Exception
-Handling, ,Breakpoints and exceptions}.
+@item catch throw
+@itemx catch catch
+Debug C++ exception handling using these commands. @xref{Set
+Catchpoints, , Setting catchpoints}.
@cindex inheritance
@item ptype @var{typename}
@@ -6005,6 +6838,29 @@ Choose whether to print derived (actual) or declared types of objects.
@itemx show print vtbl
Control the format for printing virtual function tables.
@xref{Print Settings, ,Print settings}.
+@ifset HPPA
+(The @code{vtbl} commands do not work on programs compiled with the HP
+ANSI C++ compiler (@code{aCC}).)
+
+@kindex set overload-resolution
+@cindex overloaded functions
+@item set overload-resolution on
+Enable overload resolution for C++ expression evaluation. The default
+is on. For overloaded functions, @value{GDBN} evaluates the arguments
+and searches for a function whose signature matches the argument types,
+using the standard C++ conversion rules (@pxref{Cplus expressions, ,C++
+expressions} for details). If it cannot find a match, it emits a
+message.
+
+@item set overload-resolution off
+Disable overload resolution for C++ expression evaluation. For
+overloaded functions that are not class member functions, @value{GDBN}
+chooses the first function of the specified name that it finds in the
+symbol table, whether or not its arguments are of the correct type. For
+overloaded functions that are class member functions, @value{GDBN}
+searches for a function whose signature @emph{exactly} matches the
+argument types.
+@end ifset
@item @r{Overloaded symbol names}
You can specify a particular definition of an overloaded symbol, using
@@ -6020,7 +6876,7 @@ available choices, or to finish the type list for you.
@end ifclear
@ifset MOD2
-@node Modula-2
+@node Modula-2, ,C , Support
@subsection Modula-2
@cindex Modula-2
@@ -6034,7 +6890,7 @@ table.
@cindex expressions in Modula-2
@menu
* M2 Operators:: Built-in operators
-* Built-In Func/Proc:: Built-in functions and procedures
+* Built-In Func/Proc:: Built-in functions and procedures
* M2 Constants:: Modula-2 constants
* M2 Defaults:: Default settings for Modula-2
* Deviations:: Deviations from standard Modula-2
@@ -6043,7 +6899,7 @@ table.
* GDB/M2:: @value{GDBN} and Modula-2
@end menu
-@node M2 Operators
+@node M2 Operators, Built-In Func/Proc, Modula-2, Modula-2
@subsubsection Operators
@cindex Modula-2 operators
@@ -6167,7 +7023,7 @@ treats the use of the operator @code{IN}, or the use of operators
@end quotation
@cindex Modula-2 built-ins
-@node Built-In Func/Proc
+@node Built-In Func/Proc, M2 Constants, M2 Operators, Modula-2
@subsubsection Built-in functions and procedures
Modula-2 also makes available several built-in procedures and functions.
@@ -6279,7 +7135,7 @@ an error.
@end quotation
@cindex Modula-2 constants
-@node M2 Constants
+@node M2 Constants, M2 Defaults, Built-In Func/Proc, Modula-2
@subsubsection Constants
@value{GDBN} allows you to express the constants of Modula-2 in the following
@@ -6328,7 +7184,7 @@ Pointer constants consist of integral values only.
Set constants are not yet supported.
@end itemize
-@node M2 Defaults
+@node M2 Defaults, Deviations, M2 Constants, Modula-2
@subsubsection Modula-2 defaults
@cindex Modula-2 defaults
@@ -6342,7 +7198,7 @@ code compiled from a file whose name ends with @file{.mod} sets the
working language to Modula-2. @xref{Automatically, ,Having @value{GDBN} set
the language automatically}, for further details.
-@node Deviations
+@node Deviations, M2 Checks, M2 Defaults, Modula-2
@subsubsection Deviations from standard Modula-2
@cindex Modula-2, deviations from
@@ -6372,7 +7228,7 @@ argument.
All built-in procedures both modify @emph{and} return their argument.
@end itemize
-@node M2 Checks
+@node M2 Checks, M2 Scope, Deviations, Modula-2
@subsubsection Modula-2 type and range checks
@cindex Modula-2 checks
@@ -6400,7 +7256,7 @@ whose types are not equivalent is an error.
Range checking is done on all mathematical operations, assignment, array
index bounds, and all built-in functions and procedures.
-@node M2 Scope
+@node M2 Scope, GDB/M2, M2 Checks, Modula-2
@subsubsection The scope operators @code{::} and @code{.}
@cindex scope
@kindex .
@@ -6440,7 +7296,7 @@ an error if the identifier @var{id} was not imported from definition
module @var{module}, or if @var{id} is not an identifier in
@var{module}.
-@node GDB/M2
+@node GDB/M2, , M2 Scope, Modula-2
@subsubsection @value{GDBN} and Modula-2
Some @value{GDBN} commands have little use when debugging Modula-2 programs.
@@ -6463,7 +7319,7 @@ interpreted as the beginning of a comment. Use @code{<>} instead.
@end ifset
@end ifclear
-@node Symbols
+@node Symbols, Altering, Languages, Top
@chapter Examining the Symbol Table
The commands described in this section allow you to inquire about the
@@ -6617,6 +7473,7 @@ from the @code{ptype} command can be overwhelming and hard to use. The
which match the regular-expression @var{regexp}.
@end ignore
+@ifclear HPPA
@cindex reloading symbols
Some systems allow individual object files that make up your program to
be replaced without stopping and restarting your program.
@@ -6645,6 +7502,31 @@ different directories or libraries) with the same name.
@item show symbol-reloading
Show the current @code{on} or @code{off} setting.
@end table
+@end ifclear
+
+@ifset HPPA
+@kindex set opaque-type-resolution
+@item set opaque-type-resolution on
+Tell @value{GDBN} to resolve opaque types. An opaque type is a type
+declared as a pointer to a @code{struct}, @code{class}, or
+@code{union}---for example, @code{struct MyType *}---that is used in one
+source file although the full declaration of @code{struct MyType} is in
+another source file. The default is on.
+
+A change in the setting of this subcommand will not take effect until
+the next time symbols for a file are loaded.
+
+@item set opaque-type-resolution off
+Tell @value{GDBN} not to resolve opaque types. In this case, the type
+is printed as follows:
+@smallexample
+@{<no data fields>@}
+@end smallexample
+
+@kindex show opaque-type-resolution
+@item show opaque-type-resolution
+Show whether opaque types are resolved or not.
+@end ifset
@kindex maint print symbols
@cindex symbol dump
@@ -6669,7 +7551,7 @@ required for each object file from which @value{GDBN} has read some symbols.
@value{GDBN} reads symbols (in the description of @code{symbol-file}).
@end table
-@node Altering
+@node Altering, GDB Files, Symbols, Top
@chapter Altering Execution
Once you think you have found an error in your program, you might want to
@@ -6700,7 +7582,7 @@ at a different address, or even return prematurely from a function.
* Patching:: Patching your program
@end menu
-@node Assignment
+@node Assignment, Jumping, Altering, Altering
@section Assignment to variables
@cindex assignment
@@ -6728,13 +7610,14 @@ really the same as @code{print} except that the expression's value is
not printed and is not put in the value history (@pxref{Value History,
,Value history}). The expression is evaluated only for its effects.
+@ifclear HPPA
If the beginning of the argument string of the @code{set} command
appears identical to a @code{set} subcommand, use the @code{set
variable} command instead of just @code{set}. This command is identical
-to @code{set} except for its lack of subcommands. For example, if
-your program has a variable @code{width}, you get
-an error if you try to set a new value with just @samp{set width=13},
-because @value{GDBN} has the command @code{set width}:
+to @code{set} except for its lack of subcommands. For example, if your
+program has a variable @code{width}, you get an error if you try to set
+a new value with just @samp{set width=13}, because @value{GDBN} has the
+command @code{set width}:
@example
(@value{GDBP}) whatis width
@@ -6752,6 +7635,43 @@ order to actually set the program's variable @code{width}, use
@example
(@value{GDBP}) set var width=47
@end example
+@end ifclear
+@ifset HPPA
+Because the @code{set} command has many subcommands that can conflict
+with the names of program variables, it is a good idea to use the
+@code{set variable} command instead of just @code{set}. For example, if
+your program has a variable @code{g}, you run into problems if you try
+to set a new value with just @samp{set g=4}, because @value{GDBN} has
+the command @code{set gnutarget}, abbreviated @code{set g}:
+
+@example
+@group
+(@value{GDBP}) whatis g
+type = double
+(@value{GDBP}) p g
+$1 = 1
+(@value{GDBP}) set g=4
+(gdb) p g
+$2 = 1
+(@value{GDBP}) r
+The program being debugged has been started already.
+Start it from the beginning? (y or n) y
+Starting program: /home/smith/cc_progs/a.out
+"/home/smith/cc_progs/a.out": can't open to read symbols: Invalid bfd target.
+(@value{GDBP}) show g
+The current BFD target is "=4".
+@end group
+@end example
+
+@noindent
+The program variable @code{g} did not change, and you silently set the
+@code{gnutarget} to an invalid value. In order to set the variable
+@code{g}, use
+
+@example
+(@value{GDBP}) set var g=4
+@end example
+@end ifset
@value{GDBN} allows more implicit conversions in assignments than C; you can
freely store an integer value into a pointer variable or vice versa,
@@ -6773,7 +7693,7 @@ set @{int@}0x83040 = 4
@noindent
stores the value 4 into that memory location.
-@node Jumping
+@node Jumping, Signaling, Assignment, Altering
@section Continuing at a different address
Ordinarily, when you continue your program, you do so at the place where
@@ -6786,7 +7706,9 @@ an address of your own choosing, with the following commands:
Resume execution at line @var{linespec}. Execution stops again
immediately if there is a breakpoint there. @xref{List, ,Printing
source lines}, for a description of the different forms of
-@var{linespec}.
+@var{linespec}. It is common practice to use the @code{tbreak} command
+in conjunction with @code{jump}. @xref{Set Breaks, ,Setting
+breakpoints}.
The @code{jump} command does not change the current stack frame, or
the stack pointer, or the contents of any memory location or any
@@ -6802,6 +7724,8 @@ well acquainted with the machine-language code of your program.
Resume execution at the instruction at address @var{address}.
@end table
+@ifclear HPPA
+@c Doesn't work on HP-UX; have to set $pcoqh and $pcoqt.
You can get much the same effect as the @code{jump} command by storing a
new value into the register @code{$pc}. The difference is that this
does not start your program running; it only changes the address of where it
@@ -6815,14 +7739,16 @@ set $pc = 0x485
makes the next @code{continue} command or stepping command execute at
address @code{0x485}, rather than at the address where your program stopped.
@xref{Continuing and Stepping, ,Continuing and stepping}.
+@end ifclear
-The most common occasion to use the @code{jump} command is to back up--
-perhaps with more breakpoints set--over a portion of a program that has
-already executed, in order to examine its execution in more detail.
+The most common occasion to use the @code{jump} command is to back
+up---perhaps with more breakpoints set---over a portion of a program
+that has already executed, in order to examine its execution in more
+detail.
@ifclear BARETARGET
@c @group
-@node Signaling
+@node Signaling, Returning, Jumping, Altering
@section Giving your program a signal
@table @code
@@ -6852,7 +7778,7 @@ passes the signal directly to your program.
@end ifclear
-@node Returning
+@node Returning, Calling, Signaling, Altering
@section Returning from a function
@table @code
@@ -6883,7 +7809,7 @@ returned. In contrast, the @code{finish} command (@pxref{Continuing
and Stepping, ,Continuing and stepping}) resumes execution until the
selected stack frame returns naturally.
-@node Calling
+@node Calling, Patching, Returning, Altering
@section Calling program functions
@cindex calling functions
@@ -6899,13 +7825,15 @@ execute a function from your program, but without cluttering the output
with @code{void} returned values. If the result is not void, it
is printed and saved in the value history.
-A new user-controlled variable, @var{call_scratch_address}, specifies
-the location of a scratch area to be used when @value{GDBN} calls a
-function in the target. This is necessary because the usual method
-of putting the scratch area on the stack does not work in systems that
-have separate instruction and data spaces.
+@ifclear HPPA
+For the A29K, a user-controlled variable @code{call_scratch_address},
+specifies the location of a scratch area to be used when @value{GDBN}
+calls a function in the target. This is necessary because the usual
+method of putting the scratch area on the stack does not work in systems
+that have separate instruction and data spaces.
+@end ifclear
-@node Patching
+@node Patching, , Calling, Altering
@section Patching programs
@cindex patching binaries
@cindex writing into executables
@@ -6955,7 +7883,7 @@ and core files
are opened for writing as well as reading.
@end table
-@node GDB Files
+@node GDB Files, Targets, Altering, Top
@chapter @value{GDBN} Files
@value{GDBN} needs to know the file name of the program to be debugged, both in
@@ -6970,7 +7898,7 @@ the name of the core dump file.
* Symbol Errors:: Errors reading symbol files
@end menu
-@node Files
+@node Files, Symbol Errors, GDB Files, GDB Files
@section Commands to specify files
@cindex symbol table
@@ -7005,6 +7933,7 @@ directories to search, just as the shell does when looking for a program
to run. You can change the value of this variable, for both @value{GDBN}
and your program, using the @code{path} command.
+@ifclear HPPA
On systems with memory-mapped files, an auxiliary file
@file{@var{filename}.syms} may hold symbol table information for
@var{filename}. If so, @value{GDBN} maps in the symbol table from
@@ -7013,6 +7942,7 @@ descriptions of the file options @samp{-mapped} and @samp{-readnow}
(available on the command line, and with the commands @code{file},
@code{symbol-file}, or @code{add-symbol-file}, described below),
for more information.
+@end ifclear
@item file
@code{file} with no argument makes @value{GDBN} discard any information it
@@ -7046,26 +7976,32 @@ executing it once.
When @value{GDBN} is configured for a particular environment, it
understands debugging information in whatever format is the standard
generated for that environment; you may use either a @sc{gnu} compiler, or
-other compilers that adhere to the local conventions. Best results are
-usually obtained from @sc{gnu} compilers; for example, using @code{@value{GCC}}
-you can generate debugging information for optimized code.
-
-On some kinds of object files, the @code{symbol-file} command does not
-normally read the symbol table in full right away. Instead, it scans
-the symbol table quickly to find which source files and which symbols
-are present. The details are read later, one source file at a time,
-as they are needed.
-
-The purpose of this two-stage reading strategy is to make @value{GDBN} start up
-faster. For the most part, it is invisible except for occasional
-pauses while the symbol table details for a particular source file are
-being read. (The @code{set verbose} command can turn these pauses
-into messages if desired. @xref{Messages/Warnings, ,Optional warnings
-and messages}.)
+other compilers that adhere to the local conventions.
+@ifclear HPPA
+Best results are usually obtained from @sc{gnu} compilers; for example,
+using @code{@value{GCC}} you can generate debugging information for
+optimized code.
+@end ifclear
+
+For most kinds of object files, with the exception of old SVR3 systems
+using COFF, the @code{symbol-file} command does not normally read the
+symbol table in full right away. Instead, it scans the symbol table
+quickly to find which source files and which symbols are present. The
+details are read later, one source file at a time, as they are needed.
+The purpose of this two-stage reading strategy is to make @value{GDBN}
+start up faster. For the most part, it is invisible except for
+occasional pauses while the symbol table details for a particular source
+file are being read. (The @code{set verbose} command can turn these
+pauses into messages if desired. @xref{Messages/Warnings, ,Optional
+warnings and messages}.)
+
+@ifclear HPPA
We have not implemented the two-stage strategy for COFF yet. When the
symbol table is stored in COFF format, @code{symbol-file} reads the
-symbol table data in full right away.
+symbol table data in full right away. Note that ``stabs-in-COFF''
+still does the two-stage strategy, since the debug info is actually
+in stabs format.
@kindex readnow
@cindex reading symbols immediately
@@ -7079,8 +8015,10 @@ You can override the @value{GDBN} two-stage strategy for reading symbol
tables by using the @samp{-readnow} option with any of the commands that
load symbol table information, if you want to be sure @value{GDBN} has the
entire symbol table available.
+@end ifclear
@ifclear BARETARGET
+@ifclear HPPA
If memory-mapped files are available on your system through the
@code{mmap} system call, you can use another option, @samp{-mapped}, to
cause @value{GDBN} to write the symbols for your program into a reusable
@@ -7102,6 +8040,7 @@ needed.
The @file{.syms} file is specific to the host machine where you run
@value{GDBN}. It holds an exact image of the internal @value{GDBN}
symbol table. It cannot be shared across multiple host platforms.
+@end ifclear
@c FIXME: for now no mention of directories, since this seems to be in
@c flux. 13mar1992 status is that in theory GDB would look either in
@@ -7129,54 +8068,8 @@ program is running. To do this, use the @code{kill} command
(@pxref{Kill Process, ,Killing the child process}).
@end ifclear
-@kindex load @var{filename}
-@item load @var{filename}
-@ifset GENERIC
-Depending on what remote debugging facilities are configured into
-@value{GDBN}, the @code{load} command may be available. Where it exists, it
-is meant to make @var{filename} (an executable) available for debugging
-on the remote system---by downloading, or dynamic linking, for example.
-@code{load} also records the @var{filename} symbol table in @value{GDBN}, like
-the @code{add-symbol-file} command.
-
-If your @value{GDBN} does not have a @code{load} command, attempting to
-execute it gets the error message ``@code{You can't do that when your
-target is @dots{}}''
-@end ifset
-
-The file is loaded at whatever address is specified in the executable.
-For some object file formats, you can specify the load address when you
-link the program; for other formats, like a.out, the object file format
-specifies a fixed address.
-@c FIXME! This would be a good place for an xref to the GNU linker doc.
-
-@ifset VXWORKS
-On VxWorks, @code{load} links @var{filename} dynamically on the
-current target system as well as adding its symbols in @value{GDBN}.
-@end ifset
-
-@ifset I960
-@cindex download to Nindy-960
-With the Nindy interface to an Intel 960 board, @code{load}
-downloads @var{filename} to the 960 as well as adding its symbols in
-@value{GDBN}.
-@end ifset
-
-@ifset H8
-@cindex download to H8/300 or H8/500
-@cindex H8/300 or H8/500 download
-@cindex download to Hitachi SH
-@cindex Hitachi SH download
-When you select remote debugging to a Hitachi SH, H8/300, or H8/500 board
-(@pxref{Hitachi Remote,,@value{GDBN} and Hitachi Microprocessors}),
-the @code{load} command downloads your program to the Hitachi board and also
-opens it as the current executable target for @value{GDBN} on your host
-(like the @code{file} command).
-@end ifset
-
-@code{load} does not repeat if you press @key{RET} again after using it.
-
@ifclear BARETARGET
+@ifclear HPPA
@kindex add-symbol-file
@cindex dynamic linking
@item add-symbol-file @var{filename} @var{address}
@@ -7207,7 +8100,9 @@ operating system for the Motorola 88k. @value{GDBN} automatically looks for
shared libraries, however if @value{GDBN} does not find yours, you can run
@code{add-shared-symbol-file}. It takes no arguments.
@end ifclear
+@end ifclear
+@ifclear HPPA
@kindex section
@item section
The @code{section} command changes the base address of section SECTION of
@@ -7216,6 +8111,7 @@ section addresses, (such as in the a.out format), or when the addresses
specified in the file itself are wrong. Each section must be changed
separately. The ``info files'' command lists all the sections and their
addresses.
+@end ifclear
@kindex info files
@kindex info target
@@ -7241,12 +8137,23 @@ name and remembers it that way.
@ifclear BARETARGET
@cindex shared libraries
-@value{GDBN} supports SunOS, SVr4, Irix 5, and IBM RS/6000 shared libraries.
+@ifclear HPPA
+@c added HP-UX -- Kim (HP writer)
+@value{GDBN} supports HP-UX, SunOS, SVr4, Irix 5, and IBM RS/6000 shared
+libraries.
+@end ifclear
+@ifset HPPA
+@value{GDBN} supports HP-UX shared libraries.
+@end ifset
@value{GDBN} automatically loads symbol definitions from shared libraries
when you use the @code{run} command, or when you examine a core file.
(Before you issue the @code{run} command, @value{GDBN} does not understand
references to a function in a shared library, however---unless you are
debugging a core file).
+@ifset HPPA
+If the program loads a library explicitly, @value{GDBN} automatically
+loads the symbols at the time of the @code{shl_load} call.
+@end ifset
@c FIXME: some @value{GDBN} release may permit some refs to undef
@c FIXME...symbols---eg in a break cmd---assuming they are from a shared
@c FIXME...lib; check this from time to time when updating manual
@@ -7270,9 +8177,39 @@ required by your program for a core file or after typing @code{run}. If
@var{regex} is omitted all shared libraries required by your program are
loaded.
@end table
+
+@ifset HPPA
+@value{GDBN} detects the loading of a shared library and automatically
+reads in symbols from the newly loaded library, up to a threshold that
+is initially set but that you can modify if you wish.
+
+Beyond that threshold, symbols from shared libraries must be explicitly
+loaded. To load these symbols, use the command @code{sharedlibrary}
+@var{filename}. The base address of the shared library is determined
+automatically by @value{GDBN} and need not be specified.
+
+To display or set the threshold, use the commands:
+
+@table @code
+@kindex set auto-solib-add
+@item set auto-solib-add @var{threshold}
+Set the autoloading size threshold, in megabytes. If @var{threshold} is
+nonzero, symbols from all shared object libraries will be loaded
+automatically when the inferior begins execution or when the dynamic
+linker informs @value{GDBN} that a new library has been loaded, until
+the symbol table of the program and libraries exceeds this threshold.
+Otherwise, symbols must be loaded manually, using the
+@code{sharedlibrary} command. The default threshold is 100 megabytes.
+
+@kindex show auto-solib-add
+@item show auto-solib-add
+Display the current autoloading size threshold, in megabytes.
+@end table
+@end ifset
+
@end ifclear
-@node Symbol Errors
+@node Symbol Errors, , Files, GDB Files
@section Errors reading symbol files
While reading a symbol file, @value{GDBN} occasionally encounters problems,
@@ -7368,12 +8305,13 @@ for it.
@value{GDBN} could not parse a type specification output by the compiler.
@end table
-@node Targets
+@node Targets, Controlling GDB, GDB Files, Top
@chapter Specifying a Debugging Target
@cindex debugging target
@kindex target
A @dfn{target} is the execution environment occupied by your program.
+@ifclear HPPA
@ifclear BARETARGET
Often, @value{GDBN} runs in the same host environment as your program; in
that case, the debugging target is specified as a side effect when you
@@ -7382,6 +8320,29 @@ flexibility---for example, running @value{GDBN} on a physically separate
host, or controlling a standalone system over a serial port or a
realtime system over a TCP/IP connection---you
@end ifclear
+@end ifclear
+@ifset HPPA
+On HP-UX systems, @value{GDBN} has been configured to support debugging
+of processes running on the PA-RISC architecture. This means that the
+only possible targets are:
+
+@itemize @bullet
+@item
+An executable that has been compiled and linked to run on HP-UX
+
+@item
+A live HP-UX process, either started by @value{GDBN} (with the
+@code{run} command) or started outside of @value{GDBN} and attached to
+(with the @code{attach} command)
+
+@item
+A core file generated by an HP-UX process that previously aborted
+execution
+@end itemize
+
+@value{GDBN} on HP-UX has not been configured to support remote
+debugging, or to support programs running on other platforms. You
+@end ifset
@ifset BARETARGET
You
@end ifset
@@ -7392,10 +8353,14 @@ targets}).
@menu
* Active Targets:: Active targets
* Target Commands:: Commands for managing targets
+@ifset REMOTESTUB
+* Byte Order:: Choosing target byte order
* Remote:: Remote debugging
+@end ifset
+
@end menu
-@node Active Targets
+@node Active Targets, Target Commands, Targets, Targets
@section Active targets
@cindex stacking targets
@cindex active targets
@@ -7441,7 +8406,7 @@ the @code{attach} command (@pxref{Attach, ,Debugging an
already-running process}).
@end ifclear
-@node Target Commands
+@node Target Commands, Byte Order, Active Targets, Targets
@section Commands for managing targets
@table @code
@@ -7475,14 +8440,14 @@ select it.
@kindex set gnutarget
@item set gnutarget @var{args}
-@value{GDBN}uses its own library BFD to read your files. @value{GDBN}
+@value{GDBN} uses its own library BFD to read your files. @value{GDBN}
knows whether it is reading an @dfn{executable},
-a @dfn{core}, or a @dfn{.o} file, however you can specify the file format
+a @dfn{core}, or a @dfn{.o} file; however, you can specify the file format
with the @code{set gnutarget} command. Unlike most @code{target} commands,
with @code{gnutarget} the @code{target} refers to a program, not a machine.
@emph{Warning:} To specify a file format with @code{set gnutarget},
-you must know the actual BFD name.
+you must know the actual BFD name.
@noindent @xref{Files, , Commands to specify files}.
@@ -7490,12 +8455,17 @@ you must know the actual BFD name.
@item show gnutarget
Use the @code{show gnutarget} command to display what file format
@code{gnutarget} is set to read. If you have not set @code{gnutarget},
-@value{GDBN} will determine the file format for each file automatically
-and @code{show gnutarget} displays @code{The current BDF target is "auto"}.
+@value{GDBN} will determine the file format for each file automatically,
+and @code{show gnutarget} displays @samp{The current BDF target is "auto"}.
@end table
+@ifclear HPPA
Here are some common targets (available, or not, depending on the GDB
configuration):
+@end ifclear
+@ifset HPPA
+These are the valid targets on HP-UX systems:
+@end ifset
@table @code
@kindex target exec
@@ -7510,7 +8480,6 @@ A core dump file. @samp{target core @var{filename}} is the same as
@samp{core-file @var{filename}}.
@end ifclear
-@ifset REMOTESTUB
@kindex target remote
@item target remote @var{dev}
Remote serial target in GDB-specific protocol. The argument @var{dev}
@@ -7519,20 +8488,27 @@ specifies what serial device to use for the connection (e.g.
now supports the @code{load} command. This is only useful if you have
some other way of getting the stub to the target system, and you can put
it somewhere in memory where it won't get clobbered by the download.
-@end ifset
-@ifset SIMS
+@ifclear HPPA
@kindex target sim
@item target sim
CPU simulator. @xref{Simulator,,Simulated CPU Target}.
-@end ifset
+@end ifclear
+@end table
-@ifset AMD29K
-@kindex target udi
-@item target udi @var{keyword}
-Remote AMD29K target, using the AMD UDI protocol. The @var{keyword}
-argument specifies which 29K board or simulator to use. @xref{UDI29K
-Remote,,The UDI protocol for AMD29K}.
+The following targets are all CPU-specific, and only available for
+specific configurations.
+@c should organize by CPU
+
+@table @code
+
+@kindex target abug
+@item target abug @var{dev}
+ABug ROM monitor for M68K.
+
+@kindex target adapt
+@item target adapt @var{dev}
+Adapt monitor for A29K.
@kindex target amd-eb
@item target amd-eb @var{dev} @var{speed} @var{PROG}
@@ -7543,27 +8519,127 @@ Remote PC-resident AMD EB29K board, attached over serial lines.
name of the program to be debugged, as it appears to DOS on the PC.
@xref{EB29K Remote, ,The EBMON protocol for AMD29K}.
-@end ifset
-@ifset H8
+@kindex target array
+@item target array @var{dev}
+Array Tech LSI33K RAID controller board.
+
+@kindex target bug
+@item target bug @var{dev}
+BUG monitor, running on a MVME187 (m88k) board.
+
+@kindex target cpu32bug
+@item target cpu32bug @var{dev}
+CPU32BUG monitor, running on a CPU32 (M68K) board.
+
+@kindex target dbug
+@item target dbug @var{dev}
+dBUG ROM monitor for Motorola ColdFire.
+
+@kindex target ddb
+@item target ddb @var{dev}
+NEC's DDB monitor for Mips Vr4300.
+
+@kindex target dink32
+@item target dink32 @var{dev}
+DINK32 ROM monitor for PowerPC.
+
+@kindex target e7000
+@item target e7000 @var{dev}
+E7000 emulator for Hitachi H8 and SH.
+
+@kindex target es1800
+@item target es1800 @var{dev}
+ES-1800 emulator for M68K.
+
+@kindex target est
+@item target est @var{dev}
+EST-300 ICE monitor, running on a CPU32 (M68K) board.
+
@kindex target hms
@item target hms @var{dev}
A Hitachi SH, H8/300, or H8/500 board, attached via serial line to your host.
@ifclear H8EXCLUSIVE
Use special commands @code{device} and @code{speed} to control the serial
line and the communications speed used.
-@end ifclear
@xref{Hitachi Remote,,@value{GDBN} and Hitachi Microprocessors}.
-@end ifset
-@ifset I960
+@kindex target lsi
+@item target lsi @var{dev}
+LSI ROM monitor for Mips.
+
+@kindex target m32r
+@item target m32r @var{dev}
+Mitsubishi M32R/D ROM monitor.
+
+@kindex target mips
+@item target mips @var{dev}
+IDT/SIM ROM monitor for Mips.
+
+@kindex target mon960
+@item target mon960 @var{dev}
+MON960 monitor for Intel i960.
+
@kindex target nindy
@item target nindy @var{devicename}
An Intel 960 board controlled by a Nindy Monitor. @var{devicename} is
the name of the serial device to use for the connection, e.g.
@file{/dev/ttya}. @xref{i960-Nindy Remote, ,@value{GDBN} with a remote i960 (Nindy)}.
-@end ifset
-@ifset ST2000
+@kindex target nrom
+@item target nrom @var{dev}
+NetROM ROM emulator. This target only supports downloading.
+
+@kindex target op50n
+@item target op50n @var{dev}
+OP50N monitor, running on an OKI HPPA board.
+
+@kindex target pmon
+@item target pmon @var{dev}
+PMON ROM monitor for Mips.
+
+@kindex target ppcbug
+@item target ppcbug @var{dev}
+@kindex target ppcbug1
+@item target ppcbug1 @var{dev}
+PPCBUG ROM monitor for PowerPC.
+
+@kindex target r3900
+@item target r3900 @var{dev}
+Densan DVE-R3900 ROM monitor for Toshiba R3900 Mips.
+
+@kindex target rdi
+@item target rdi @var{dev}
+ARM Angel monitor, via RDI library interface.
+
+@kindex target rdp
+@item target rdp @var{dev}
+ARM Demon monitor.
+
+@kindex target rom68k
+@item target rom68k @var{dev}
+ROM 68K monitor, running on an M68K IDP board.
+
+@kindex target rombug
+@item target rombug @var{dev}
+ROMBUG ROM monitor for OS/9000.
+
+@kindex target sds
+@item target sds @var{dev}
+SDS monitor, running on a PowerPC board (such as Motorola's ADS).
+
+@kindex target sparclite
+@item target sparclite @var{dev}
+Fujitsu sparclite boards, used only for the purpose of loading.
+You must use an additional command to debug the program.
+For example: target remote @var{dev} using @value{GDBN} standard
+remote protocol.
+
+@kindex target sh3
+@kindex target sh3e
+@item target sh3 @var{dev}
+@item target sh3e @var{dev}
+Hitachi SH-3 and SH-3E target systems.
+
@kindex target st2000
@item target st2000 @var{dev} @var{speed}
A Tandem ST2000 phone switch, running Tandem's STDBUG protocol. @var{dev}
@@ -7571,46 +8647,24 @@ is the name of the device attached to the ST2000 serial line;
@var{speed} is the communication line speed. The arguments are not used
if @value{GDBN} is configured to connect to the ST2000 using TCP or Telnet.
@xref{ST2000 Remote,,@value{GDBN} with a Tandem ST2000}.
-@end ifset
-@ifset VXWORKS
+@kindex target udi
+@item target udi @var{keyword}
+Remote AMD29K target, using the AMD UDI protocol. The @var{keyword}
+argument specifies which 29K board or simulator to use. @xref{UDI29K
+Remote,,The UDI protocol for AMD29K}.
+
@kindex target vxworks
@item target vxworks @var{machinename}
A VxWorks system, attached via TCP/IP. The argument @var{machinename}
is the target system's machine name or IP address.
@xref{VxWorks Remote, ,@value{GDBN} and VxWorks}.
-@end ifset
-
-@kindex target cpu32bug
-@item target cpu32bug @var{dev}
-CPU32BUG monitor, running on a CPU32 (M68K) board.
-
-@kindex target op50n
-@item target op50n @var{dev}
-OP50N monitor, running on an OKI HPPA board.
@kindex target w89k
@item target w89k @var{dev}
W89K monitor, running on a Winbond HPPA board.
-@kindex target est
-@item target est @var{dev}
-EST-300 ICE monitor, running on a CPU32 (M68K) board.
-
-@kindex target rom68k
-@item target rom68k @var{dev}
-ROM 68K monitor, running on an IDP board.
-
-@kindex target array
-@item target array @var{dev}
-Array Tech LSI33K RAID controller board.
-
-@kindex target sparclite
-@item target sparclite @var{dev}
-Fujitsu sparclite boards, used only for the purpose of loading.
-You must use an additional command to debug the program.
-For example: target remote @var{dev} using @value{GDBN} standard
-remote protocol.
+@end ifclear
@end table
@ifset GENERIC
@@ -7618,6 +8672,61 @@ Different targets are available on different configurations of @value{GDBN};
your configuration may have more or fewer targets.
@end ifset
+Many remote targets require you to download the executable's code
+once you've successfully established a connection.
+
+@table @code
+
+@kindex load @var{filename}
+@item load @var{filename}
+@ifset GENERIC
+Depending on what remote debugging facilities are configured into
+@value{GDBN}, the @code{load} command may be available. Where it exists, it
+is meant to make @var{filename} (an executable) available for debugging
+on the remote system---by downloading, or dynamic linking, for example.
+@code{load} also records the @var{filename} symbol table in @value{GDBN}, like
+the @code{add-symbol-file} command.
+
+If your @value{GDBN} does not have a @code{load} command, attempting to
+execute it gets the error message ``@code{You can't do that when your
+target is @dots{}}''
+@end ifset
+
+The file is loaded at whatever address is specified in the executable.
+For some object file formats, you can specify the load address when you
+link the program; for other formats, like a.out, the object file format
+specifies a fixed address.
+@c FIXME! This would be a good place for an xref to the GNU linker doc.
+
+@ifset VXWORKS
+On VxWorks, @code{load} links @var{filename} dynamically on the
+current target system as well as adding its symbols in @value{GDBN}.
+@end ifset
+
+@ifset I960
+@cindex download to Nindy-960
+With the Nindy interface to an Intel 960 board, @code{load}
+downloads @var{filename} to the 960 as well as adding its symbols in
+@value{GDBN}.
+@end ifset
+
+@ifset H8
+@cindex download to H8/300 or H8/500
+@cindex H8/300 or H8/500 download
+@cindex download to Hitachi SH
+@cindex Hitachi SH download
+When you select remote debugging to a Hitachi SH, H8/300, or H8/500 board
+(@pxref{Hitachi Remote,,@value{GDBN} and Hitachi Microprocessors}),
+the @code{load} command downloads your program to the Hitachi board and also
+opens it as the current executable target for @value{GDBN} on your host
+(like the @code{file} command).
+@end ifset
+
+@code{load} does not repeat if you press @key{RET} again after using it.
+@end table
+
+@ifset REMOTESTUB
+@node Byte Order, Remote, Target Commands, Targets
@section Choosing target byte order
@cindex choosing target byte order
@cindex target byte order
@@ -7626,17 +8735,37 @@ your configuration may have more or fewer targets.
@kindex set endian auto
@kindex show endian
-You can now choose which byte order to use with a target system.
-Use the @code{set endian big} and @code{set endian little} commands.
-Use the @code{set endian auto} command to instruct
-@value{GDBN} to use the byte order associated with the executable.
-You can see the current setting for byte order with the @code{show endian}
-command.
-
-@emph{Warning:} Currently, only embedded MIPS configurations support
-dynamic selection of target byte order.
+Some types of processors, such as the MIPS, PowerPC, and Hitachi SH,
+offer the ability to run either big-endian or little-endian byte
+orders. Usually the executable or symbol will include a bit to
+designate the endian-ness, and you will not need to worry about
+which to use. However, you may still find it useful to adjust
+GDB's idea of processor endian-ness manually.
+
+@table @code
+@kindex set endian big
+@item set endian big
+Instruct @value{GDBN} to assume the target is big-endian.
+
+@kindex set endian little
+@item set endian little
+Instruct @value{GDBN} to assume the target is little-endian.
+
+@kindex set endian auto
+@item set endian auto
+Instruct @value{GDBN} to use the byte order associated with the
+executable.
+
+@item show endian
+Display @value{GDBN}'s current idea of the target byte order.
+
+@end table
+
+Note that these commands merely adjust interpretation of symbolic
+data on the host, and that they have absolutely no effect on the
+target system.
-@node Remote
+@node Remote, , Byte Order, Targets
@section Remote debugging
@cindex remote debugging
@@ -7655,6 +8784,7 @@ communicate with @value{GDBN}.
Other remote targets may be available in your
configuration of @value{GDBN}; use @code{help target} to list them.
+@end ifset
@ifset GENERIC
@c Text on starting up GDB in various specific cases; it goes up front
@@ -7683,6 +8813,9 @@ configuration of @value{GDBN}; use @code{help target} to list them.
@ifset MIPS
* MIPS Remote:: @value{GDBN} and MIPS boards
@end ifset
+@ifset SPARCLET
+* Sparclet Remote:: @value{GDBN} and Sparclet boards
+@end ifset
@ifset SIMS
* Simulator:: Simulated CPU target
@end ifset
@@ -7708,7 +8841,7 @@ here.
* Messages/Warnings:: Optional warnings and messages
@end menu
-@node Prompt
+@node Prompt, Editing, Controlling GDB, Controlling GDB
@section Prompt
@cindex prompt
@@ -7734,7 +8867,7 @@ Directs @value{GDBN} to use @var{newprompt} as its prompt string henceforth.
Prints a line of the form: @samp{Gdb's prompt is: @var{your-prompt}}
@end table
-@node Editing
+@node Editing, History, Prompt, Controlling GDB
@section Command editing
@cindex readline
@cindex command line editing
@@ -7764,7 +8897,7 @@ Disable command line editing.
Show whether command line editing is enabled.
@end table
-@node History
+@node History, Screen Size, Editing, Controlling GDB
@section Command history
@value{GDBN} can keep track of the commands you type during your
@@ -7860,7 +8993,7 @@ Print ten commands centered on command number @var{n}.
Print ten commands just after the commands last printed.
@end table
-@node Screen Size
+@node Screen Size, Numbers, History, Controlling GDB
@section Screen size
@cindex size of screen
@cindex pauses in output
@@ -7901,7 +9034,7 @@ Likewise, you can specify @samp{set width 0} to prevent @value{GDBN}
from wrapping its output.
@end table
-@node Numbers
+@node Numbers, Messages/Warnings, Screen Size, Controlling GDB
@section Numbers
@cindex number representation
@cindex entering numbers
@@ -7947,7 +9080,7 @@ Display the current default base for numeric input.
Display the current default base for numeric display.
@end table
-@node Messages/Warnings
+@node Messages/Warnings, , Numbers, Controlling GDB
@section Optional warnings and messages
By default, @value{GDBN} is silent about its inner workings. If you are running
@@ -8018,7 +9151,7 @@ Enables confirmation requests (the default).
Displays state of confirmation requests.
@end table
-@node Sequences
+@node Sequences, Emacs, Controlling GDB, Top
@chapter Canned Sequences of Commands
Aside from breakpoint commands (@pxref{Break Commands, ,Breakpoint
@@ -8027,12 +9160,12 @@ for execution as a unit: user-defined commands and command files.
@menu
* Define:: User-defined commands
-* Hooks:: User-defined command hooks
+* Hooks:: User-defined command hooks
* Command Files:: Command files
* Output:: Commands for controlled output
@end menu
-@node Define
+@node Define, Hooks, Sequences, Sequences
@section User-defined commands
@cindex user-defined command
@@ -8121,7 +9254,7 @@ without asking when used inside a user-defined command. Many @value{GDBN}
commands that normally print messages to say what they are doing omit the
messages when used in a user-defined command.
-@node Hooks
+@node Hooks, Command Files, Define, Sequences
@section User-defined command hooks
@cindex command files
@@ -8167,7 +9300,7 @@ If an error occurs during the execution of your hook, execution of
If you try to define a hook which does not match any known command, you
get a warning from the @code{define} command.
-@node Command Files
+@node Command Files, Output, Hooks, Sequences
@section Command files
@cindex command files
@@ -8177,25 +9310,24 @@ An empty line in a command file does nothing; it does not mean to repeat
the last command, as it would from the terminal.
@cindex init file
-@cindex @file{@value{GDBINIT}}
+@cindex @file{.gdbinit}
When you start @value{GDBN}, it automatically executes commands from its
-@dfn{init files}. These are files named @file{@value{GDBINIT}}.
-@value{GDBN} reads the init file (if any) in your home directory, then
-processes command line options and operands, and then reads the init
-file (if any) in the current working directory. This is so the init
-file in your home directory can set options (such as @code{set
-complaints}) which affect the processing of the command line options and
-operands. The init files are not executed if you use the @samp{-nx}
-option; @pxref{Mode Options, ,Choosing modes}.
+@dfn{init files}. These are files named @file{.gdbinit} on Unix, or
+@file{gdb.ini} on DOS/Windows. @value{GDBN} reads the init file (if
+any) in your home directory, then processes command line options and
+operands, and then reads the init file (if any) in the current working
+directory. This is so the init file in your home directory can set
+options (such as @code{set complaints}) which affect the processing of
+the command line options and operands. The init files are not executed
+if you use the @samp{-nx} option; @pxref{Mode Options, ,Choosing modes}.
@ifset GENERIC
@cindex init file name
On some configurations of @value{GDBN}, the init file is known by a
different name (these are typically environments where a specialized
-form of @value{GDBN} may need to coexist with other forms,
-hence a different name
-for the specialized version's init file). These are the environments
-with special init file names:
+form of @value{GDBN} may need to coexist with other forms, hence a
+different name for the specialized version's init file). These are the
+environments with special init file names:
@kindex .vxgdbinit
@itemize @bullet
@@ -8230,7 +9362,7 @@ without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
when called from command files.
-@node Output
+@node Output, , Command Files, Sequences
@section Commands for controlled output
During the execution of a command file or a user-defined command, normal
@@ -8307,7 +9439,7 @@ letter.
@end table
@ifclear DOSHOST
-@node Emacs
+@node Emacs, GDB Bugs, Sequences, Top
@chapter Using @value{GDBN} under @sc{gnu} Emacs
@cindex Emacs
@@ -8320,6 +9452,9 @@ To use this interface, use the command @kbd{M-x gdb} in Emacs. Give the
executable file you want to debug as an argument. This command starts
@value{GDBN} as a subprocess of Emacs, with input and output through a newly
created Emacs buffer.
+@ifset HPPA
+(Do not use the @code{-tui} option to run @value{GDBN} from Emacs.)
+@end ifset
Using @value{GDBN} under Emacs is just like using @value{GDBN} normally except for two
things:
@@ -8481,36 +9616,9 @@ each value is printed in its own window.
@end ignore
@end ifclear
-@ifset LUCID
-@node Energize
-@chapter Using @value{GDBN} with Energize
-
-@cindex Energize
-The Energize Programming System is an integrated development environment
-that includes a point-and-click interface to many programming tools.
-When you use @value{GDBN} in this environment, you can use the standard
-Energize graphical interface to drive @value{GDBN}; you can also, if you
-choose, type @value{GDBN} commands as usual in a debugging window. Even if
-you use the graphical interface, the debugging window (which uses Emacs,
-and resembles the standard @sc{gnu} Emacs interface to
-@value{GDBN}) displays the
-equivalent commands, so that the history of your debugging session is
-properly reflected.
-
-When Energize starts up a @value{GDBN} session, it uses one of the
-command-line options @samp{-energize} or @samp{-cadillac} (``cadillac''
-is the name of the communications protocol used by the Energize system).
-This option makes @value{GDBN} run as one of the tools in the Energize Tool
-Set: it sends all output to the Energize kernel, and accept input from
-it as well.
-
-See the user manual for the Energize Programming System for
-information on how to use the Energize graphical interface and the other
-development tools that Energize integrates with @value{GDBN}.
-
-@end ifset
-
@node GDB Bugs
+@c links whacked to pacify makeinfo
+@c , Command Line Editing, Emacs, Top
@chapter Reporting Bugs in @value{GDBN}
@cindex bugs in @value{GDBN}
@cindex reporting bugs in @value{GDBN}
@@ -8530,7 +9638,7 @@ information that enables us to fix the bug.
* Bug Reporting:: How to report bugs
@end menu
-@node Bug Criteria
+@node Bug Criteria, Bug Reporting, GDB Bugs, GDB Bugs
@section Have you found a bug?
@cindex bug criteria
@@ -8546,7 +9654,9 @@ If the debugger gets a fatal signal, for any input whatever, that is a
@cindex error on valid input
@item
-If @value{GDBN} produces an error message for valid input, that is a bug.
+If @value{GDBN} produces an error message for valid input, that is a
+bug. (Note that if you're cross debugging, the problem may also be
+somewhere in the connection to the target.)
@cindex invalid input
@item
@@ -8560,11 +9670,12 @@ If you are an experienced user of debugging tools, your suggestions
for improvement of @value{GDBN} are welcome in any case.
@end itemize
-@node Bug Reporting
+@node Bug Reporting, , Bug Criteria, GDB Bugs
@section How to report bugs
@cindex bug reports
@cindex @value{GDBN} bugs, reporting
+@ifclear HPPA
A number of companies and individuals offer support for @sc{gnu} products.
If you obtained @value{GDBN} from a support organization, we recommend you
contact that organization first.
@@ -8572,18 +9683,19 @@ contact that organization first.
You can find contact information for many support companies and
individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
distribution.
+@c should add a web page ref...
-In any event, we also recommend that you send bug reports for @value{GDBN} to one
-of these addresses:
+In any event, we also recommend that you send bug reports for
+@value{GDBN} to this addresses:
@example
bug-gdb@@prep.ai.mit.edu
-@{ucbvax|mit-eddie|uunet@}!prep.ai.mit.edu!bug-gdb
@end example
@strong{Do not send bug reports to @samp{info-gdb}, or to
-@samp{help-gdb}, or to any newsgroups.} Most users of @value{GDBN} do not want to
-receive bug reports. Those that do have arranged to receive @samp{bug-gdb}.
+@samp{help-gdb}, or to any newsgroups.} Most users of @value{GDBN} do
+not want to receive bug reports. Those that do have arranged to receive
+@samp{bug-gdb}.
The mailing list @samp{bug-gdb} has a newsgroup @samp{gnu.gdb.bug} which
serves as a repeater. The mailing list and the newsgroup carry exactly
@@ -8603,6 +9715,15 @@ Free Software Foundation Inc.
Boston, MA 02111-1307
USA
@end example
+@end ifclear
+
+@ifset HPPA
+If you obtained HP GDB as part of your HP ANSI C or HP ANSI C++ compiler
+kit, report problems to your HP Support Representative.
+
+If you obtained HP GDB from the Hewlett-Packard Web site, report
+problems by electronic mail to @code{wdb-www@@ch.hp.com}.
+@end ifset
The fundamental principle of reporting bugs usefully is this:
@strong{report all the facts}. If you are not sure whether to state a
@@ -8618,16 +9739,10 @@ of that location would fool the debugger into doing the right thing despite
the bug. Play it safe and give a specific, complete example. That is the
easiest thing for you to do, and the most helpful.
-Keep in mind that the purpose of a bug report is to enable us to fix
-the bug if it is new to us.
-@c
-@c FIX ME!!--What the heck does the following sentence mean,
-@c in the context of the one above?
-@c
-@c It is not as important as what happens if the bug is already known.
-@c
-Therefore, always write your bug reports on
-the assumption that the bug has not been reported previously.
+Keep in mind that the purpose of a bug report is to enable us to fix the
+bug. It may be that the bug has been reported previously, but neither
+you nor we can know that unless your bug report is complete and
+self-contained.
Sometimes people give a few sketchy facts and ask, ``Does this ring a
bell?'' Those bug reports are useless, and we urge everyone to
@@ -8638,8 +9753,9 @@ To enable us to fix the bug, you should include all these things:
@itemize @bullet
@item
-The version of @value{GDBN}. @value{GDBN} announces it if you start with no
-arguments; you can also print it at any time using @code{show version}.
+The version of @value{GDBN}. @value{GDBN} announces it if you start
+with no arguments; you can also print it at any time using @code{show
+version}.
Without this, we will not know whether there is any point in looking for
the bug in the current version of @value{GDBN}.
@@ -8648,13 +9764,18 @@ the bug in the current version of @value{GDBN}.
The type of machine you are using, and the operating system name and
version number.
+@ifclear HPPA
@item
What compiler (and its version) was used to compile @value{GDBN}---e.g.
-``@value{GCC}--2.0''.
+``@value{GCC}--2.8.1''.
+@end ifclear
@item
-What compiler (and its version) was used to compile the program you
-are debugging---e.g. ``@value{GCC}--2.0''.
+What compiler (and its version) was used to compile the program you are
+debugging---e.g. ``@value{GCC}--2.8.1'', or ``HP92453-01 A.10.32.03 HP
+C Compiler''. For GCC, you can say @code{gcc --version} to get this
+information; for other compilers, see the documentation for those
+compilers.
@item
The command arguments you gave the compiler to compile your example and
@@ -8673,20 +9794,21 @@ reproduce the bug.
A description of what behavior you observe that you believe is
incorrect. For example, ``It gets a fatal signal.''
-Of course, if the bug is that @value{GDBN} gets a fatal signal, then we will
-certainly notice it. But if the bug is incorrect output, we might not
-notice unless it is glaringly wrong. You might as well not give us a
-chance to make a mistake.
+Of course, if the bug is that @value{GDBN} gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might
+not notice unless it is glaringly wrong. You might as well not give us
+a chance to make a mistake.
Even if the problem you experience is a fatal signal, you should still
-say so explicitly. Suppose something strange is going on, such as,
-your copy of @value{GDBN} is out of synch, or you have encountered a
-bug in the C library on your system. (This has happened!) Your copy
-might crash and ours would not. If you told us to expect a crash,
-then when ours fails to crash, we would know that the bug was not
-happening for us. If you had not told us to expect a crash, then we
-would not be able to draw any conclusion from our observations.
-
+say so explicitly. Suppose something strange is going on, such as, your
+copy of @value{GDBN} is out of synch, or you have encountered a bug in
+the C library on your system. (This has happened!) Your copy might
+crash and ours would not. If you told us to expect a crash, then when
+ours fails to crash, we would know that the bug was not happening for
+us. If you had not told us to expect a crash, then we would not be able
+to draw any conclusion from our observations.
+
+@ifclear HPPA
@item
If you wish to suggest changes to the @value{GDBN} source, send us context
diffs. If you even discuss something in the @value{GDBN} source, refer to
@@ -8694,6 +9816,7 @@ it by context, not by line number.
The line numbers in our development sources will not match those in your
sources. Your line numbers would convey no useful information to us.
+@end ifclear
@end itemize
Here are some things that are not necessary:
@@ -8752,129 +9875,12 @@ things without first using the debugger to find the facts.
@include rluser.texinfo
@include inc-hist.texi
-@ifset NOVEL
-@ifset RENAMED
-@node Renamed Commands
-@appendix Renamed Commands
-
-The following commands were renamed in @value{GDBN} 4, in order to make the
-command set as a whole more consistent and easier to use and remember:
-
-@kindex add-syms
-@kindex delete environment
-@kindex info copying
-@kindex info convenience
-@kindex info directories
-@kindex info editing
-@kindex info history
-@kindex info targets
-@kindex info values
-@kindex info version
-@kindex info warranty
-@kindex set addressprint
-@kindex set arrayprint
-@kindex set prettyprint
-@kindex set screen-height
-@kindex set screen-width
-@kindex set unionprint
-@kindex set vtblprint
-@kindex set demangle
-@kindex set asm-demangle
-@kindex set sevenbit-strings
-@kindex set array-max
-@kindex set caution
-@kindex set history write
-@kindex show addressprint
-@kindex show arrayprint
-@kindex show prettyprint
-@kindex show screen-height
-@kindex show screen-width
-@kindex show unionprint
-@kindex show vtblprint
-@kindex show demangle
-@kindex show asm-demangle
-@kindex show sevenbit-strings
-@kindex show array-max
-@kindex show caution
-@kindex show history write
-@kindex unset
-
-@c TEXI2ROFF-KILL
-@ifinfo
-@c END TEXI2ROFF-KILL
-@example
-OLD COMMAND NEW COMMAND
-@c TEXI2ROFF-KILL
---------------- -------------------------------
-@c END TEXI2ROFF-KILL
-add-syms add-symbol-file
-delete environment unset environment
-info convenience show convenience
-info copying show copying
-info directories show directories
-info editing show commands
-info history show values
-info targets help target
-info values show values
-info version show version
-info warranty show warranty
-set/show addressprint set/show print address
-set/show array-max set/show print elements
-set/show arrayprint set/show print array
-set/show asm-demangle set/show print asm-demangle
-set/show caution set/show confirm
-set/show demangle set/show print demangle
-set/show history write set/show history save
-set/show prettyprint set/show print pretty
-set/show screen-height set/show height
-set/show screen-width set/show width
-set/show sevenbit-strings set/show print sevenbit-strings
-set/show unionprint set/show print union
-set/show vtblprint set/show print vtbl
-
-unset [No longer an alias for delete]
-@end example
-@c TEXI2ROFF-KILL
-@end ifinfo
-
-@tex
-\vskip \parskip\vskip \baselineskip
-\halign{\tt #\hfil &\qquad#&\tt #\hfil\cr
-{\bf Old Command} &&{\bf New Command}\cr
-add-syms &&add-symbol-file\cr
-delete environment &&unset environment\cr
-info convenience &&show convenience\cr
-info copying &&show copying\cr
-info directories &&show directories \cr
-info editing &&show commands\cr
-info history &&show values\cr
-info targets &&help target\cr
-info values &&show values\cr
-info version &&show version\cr
-info warranty &&show warranty\cr
-set{\rm / }show addressprint &&set{\rm / }show print address\cr
-set{\rm / }show array-max &&set{\rm / }show print elements\cr
-set{\rm / }show arrayprint &&set{\rm / }show print array\cr
-set{\rm / }show asm-demangle &&set{\rm / }show print asm-demangle\cr
-set{\rm / }show caution &&set{\rm / }show confirm\cr
-set{\rm / }show demangle &&set{\rm / }show print demangle\cr
-set{\rm / }show history write &&set{\rm / }show history save\cr
-set{\rm / }show prettyprint &&set{\rm / }show print pretty\cr
-set{\rm / }show screen-height &&set{\rm / }show height\cr
-set{\rm / }show screen-width &&set{\rm / }show width\cr
-set{\rm / }show sevenbit-strings &&set{\rm / }show print sevenbit-strings\cr
-set{\rm / }show unionprint &&set{\rm / }show print union\cr
-set{\rm / }show vtblprint &&set{\rm / }show print vtbl\cr
-\cr
-unset &&\rm(No longer an alias for delete)\cr
-}
-@end tex
-@c END TEXI2ROFF-KILL
-@end ifset
-@end ifset
@ifclear PRECONFIGURED
+@ifclear HPPA
@node Formatting Documentation
+@c links whacked to pacify makeinfo
+@c , Installing GDB, Renamed Commands, Top
@appendix Formatting Documentation
@cindex @value{GDBN} reference card
@@ -8908,22 +9914,22 @@ on-line information and a printed manual. You can use one of the Info
formatting commands to create the on-line version of the documentation
and @TeX{} (or @code{texi2roff}) to typeset the printed version.
-@value{GDBN} includes an already formatted copy of the on-line Info version of
-this manual in the @file{gdb} subdirectory. The main Info file is
-@file{gdb-@r{version-number}/gdb/gdb.info}, and it refers to
+@value{GDBN} includes an already formatted copy of the on-line Info
+version of this manual in the @file{gdb} subdirectory. The main Info
+file is @file{gdb-@value{GDBVN}/gdb/gdb.info}, and it refers to
subordinate files matching @samp{gdb.info*} in the same directory. If
necessary, you can print out these files, or read them with any editor;
-but they are easier to read using the @code{info} subsystem in @sc{gnu} Emacs
-or the standalone @code{info} program, available as part of the @sc{gnu}
-Texinfo distribution.
+but they are easier to read using the @code{info} subsystem in @sc{gnu}
+Emacs or the standalone @code{info} program, available as part of the
+@sc{gnu} Texinfo distribution.
If you want to format these Info files yourself, you need one of the
Info formatting programs, such as @code{texinfo-format-buffer} or
@code{makeinfo}.
-If you have @code{makeinfo} installed, and are in the top level @value{GDBN}
-source directory (@file{gdb-@value{GDBVN}}, in the case of version @value{GDBVN}), you can
-make the Info file by typing:
+If you have @code{makeinfo} installed, and are in the top level
+@value{GDBN} source directory (@file{gdb-@value{GDBVN}}, in the case of
+version @value{GDBVN}), you can make the Info file by typing:
@example
cd gdb
@@ -8952,17 +9958,50 @@ directory.
If you have @TeX{} and a @sc{dvi} printer program installed, you can
typeset and print this manual. First switch to the the @file{gdb}
subdirectory of the main source directory (for example, to
-@file{gdb-@value{GDBVN}/gdb}) and then type:
+@file{gdb-@value{GDBVN}/gdb}) and type:
@example
make gdb.dvi
@end example
-@node Installing GDB
+Then give @file{gdb.dvi} to your @sc{dvi} printing program.
+@end ifclear
+
+@node Installing GDB, Index, Using History Interactively, Top
@appendix Installing @value{GDBN}
@cindex configuring @value{GDBN}
@cindex installation
+@ifset HPPA
+If you obtain @value{GDBN} (HP WDB 0.75) as part of your HP ANSI C or
+HP ANSI C++ Developer's Kit at HP-UX Release 11.0, you do not have to
+take any special action to build or install @value{GDBN}.
+
+If you obtain @value{GDBN} (HP WDB 0.75) from an HP web site, you may
+download either a @code{swinstall}-able package or a source tree, or
+both.
+
+Most customers will want to install the @value{GDBN} binary that is part
+of the @code{swinstall}-able package. To do so, use a command of the
+form
+
+@smallexample
+/usr/sbin/swinstall -s @var{package-name} WDB
+@end smallexample
+
+Alternatively, it is possible to build @value{GDBN} from the source
+distribution. Sophisticated customers who want to modify the debugger
+sources to tailor @value{GDBN} to their their needs may wish to do this.
+The source distribution consists of a @code{tar}'ed source tree rooted
+at @file{gdb-4.16/...}. The instructions that follow describe how to
+build a @file{gdb} executable from this source tree. HP believes that
+these instructions apply to the WDB source tree that it distributes.
+However, HP does not explicitly support building a @file{gdb} for any
+non-HP platform from the WDB source tree. It may work, but HP has not
+tested it for any platforms other than those described in the WDB 0.75
+Release Notes.
+@end ifset
+
@value{GDBN} comes with a @code{configure} script that automates the process
of preparing @value{GDBN} for installation; you can then use @code{make} to
build the @code{gdb} program.
@@ -9075,10 +10114,10 @@ let @value{GDBN} debug child processes whose programs are not readable.
@menu
* Separate Objdir:: Compiling @value{GDBN} in another directory
* Config Names:: Specifying names for hosts and targets
-* configure Options:: Summary of options for configure
+* Configure Options:: Summary of options for configure
@end menu
-@node Separate Objdir
+@node Separate Objdir, Config Names, Installing GDB, Installing GDB
@section Compiling @value{GDBN} in another directory
If you want to run @value{GDBN} versions for several host or target machines,
@@ -9139,7 +10178,7 @@ directories, you can run @code{make} on them in parallel (for example,
if they are NFS-mounted on each of the hosts); they will not interfere
with each other.
-@node Config Names
+@node Config Names, Configure Options, Separate Objdir, Installing GDB
@section Specifying names for hosts and targets
The specifications used for hosts and targets in the @code{configure}
@@ -9163,25 +10202,25 @@ script, if you wish, or you can use it to test your guesses on
abbreviations---for example:
@smallexample
+% sh config.sub i386-linux
+i386-pc-linux-gnu
+% sh config.sub alpha-linux
+alpha-unknown-linux-gnu
+% sh config.sub hp9k700
+hppa1.1-hp-hpux
% sh config.sub sun4
sparc-sun-sunos4.1.1
% sh config.sub sun3
m68k-sun-sunos4.1.1
-% sh config.sub decstation
-mips-dec-ultrix4.2
-% sh config.sub hp300bsd
-m68k-hp-bsd
-% sh config.sub i386v
-i386-unknown-sysv
-% sh config.sub i786v
-Invalid configuration `i786v': machine `i786v' not recognized
+% sh config.sub i986v
+Invalid configuration `i986v': machine `i986v' not recognized
@end smallexample
@noindent
@code{config.sub} is also distributed in the @value{GDBN} source
directory (@file{gdb-@value{GDBVN}}, for version @value{GDBVN}).
-@node configure Options
+@node Configure Options, , Config Names, Installing GDB
@section @code{configure} options
Here is a summary of the @code{configure} options and arguments that
@@ -9192,9 +10231,11 @@ Does,,configure.info}, for a full explanation of @code{configure}.
@example
configure @r{[}--help@r{]}
@r{[}--prefix=@var{dir}@r{]}
+ @r{[}--exec-prefix=@var{dir}@r{]}
@r{[}--srcdir=@var{dirname}@r{]}
@r{[}--norecursion@r{]} @r{[}--rm@r{]}
- @r{[}--target=@var{target}@r{]} @var{host}
+ @r{[}--target=@var{target}@r{]}
+ @var{host}
@end example
@noindent
@@ -9206,10 +10247,14 @@ You may introduce options with a single @samp{-} rather than
@item --help
Display a quick summary of how to invoke @code{configure}.
-@item -prefix=@var{dir}
+@item --prefix=@var{dir}
Configure the source to install programs and files under directory
@file{@var{dir}}.
+@item --exec-prefix=@var{dir}
+Configure the source to install programs under directory
+@file{@var{dir}}.
+
@c avoid splitting the warning from the explanation:
@need 2000
@item --srcdir=@var{dirname}
@@ -9228,16 +10273,6 @@ the working directory in parallel to the source directories below
Configure only the directory level where @code{configure} is executed; do not
propagate configuration to subdirectories.
-@item --rm
-@emph{Remove} files otherwise built during configuration.
-
-@c This does not work (yet if ever). FIXME.
-@c @item --parse=@var{lang} @dots{}
-@c Configure the @value{GDBN} expression parser to parse the listed languages.
-@c @samp{all} configures @value{GDBN} for all supported languages. To get a
-@c list of all supported languages, omit the argument. Without this
-@c option, @value{GDBN} is configured to parse all supported languages.
-
@item --target=@var{target}
Configure @value{GDBN} for cross-debugging programs running on the specified
@var{target}. Without this option, @value{GDBN} is configured to debug
@@ -9251,13 +10286,12 @@ Configure @value{GDBN} to run on the specified @var{host}.
There is no convenient way to generate a list of all available hosts.
@end table
-@noindent
-@code{configure} accepts other options, for compatibility with
-configuring other @sc{gnu} tools recursively; but these are the only
-options that affect @value{GDBN} or its supporting libraries.
+There are many other options available as well, but they are generally
+needed for special purposes only.
@end ifclear
-@node Index
+
+@node Index, , Installing GDB, Top
@unnumbered Index
@printindex cp
diff --git a/contrib/gdb/gdb/doc/gdbint.texinfo b/contrib/gdb/gdb/doc/gdbint.texinfo
index c7f4390..33b5979 100644
--- a/contrib/gdb/gdb/doc/gdbint.texinfo
+++ b/contrib/gdb/gdb/doc/gdbint.texinfo
@@ -1,6 +1,5 @@
\input texinfo
@setfilename gdbint.info
-@c $Id: gdbint.texinfo,v 1.84 1996/01/11 20:08:19 fnf Exp $
@ifinfo
@format
@@ -13,18 +12,19 @@ END-INFO-DIR-ENTRY
@ifinfo
This file documents the internals of the GNU debugger GDB.
-Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
-Contributed by Cygnus Support. Written by John Gilmore.
+Copyright 1990-1999 Free Software Foundation, Inc.
+Contributed by Cygnus Solutions. Written by John Gilmore.
+Second Edition by Stan Shebs.
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
@ignore
Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy or distribute modified versions of this
@@ -34,24 +34,28 @@ regarded as a program in the language TeX).
@setchapternewpage off
@settitle GDB Internals
+
@titlepage
-@title{Working in GDB}
+@title{GDB Internals}
@subtitle{A guide to the internals of the GNU debugger}
@author John Gilmore
-@author Cygnus Support
+@author Cygnus Solutions
+@author Second Edition:
+@author Stan Shebs
+@author Cygnus Solutions
@page
@tex
\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
-\xdef\manvers{\$Revision: 1.84 $} % For use in headers, footers too
+\xdef\manvers{\$Revision: 1.107 $} % For use in headers, footers too
{\parskip=0pt
-\hfill Cygnus Support\par
+\hfill Cygnus Solutions\par
\hfill \manvers\par
\hfill \TeX{}info \texinfoversion\par
}
@end tex
@vskip 0pt plus 1filll
-Copyright @copyright{} 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+Copyright @copyright{} 1990-1999 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -64,181 +68,111 @@ are preserved on all copies.
@c not for TeX). Existing GNU manuals seem inconsistent on this point.
@top Scope of this Document
-This document documents the internals of the GNU debugger, GDB. It is
-intended to document aspects of GDB which apply across many different
-parts of GDB (for example, @pxref{Coding Style}), or which are global
-aspects of design (for example, what are the major modules and which
-files document them in detail?). Information which pertains to specific
-data structures, functions, variables, etc., should be put in comments
-in the source code, not here. It is more likely to get noticed and kept
-up to date there. Some of the information in this document should
-probably be moved into comments.
+This document documents the internals of the GNU debugger, GDB. It
+includes description of GDB's key algorithms and operations, as well
+as the mechanisms that adapt GDB to specific hosts and targets.
@menu
-* README:: The README File
-* Getting Started:: Getting started working on GDB
-* Debugging GDB:: Debugging GDB with itself
-* New Architectures:: Defining a New Host or Target Architecture
-* Config:: Adding a New Configuration
-* Host:: Adding a New Host
-* Native:: Adding a New Native Configuration
-* Target:: Adding a New Target
-* Languages:: Defining New Source Languages
-* Releases:: Configuring GDB for Release
-* Partial Symbol Tables:: How GDB reads symbols quickly at startup
-* Types:: How GDB keeps track of types
-* BFD support for GDB:: How BFD and GDB interface
-* Symbol Reading:: Defining New Symbol Readers
-* Cleanups:: Cleanups
-* Wrapping:: Wrapping Output Lines
-* Frames:: Keeping track of function calls
-* Remote Stubs:: Code that runs in targets and talks to GDB
-* Longjmp Support:: Stepping through longjmp's in the target
-* Coding Style:: Strunk and White for GDB maintainers
-* Clean Design:: Frank Lloyd Wright for GDB maintainers
-* Submitting Patches:: How to get your changes into GDB releases
-* Host Conditionals:: What features exist in the host
-* Target Conditionals:: What features exist in the target
-* Native Conditionals:: Conditionals for when host and target are same
-* Obsolete Conditionals:: Conditionals that don't exist any more
-* XCOFF:: The Object file format used on IBM's RS/6000
+* Requirements::
+* Overall Structure::
+* Algorithms::
+* User Interface::
+* Symbol Handling::
+* Language Support::
+* Host Definition::
+* Target Architecture Definition::
+* Target Vector Definition::
+* Native Debugging::
+* Support Libraries::
+* Coding::
+* Porting GDB::
+* Hints::
@end menu
-@node README
-@chapter The @file{README} File
+@node Requirements
-Check the @file{README} file, it often has useful information that does not
-appear anywhere else in the directory.
+@chapter Requirements
-@node Getting Started
-@chapter Getting Started Working on GDB
+Before diving into the internals, you should understand the formal
+requirements and other expectations for GDB. Although some of these may
+seem obvious, there have been proposals for GDB that have run counter to
+these requirements.
-GDB is a large and complicated program, and if you first starting to
-work on it, it can be hard to know where to start. Fortunately, if you
-know how to go about it, there are ways to figure out what is going on:
+First of all, GDB is a debugger. It's not designed to be a front panel
+for embedded systems. It's not a text editor. It's not a shell. It's
+not a programming environment.
-@itemize @bullet
-@item
-This manual, the GDB Internals manual, has information which applies
-generally to many parts of GDB.
+GDB is an interactive tool. Although a batch mode is available, GDB's
+primary role is to interact with a human programmer.
-@item
-Information about particular functions or data structures are located in
-comments with those functions or data structures. If you run across a
-function or a global variable which does not have a comment correctly
-explaining what is does, this can be thought of as a bug in GDB; feel
-free to submit a bug report, with a suggested comment if you can figure
-out what the comment should say (@pxref{Submitting Patches}). If you
-find a comment which is actually wrong, be especially sure to report that.
+GDB should be responsive to the user. A programmer hot on the trail of
+a nasty bug, and operating under a looming deadline, is going to be very
+impatient of everything, including the response time to debugger
+commands.
-Comments explaining the function of macros defined in host, target, or
-native dependent files can be in several places. Sometimes they are
-repeated every place the macro is defined. Sometimes they are where the
-macro is used. Sometimes there is a header file which supplies a
-default definition of the macro, and the comment is there. This manual
-also has a list of macros (@pxref{Host Conditionals}, @pxref{Target
-Conditionals}, @pxref{Native Conditionals}, and @pxref{Obsolete
-Conditionals}) with some documentation.
+GDB should be relatively permissive, such as for expressions. While the
+compiler should be picky (or have the option to be made picky), since
+source code lives for a long time usually, the programmer doing
+debugging shouldn't be spending time figuring out to mollify the
+debugger.
-@item
-Start with the header files. Once you some idea of how GDB's internal
-symbol tables are stored (see @file{symtab.h}, @file{gdbtypes.h}), you
-will find it much easier to understand the code which uses and creates
-those symbol tables.
+GDB will be called upon to deal with really large programs. Executable
+sizes of 50 to 100 megabytes occur regularly, and we've heard reports of
+programs approaching 1 gigabyte in size.
-@item
-You may wish to process the information you are getting somehow, to
-enhance your understanding of it. Summarize it, translate it to another
-language, add some (perhaps trivial or non-useful) feature to GDB, use
-the code to predict what a test case would do and write the test case
-and verify your prediction, etc. If you are reading code and your eyes
-are starting to glaze over, this is a sign you need to use a more active
-approach.
+GDB should be able to run everywhere. No other debugger is available
+for even half as many configurations as GDB supports.
-@item
-Once you have a part of GDB to start with, you can find more
-specifically the part you are looking for by stepping through each
-function with the @code{next} command. Do not use @code{step} or you
-will quickly get distracted; when the function you are stepping through
-calls another function try only to get a big-picture understanding
-(perhaps using the comment at the beginning of the function being
-called) of what it does. This way you can identify which of the
-functions being called by the function you are stepping through is the
-one which you are interested in. You may need to examine the data
-structures generated at each stage, with reference to the comments in
-the header files explaining what the data structures are supposed to
-look like.
-Of course, this same technique can be used if you are just reading the
-code, rather than actually stepping through it. The same general
-principle applies---when the code you are looking at calls something
-else, just try to understand generally what the code being called does,
-rather than worrying about all its details.
+@node Overall Structure
-@item
-A good place to start when tracking down some particular area is with a
-command which invokes that feature. Suppose you want to know how
-single-stepping works. As a GDB user, you know that the @code{step}
-command invokes single-stepping. The command is invoked via command
-tables (see @file{command.h}); by convention the function which actually
-performs the command is formed by taking the name of the command and
-adding @samp{_command}, or in the case of an @code{info} subcommand,
-@samp{_info}. For example, the @code{step} command invokes the
-@code{step_command} function and the @code{info display} command invokes
-@code{display_info}. When this convention is not followed, you might
-have to use @code{grep} or @kbd{M-x tags-search} in emacs, or run GDB on
-itself and set a breakpoint in @code{execute_command}.
+@chapter Overall Structure
-@item
-If all of the above fail, it may be appropriate to ask for information
-on @code{bug-gdb}. But @emph{never} post a generic question like ``I was
-wondering if anyone could give me some tips about understanding
-GDB''---if we had some magic secret we would put it in this manual.
-Suggestions for improving the manual are always welcome, of course.
-@end itemize
+GDB consists of three major subsystems: user interface, symbol handling
+(the ``symbol side''), and target system handling (the ``target side'').
-Good luck!
+Ther user interface consists of several actual interfaces, plus
+supporting code.
-@node Debugging GDB
-@chapter Debugging GDB with itself
-If GDB is limping on your machine, this is the preferred way to get it
-fully functional. Be warned that in some ancient Unix systems, like
-Ultrix 4.2, a program can't be running in one process while it is being
-debugged in another. Rather than typing the command @code{@w{./gdb
-./gdb}}, which works on Suns and such, you can copy @file{gdb} to
-@file{gdb2} and then type @code{@w{./gdb ./gdb2}}.
+The symbol side consists of object file readers, debugging info
+interpreters, symbol table management, source language expression
+parsing, type and value printing.
-When you run GDB in the GDB source directory, it will read a
-@file{.gdbinit} file that sets up some simple things to make debugging
-gdb easier. The @code{info} command, when executed without a subcommand
-in a GDB being debugged by gdb, will pop you back up to the top level
-gdb. See @file{.gdbinit} for details.
+The target side consists of execution control, stack frame analysis, and
+physical target manipulation.
-If you use emacs, you will probably want to do a @code{make TAGS} after
-you configure your distribution; this will put the machine dependent
-routines for your local machine where they will be accessed first by
-@kbd{M-.}
+The target side/symbol side division is not formal, and there are a
+number of exceptions. For instance, core file support involves symbolic
+elements (the basic core file reader is in BFD) and target elements (it
+supplies the contents of memory and the values of registers). Instead,
+this division is useful for understanding how the minor subsystems
+should fit together.
-Also, make sure that you've either compiled GDB with your local cc, or
-have run @code{fixincludes} if you are compiling with gcc.
+@section The Symbol Side
+
+The symbolic side of GDB can be thought of as ``everything you can do in
+GDB without having a live program running''. For instance, you can look
+at the types of variables, and evaluate many kinds of expressions.
-@node New Architectures
-@chapter Defining a New Host or Target Architecture
+@section The Target Side
-When building support for a new host and/or target, much of the work you
-need to do is handled by specifying configuration files;
-@pxref{Config,,Adding a New Configuration}. Further work can be
-divided into ``host-dependent'' (@pxref{Host,,Adding a New Host}) and
-``target-dependent'' (@pxref{Target,,Adding a New Target}). The
-following discussion is meant to explain the difference between hosts
-and targets.
+The target side of GDB is the ``bits and bytes manipulator''. Although
+it may make reference to symbolic info here and there, most of the
+target side will run with only a stripped executable available -- or
+even no executable at all, in remote debugging cases.
-@heading What is considered ``host-dependent'' versus ``target-dependent''?
+Operations such as disassembly, stack frame crawls, and register
+display, are able to work with no symbolic info at all. In some cases,
+such as disassembly, GDB will use symbolic info to present addresses
+relative to symbols rather than as raw numbers, but it will work either
+way.
+
+@section Configurations
@dfn{Host} refers to attributes of the system where GDB runs.
@dfn{Target} refers to the system where the program being debugged
-executes. In most cases they are the same machine, in which case
-a third type of @dfn{Native} attributes come into play.
+executes. In most cases they are the same machine, in which case a
+third type of @dfn{Native} attributes come into play.
Defines and include files needed to build on the host are host support.
Examples are tty support, system defined types, host byte order, host
@@ -253,614 +187,267 @@ Information that is only needed when the host and target are the same,
is native dependent. One example is Unix child process support; if the
host and target are not the same, doing a fork to start the target
process is a bad idea. The various macros needed for finding the
-registers in the @code{upage}, running @code{ptrace}, and such are all in the
-native-dependent files.
-
-Another example of native-dependent code is support for features
-that are really part of the target environment, but which require
-@code{#include} files that are only available on the host system.
-Core file handling and @code{setjmp} handling are two common cases.
+registers in the @code{upage}, running @code{ptrace}, and such are all
+in the native-dependent files.
-When you want to make GDB work ``native'' on a particular
-machine, you have to include all three kinds of information.
+Another example of native-dependent code is support for features that
+are really part of the target environment, but which require
+@code{#include} files that are only available on the host system. Core
+file handling and @code{setjmp} handling are two common cases.
-The dependent information in GDB is organized into files by naming
-conventions.
+When you want to make GDB work ``native'' on a particular machine, you
+have to include all three kinds of information.
-Host-Dependent Files
-@table @file
-@item config/*/*.mh
-Sets Makefile parameters
-@item config/*/xm-*.h
-Global #include's and #define's and definitions
-@item *-xdep.c
-Global variables and functions
-@end table
-
-Native-Dependent Files
-@table @file
-@item config/*/*.mh
-Sets Makefile parameters (for @emph{both} host and native)
-@item config/*/nm-*.h
-#include's and #define's and definitions. This file
-is only included by the small number of modules that need it,
-so beware of doing feature-test #define's from its macros.
-@item *-nat.c
-global variables and functions
-@end table
-
-Target-Dependent Files
-@table @file
-@item config/*/*.mt
-Sets Makefile parameters
-@item config/*/tm-*.h
-Global #include's and #define's and definitions
-@item *-tdep.c
-Global variables and functions
-@end table
-At this writing, most supported hosts have had their host and native
-dependencies sorted out properly. There are a few stragglers, which
-can be recognized by the absence of NATDEPFILES lines in their
-@file{config/*/*.mh}.
+@node Algorithms
-@node Config
-@chapter Adding a New Configuration
+@chapter Algorithms
-Most of the work in making GDB compile on a new machine is in specifying
-the configuration of the machine. This is done in a dizzying variety of
-header files and configuration scripts, which we hope to make more
-sensible soon. Let's say your new host is called an @var{xxx} (e.g.
-@samp{sun4}), and its full three-part configuration name is
-@code{@var{xarch}-@var{xvend}-@var{xos}} (e.g. @samp{sparc-sun-sunos4}). In
-particular:
+GDB uses a number of debugging-specific algorithms. They are often not
+very complicated, but get lost in the thicket of special cases and
+real-world issues. This chapter describes the basic algorithms and
+mentions some of the specific target definitions that they use.
-In the top level directory, edit @file{config.sub} and add @var{xarch},
-@var{xvend}, and @var{xos} to the lists of supported architectures,
-vendors, and operating systems near the bottom of the file. Also, add
-@var{xxx} as an alias that maps to
-@code{@var{xarch}-@var{xvend}-@var{xos}}. You can test your changes by
-running
-
-@example
-./config.sub @var{xxx}
-@end example
-@noindent
-and
-@example
-./config.sub @code{@var{xarch}-@var{xvend}-@var{xos}}
-@end example
-@noindent
-which should both respond with @code{@var{xarch}-@var{xvend}-@var{xos}}
-and no error messages.
-
-Now, go to the @file{bfd} directory and
-create a new file @file{bfd/hosts/h-@var{xxx}.h}. Examine the
-other @file{h-*.h} files as templates, and create one that brings in the
-right include files for your system, and defines any host-specific
-macros needed by BFD, the Binutils, GNU LD, or the Opcodes directories.
-(They all share the bfd @file{hosts} directory and the @file{configure.host}
-file.)
-
-Then edit @file{bfd/configure.host}. Add a line to recognize your
-@code{@var{xarch}-@var{xvend}-@var{xos}} configuration, and set
-@code{my_host} to @var{xxx} when you recognize it. This will cause your
-file @file{h-@var{xxx}.h} to be linked to @file{sysdep.h} at configuration
-time. When creating the line that recognizes your configuration,
-only match the fields that you really need to match; e.g. don't
-match the architecture or manufacturer if the OS is sufficient
-to distinguish the configuration that your @file{h-@var{xxx}.h} file supports.
-Don't match the manufacturer name unless you really need to.
-This should make future ports easier.
-
-Also, if this host requires any changes to the Makefile, create a file
-@file{bfd/config/@var{xxx}.mh}, which includes the required lines.
-
-It's possible that the @file{libiberty} and @file{readline} directories
-won't need any changes for your configuration, but if they do, you can
-change the @file{configure.in} file there to recognize your system and
-map to an @file{mh-@var{xxx}} file. Then add @file{mh-@var{xxx}}
-to the @file{config/} subdirectory, to set any makefile variables you
-need. The only current options in there are things like @samp{-DSYSV}.
-(This @file{mh-@var{xxx}} naming convention differs from elsewhere
-in GDB, by historical accident. It should be cleaned up so that all
-such files are called @file{@var{xxx}.mh}.)
-
-Aha! Now to configure GDB itself! Edit
-@file{gdb/configure.in} to recognize your system and set @code{gdb_host}
-to @var{xxx}, and (unless your desired target is already available) also
-set @code{gdb_target} to something appropriate (for instance,
-@var{xxx}). To handle new hosts, modify the segment after the comment
-@samp{# per-host}; to handle new targets, modify after @samp{#
-per-target}.
-@c Would it be simpler to just use different per-host and per-target
-@c *scripts*, and call them from {configure} ?
-
-Finally, you'll need to specify and define GDB's host-, native-, and
-target-dependent @file{.h} and @file{.c} files used for your
-configuration; the next two chapters discuss those.
-
-
-@node Host
-@chapter Adding a New Host
-
-Once you have specified a new configuration for your host
-(@pxref{Config,,Adding a New Configuration}), there are three remaining
-pieces to making GDB work on a new machine. First, you have to make it
-host on the new machine (compile there, handle that machine's terminals
-properly, etc). If you will be cross-debugging to some other kind of
-system that's already supported, you are done.
-
-If you want to use GDB to debug programs that run on the new machine,
-you have to get it to understand the machine's object files, symbol
-files, and interfaces to processes; @pxref{Target,,Adding a New Target}
-and @pxref{Native,,Adding a New Native Configuration}
-
-Several files control GDB's configuration for host systems:
-
-@table @file
-@item gdb/config/@var{arch}/@var{xxx}.mh
-Specifies Makefile fragments needed when hosting on machine @var{xxx}.
-In particular, this lists the required machine-dependent object files,
-by defining @samp{XDEPFILES=@dots{}}. Also
-specifies the header file which describes host @var{xxx}, by defining
-@code{XM_FILE= xm-@var{xxx}.h}. You can also define @code{CC},
-@code{REGEX} and @code{REGEX1}, @code{SYSV_DEFINE}, @code{XM_CFLAGS},
-@code{XM_ADD_FILES}, @code{XM_CLIBS}, @code{XM_CDEPS},
-etc.; see @file{Makefile.in}.
-
-@item gdb/config/@var{arch}/xm-@var{xxx}.h
-(@file{xm.h} is a link to this file, created by configure).
-Contains C macro definitions describing the host system environment,
-such as byte order, host C compiler and library, ptrace support,
-and core file structure. Crib from existing @file{xm-*.h} files
-to create a new one.
-
-@item gdb/@var{xxx}-xdep.c
-Contains any miscellaneous C code required for this machine
-as a host. On many machines it doesn't exist at all. If it does
-exist, put @file{@var{xxx}-xdep.o} into the @code{XDEPFILES} line
-in @file{gdb/config/mh-@var{xxx}}.
-@end table
-
-@subheading Generic Host Support Files
-
-There are some ``generic'' versions of routines that can be used by
-various systems. These can be customized in various ways by macros
-defined in your @file{xm-@var{xxx}.h} file. If these routines work for
-the @var{xxx} host, you can just include the generic file's name (with
-@samp{.o}, not @samp{.c}) in @code{XDEPFILES}.
+@section Frames
-Otherwise, if your machine needs custom support routines, you will need
-to write routines that perform the same functions as the generic file.
-Put them into @code{@var{xxx}-xdep.c}, and put @code{@var{xxx}-xdep.o}
-into @code{XDEPFILES}.
-
-@table @file
-@item ser-bsd.c
-This contains serial line support for Berkeley-derived Unix systems.
-
-@item ser-go32.c
-This contains serial line support for 32-bit programs running under DOS
-using the GO32 execution environment.
-
-@item ser-termios.c
-This contains serial line support for System V-derived Unix systems.
-@end table
+A frame is a construct that GDB uses to keep track of calling and called
+functions.
-Now, you are now ready to try configuring GDB to compile using your system
-as its host. From the top level (above @file{bfd}, @file{gdb}, etc), do:
+@code{FRAME_FP} in the machine description has no meaning to the
+machine-independent part of GDB, except that it is used when setting up
+a new frame from scratch, as follows:
@example
-./configure @var{xxx} --target=vxworks960
+ create_new_frame (read_register (FP_REGNUM), read_pc ()));
@end example
-This will configure your system to cross-compile for VxWorks on
-the Intel 960, which is probably not what you really want, but it's
-a test case that works at this stage. (You haven't set up to be
-able to debug programs that run @emph{on} @var{xxx} yet.)
-
-If this succeeds, you can try building it all with:
-
-@example
-make
-@end example
+Other than that, all the meaning imparted to @code{FP_REGNUM} is
+imparted by the machine-dependent code. So, @code{FP_REGNUM} can have
+any value that is convenient for the code that creates new frames.
+(@code{create_new_frame} calls @code{INIT_EXTRA_FRAME_INFO} if it is
+defined; that is where you should use the @code{FP_REGNUM} value, if
+your frames are nonstandard.)
+
+Given a GDB frame, define @code{FRAME_CHAIN} to determine the address of
+the calling function's frame. This will be used to create a new GDB
+frame struct, and then @code{INIT_EXTRA_FRAME_INFO} and
+@code{INIT_FRAME_PC} will be called for the new frame.
+
+@section Breakpoint Handling
+
+In general, a breakpoint is a user-designated location in the program
+where the user wants to regain control if program execution ever reaches
+that location.
+
+There are two main ways to implement breakpoints; either as ``hardware''
+breakpoints or as ``software'' breakpoints.
+
+Hardware breakpoints are sometimes available as a builtin debugging
+features with some chips. Typically these work by having dedicated
+register into which the breakpoint address may be stored. If the PC
+ever matches a value in a breakpoint registers, the CPU raises an
+exception and reports it to GDB. Another possibility is when an
+emulator is in use; many emulators include circuitry that watches the
+address lines coming out from the processor, and force it to stop if the
+address matches a breakpoint's address. A third possibility is that the
+target already has the ability to do breakpoints somehow; for instance,
+a ROM monitor may do its own software breakpoints. So although these
+are not literally ``hardware breakpoints'', from GDB's point of view
+they work the same; GDB need not do nothing more than set the breakpoint
+and wait for something to happen.
+
+Since they depend on hardware resources, hardware breakpoints may be
+limited in number; when the user asks for more, GDB will start trying to
+set software breakpoints.
+
+Software breakpoints require GDB to do somewhat more work. The basic
+theory is that GDB will replace a program instruction a trap, illegal
+divide, or some other instruction that will cause an exception, and then
+when it's encountered, GDB will take the exception and stop the program.
+When the user says to continue, GDB will restore the original
+instruction, single-step, re-insert the trap, and continue on.
+
+Since it literally overwrites the program being tested, the program area
+must be writeable, so this technique won't work on programs in ROM. It
+can also distort the behavior of programs that examine themselves,
+although the situation would be highly unusual.
+
+Also, the software breakpoint instruction should be the smallest size of
+instruction, so it doesn't overwrite an instruction that might be a jump
+target, and cause disaster when the program jumps into the middle of the
+breakpoint instruction. (Strictly speaking, the breakpoint must be no
+larger than the smallest interval between instructions that may be jump
+targets; perhaps there is an architecture where only even-numbered
+instructions may jumped to.) Note that it's possible for an instruction
+set not to have any instructions usable for a software breakpoint,
+although in practice only the ARC has failed to define such an
+instruction.
+
+The basic definition of the software breakpoint is the macro
+@code{BREAKPOINT}.
+
+Basic breakpoint object handling is in @file{breakpoint.c}. However,
+much of the interesting breakpoint action is in @file{infrun.c}.
+
+@section Single Stepping
+
+@section Signal Handling
+
+@section Thread Handling
+
+@section Inferior Function Calls
+
+@section Longjmp Support
-Repeat until the program configures, compiles, links, and runs.
-When run, it won't be able to do much (unless you have a VxWorks/960
-board on your network) but you will know that the host support is
-pretty well done.
+GDB has support for figuring out that the target is doing a
+@code{longjmp} and for stopping at the target of the jump, if we are
+stepping. This is done with a few specialized internal breakpoints,
+which are visible in the @code{maint info breakpoint} command.
-Good luck! Comments and suggestions about this section are particularly
-welcome; send them to @samp{bug-gdb@@prep.ai.mit.edu}.
+To make this work, you need to define a macro called
+@code{GET_LONGJMP_TARGET}, which will examine the @code{jmp_buf}
+structure and extract the longjmp target address. Since @code{jmp_buf}
+is target specific, you will need to define it in the appropriate
+@file{tm-@var{xyz}.h} file. Look in @file{tm-sun4os4.h} and
+@file{sparc-tdep.c} for examples of how to do this.
-@node Native
-@chapter Adding a New Native Configuration
+@node User Interface
-If you are making GDB run native on the @var{xxx} machine, you have
-plenty more work to do. Several files control GDB's configuration for
-native support:
+@chapter User Interface
-@table @file
-@item gdb/config/@var{xarch}/@var{xxx}.mh
-Specifies Makefile fragments needed when hosting @emph{or native}
-on machine @var{xxx}.
-In particular, this lists the required native-dependent object files,
-by defining @samp{NATDEPFILES=@dots{}}. Also
-specifies the header file which describes native support on @var{xxx},
-by defining @samp{NAT_FILE= nm-@var{xxx}.h}.
-You can also define @samp{NAT_CFLAGS},
-@samp{NAT_ADD_FILES}, @samp{NAT_CLIBS}, @samp{NAT_CDEPS},
-etc.; see @file{Makefile.in}.
+GDB has several user interfaces. Although the command-line interface
+is the most common and most familiar, there are others.
-@item gdb/config/@var{arch}/nm-@var{xxx}.h
-(@file{nm.h} is a link to this file, created by configure).
-Contains C macro definitions describing the native system environment,
-such as child process control and core file support.
-Crib from existing @file{nm-*.h} files to create a new one.
+@section Command Interpreter
-@item gdb/@var{xxx}-nat.c
-Contains any miscellaneous C code required for this native support
-of this machine. On some machines it doesn't exist at all.
-@end table
+The command interpreter in GDB is fairly simple. It is designed to
+allow for the set of commands to be augmented dynamically, and also
+has a recursive subcommand capability, where the first argument to
+a command may itself direct a lookup on a different command list.
-@subheading Generic Native Support Files
+For instance, the @code{set} command just starts a lookup on the
+@code{setlist} command list, while @code{set thread} recurses
+to the @code{set_thread_cmd_list}.
-There are some ``generic'' versions of routines that can be used by
-various systems. These can be customized in various ways by macros
-defined in your @file{nm-@var{xxx}.h} file. If these routines work for
-the @var{xxx} host, you can just include the generic file's name (with
-@samp{.o}, not @samp{.c}) in @code{NATDEPFILES}.
+To add commands in general, use @code{add_cmd}. @code{add_com} adds to
+the main command list, and should be used for those commands. The usual
+place to add commands is in the @code{_initialize_@var{xyz}} routines at the
+ends of most source files.
-Otherwise, if your machine needs custom support routines, you will need
-to write routines that perform the same functions as the generic file.
-Put them into @code{@var{xxx}-nat.c}, and put @code{@var{xxx}-nat.o}
-into @code{NATDEPFILES}.
+@section Console Printing
-@table @file
+@section TUI
-@item inftarg.c
-This contains the @emph{target_ops vector} that supports Unix child
-processes on systems which use ptrace and wait to control the child.
+@section libgdb
-@item procfs.c
-This contains the @emph{target_ops vector} that supports Unix child
-processes on systems which use /proc to control the child.
+@code{libgdb} was an abortive project of years ago. The theory was to
+provide an API to GDB's functionality.
-@item fork-child.c
-This does the low-level grunge that uses Unix system calls
-to do a "fork and exec" to start up a child process.
+@node Symbol Handling
-@item infptrace.c
-This is the low level interface to inferior processes for systems
-using the Unix @code{ptrace} call in a vanilla way.
+@chapter Symbol Handling
-@item core-aout.c::fetch_core_registers()
-Support for reading registers out of a core file. This routine calls
-@code{register_addr()}, see below.
-Now that BFD is used to read core files, virtually all machines should
-use @code{core-aout.c}, and should just provide @code{fetch_core_registers} in
-@code{@var{xxx}-nat.c} (or @code{REGISTER_U_ADDR} in @code{nm-@var{xxx}.h}).
+Symbols are a key part of GDB's operation. Symbols include variables,
+functions, and types.
-@item core-aout.c::register_addr()
-If your @code{nm-@var{xxx}.h} file defines the macro
-@code{REGISTER_U_ADDR(addr, blockend, regno)}, it should be defined to
-set @code{addr} to the offset within the @samp{user}
-struct of GDB register number @code{regno}. @code{blockend} is the
-offset within the ``upage'' of @code{u.u_ar0}.
-If @code{REGISTER_U_ADDR} is defined,
-@file{core-aout.c} will define the @code{register_addr()} function and use
-the macro in it. If you do not define @code{REGISTER_U_ADDR}, but you
-are using the standard @code{fetch_core_registers()}, you will need to
-define your own version of @code{register_addr()}, put it into your
-@code{@var{xxx}-nat.c} file, and be sure @code{@var{xxx}-nat.o} is in
-the @code{NATDEPFILES} list. If you have your own
-@code{fetch_core_registers()}, you may not need a separate
-@code{register_addr()}. Many custom @code{fetch_core_registers()}
-implementations simply locate the registers themselves.@refill
-@end table
+@section Symbol Reading
-When making GDB run native on a new operating system,
-to make it possible to debug
-core files, you will need to either write specific code for parsing your
-OS's core files, or customize @file{bfd/trad-core.c}. First, use
-whatever @code{#include} files your machine uses to define the struct of
-registers that is accessible (possibly in the u-area) in a core file
-(rather than @file{machine/reg.h}), and an include file that defines whatever
-header exists on a core file (e.g. the u-area or a @samp{struct core}). Then
-modify @code{trad_unix_core_file_p()} to use these values to set up the
-section information for the data segment, stack segment, any other
-segments in the core file (perhaps shared library contents or control
-information), ``registers'' segment, and if there are two discontiguous
-sets of registers (e.g. integer and float), the ``reg2'' segment. This
-section information basically delimits areas in the core file in a
-standard way, which the section-reading routines in BFD know how to seek
-around in.
+GDB reads symbols from ``symbol files''. The usual symbol file is the
+file containing the program which GDB is debugging. GDB can be directed
+to use a different file for symbols (with the @code{symbol-file}
+command), and it can also read more symbols via the ``add-file'' and
+``load'' commands, or while reading symbols from shared libraries.
-Then back in GDB, you need a matching routine called
-@code{fetch_core_registers()}. If you can use the generic one, it's in
-@file{core-aout.c}; if not, it's in your @file{@var{xxx}-nat.c} file.
-It will be passed a char pointer to the entire ``registers'' segment,
-its length, and a zero; or a char pointer to the entire ``regs2''
-segment, its length, and a 2. The routine should suck out the supplied
-register values and install them into GDB's ``registers'' array.
-(@xref{New Architectures,,Defining a New Host or Target Architecture},
-for more info about this.)
+Symbol files are initially opened by code in @file{symfile.c} using the
+BFD library. BFD identifies the type of the file by examining its
+header. @code{symfile_init} then uses this identification to locate a
+set of symbol-reading functions.
-If your system uses @file{/proc} to control processes, and uses ELF
-format core files, then you may be able to use the same routines
-for reading the registers out of processes and out of core files.
+Symbol reading modules identify themselves to GDB by calling
+@code{add_symtab_fns} during their module initialization. The argument
+to @code{add_symtab_fns} is a @code{struct sym_fns} which contains the
+name (or name prefix) of the symbol format, the length of the prefix,
+and pointers to four functions. These functions are called at various
+times to process symbol-files whose identification matches the specified
+prefix.
-@node Target
-@chapter Adding a New Target
+The functions supplied by each module are:
-For a new target called @var{ttt}, first specify the configuration as
-described in @ref{Config,,Adding a New Configuration}. If your new
-target is the same as your new host, you've probably already done that.
+@table @code
+@item @var{xyz}_symfile_init(struct sym_fns *sf)
-A variety of files specify attributes of the GDB target environment:
+Called from @code{symbol_file_add} when we are about to read a new
+symbol file. This function should clean up any internal state (possibly
+resulting from half-read previous files, for example) and prepare to
+read a new symbol file. Note that the symbol file which we are reading
+might be a new "main" symbol file, or might be a secondary symbol file
+whose symbols are being added to the existing symbol table.
+
+The argument to @code{@var{xyz}_symfile_init} is a newly allocated
+@code{struct sym_fns} whose @code{bfd} field contains the BFD for the
+new symbol file being read. Its @code{private} field has been zeroed,
+and can be modified as desired. Typically, a struct of private
+information will be @code{malloc}'d, and a pointer to it will be placed
+in the @code{private} field.
+
+There is no result from @code{@var{xyz}_symfile_init}, but it can call
+@code{error} if it detects an unavoidable problem.
-@table @file
-@item gdb/config/@var{arch}/@var{ttt}.mt
-Contains a Makefile fragment specific to this target.
-Specifies what object files are needed for target @var{ttt}, by
-defining @samp{TDEPFILES=@dots{}}.
-Also specifies the header file which describes @var{ttt}, by defining
-@samp{TM_FILE= tm-@var{ttt}.h}. You can also define @samp{TM_CFLAGS},
-@samp{TM_CLIBS}, @samp{TM_CDEPS},
-and other Makefile variables here; see @file{Makefile.in}.
+@item @var{xyz}_new_init()
-@item gdb/config/@var{arch}/tm-@var{ttt}.h
-(@file{tm.h} is a link to this file, created by configure).
-Contains macro definitions about the target machine's
-registers, stack frame format and instructions.
-Crib from existing @file{tm-*.h} files when building a new one.
+Called from @code{symbol_file_add} when discarding existing symbols.
+This function need only handle the symbol-reading module's internal
+state; the symbol table data structures visible to the rest of GDB will
+be discarded by @code{symbol_file_add}. It has no arguments and no
+result. It may be called after @code{@var{xyz}_symfile_init}, if a new
+symbol table is being read, or may be called alone if all symbols are
+simply being discarded.
-@item gdb/@var{ttt}-tdep.c
-Contains any miscellaneous code required for this target machine.
-On some machines it doesn't exist at all. Sometimes the macros
-in @file{tm-@var{ttt}.h} become very complicated, so they are
-implemented as functions here instead, and the macro is simply
-defined to call the function.
-
-@item gdb/exec.c
-Defines functions for accessing files that are
-executable on the target system. These functions open and examine an
-exec file, extract data from one, write data to one, print information
-about one, etc. Now that executable files are handled with BFD, every
-target should be able to use the generic exec.c rather than its
-own custom code.
-
-@item gdb/@var{arch}-pinsn.c
-Prints (disassembles) the target machine's instructions.
-This file is usually shared with other target machines which use the
-same processor, which is why it is @file{@var{arch}-pinsn.c} rather
-than @file{@var{ttt}-pinsn.c}.
-
-@item gdb/@var{arch}-opcode.h
-Contains some large initialized
-data structures describing the target machine's instructions.
-This is a bit strange for a @file{.h} file, but it's OK since
-it is only included in one place. @file{@var{arch}-opcode.h} is shared
-between the debugger and the assembler, if the GNU assembler has been
-ported to the target machine.
+@item @var{xyz}_symfile_read(struct sym_fns *sf, CORE_ADDR addr, int mainline)
-@item gdb/config/@var{arch}/tm-@var{arch}.h
-This often exists to describe the basic layout of the target machine's
-processor chip (registers, stack, etc).
-If used, it is included by @file{tm-@var{xxx}.h}. It can
-be shared among many targets that use the same processor.
+Called from @code{symbol_file_add} to actually read the symbols from a
+symbol-file into a set of psymtabs or symtabs.
-@item gdb/@var{arch}-tdep.c
-Similarly, there are often common subroutines that are shared by all
-target machines that use this particular architecture.
+@code{sf} points to the struct sym_fns originally passed to
+@code{@var{xyz}_sym_init} for possible initialization. @code{addr} is
+the offset between the file's specified start address and its true
+address in memory. @code{mainline} is 1 if this is the main symbol
+table being read, and 0 if a secondary symbol file (e.g. shared library
+or dynamically loaded file) is being read.@refill
@end table
-When adding support for a new target machine, there are various areas
-of support that might need change, or might be OK.
-
-If you are using an existing object file format (a.out or COFF),
-there is probably little to be done. See @file{bfd/doc/bfd.texinfo}
-for more information on writing new a.out or COFF versions.
-
-If you need to add a new object file format, you must first add it to
-BFD. This is beyond the scope of this document right now. Basically
-you must build a transfer vector (of type @code{bfd_target}), which will
-mean writing all the required routines, and add it to the list in
-@file{bfd/targets.c}.
-
-You must then arrange for the BFD code to provide access to the
-debugging symbols. Generally GDB will have to call swapping routines
-from BFD and a few other BFD internal routines to locate the debugging
-information. As much as possible, GDB should not depend on the BFD
-internal data structures.
-
-For some targets (e.g., COFF), there is a special transfer vector used
-to call swapping routines, since the external data structures on various
-platforms have different sizes and layouts. Specialized routines that
-will only ever be implemented by one object file format may be called
-directly. This interface should be described in a file
-@file{bfd/libxxx.h}, which is included by GDB.
-
-If you are adding a new operating system for an existing CPU chip, add a
-@file{tm-@var{xos}.h} file that describes the operating system
-facilities that are unusual (extra symbol table info; the breakpoint
-instruction needed; etc). Then write a
-@file{tm-@var{xarch}-@var{xos}.h} that just @code{#include}s
-@file{tm-@var{xarch}.h} and @file{tm-@var{xos}.h}. (Now that we have
-three-part configuration names, this will probably get revised to
-separate the @var{xos} configuration from the @var{xarch}
-configuration.)
-
-
-@node Languages
-@chapter Adding a Source Language to GDB
-
-To add other languages to GDB's expression parser, follow the following steps:
-
-@table @emph
-@item Create the expression parser.
-
-This should reside in a file @file{@var{lang}-exp.y}. Routines for building
-parsed expressions into a @samp{union exp_element} list are in @file{parse.c}.
-
-Since we can't depend upon everyone having Bison, and YACC produces
-parsers that define a bunch of global names, the following lines
-@emph{must} be included at the top of the YACC parser, to prevent
-the various parsers from defining the same global names:
-
-@example
-#define yyparse @var{lang}_parse
-#define yylex @var{lang}_lex
-#define yyerror @var{lang}_error
-#define yylval @var{lang}_lval
-#define yychar @var{lang}_char
-#define yydebug @var{lang}_debug
-#define yypact @var{lang}_pact
-#define yyr1 @var{lang}_r1
-#define yyr2 @var{lang}_r2
-#define yydef @var{lang}_def
-#define yychk @var{lang}_chk
-#define yypgo @var{lang}_pgo
-#define yyact @var{lang}_act
-#define yyexca @var{lang}_exca
-#define yyerrflag @var{lang}_errflag
-#define yynerrs @var{lang}_nerrs
-@end example
-
-At the bottom of your parser, define a @code{struct language_defn} and
-initialize it with the right values for your language. Define an
-@code{initialize_@var{lang}} routine and have it call
-@samp{add_language(@var{lang}_language_defn)} to tell the rest of GDB
-that your language exists. You'll need some other supporting variables
-and functions, which will be used via pointers from your
-@code{@var{lang}_language_defn}. See the declaration of @code{struct
-language_defn} in @file{language.h}, and the other @file{*-exp.y} files,
-for more information.
-
-@item Add any evaluation routines, if necessary
-
-If you need new opcodes (that represent the operations of the language),
-add them to the enumerated type in @file{expression.h}. Add support
-code for these operations in @code{eval.c:evaluate_subexp()}. Add cases
-for new opcodes in two functions from @file{parse.c}:
-@code{prefixify_subexp()} and @code{length_of_subexp()}. These compute
-the number of @code{exp_element}s that a given operation takes up.
-
-@item Update some existing code
-
-Add an enumerated identifier for your language to the enumerated type
-@code{enum language} in @file{defs.h}.
-
-Update the routines in @file{language.c} so your language is included. These
-routines include type predicates and such, which (in some cases) are
-language dependent. If your language does not appear in the switch
-statement, an error is reported.
-
-Also included in @file{language.c} is the code that updates the variable
-@code{current_language}, and the routines that translate the
-@code{language_@var{lang}} enumerated identifier into a printable
-string.
-
-Update the function @code{_initialize_language} to include your language. This
-function picks the default language upon startup, so is dependent upon
-which languages that GDB is built for.
-
-Update @code{allocate_symtab} in @file{symfile.c} and/or symbol-reading
-code so that the language of each symtab (source file) is set properly.
-This is used to determine the language to use at each stack frame level.
-Currently, the language is set based upon the extension of the source
-file. If the language can be better inferred from the symbol
-information, please set the language of the symtab in the symbol-reading
-code.
-
-Add helper code to @code{expprint.c:print_subexp()} to handle any new
-expression opcodes you have added to @file{expression.h}. Also, add the
-printed representations of your operators to @code{op_print_tab}.
-
-@item Add a place of call
-
-Add a call to @code{@var{lang}_parse()} and @code{@var{lang}_error} in
-@code{parse.c:parse_exp_1()}.
-
-@item Use macros to trim code
-
-The user has the option of building GDB for some or all of the
-languages. If the user decides to build GDB for the language
-@var{lang}, then every file dependent on @file{language.h} will have the
-macro @code{_LANG_@var{lang}} defined in it. Use @code{#ifdef}s to
-leave out large routines that the user won't need if he or she is not
-using your language.
-
-Note that you do not need to do this in your YACC parser, since if GDB
-is not build for @var{lang}, then @file{@var{lang}-exp.tab.o} (the
-compiled form of your parser) is not linked into GDB at all.
-
-See the file @file{configure.in} for how GDB is configured for different
-languages.
-
-@item Edit @file{Makefile.in}
+In addition, if a symbol-reading module creates psymtabs when
+@var{xyz}_symfile_read is called, these psymtabs will contain a pointer
+to a function @code{@var{xyz}_psymtab_to_symtab}, which can be called
+from any point in the GDB symbol-handling code.
-Add dependencies in @file{Makefile.in}. Make sure you update the macro
-variables such as @code{HFILES} and @code{OBJS}, otherwise your code may
-not get linked in, or, worse yet, it may not get @code{tar}red into the
-distribution!
+@table @code
+@item @var{xyz}_psymtab_to_symtab (struct partial_symtab *pst)
+
+Called from @code{psymtab_to_symtab} (or the PSYMTAB_TO_SYMTAB macro) if
+the psymtab has not already been read in and had its @code{pst->symtab}
+pointer set. The argument is the psymtab to be fleshed-out into a
+symtab. Upon return, pst->readin should have been set to 1, and
+pst->symtab should contain a pointer to the new corresponding symtab, or
+zero if there were no symbols in that part of the symbol file.
@end table
+@section Partial Symbol Tables
-@node Releases
-@chapter Configuring GDB for Release
-
-From the top level directory (containing @file{gdb}, @file{bfd},
-@file{libiberty}, and so on):
-@example
-make -f Makefile.in gdb.tar.gz
-@end example
-
-This will properly configure, clean, rebuild any files that are
-distributed pre-built (e.g. @file{c-exp.tab.c} or @file{refcard.ps}),
-and will then make a tarfile. (If the top level directory has already
-been configured, you can just do @code{make gdb.tar.gz} instead.)
+GDB has three types of symbol tables.
-This procedure requires:
@itemize @bullet
-@item symbolic links
-@item @code{makeinfo} (texinfo2 level)
-@item @TeX{}
-@item @code{dvips}
-@item @code{yacc} or @code{bison}
-@end itemize
-@noindent
-@dots{} and the usual slew of utilities (@code{sed}, @code{tar}, etc.).
-@subheading TEMPORARY RELEASE PROCEDURE FOR DOCUMENTATION
+@item full symbol tables (symtabs). These contain the main information
+about symbols and addresses.
-@file{gdb.texinfo} is currently marked up using the texinfo-2 macros,
-which are not yet a default for anything (but we have to start using
-them sometime).
-
-For making paper, the only thing this implies is the right generation of
-@file{texinfo.tex} needs to be included in the distribution.
-
-For making info files, however, rather than duplicating the texinfo2
-distribution, generate @file{gdb-all.texinfo} locally, and include the files
-@file{gdb.info*} in the distribution. Note the plural; @code{makeinfo} will
-split the document into one overall file and five or so included files.
+@item partial symbol tables (psymtabs). These contain enough
+information to know when to read the corresponding part of the full
+symbol table.
-
-@node Partial Symbol Tables
-@chapter Partial Symbol Tables
-
-GDB has three types of symbol tables.
-
-@itemize @bullet
-@item full symbol tables (symtabs). These contain the main
-information about symbols and addresses.
-@item partial symbol tables (psymtabs). These contain enough
-information to know when to read the corresponding
-part of the full symbol table.
-@item minimal symbol tables (msymtabs). These contain information
+@item minimal symbol tables (msymtabs). These contain information
gleaned from non-debugging symbols.
+
@end itemize
This section describes partial symbol tables.
@@ -872,27 +459,28 @@ need to be re-read and fully digested later, when the user needs the
information. The speed of this pass causes GDB to start up very
quickly. Later, as the detailed rereading occurs, it occurs in small
pieces, at various times, and the delay therefrom is mostly invisible to
-the user. (@xref{Symbol Reading}.)
+the user.
+@c (@xref{Symbol Reading}.)
The symbols that show up in a file's psymtab should be, roughly, those
visible to the debugger's user when the program is not running code from
-that file. These include external symbols and types, static
-symbols and types, and enum values declared at file scope.
+that file. These include external symbols and types, static symbols and
+types, and enum values declared at file scope.
The psymtab also contains the range of instruction addresses that the
full symbol table would represent.
-The idea is that there are only two ways for the user (or much of
-the code in the debugger) to reference a symbol:
+The idea is that there are only two ways for the user (or much of the
+code in the debugger) to reference a symbol:
@itemize @bullet
@item by its address
-(e.g. execution stops at some address which is inside a function
-in this file). The address will be noticed to be in the
-range of this psymtab, and the full symtab will be read in.
-@code{find_pc_function}, @code{find_pc_line}, and other @code{find_pc_@dots{}}
-functions handle this.
+(e.g. execution stops at some address which is inside a function in this
+file). The address will be noticed to be in the range of this psymtab,
+and the full symtab will be read in. @code{find_pc_function},
+@code{find_pc_line}, and other @code{find_pc_@dots{}} functions handle
+this.
@item by its name
(e.g. the user asks to print a variable, or set a breakpoint on a
@@ -900,9 +488,9 @@ function). Global names and file-scope names will be found in the
psymtab, which will cause the symtab to be pulled in. Local names will
have to be qualified by a global name, or a file-scope name, in which
case we will have already read in the symtab as we evaluated the
-qualifier. Or, a local symbol can be referenced when
-we are "in" a local scope, in which case the first case applies.
-@code{lookup_symbol} does most of the work here.
+qualifier. Or, a local symbol can be referenced when we are "in" a
+local scope, in which case the first case applies. @code{lookup_symbol}
+does most of the work here.
@end itemize
@@ -915,578 +503,398 @@ either, so types need not appear, unless they will be referenced by
name.
It is a bug for GDB to behave one way when only a psymtab has been read,
-and another way if the corresponding symtab has been read in. Such
-bugs are typically caused by a psymtab that does not contain all the
-visible symbols, or which has the wrong instruction address ranges.
-
-The psymtab for a particular section of a symbol-file (objfile)
-could be thrown away after the symtab has been read in. The symtab
-should always be searched before the psymtab, so the psymtab will
-never be used (in a bug-free environment). Currently,
-psymtabs are allocated on an obstack, and all the psymbols themselves
-are allocated in a pair of large arrays on an obstack, so there is
-little to be gained by trying to free them unless you want to do a lot
-more work.
-
-@node Types
-@chapter Types
+and another way if the corresponding symtab has been read in. Such bugs
+are typically caused by a psymtab that does not contain all the visible
+symbols, or which has the wrong instruction address ranges.
+
+The psymtab for a particular section of a symbol-file (objfile) could be
+thrown away after the symtab has been read in. The symtab should always
+be searched before the psymtab, so the psymtab will never be used (in a
+bug-free environment). Currently, psymtabs are allocated on an obstack,
+and all the psymbols themselves are allocated in a pair of large arrays
+on an obstack, so there is little to be gained by trying to free them
+unless you want to do a lot more work.
+
+@section Types
Fundamental Types (e.g., FT_VOID, FT_BOOLEAN).
These are the fundamental types that GDB uses internally. Fundamental
-types from the various debugging formats (stabs, ELF, etc) are mapped into
-one of these. They are basically a union of all fundamental types that
-gdb knows about for all the languages that GDB knows about.
+types from the various debugging formats (stabs, ELF, etc) are mapped
+into one of these. They are basically a union of all fundamental types
+that gdb knows about for all the languages that GDB knows about.
Type Codes (e.g., TYPE_CODE_PTR, TYPE_CODE_ARRAY).
Each time GDB builds an internal type, it marks it with one of these
-types. The type may be a fundamental type, such as TYPE_CODE_INT, or
-a derived type, such as TYPE_CODE_PTR which is a pointer to another
-type. Typically, several FT_* types map to one TYPE_CODE_* type, and
-are distinguished by other members of the type struct, such as whether
-the type is signed or unsigned, and how many bits it uses.
+types. The type may be a fundamental type, such as TYPE_CODE_INT, or a
+derived type, such as TYPE_CODE_PTR which is a pointer to another type.
+Typically, several FT_* types map to one TYPE_CODE_* type, and are
+distinguished by other members of the type struct, such as whether the
+type is signed or unsigned, and how many bits it uses.
Builtin Types (e.g., builtin_type_void, builtin_type_char).
-These are instances of type structs that roughly correspond to fundamental
-types and are created as global types for GDB to use for various ugly
-historical reasons. We eventually want to eliminate these. Note for
-example that builtin_type_int initialized in gdbtypes.c is basically the
-same as a TYPE_CODE_INT type that is initialized in c-lang.c for an
-FT_INTEGER fundamental type. The difference is that the builtin_type is
-not associated with any particular objfile, and only one instance exists,
-while c-lang.c builds as many TYPE_CODE_INT types as needed, with each
-one associated with some particular objfile.
+These are instances of type structs that roughly correspond to
+fundamental types and are created as global types for GDB to use for
+various ugly historical reasons. We eventually want to eliminate these.
+Note for example that builtin_type_int initialized in gdbtypes.c is
+basically the same as a TYPE_CODE_INT type that is initialized in
+c-lang.c for an FT_INTEGER fundamental type. The difference is that the
+builtin_type is not associated with any particular objfile, and only one
+instance exists, while c-lang.c builds as many TYPE_CODE_INT types as
+needed, with each one associated with some particular objfile.
-@node BFD support for GDB
-@chapter Binary File Descriptor Library Support for GDB
+@section Object File Formats
-BFD provides support for GDB in several ways:
+@subsection a.out
-@table @emph
-@item identifying executable and core files
-BFD will identify a variety of file types, including a.out, coff, and
-several variants thereof, as well as several kinds of core files.
+The @file{a.out} format is the original file format for Unix. It
+consists of three sections: text, data, and bss, which are for program
+code, initialized data, and uninitialized data, respectively.
-@item access to sections of files
-BFD parses the file headers to determine the names, virtual addresses,
-sizes, and file locations of all the various named sections in files
-(such as the text section or the data section). GDB simply calls
-BFD to read or write section X at byte offset Y for length Z.
+The @file{a.out} format is so simple that it doesn't have any reserved
+place for debugging information. (Hey, the original Unix hackers used
+@file{adb}, which is a machine-language debugger.) The only debugging
+format for @file{a.out} is stabs, which is encoded as a set of normal
+symbols with distinctive attributes.
-@item specialized core file support
-BFD provides routines to determine the failing command name stored
-in a core file, the signal with which the program failed, and whether
-a core file matches (i.e. could be a core dump of) a particular executable
-file.
+The basic @file{a.out} reader is in @file{dbxread.c}.
-@item locating the symbol information
-GDB uses an internal interface of BFD to determine where to find the
-symbol information in an executable file or symbol-file. GDB itself
-handles the reading of symbols, since BFD does not ``understand'' debug
-symbols, but GDB uses BFD's cached information to find the symbols,
-string table, etc.
-@end table
+@subsection COFF
-@c The interface for symbol reading is described in @ref{Symbol
-@c Reading,,Symbol Reading}.
+The COFF format was introduced with System V Release 3 (SVR3) Unix.
+COFF files may have multiple sections, each prefixed by a header. The
+number of sections is limited.
+The COFF specification includes support for debugging. Although this
+was a step forward, the debugging information was woefully limited. For
+instance, it was not possible to represent code that came from an
+included file.
-@node Symbol Reading
-@chapter Symbol Reading
+The COFF reader is in @file{coffread.c}.
-GDB reads symbols from "symbol files". The usual symbol file is the
-file containing the program which GDB is debugging. GDB can be directed
-to use a different file for symbols (with the ``symbol-file''
-command), and it can also read more symbols via the ``add-file'' and ``load''
-commands, or while reading symbols from shared libraries.
+@subsection ECOFF
-Symbol files are initially opened by @file{symfile.c} using the BFD
-library. BFD identifies the type of the file by examining its header.
-@code{symfile_init} then uses this identification to locate a
-set of symbol-reading functions.
+ECOFF is an extended COFF originally introduced for Mips and Alpha
+workstations.
-Symbol reading modules identify themselves to GDB by calling
-@code{add_symtab_fns} during their module initialization. The argument
-to @code{add_symtab_fns} is a @code{struct sym_fns} which contains
-the name (or name prefix) of the symbol format, the length of the prefix,
-and pointers to four functions. These functions are called at various
-times to process symbol-files whose identification matches the specified
-prefix.
+The basic ECOFF reader is in @file{mipsread.c}.
-The functions supplied by each module are:
+@subsection XCOFF
-@table @code
-@item @var{xxx}_symfile_init(struct sym_fns *sf)
+The IBM RS/6000 running AIX uses an object file format called XCOFF.
+The COFF sections, symbols, and line numbers are used, but debugging
+symbols are dbx-style stabs whose strings are located in the
+@samp{.debug} section (rather than the string table). For more
+information, see @xref{Top,,,stabs,The Stabs Debugging Format}.
-Called from @code{symbol_file_add} when we are about to read a new
-symbol file. This function should clean up any internal state
-(possibly resulting from half-read previous files, for example)
-and prepare to read a new symbol file. Note that the symbol file
-which we are reading might be a new "main" symbol file, or might
-be a secondary symbol file whose symbols are being added to the
-existing symbol table.
-
-The argument to @code{@var{xxx}_symfile_init} is a newly allocated
-@code{struct sym_fns} whose @code{bfd} field contains the BFD
-for the new symbol file being read. Its @code{private} field
-has been zeroed, and can be modified as desired. Typically,
-a struct of private information will be @code{malloc}'d, and
-a pointer to it will be placed in the @code{private} field.
-
-There is no result from @code{@var{xxx}_symfile_init}, but it can call
-@code{error} if it detects an unavoidable problem.
+The shared library scheme has a clean interface for figuring out what
+shared libraries are in use, but the catch is that everything which
+refers to addresses (symbol tables and breakpoints at least) needs to be
+relocated for both shared libraries and the main executable. At least
+using the standard mechanism this can only be done once the program has
+been run (or the core file has been read).
-@item @var{xxx}_new_init()
+@subsection PE
-Called from @code{symbol_file_add} when discarding existing symbols.
-This function need only handle
-the symbol-reading module's internal state; the symbol table data
-structures visible to the rest of GDB will be discarded by
-@code{symbol_file_add}. It has no arguments and no result.
-It may be called after @code{@var{xxx}_symfile_init}, if a new symbol
-table is being read, or may be called alone if all symbols are
-simply being discarded.
+Windows 95 and NT use the PE (Portable Executable) format for their
+executables. PE is basically COFF with additional headers.
-@item @var{xxx}_symfile_read(struct sym_fns *sf, CORE_ADDR addr, int mainline)
+While BFD includes special PE support, GDB needs only the basic
+COFF reader.
-Called from @code{symbol_file_add} to actually read the symbols from a
-symbol-file into a set of psymtabs or symtabs.
+@subsection ELF
-@code{sf} points to the struct sym_fns originally passed to
-@code{@var{xxx}_sym_init} for possible initialization. @code{addr} is the
-offset between the file's specified start address and its true address
-in memory. @code{mainline} is 1 if this is the main symbol table being
-read, and 0 if a secondary symbol file (e.g. shared library or
-dynamically loaded file) is being read.@refill
-@end table
+The ELF format came with System V Release 4 (SVR4) Unix. ELF is similar
+to COFF in being organized into a number of sections, but it removes
+many of COFF's limitations.
-In addition, if a symbol-reading module creates psymtabs when
-@var{xxx}_symfile_read is called, these psymtabs will contain a pointer to
-a function @code{@var{xxx}_psymtab_to_symtab}, which can be called from
-any point in the GDB symbol-handling code.
+The basic ELF reader is in @file{elfread.c}.
-@table @code
-@item @var{xxx}_psymtab_to_symtab (struct partial_symtab *pst)
-
-Called from @code{psymtab_to_symtab} (or the PSYMTAB_TO_SYMTAB
-macro) if the psymtab has not already been read in and had its
-@code{pst->symtab} pointer set. The argument is the psymtab
-to be fleshed-out into a symtab. Upon return, pst->readin
-should have been set to 1, and pst->symtab should contain a
-pointer to the new corresponding symtab, or zero if there
-were no symbols in that part of the symbol file.
-@end table
+@subsection SOM
+SOM is HP's object file and debug format (not to be confused with IBM's
+SOM, which is a cross-language ABI).
-@node Cleanups
-@chapter Cleanups
+The SOM reader is in @file{hpread.c}.
-Cleanups are a structured way to deal with things that need to be done
-later. When your code does something (like @code{malloc} some memory, or open
-a file) that needs to be undone later (e.g. free the memory or close
-the file), it can make a cleanup. The cleanup will be done at some
-future point: when the command is finished, when an error occurs, or
-when your code decides it's time to do cleanups.
+@subsection Other File Formats
-You can also discard cleanups, that is, throw them away without doing
-what they say. This is only done if you ask that it be done.
+Other file formats that have been supported by GDB include Netware
+Loadable Modules (@file{nlmread.c}.
-Syntax:
+@section Debugging File Formats
-@table @code
-@item struct cleanup *@var{old_chain};
-Declare a variable which will hold a cleanup chain handle.
+This section describes characteristics of debugging information that
+are independent of the object file format.
-@item @var{old_chain} = make_cleanup (@var{function}, @var{arg});
-Make a cleanup which will cause @var{function} to be called with @var{arg}
-(a @code{char *}) later. The result, @var{old_chain}, is a handle that can be
-passed to @code{do_cleanups} or @code{discard_cleanups} later. Unless you are
-going to call @code{do_cleanups} or @code{discard_cleanups} yourself,
-you can ignore the result from @code{make_cleanup}.
+@subsection stabs
+@code{stabs} started out as special symbols within the @code{a.out}
+format. Since then, it has been encapsulated into other file
+formats, such as COFF and ELF.
-@item do_cleanups (@var{old_chain});
-Perform all cleanups done since @code{make_cleanup} returned @var{old_chain}.
-E.g.:
-@example
-make_cleanup (a, 0);
-old = make_cleanup (b, 0);
-do_cleanups (old);
-@end example
-@noindent
-will call @code{b()} but will not call @code{a()}. The cleanup that calls @code{a()} will remain
-in the cleanup chain, and will be done later unless otherwise discarded.@refill
+While @file{dbxread.c} does some of the basic stab processing,
+including for encapsulated versions, @file{stabsread.c} does
+the real work.
-@item discard_cleanups (@var{old_chain});
-Same as @code{do_cleanups} except that it just removes the cleanups from the
-chain and does not call the specified functions.
+@subsection COFF
-@end table
+The basic COFF definition includes debugging information. The level
+of support is minimal and non-extensible, and is not often used.
-Some functions, e.g. @code{fputs_filtered()} or @code{error()}, specify that they
-``should not be called when cleanups are not in place''. This means
-that any actions you need to reverse in the case of an error or
-interruption must be on the cleanup chain before you call these functions,
-since they might never return to your code (they @samp{longjmp} instead).
+@subsection Mips debug (Third Eye)
+ECOFF includes a definition of a special debug format.
-@node Wrapping
-@chapter Wrapping Output Lines
+The file @file{mdebugread.c} implements reading for this format.
-Output that goes through @code{printf_filtered} or @code{fputs_filtered} or
-@code{fputs_demangled} needs only to have calls to @code{wrap_here} added
-in places that would be good breaking points. The utility routines
-will take care of actually wrapping if the line width is exceeded.
+@subsection DWARF 1
-The argument to @code{wrap_here} is an indentation string which is printed
-@emph{only} if the line breaks there. This argument is saved away and used
-later. It must remain valid until the next call to @code{wrap_here} or
-until a newline has been printed through the @code{*_filtered} functions.
-Don't pass in a local variable and then return!
+DWARF 1 is a debugging format that was originally designed to be
+used with ELF in SVR4 systems.
-It is usually best to call @code{wrap_here()} after printing a comma or space.
-If you call it before printing a space, make sure that your indentation
-properly accounts for the leading space that will print if the line wraps
-there.
+@c CHILL_PRODUCER
+@c GCC_PRODUCER
+@c GPLUS_PRODUCER
+@c LCC_PRODUCER
+@c If defined, these are the producer strings in a DWARF 1 file. All of
+@c these have reasonable defaults already.
-Any function or set of functions that produce filtered output must finish
-by printing a newline, to flush the wrap buffer, before switching to
-unfiltered (``@code{printf}'') output. Symbol reading routines that print
-warnings are a good example.
+The DWARF 1 reader is in @file{dwarfread.c}.
+@subsection DWARF 2
-@node Frames
-@chapter Frames
+DWARF 2 is an improved but incompatible version of DWARF 1.
-A frame is a construct that GDB uses to keep track of calling and called
-functions.
+The DWARF 2 reader is in @file{dwarf2read.c}.
-@table @code
-@item FRAME_FP
-in the machine description has no meaning to the machine-independent
-part of GDB, except that it is used when setting up a new frame from
-scratch, as follows:
+@subsection SOM
-@example
- create_new_frame (read_register (FP_REGNUM), read_pc ()));
-@end example
+Like COFF, the SOM definition includes debugging information.
-Other than that, all the meaning imparted to @code{FP_REGNUM} is imparted by
-the machine-dependent code. So, @code{FP_REGNUM} can have any value that
-is convenient for the code that creates new frames. (@code{create_new_frame}
-calls @code{INIT_EXTRA_FRAME_INFO} if it is defined; that is where you should
-use the @code{FP_REGNUM} value, if your frames are nonstandard.)
-
-@item FRAME_CHAIN
-Given a GDB frame, determine the address of the calling function's
-frame. This will be used to create a new GDB frame struct, and then
-@code{INIT_EXTRA_FRAME_INFO} and @code{INIT_FRAME_PC} will be called for
-the new frame.
-@end table
+@section Adding a New Symbol Reader to GDB
-@node Remote Stubs
-@chapter Remote Stubs
+If you are using an existing object file format (a.out, COFF, ELF, etc),
+there is probably little to be done.
-GDB's file @file{remote.c} talks a serial protocol to code that runs
-in the target system. GDB provides several sample ``stubs'' that can
-be integrated into target programs or operating systems for this purpose;
-they are named @file{*-stub.c}.
+If you need to add a new object file format, you must first add it to
+BFD. This is beyond the scope of this document.
-The GDB user's manual describes how to put such a stub into your target
-code. What follows is a discussion of integrating the SPARC stub
-into a complicated operating system (rather than a simple program),
-by Stu Grossman, the author of this stub.
+You must then arrange for the BFD code to provide access to the
+debugging symbols. Generally GDB will have to call swapping routines
+from BFD and a few other BFD internal routines to locate the debugging
+information. As much as possible, GDB should not depend on the BFD
+internal data structures.
-The trap handling code in the stub assumes the following upon entry to
-trap_low:
+For some targets (e.g., COFF), there is a special transfer vector used
+to call swapping routines, since the external data structures on various
+platforms have different sizes and layouts. Specialized routines that
+will only ever be implemented by one object file format may be called
+directly. This interface should be described in a file
+@file{bfd/libxyz.h}, which is included by GDB.
-@enumerate
-@item %l1 and %l2 contain pc and npc respectively at the time of the trap
-@item traps are disabled
-@item you are in the correct trap window
-@end enumerate
-As long as your trap handler can guarantee those conditions, then there is no
-reason why you shouldn't be able to `share' traps with the stub. The stub has
-no requirement that it be jumped to directly from the hardware trap vector.
-That is why it calls @code{exceptionHandler()}, which is provided by the external
-environment. For instance, this could setup the hardware traps to actually
-execute code which calls the stub first, and then transfers to its own trap
-handler.
+@node Language Support
-For the most point, there probably won't be much of an issue with `sharing'
-traps, as the traps we use are usually not used by the kernel, and often
-indicate unrecoverable error conditions. Anyway, this is all controlled by a
-table, and is trivial to modify.
-The most important trap for us is for @code{ta 1}. Without that, we
-can't single step or do breakpoints. Everything else is unnecessary
-for the proper operation of the debugger/stub.
+@chapter Language Support
-From reading the stub, it's probably not obvious how breakpoints work. They
-are simply done by deposit/examine operations from GDB.
+GDB's language support is mainly driven by the symbol reader, although
+it is possible for the user to set the source language manually.
-@node Longjmp Support
-@chapter Longjmp Support
+GDB chooses the source language by looking at the extension of the file
+recorded in the debug info; @code{.c} means C, @code{.f} means Fortran,
+etc. It may also use a special-purpose language identifier if the debug
+format supports it, such as DWARF.
-GDB has support for figuring out that the target is doing a
-@code{longjmp} and for stopping at the target of the jump, if we are
-stepping. This is done with a few specialized internal breakpoints,
-which are visible in the @code{maint info breakpoint} command.
+@section Adding a Source Language to GDB
-To make this work, you need to define a macro called
-@code{GET_LONGJMP_TARGET}, which will examine the @code{jmp_buf}
-structure and extract the longjmp target address. Since @code{jmp_buf}
-is target specific, you will need to define it in the appropriate
-@file{tm-xxx.h} file. Look in @file{tm-sun4os4.h} and
-@file{sparc-tdep.c} for examples of how to do this.
+To add other languages to GDB's expression parser, follow the following
+steps:
-@node Coding Style
-@chapter Coding Style
+@table @emph
+@item Create the expression parser.
-GDB is generally written using the GNU coding standards, as described in
-@file{standards.texi}, which is available for anonymous FTP from GNU
-archive sites. There are some additional considerations for GDB
-maintainers that reflect the unique environment and style of GDB
-maintenance. If you follow these guidelines, GDB will be more
-consistent and easier to maintain.
+This should reside in a file @file{@var{lang}-exp.y}. Routines for
+building parsed expressions into a @samp{union exp_element} list are in
+@file{parse.c}.
-GDB's policy on the use of prototypes is that prototypes are used
-to @emph{declare} functions but never to @emph{define} them. Simple
-macros are used in the declarations, so that a non-ANSI compiler can
-compile GDB without trouble. The simple macro calls are used like
-this:
+Since we can't depend upon everyone having Bison, and YACC produces
+parsers that define a bunch of global names, the following lines
+@emph{must} be included at the top of the YACC parser, to prevent the
+various parsers from defining the same global names:
-@example @code
-extern int
-memory_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+@example
+#define yyparse @var{lang}_parse
+#define yylex @var{lang}_lex
+#define yyerror @var{lang}_error
+#define yylval @var{lang}_lval
+#define yychar @var{lang}_char
+#define yydebug @var{lang}_debug
+#define yypact @var{lang}_pact
+#define yyr1 @var{lang}_r1
+#define yyr2 @var{lang}_r2
+#define yydef @var{lang}_def
+#define yychk @var{lang}_chk
+#define yypgo @var{lang}_pgo
+#define yyact @var{lang}_act
+#define yyexca @var{lang}_exca
+#define yyerrflag @var{lang}_errflag
+#define yynerrs @var{lang}_nerrs
@end example
-Note the double parentheses around the parameter types. This allows
-an arbitrary number of parameters to be described, without freaking
-out the C preprocessor. When the function has no parameters, it
-should be described like:
+At the bottom of your parser, define a @code{struct language_defn} and
+initialize it with the right values for your language. Define an
+@code{initialize_@var{lang}} routine and have it call
+@samp{add_language(@var{lang}_language_defn)} to tell the rest of GDB
+that your language exists. You'll need some other supporting variables
+and functions, which will be used via pointers from your
+@code{@var{lang}_language_defn}. See the declaration of @code{struct
+language_defn} in @file{language.h}, and the other @file{*-exp.y} files,
+for more information.
-@example @code
-void
-noprocess PARAMS ((void));
-@end example
+@item Add any evaluation routines, if necessary
-The @code{PARAMS} macro expands to its argument in ANSI C, or to a simple
-@code{()} in traditional C.
+If you need new opcodes (that represent the operations of the language),
+add them to the enumerated type in @file{expression.h}. Add support
+code for these operations in @code{eval.c:evaluate_subexp()}. Add cases
+for new opcodes in two functions from @file{parse.c}:
+@code{prefixify_subexp()} and @code{length_of_subexp()}. These compute
+the number of @code{exp_element}s that a given operation takes up.
-All external functions should have a @code{PARAMS} declaration in a
-header file that callers include. All static functions should have such
-a declaration near the top of their source file.
+@item Update some existing code
-We don't have a gcc option that will properly check that these rules
-have been followed, but it's GDB policy, and we periodically check it
-using the tools available (plus manual labor), and clean up any remnants.
+Add an enumerated identifier for your language to the enumerated type
+@code{enum language} in @file{defs.h}.
-@node Clean Design
-@chapter Clean Design
+Update the routines in @file{language.c} so your language is included.
+These routines include type predicates and such, which (in some cases)
+are language dependent. If your language does not appear in the switch
+statement, an error is reported.
-In addition to getting the syntax right, there's the little question of
-semantics. Some things are done in certain ways in GDB because long
-experience has shown that the more obvious ways caused various kinds of
-trouble. In particular:
+Also included in @file{language.c} is the code that updates the variable
+@code{current_language}, and the routines that translate the
+@code{language_@var{lang}} enumerated identifier into a printable
+string.
-@table @bullet
-@item
-You can't assume the byte order of anything that comes from a
-target (including @var{value}s, object files, and instructions). Such
-things must be byte-swapped using @code{SWAP_TARGET_AND_HOST} in GDB,
-or one of the swap routines defined in @file{bfd.h}, such as @code{bfd_get_32}.
+Update the function @code{_initialize_language} to include your
+language. This function picks the default language upon startup, so is
+dependent upon which languages that GDB is built for.
-@item
-You can't assume that you know what interface is being used to talk to
-the target system. All references to the target must go through the
-current @code{target_ops} vector.
+Update @code{allocate_symtab} in @file{symfile.c} and/or symbol-reading
+code so that the language of each symtab (source file) is set properly.
+This is used to determine the language to use at each stack frame level.
+Currently, the language is set based upon the extension of the source
+file. If the language can be better inferred from the symbol
+information, please set the language of the symtab in the symbol-reading
+code.
-@item
-You can't assume that the host and target machines are the same machine
-(except in the ``native'' support modules).
-In particular, you can't assume that the target machine's header files
-will be available on the host machine. Target code must bring along its
-own header files -- written from scratch or explicitly donated by their
-owner, to avoid copyright problems.
+Add helper code to @code{expprint.c:print_subexp()} to handle any new
+expression opcodes you have added to @file{expression.h}. Also, add the
+printed representations of your operators to @code{op_print_tab}.
-@item
-Insertion of new @code{#ifdef}'s will be frowned upon. It's much better
-to write the code portably than to conditionalize it for various systems.
+@item Add a place of call
-@item
-New @code{#ifdef}'s which test for specific compilers or manufacturers
-or operating systems are unacceptable. All @code{#ifdef}'s should test
-for features. The information about which configurations contain which
-features should be segregated into the configuration files. Experience
-has proven far too often that a feature unique to one particular system
-often creeps into other systems; and that a conditional based on
-some predefined macro for your current system will become worthless
-over time, as new versions of your system come out that behave differently
-with regard to this feature.
+Add a call to @code{@var{lang}_parse()} and @code{@var{lang}_error} in
+@code{parse.c:parse_exp_1()}.
-@item
-Adding code that handles specific architectures, operating systems, target
-interfaces, or hosts, is not acceptable in generic code. If a hook
-is needed at that point, invent a generic hook and define it for your
-configuration, with something like:
+@item Use macros to trim code
-@example
-#ifdef WRANGLE_SIGNALS
- WRANGLE_SIGNALS (signo);
-#endif
-@end example
+The user has the option of building GDB for some or all of the
+languages. If the user decides to build GDB for the language
+@var{lang}, then every file dependent on @file{language.h} will have the
+macro @code{_LANG_@var{lang}} defined in it. Use @code{#ifdef}s to
+leave out large routines that the user won't need if he or she is not
+using your language.
-In your host, target, or native configuration file, as appropriate,
-define @code{WRANGLE_SIGNALS} to do the machine-dependent thing. Take
-a bit of care in defining the hook, so that it can be used by other
-ports in the future, if they need a hook in the same place.
+Note that you do not need to do this in your YACC parser, since if GDB
+is not build for @var{lang}, then @file{@var{lang}-exp.tab.o} (the
+compiled form of your parser) is not linked into GDB at all.
-If the hook is not defined, the code should do whatever "most" machines
-want. Using @code{#ifdef}, as above, is the preferred way to do this,
-but sometimes that gets convoluted, in which case use
+See the file @file{configure.in} for how GDB is configured for different
+languages.
-@example
-#ifndef SPECIAL_FOO_HANDLING
-#define SPECIAL_FOO_HANDLING(pc, sp) (0)
-#endif
-@end example
+@item Edit @file{Makefile.in}
-where the macro is used or in an appropriate header file.
+Add dependencies in @file{Makefile.in}. Make sure you update the macro
+variables such as @code{HFILES} and @code{OBJS}, otherwise your code may
+not get linked in, or, worse yet, it may not get @code{tar}red into the
+distribution!
-Whether to include a @dfn{small} hook, a hook around the exact pieces of
-code which are system-dependent, or whether to replace a whole function
-with a hook depends on the case. A good example of this dilemma can be
-found in @code{get_saved_register}. All machines that GDB 2.8 ran on
-just needed the @code{FRAME_FIND_SAVED_REGS} hook to find the saved
-registers. Then the SPARC and Pyramid came along, and
-@code{HAVE_REGISTER_WINDOWS} and @code{REGISTER_IN_WINDOW_P} were
-introduced. Then the 29k and 88k required the @code{GET_SAVED_REGISTER}
-hook. The first three are examples of small hooks; the latter replaces
-a whole function. In this specific case, it is useful to have both
-kinds; it would be a bad idea to replace all the uses of the small hooks
-with @code{GET_SAVED_REGISTER}, since that would result in much
-duplicated code. Other times, duplicating a few lines of code here or
-there is much cleaner than introducing a large number of small hooks.
+@end table
-Another way to generalize GDB along a particular interface is with an
-attribute struct. For example, GDB has been generalized to handle
-multiple kinds of remote interfaces -- not by #ifdef's everywhere, but
-by defining the "target_ops" structure and having a current target (as
-well as a stack of targets below it, for memory references). Whenever
-something needs to be done that depends on which remote interface we are
-using, a flag in the current target_ops structure is tested (e.g.
-`target_has_stack'), or a function is called through a pointer in the
-current target_ops structure. In this way, when a new remote interface
-is added, only one module needs to be touched -- the one that actually
-implements the new remote interface. Other examples of
-attribute-structs are BFD access to multiple kinds of object file
-formats, or GDB's access to multiple source languages.
-Please avoid duplicating code. For example, in GDB 3.x all the code
-interfacing between @code{ptrace} and the rest of GDB was duplicated in
-@file{*-dep.c}, and so changing something was very painful. In GDB 4.x,
-these have all been consolidated into @file{infptrace.c}.
-@file{infptrace.c} can deal with variations between systems the same way
-any system-independent file would (hooks, #if defined, etc.), and
-machines which are radically different don't need to use infptrace.c at
-all.
+@node Host Definition
-@item
-@emph{Do} write code that doesn't depend on the sizes of C data types,
-the format of the host's floating point numbers, the alignment of anything,
-or the order of evaluation of expressions. In short, follow good
-programming practices for writing portable C code.
+@chapter Host Definition
-@end table
+With the advent of autoconf, it's rarely necessary to have host
+definition machinery anymore.
-@node Submitting Patches
-@chapter Submitting Patches
+@section Adding a New Host
-Thanks for thinking of offering your changes back to the community of
-GDB users. In general we like to get well designed enhancements.
-Thanks also for checking in advance about the best way to transfer the
-changes.
+Most of GDB's host configuration support happens via autoconf. It
+should be rare to need new host-specific definitions. GDB still uses
+the host-specific definitions and files listed below, but these mostly
+exist for historical reasons, and should eventually disappear.
-The two main problems with getting your patches in are,
+Several files control GDB's configuration for host systems:
+
+@table @file
+
+@item gdb/config/@var{arch}/@var{xyz}.mh
+Specifies Makefile fragments needed when hosting on machine @var{xyz}.
+In particular, this lists the required machine-dependent object files,
+by defining @samp{XDEPFILES=@dots{}}. Also specifies the header file
+which describes host @var{xyz}, by defining @code{XM_FILE=
+xm-@var{xyz}.h}. You can also define @code{CC}, @code{SYSV_DEFINE},
+@code{XM_CFLAGS}, @code{XM_ADD_FILES}, @code{XM_CLIBS}, @code{XM_CDEPS},
+etc.; see @file{Makefile.in}.
-@table @bullet
-@item
-The GDB maintainers will only install ``cleanly designed'' patches.
-You may not always agree on what is clean design.
-@pxref{Coding Style}, @pxref{Clean Design}.
+@item gdb/config/@var{arch}/xm-@var{xyz}.h
+(@file{xm.h} is a link to this file, created by configure). Contains C
+macro definitions describing the host system environment, such as byte
+order, host C compiler and library.
+
+@item gdb/@var{xyz}-xdep.c
+Contains any miscellaneous C code required for this machine as a host.
+On most machines it doesn't exist at all. If it does exist, put
+@file{@var{xyz}-xdep.o} into the @code{XDEPFILES} line in
+@file{gdb/config/@var{arch}/@var{xyz}.mh}.
-@item
-If the maintainers don't have time to put the patch in when it
-arrives, or if there is any question about a patch, it
-goes into a large queue with everyone else's patches and
-bug reports.
@end table
-I don't know how to get past these problems except by continuing to try.
+@subheading Generic Host Support Files
-There are two issues here -- technical and legal.
+There are some ``generic'' versions of routines that can be used by
+various systems. These can be customized in various ways by macros
+defined in your @file{xm-@var{xyz}.h} file. If these routines work for
+the @var{xyz} host, you can just include the generic file's name (with
+@samp{.o}, not @samp{.c}) in @code{XDEPFILES}.
-The legal issue is that to incorporate substantial changes requires a
-copyright assignment from you and/or your employer, granting ownership
-of the changes to the Free Software Foundation. You can get the
-standard document for doing this by sending mail to
-@code{gnu@@prep.ai.mit.edu} and asking for it. I recommend that people
-write in "All programs owned by the Free Software Foundation" as "NAME
-OF PROGRAM", so that changes in many programs (not just GDB, but GAS,
-Emacs, GCC, etc) can be contributed with only one piece of legalese
-pushed through the bureacracy and filed with the FSF. I can't start
-merging changes until this paperwork is received by the FSF (their
-rules, which I follow since I maintain it for them).
+Otherwise, if your machine needs custom support routines, you will need
+to write routines that perform the same functions as the generic file.
+Put them into @code{@var{xyz}-xdep.c}, and put @code{@var{xyz}-xdep.o}
+into @code{XDEPFILES}.
-Technically, the easiest way to receive changes is to receive each
-feature as a small context diff or unidiff, suitable for "patch".
-Each message sent to me should include the changes to C code and
-header files for a single feature, plus ChangeLog entries for each
-directory where files were modified, and diffs for any changes needed
-to the manuals (gdb/doc/gdb.texi or gdb/doc/gdbint.texi). If there
-are a lot of changes for a single feature, they can be split down
-into multiple messages.
+@table @file
-In this way, if I read and like the feature, I can add it to the
-sources with a single patch command, do some testing, and check it in.
-If you leave out the ChangeLog, I have to write one. If you leave
-out the doc, I have to puzzle out what needs documenting. Etc.
+@item ser-unix.c
+This contains serial line support for Unix systems. This is always
+included, via the makefile variable @code{SER_HARDWIRE}; override this
+variable in the @file{.mh} file to avoid it.
-The reason to send each change in a separate message is that I will
-not install some of the changes. They'll be returned to you with
-questions or comments. If I'm doing my job, my message back to you
-will say what you have to fix in order to make the change acceptable.
-The reason to have separate messages for separate features is so
-that other changes (which I @emph{am} willing to accept) can be installed
-while one or more changes are being reworked. If multiple features
-are sent in a single message, I tend to not put in the effort to sort
-out the acceptable changes from the unacceptable, so none of the
-features get installed until all are acceptable.
+@item ser-go32.c
+This contains serial line support for 32-bit programs running under DOS,
+using the GO32 execution environment.
-If this sounds painful or authoritarian, well, it is. But I get a lot
-of bug reports and a lot of patches, and most of them don't get
-installed because I don't have the time to finish the job that the bug
-reporter or the contributor could have done. Patches that arrive
-complete, working, and well designed, tend to get installed on the day
-they arrive. The others go into a queue and get installed if and when
-I scan back over the queue -- which can literally take months
-sometimes. It's in both our interests to make patch installation easy
--- you get your changes installed, and I make some forward progress on
-GDB in a normal 12-hour day (instead of them having to wait until I
-have a 14-hour or 16-hour day to spend cleaning up patches before I
-can install them).
+@item ser-tcp.c
+This contains generic TCP support using sockets.
-Please send patches to @code{bug-gdb@@prep.ai.mit.edu}, if they are less
-than about 25,000 characters. If longer than that, either make them
-available somehow (e.g. anonymous FTP), and announce it on
-@code{bug-gdb}, or send them directly to the GDB maintainers at
-@code{gdb-patches@@cygnus.com}.
+@end table
-@node Host Conditionals
-@chapter Host Conditionals
+@section Host Conditionals
When GDB is configured and compiled, various macros are defined or left
undefined, to control compilation based on the attributes of the host
@@ -1494,110 +902,73 @@ system. These macros and their meanings (or if the meaning is not
documented here, then one of the source files where they are used is
indicated) are:
-@emph{NOTE: For now, both host and target conditionals are here.
-Eliminate target conditionals from this list as they are identified.}
-
@table @code
-@item BLOCK_ADDRESS_FUNCTION_RELATIVE
-dbxread.c
-
@item GDBINIT_FILENAME
The default name of GDB's initialization file (normally @file{.gdbinit}).
@item MEM_FNS_DECLARED
-Your host config file defines this if it includes
-declarations of @code{memcpy} and @code{memset}. Define this
-to avoid conflicts between the native include
-files and the declarations in @file{defs.h}.
+Your host config file defines this if it includes declarations of
+@code{memcpy} and @code{memset}. Define this to avoid conflicts between
+the native include files and the declarations in @file{defs.h}.
@item NO_SYS_FILE
Define this if your system does not have a @code{<sys/file.h>}.
@item SIGWINCH_HANDLER
-If your host defines @code{SIGWINCH}, you can define this to
-be the name of a function to be called if @code{SIGWINCH} is received.
+If your host defines @code{SIGWINCH}, you can define this to be the name
+of a function to be called if @code{SIGWINCH} is received.
@item SIGWINCH_HANDLER_BODY
-Define this to expand into code that will define the function
-named by the expansion of @code{SIGWINCH_HANDLER}.
-
-@item ADDITIONAL_OPTIONS
-main.c
-@item ADDITIONAL_OPTION_CASES
-main.c
-@item ADDITIONAL_OPTION_HANDLER
-main.c
-@item ADDITIONAL_OPTION_HELP
-main.c
-
-@item AIX_BUGGY_PTRACE_CONTINUE
-infptrace.c
+Define this to expand into code that will define the function named by
+the expansion of @code{SIGWINCH_HANDLER}.
@item ALIGN_STACK_ON_STARTUP
-Define this if your system is of a sort that will crash in @code{tgetent}
-if the stack happens not to be longword-aligned when @code{main} is
-called. This is a rare situation, but is known to occur on several
-different types of systems.
-
-@item CFRONT_PRODUCER
-dwarfread.c
-@item DBX_PARM_SYMBOL_CLASS
-stabsread.c
+Define this if your system is of a sort that will crash in
+@code{tgetent} if the stack happens not to be longword-aligned when
+@code{main} is called. This is a rare situation, but is known to occur
+on several different types of systems.
+
+@item CRLF_SOURCE_FILES
+Define this if host files use @code{\r\n} rather than @code{\n} as a
+line terminator. This will cause source file listings to omit @code{\r}
+characters when printing and it will allow \r\n line endings of files
+which are "sourced" by gdb. It must be possible to open files in binary
+mode using @code{O_BINARY} or, for fopen, @code{"rb"}.
@item DEFAULT_PROMPT
The default value of the prompt string (normally @code{"(gdb) "}).
@item DEV_TTY
-symmisc.c
-@item DO_REGISTERS_INFO
-infcmd.c
+The name of the generic TTY device, defaults to @code{"/dev/tty"}.
@item FCLOSE_PROVIDED
-Define this if the system declares @code{fclose} in the headers included in
-@code{defs.h}. This isn't needed unless your compiler is unusually anal.
-
-@sc{ANSI} definition.
-
-@item FILES_INFO_HOOK
-target.c
-@item FLOAT_INFO
-infcmd.c
+Define this if the system declares @code{fclose} in the headers included
+in @code{defs.h}. This isn't needed unless your compiler is unusually
+anal.
@item FOPEN_RB
Define this if binary files are opened the same way as text files.
-@item GCC2_COMPILED_FLAG_SYMBOL
-dbxread.c
-@item GCC_COMPILED_FLAG_SYMBOL
-dbxread.c
-@item GCC_MANGLE_BUG
-symtab.c
-@item GCC_PRODUCER
-dwarfread.c
-
@item GETENV_PROVIDED
-Define this if the system declares @code{getenv} in its headers included in
-@code{defs.h}. This isn't needed unless your compiler is unusually anal.
-
-@item GPLUS_PRODUCER
-dwarfread.c
+Define this if the system declares @code{getenv} in its headers included
+in @code{defs.h}. This isn't needed unless your compiler is unusually
+anal.
@item HAVE_MMAP
In some cases, use the system call @code{mmap} for reading symbol
tables. For some machines this allows for sharing and quick updates.
@item HAVE_SIGSETMASK
-Define this if the host system has job control, but does not
-define @code{sigsetmask()}.
-Currently, this is only true of the RS/6000.
+Define this if the host system has job control, but does not define
+@code{sigsetmask()}. Currently, this is only true of the RS/6000.
@item HAVE_TERMIO
-inflow.c
+Define this if the host system has @code{termio.h}.
@item HOST_BYTE_ORDER
-The ordering of bytes in the host.
-This must be defined to be either @code{BIG_ENDIAN} or @code{LITTLE_ENDIAN}.
+The ordering of bytes in the host. This must be defined to be either
+@code{BIG_ENDIAN} or @code{LITTLE_ENDIAN}.
@item INT_MAX
@item INT_MIN
@@ -1609,54 +980,46 @@ Values for host-side constants.
@item ISATTY
Substitute for isatty, if not available.
-@item KERNEL_DEBUGGING
-tm-ultra3.h
-
-@item KERNEL_U_ADDR
-Define this to the address of the @code{u} structure (the ``user struct'',
-also known as the ``u-page'') in kernel virtual memory. GDB needs to know
-this so that it can subtract this address from absolute addresses in
-the upage, that are obtained via ptrace or from core files. On systems
-that don't need this value, set it to zero.
-
-@item KERNEL_U_ADDR_BSD
-Define this to cause GDB to determine the address of @code{u} at runtime,
-by using Berkeley-style @code{nlist} on the kernel's image in the root
-directory.
-
-@item KERNEL_U_ADDR_HPUX
-Define this to cause GDB to determine the address of @code{u} at runtime,
-by using HP-style @code{nlist} on the kernel's image in the root
-directory.
-
-@item LCC_PRODUCER
-dwarfread.c
-
@item LONGEST
-This is the longest integer type available on the host.
-If not defined, it will default to @code{long long} or @code{long},
-depending on @code{CC_HAS_LONG_LONG}.
+This is the longest integer type available on the host. If not defined,
+it will default to @code{long long} or @code{long}, depending on
+@code{CC_HAS_LONG_LONG}.
@item CC_HAS_LONG_LONG
-Define this if the host C compiler supports ``long long''.
-This will be defined automatically if GNU CC is used to compile GDB.
+Define this if the host C compiler supports ``long long''. This is set
+by the configure script.
@item PRINTF_HAS_LONG_LONG
-Define this if the host can handle printing of long long integers via a
-format directive ``ll''.
+Define this if the host can handle printing of long long integers via
+the printf format directive ``ll''. This is set by the configure script.
+
+@item HAVE_LONG_DOUBLE
+Define this if the host C compiler supports ``long double''. This is
+set by the configure script.
+
+@item PRINTF_HAS_LONG_DOUBLE
+Define this if the host can handle printing of long double float-point
+numbers via the printf format directive ``Lg''. This is set by the
+configure script.
+
+@item SCANF_HAS_LONG_DOUBLE
+Define this if the host can handle the parsing of long double
+float-point numbers via the scanf format directive directive
+``Lg''. This is set by the configure script.
@item LSEEK_NOT_LINEAR
-source.c
-@item L_LNNO32
-coffread.c
+Define this if @code{lseek (n)} does not necessarily move to byte number
+@code{n} in the file. This is only used when reading source files. It
+is normally faster to define @code{CRLF_SOURCE_FILES} when possible.
@item L_SET
-This macro is used as the argument to lseek (or, most commonly, bfd_seek).
-FIXME, should be replaced by SEEK_SET instead, which is the POSIX equivalent.
+This macro is used as the argument to lseek (or, most commonly,
+bfd_seek). FIXME, should be replaced by SEEK_SET instead, which is the
+POSIX equivalent.
@item MAINTENANCE_CMDS
-If the value of this is 1, then a number of optional maintenance commands
-are compiled in.
+If the value of this is 1, then a number of optional maintenance
+commands are compiled in.
@item MALLOC_INCOMPATIBLE
Define this if the system's prototype for @code{malloc} differs from the
@@ -1674,272 +1037,190 @@ whether job control is available.
@item NORETURN
If defined, this should be one or more tokens, such as @code{volatile},
-that can be used in both the declaration and definition of functions
-to indicate that they never return. The default is already set
-correctly if compiling with GCC.
-This will almost never need to be defined.
+that can be used in both the declaration and definition of functions to
+indicate that they never return. The default is already set correctly
+if compiling with GCC. This will almost never need to be defined.
@item ATTR_NORETURN
If defined, this should be one or more tokens, such as
@code{__attribute__ ((noreturn))}, that can be used in the declarations
of functions to indicate that they never return. The default is already
-set correctly if compiling with GCC.
-This will almost never need to be defined.
-
-@item NOTICE_SIGNAL_HANDLING_CHANGE
-infrun.c
-@item NO_HIF_SUPPORT
-remote-mm.c
-@item NO_JOB_CONTROL
-signals.h
+set correctly if compiling with GCC. This will almost never need to be
+defined.
-@item NO_MMALLOC
+@item USE_MMALLOC
GDB will use the @code{mmalloc} library for memory allocation for symbol
-reading, unless this symbol is defined. Define it on systems
-on which @code{mmalloc} does not
-work for some reason. One example is the DECstation, where its RPC
-library can't cope with our redefinition of @code{malloc} to call
-@code{mmalloc}. When defining @code{NO_MMALLOC}, you will also have
-to override the setting of @code{MMALLOC_LIB} to empty, in the Makefile.
-Therefore, this define is usually set on the command line by overriding
-@code{MMALLOC_DISABLE} in @file{config/*/*.mh}, rather than by defining
-it in @file{xm-*.h}.
-
-@item NO_MMALLOC_CHECK
+reading if this symbol is defined. Be careful defining it since there
+are systems on which @code{mmalloc} does not work for some reason. One
+example is the DECstation, where its RPC library can't cope with our
+redefinition of @code{malloc} to call @code{mmalloc}. When defining
+@code{USE_MMALLOC}, you will also have to set @code{MMALLOC} in the
+Makefile, to point to the mmalloc library. This define is set when you
+configure with --with-mmalloc.
+
+@item NO_MMCHECK
Define this if you are using @code{mmalloc}, but don't want the overhead
-of checking the heap with @code{mmcheck}.
+of checking the heap with @code{mmcheck}. Note that on some systems,
+the C runtime makes calls to malloc prior to calling @code{main}, and if
+@code{free} is ever called with these pointers after calling
+@code{mmcheck} to enable checking, a memory corruption abort is certain
+to occur. These systems can still use mmalloc, but must define
+NO_MMCHECK.
+
+@item MMCHECK_FORCE
+Define this to 1 if the C runtime allocates memory prior to
+@code{mmcheck} being called, but that memory is never freed so we don't
+have to worry about it triggering a memory corruption abort. The
+default is 0, which means that @code{mmcheck} will only install the heap
+checking functions if there has not yet been any memory allocation
+calls, and if it fails to install the functions, gdb will issue a
+warning. This is currently defined if you configure using
+--with-mmalloc.
@item NO_SIGINTERRUPT
-remote-adapt.c
-@item NUMERIC_REG_NAMES
-mips-tdep.c
-@item N_SETV
-dbxread.c
-@item N_SET_MAGIC
-hppabsd-tdep.c
-@item ONE_PROCESS_WRITETEXT
-breakpoint.c
-@item O_BINARY
-exec.c
-@item O_RDONLY
-xm-ultra3.h
-@item PCC_SOL_BROKEN
-dbxread.c
-@item PC_LOAD_SEGMENT
-stack.c
-@item PRINT_RANDOM_SIGNAL
-infcmd.c
-@item PRINT_REGISTER_HOOK
-infcmd.c
-@item PROCESS_LINENUMBER_HOOK
-buildsym.c
-@item PROLOGUE_FIRSTLINE_OVERLAP
-infrun.c
-@item PUSH_ARGUMENTS
-valops.c
-@item PYRAMID_CONTROL_FRAME_DEBUGGING
-pyr-xdep.c
-@item PYRAMID_CORE
-pyr-xdep.c
-@item PYRAMID_PTRACE
-pyr-xdep.c
-@item REGISTER_BYTES
-remote.c
-@item REG_STACK_SEGMENT
-exec.c
-@item REG_STRUCT_HAS_ADDR
-findvar.c
-@item R_FP
-dwarfread.c
+Define this to indicate that siginterrupt() is not available.
+
@item R_OK
-xm-altos.h
-@item SEEK_END
-state.c
+Define if this is not in a system .h file.
+
+@item SEEK_CUR
@item SEEK_SET
-state.c
-@item SEM
-coffread.c
+Define these to appropriate value for the system lseek(), if not already
+defined.
-@item SHELL_COMMAND_CONCAT
-infrun.c
-@item SHELL_FILE
-infrun.c
-@item SHIFT_INST_REGS
-breakpoint.c
-@item SIGTRAP_STOP_AFTER_LOAD
-infrun.c
-@item STACK_ALIGN
-valops.c
@item STOP_SIGNAL
-main.c
-@item SUN4_COMPILER_FEATURE
-infrun.c
-@item SUN_FIXED_LBRAC_BUG
-dbxread.c
-@item SVR4_SHARED_LIBS
-solib.c
-@item SYMBOL_RELOADING_DEFAULT
-symfile.c
-@item TIOCGETC
-inflow.c
-@item TIOCGLTC
-inflow.c
-@item TIOCGPGRP
-inflow.c
-@item TIOCLGET
-inflow.c
-@item TIOCLSET
-inflow.c
-@item TIOCNOTTY
-inflow.c
-@item UPAGES
-altos-xdep.c
+This is the signal for stopping GDB. Defaults to SIGTSTP. (Only
+redefined for the Convex.)
+
@item USE_O_NOCTTY
-inflow.c
+Define this if the interior's tty should be opened with the O_NOCTTY
+flag. (FIXME: This should be a native-only flag, but @file{inflow.c} is
+always linked in.)
@item USG
-Means that System V (prior to SVR4) include files are in use.
-(FIXME: This symbol is abused in @file{infrun.c}, @file{regex.c},
-@file{remote-nindy.c}, and @file{utils.c} for other things, at the moment.)
-
-@item WRS_ORIG
-remote-vx.c
-@item alloca
-defs.h
-@item const
-defs.h
+Means that System V (prior to SVR4) include files are in use. (FIXME:
+This symbol is abused in @file{infrun.c}, @file{regex.c},
+@file{remote-nindy.c}, and @file{utils.c} for other things, at the
+moment.)
@item lint
-Define this to help lint in some stupid way.
+Define this to help placate lint in some situations.
@item volatile
-Define this to override the defaults of @code{__volatile__} or @code{/**/}.
+Define this to override the defaults of @code{__volatile__} or
+@code{/**/}.
@end table
-Platform-specific host conditionals.
-@table @code
+@node Target Architecture Definition
-@item ALTOS
-altos-xdep.c
-@item ALTOS_AS
-xm-altos.h
-@item MOTOROLA
-xm-altos.h
-@item NBPG
-altos-xdep.c
+@chapter Target Architecture Definition
-@item BCS
-tm-delta88.h
+GDB's target architecture defines what sort of machine-language programs
+GDB can work with, and how it works with them.
-@item DELTA88
-m88k-xdep.c
-@item DGUX
-m88k-xdep.c
+At present, the target architecture definition consists of a number of C
+macros.
-@item F_OK
-xm-ultra3.h
+@section Registers and Memory
-@end table
+GDB's model of the target machine is rather simple. GDB assumes the
+machine includes a bank of registers and a block of memory. Each
+register may have a different size.
-Regex conditionals.
+GDB does not have a magical way to match up with the compiler's idea of
+which registers are which; however, it is critical that they do match up
+accurately. The only way to make this work is to get accurate
+information about the order that the compiler uses, and to reflect that
+in the @code{REGISTER_NAME} and related macros.
-@table @code
+GDB can handle big-endian, little-endian, and bi-endian architectures.
-@item C_ALLOCA
-regex.c
-@item NFAILURES
-regex.c
-@item RE_NREGS
-regex.h
-@item SIGN_EXTEND_CHAR
-regex.c
-@item SWITCH_ENUM_BUG
-regex.c
-@item SYNTAX_TABLE
-regex.c
-@item Sword
-regex.c
-@item sparc
-regex.c
-@item test
-regex.c
+@section Frame Interpretation
-@end table
+@section Inferior Call Setup
-@node Target Conditionals
-@chapter Target Conditionals
+@section Compiler Characteristics
-When GDB is configured and compiled, various macros are defined or left
-undefined, to control compilation based on the attributes of the target
-system. These macros and their meanings are:
+@section Target Conditionals
-@emph{NOTE: For now, both host and target conditionals are here.
-Eliminate host conditionals from this list as they are identified.}
+This section describes the macros that you can use to define the target
+machine.
@table @code
-@item PUSH_DUMMY_FRAME
-Used in @samp{call_function_by_hand} to create an artificial stack frame.
-
-@item POP_FRAME
-Used in @samp{call_function_by_hand} to remove an artificial stack frame.
-
-@item BLOCK_ADDRESS_FUNCTION_RELATIVE
-dbxread.c
-@item PYRAMID_CONTROL_FRAME_DEBUGGING
-pyr-xdep.c
@item ADDITIONAL_OPTIONS
-main.c
@item ADDITIONAL_OPTION_CASES
-main.c
@item ADDITIONAL_OPTION_HANDLER
-main.c
@item ADDITIONAL_OPTION_HELP
-main.c
+These are a set of macros that allow the addition of additional command
+line options to GDB. They are currently used only for the unsupported
+i960 Nindy target, and should not be used in any other configuration.
@item ADDR_BITS_REMOVE (addr)
-If a raw machine address includes any bits that are not really part
-of the address, then define this macro to expand into an expression
-that zeros those bits in @var{addr}. For example, the two low-order
-bits of a Motorola 88K address may be used by some kernels for their
-own purposes, since addresses must always be 4-byte aligned, and so
-are of no use for addressing. Those bits should be filtered out with
-an expression such as @code{((addr) & ~3)}.
-
-@item ALIGN_STACK_ON_STARTUP
-main.c
-@item ALTOS
-altos-xdep.c
-@item ALTOS_AS
-xm-altos.h
-@item BCS
-tm-delta88.h
+If a raw machine address includes any bits that are not really part of
+the address, then define this macro to expand into an expression that
+zeros those bits in @var{addr}. For example, the two low-order bits of
+a Motorola 88K address may be used by some kernels for their own
+purposes, since addresses must always be 4-byte aligned, and so are of
+no use for addressing. Those bits should be filtered out with an
+expression such as @code{((addr) & ~3)}.
@item BEFORE_MAIN_LOOP_HOOK
-Define this to expand into any code that you want to execute before
-the main loop starts. Although this is not, strictly speaking,
-a target conditional, that is how it is currently being used.
-Note that if a configuration were to define it one way for a host
-and a different way for the target, GDB will probably not compile,
-let alone run correctly.
+Define this to expand into any code that you want to execute before the
+main loop starts. Although this is not, strictly speaking, a target
+conditional, that is how it is currently being used. Note that if a
+configuration were to define it one way for a host and a different way
+for the target, GDB will probably not compile, let alone run correctly.
+This is currently used only for the unsupported i960 Nindy target, and
+should not be used in any other configuration.
@item BELIEVE_PCC_PROMOTION
-coffread.c
+Define if the compiler promotes a short or char parameter to an int, but
+still reports the parameter as its original type, rather than the
+promoted type.
+
@item BELIEVE_PCC_PROMOTION_TYPE
-stabsread.c
+Define this if GDB should believe the type of a short argument when
+compiled by pcc, but look within a full int space to get its value.
+Only defined for Sun-3 at present.
@item BITS_BIG_ENDIAN
-Define this if the numbering of bits in the targets does *not* match
-the endianness of the target byte order.
-A value of 1 means that the bits are numbered in a big-endian order,
-0 means little-endian.
+Define this if the numbering of bits in the targets does *not* match the
+endianness of the target byte order. A value of 1 means that the bits
+are numbered in a big-endian order, 0 means little-endian.
-@item BLOCK_ADDRESS_ABSOLUTE
-dbxread.c
@item BREAKPOINT
-tm-m68k.h
+This is the character array initializer for the bit pattern to put into
+memory where a breakpoint is set. Although it's common to use a trap
+instruction for a breakpoint, it's not required; for instance, the bit
+pattern could be an invalid instruction. The breakpoint must be no
+longer than the shortest instruction of the architecture.
+
+@item BIG_BREAKPOINT
+@item LITTLE_BREAKPOINT
+Similar to BREAKPOINT, but used for bi-endian targets.
+
+@item REMOTE_BREAKPOINT
+@item LITTLE_REMOTE_BREAKPOINT
+@item BIG_REMOTE_BREAKPOINT
+Similar to BREAKPOINT, but used for remote targets.
+
+@item BREAKPOINT_FROM_PC (pcptr, lenptr)
+
+Use the program counter to determine the contents and size of a
+breakpoint instruction. It returns a pointer to a string of bytes that
+encode a breakpoint instruction, stores the length of the string to
+*lenptr, and adjusts pc (if necessary) to point to the actual memory
+location where the breakpoint should be inserted.
+
+Although it is common to use a trap instruction for a breakpoint, it's
+not required; for instance, the bit pattern could be an invalid
+instruction. The breakpoint must be no longer than the shortest
+instruction of the architecture.
+
+Replaces all the other BREAKPOINTs.
@item CALL_DUMMY
valops.c
@@ -1949,19 +1230,15 @@ inferior.h
valops.c
@item CANNOT_FETCH_REGISTER (regno)
-A C expression that should be nonzero if @var{regno} cannot be
-fetched from an inferior process.
-This is only relevant if @code{FETCH_INFERIOR_REGISTERS} is not
-defined.
+A C expression that should be nonzero if @var{regno} cannot be fetched
+from an inferior process. This is only relevant if
+@code{FETCH_INFERIOR_REGISTERS} is not defined.
@item CANNOT_STORE_REGISTER (regno)
A C expression that should be nonzero if @var{regno} should not be
written to the target. This is often the case for program counters,
-status words, and other special registers. If this is not defined,
-GDB will assume that all registers may be written.
-
-@item CFRONT_PRODUCER
-dwarfread.c
+status words, and other special registers. If this is not defined, GDB
+will assume that all registers may be written.
@item DO_DEFERRED_STORES
@item CLEAR_DEFERRED_STORES
@@ -1971,244 +1248,221 @@ and to cancel any deferred stores.
Currently only implemented correctly for native Sparc configurations?
@item CPLUS_MARKER
-Define this to expand into the character that G++ uses to
-distinguish compiler-generated identifiers from programmer-specified
-identifiers. By default, this expands into @code{'$'}.
-Most System V targets should define this to @code{'.'}.
+Define this to expand into the character that G++ uses to distinguish
+compiler-generated identifiers from programmer-specified identifiers.
+By default, this expands into @code{'$'}. Most System V targets should
+define this to @code{'.'}.
@item DBX_PARM_SYMBOL_CLASS
-stabsread.c
+Hook for the @code{SYMBOL_CLASS} of a parameter when decoding DBX symbol
+information. In the i960, parameters can be stored as locals or as
+args, depending on the type of the debug record.
@item DECR_PC_AFTER_BREAK
-Define this to be the amount by which to decrement the PC after
-the program encounters a breakpoint.
-This is often the number of bytes in BREAKPOINT, though not always.
-For most targets this value will be 0.
+Define this to be the amount by which to decrement the PC after the
+program encounters a breakpoint. This is often the number of bytes in
+BREAKPOINT, though not always. For most targets this value will be 0.
@item DECR_PC_AFTER_HW_BREAK
Similarly, for hardware breakpoints.
-@item DELTA88
-m88k-xdep.c
-@item DEV_TTY
-symmisc.c
-@item DGUX
-m88k-xdep.c
-
@item DISABLE_UNSETTABLE_BREAK addr
If defined, this should evaluate to 1 if @var{addr} is in a shared
library in which breakpoints cannot be set and so should be disabled.
@item DO_REGISTERS_INFO
-infcmd.c
+If defined, use this to print the value of a register or all registers.
@item END_OF_TEXT_DEFAULT
This is an expression that should designate the end of the text section
(? FIXME ?)
-@item EXTRACT_RETURN_VALUE
-tm-m68k.h
-@item EXTRACT_STRUCT_VALUE_ADDRESS
-values.c
-
-@item EXTRA_FRAME_INFO
-If defined, this must be a list of slots that may be inserted into
-the @code{frame_info} structure defined in @code{frame.h}.
+@item EXTRACT_RETURN_VALUE(type,regbuf,valbuf)
+Define this to extract a function's return value of type @var{type} from
+the raw register state @var{regbuf} and copy that, in virtual format,
+into @var{valbuf}.
+
+@item EXTRACT_STRUCT_VALUE_ADDRESS(regbuf)
+Define this to extract from an array @var{regbuf} containing the (raw)
+register state, the address in which a function should return its
+structure value, as a CORE_ADDR (or an expression that can be used as
+one).
-@item EXTRA_SYMTAB_INFO
-If defined, this must be a list of slots that may be inserted into
-the @code{symtab} structure defined in @code{symtab.h}.
-
-@item FILES_INFO_HOOK
-target.c
@item FLOAT_INFO
-infcmd.c
-@item FP0_REGNUM
-a68v-xdep.c
-@item FPC_REGNUM
-mach386-xdep.c
+If defined, then the `info float' command will print information about
+the processor's floating point unit.
+
@item FP_REGNUM
-parse.c
-@item FRAMELESS_FUNCTION_INVOCATION
-blockframe.c
+The number of the frame pointer register.
+
+@item FRAMELESS_FUNCTION_INVOCATION(fi, frameless)
+Define this to set the variable @var{frameless} to 1 if the function
+invocation represented by @var{fi} does not have a stack frame
+associated with it. Otherwise set it to 0.
+
@item FRAME_ARGS_ADDRESS_CORRECT
stack.c
-@item FRAME_CHAIN
-Given FRAME, return a pointer to the calling frame.
+@item FRAME_CHAIN(frame)
+Given @var{frame}, return a pointer to the calling frame.
-@item FRAME_CHAIN_COMBINE
-blockframe.c
-@item FRAME_CHAIN_VALID
-frame.h
-@item FRAME_CHAIN_VALID_ALTERNATE
-frame.h
-@item FRAME_FIND_SAVED_REGS
-stack.c
-@item FRAME_GET_BASEREG_VALUE
-frame.h
+@item FRAME_CHAIN_COMBINE(chain,frame)
+Define this to take the frame chain pointer and the frame's nominal
+address and produce the nominal address of the caller's frame.
+Presently only defined for HP PA.
+
+@item FRAME_CHAIN_VALID(chain,thisframe)
+
+Define this to be an expression that returns zero if the given frame is
+an outermost frame, with no caller, and nonzero otherwise. Three common
+definitions are available. @code{default_frame_chain_valid} (the
+default) is nonzero if the chain pointer is nonzero and given frame's PC
+is not inside the startup file (such as @file{crt0.o}).
+@code{alternate_frame_chain_valid} is nonzero if the chain pointer is
+nonzero and the given frame's PC is not in @code{main()} or a known
+entry point function (such as @code{_start()}).
+
+@item FRAME_INIT_SAVED_REGS(frame)
+See @file{frame.h}. Determines the address of all registers in the
+current stack frame storing each in @code{frame->saved_regs}. Space for
+@code{frame->saved_regs} shall be allocated by
+@code{FRAME_INIT_SAVED_REGS} using either
+@code{frame_saved_regs_zalloc} or @code{frame_obstack_alloc}.
+
+@var{FRAME_FIND_SAVED_REGS} and @var{EXTRA_FRAME_INFO} are deprecated.
@item FRAME_NUM_ARGS (val, fi)
-For the frame described by fi, set val to the number of arguments
+For the frame described by @var{fi}, set @var{val} to the number of arguments
that are being passed.
-@item FRAME_SPECIFICATION_DYADIC
-stack.c
-
-@item FRAME_SAVED_PC
-Given FRAME, return the pc saved there. That is, the return address.
+@item FRAME_SAVED_PC(frame)
+Given @var{frame}, return the pc saved there. That is, the return
+address.
@item FUNCTION_EPILOGUE_SIZE
For some COFF targets, the @code{x_sym.x_misc.x_fsize} field of the
function end symbol is 0. For such targets, you must define
-@code{FUNCTION_EPILOGUE_SIZE} to expand into the standard size
-of a function's epilogue.
+@code{FUNCTION_EPILOGUE_SIZE} to expand into the standard size of a
+function's epilogue.
-@item GCC2_COMPILED_FLAG_SYMBOL
-dbxread.c
@item GCC_COMPILED_FLAG_SYMBOL
-dbxread.c
-@item GCC_MANGLE_BUG
-symtab.c
-@item GCC_PRODUCER
-dwarfread.c
+@item GCC2_COMPILED_FLAG_SYMBOL
+If defined, these are the names of the symbols that GDB will look for to
+detect that GCC compiled the file. The default symbols are
+@code{gcc_compiled.} and @code{gcc2_compiled.}, respectively. (Currently
+only defined for the Delta 68.)
@item GDB_TARGET_IS_HPPA
-This determines whether horrible kludge code in dbxread.c and partial-stab.h
-is used to mangle multiple-symbol-table files from HPPA's. This should all
-be ripped out, and a scheme like elfread.c used.
+This determines whether horrible kludge code in dbxread.c and
+partial-stab.h is used to mangle multiple-symbol-table files from
+HPPA's. This should all be ripped out, and a scheme like elfread.c
+used.
@item GDB_TARGET_IS_MACH386
-mach386-xdep.c
@item GDB_TARGET_IS_SUN3
-a68v-xdep.c
@item GDB_TARGET_IS_SUN386
-sun386-xdep.c
+Kludges that should go away.
@item GET_LONGJMP_TARGET
-For most machines, this is a target-dependent parameter. On the DECstation
-and the Iris, this is a native-dependent parameter, since <setjmp.h> is
-needed to define it.
+For most machines, this is a target-dependent parameter. On the
+DECstation and the Iris, this is a native-dependent parameter, since
+<setjmp.h> is needed to define it.
-This macro determines the target PC address that longjmp() will jump
-to, assuming that we have just stopped at a longjmp breakpoint. It
-takes a CORE_ADDR * as argument, and stores the target PC value through
-this pointer. It examines the current state of the machine as needed.
+This macro determines the target PC address that longjmp() will jump to,
+assuming that we have just stopped at a longjmp breakpoint. It takes a
+CORE_ADDR * as argument, and stores the target PC value through this
+pointer. It examines the current state of the machine as needed.
@item GET_SAVED_REGISTER
-Define this if you need to supply your own definition for the
-function @code{get_saved_register}.
-Currently this is only done for the a29k.
-
-@item GPLUS_PRODUCER
-dwarfread.c
-
-@item GR64_REGNUM
-Very a29k-specific.
+Define this if you need to supply your own definition for the function
+@code{get_saved_register}. Currently this is only done for the a29k.
@item HAVE_REGISTER_WINDOWS
Define this if the target has register windows.
-@item REGISTER_IN_WINDOW_P regnum
-Define this to be an expression that is 1 is the given register is
-in the window.
+@item REGISTER_IN_WINDOW_P (regnum)
+Define this to be an expression that is 1 if the given register is in
+the window.
@item IBM6000_TARGET
-Shows that we are configured for an IBM RS/6000 target. This conditional
-should be eliminated (FIXME) and replaced by feature-specific macros.
-It was introduced in haste and we are repenting at leisure.
+Shows that we are configured for an IBM RS/6000 target. This
+conditional should be eliminated (FIXME) and replaced by
+feature-specific macros. It was introduced in haste and we are
+repenting at leisure.
@item IEEE_FLOAT
Define this if the target system uses IEEE-format floating point numbers.
-@item IGNORE_SYMBOL type
-This seems to be no longer used.
-
-@item INIT_EXTRA_FRAME_INFO (fromleaf, fci)
-If defined, this should be a C expression or statement that fills
-in the @code{EXTRA_FRAME_INFO} slots of the given frame @var{fci}.
-
-@item INIT_EXTRA_SYMTAB_INFO
-symfile.c
+@item INIT_EXTRA_FRAME_INFO (fromleaf, frame)
+If additional information about the frame is required this should be
+stored in @code{frame->extra_info}. Space for @code{frame->extra_info}
+is allocated using @code{frame_obstack_alloc}.
@item INIT_FRAME_PC (fromleaf, prev)
-This is a C statement that sets the pc of the frame pointed
-to by @var{prev}. [By default...]
-
-@item INNER_THAN
-Define this to be either @code{<} if the target's stack grows
-downward in memory, or @code{>} is the stack grows upwards.
-
-@item IN_SIGTRAMP pc name
-Define this to return true if the given pc and/or name indicates
-that the current function is a sigtramp.
-
-@item SIGTRAMP_START
-@item SIGTRAMP_END
-Define these to be the start and end address of the sigtramp.
-These will be used if defined, and @code{IN_SIGTRAMP} is not;
-otherwise the name of the sigtramp will be assumed to be @code{_sigtramp}.
-
-@item IN_SOLIB_TRAMPOLINE pc name
-Define this to evaluate to nonzero if the program is stopped in
-the trampoline that connects to a shared library.
-
-@item IS_TRAPPED_INTERNALVAR name
-This is an ugly hook to allow the specification of special actions
-that should occur as a side-effect of setting the value of a variable
-internal to GDB. Currently only used by the h8500.
-Note that this could be either a host or target conditional.
-
-@item KERNEL_DEBUGGING
-tm-ultra3.h
-@item LCC_PRODUCER
-dwarfread.c
-@item L_LNNO32
-coffread.c
-@item MIPSEL
-mips-tdep.c
-@item MOTOROLA
-xm-altos.h
-@item NBPG
-altos-xdep.c
+This is a C statement that sets the pc of the frame pointed to by
+@var{prev}. [By default...]
+
+@item INNER_THAN (lhs,rhs)
+Returns non-zero if stack address @var{lhs} is inner than (nearer to the
+stack top) stack address @var{rhs}. Define this as @code{lhs < rhs} if
+the target's stack grows downward in memory, or @code{lhs > rsh} if the
+stack grows upward.
+
+@item IN_SIGTRAMP (pc, name)
+Define this to return true if the given @var{pc} and/or @var{name}
+indicates that the current function is a sigtramp.
+
+@item SIGTRAMP_START (pc)
+@item SIGTRAMP_END (pc)
+Define these to be the start and end address of the sigtramp for the
+given @var{pc}. On machines where the address is just a compile time
+constant, the macro expansion will typically just ignore the supplied
+@var{pc}.
+
+@item IN_SOLIB_CALL_TRAMPOLINE pc name
+Define this to evaluate to nonzero if the program is stopped in the
+trampoline that connects to a shared library.
+
+@item IN_SOLIB_RETURN_TRAMPOLINE pc name
+Define this to evaluate to nonzero if the program is stopped in the
+trampoline that returns from a shared library.
+
+@item IS_TRAPPED_INTERNALVAR (name)
+This is an ugly hook to allow the specification of special actions that
+should occur as a side-effect of setting the value of a variable
+internal to GDB. Currently only used by the h8500. Note that this
+could be either a host or target conditional.
@item NEED_TEXT_START_END
-Define this if GDB should determine the start and end addresses
-of the text section. (Seems dubious.)
+Define this if GDB should determine the start and end addresses of the
+text section. (Seems dubious.)
-@item NOTICE_SIGNAL_HANDLING_CHANGE
-infrun.c
@item NO_HIF_SUPPORT
-remote-mm.c
-@item NO_SIGINTERRUPT
-remote-adapt.c
-
-@item NO_SINGLE_STEP
-Define this if the target does not support single-stepping.
-If this is defined, you must supply, in @code{*-tdep.c}, the function
-@code{single_step}, which takes a pid as argument and returns nothing.
-It must insert breakpoints at each possible destinations of the next
-instruction. See @code{sparc-tdep.c} and @code{rs6000-tdep.c}
+(Specific to the a29k.)
+
+@item SOFTWARE_SINGLE_STEP_P
+Define this as 1 if the target does not have a hardware single-step
+mechanism. The macro @code{SOFTWARE_SINGLE_STEP} must also be defined.
+
+@item SOFTWARE_SINGLE_STEP(signal,insert_breapoints_p)
+A function that inserts or removes (dependant on
+@var{insert_breapoints_p}) breakpoints at each possible destinations of
+the next instruction. See @code{sparc-tdep.c} and @code{rs6000-tdep.c}
for examples.
-@item NUMERIC_REG_NAMES
-mips-tdep.c
-@item N_SETV
-dbxread.c
-@item N_SET_MAGIC
-hppabsd-tdep.c
-@item ONE_PROCESS_WRITETEXT
-breakpoint.c
@item PCC_SOL_BROKEN
-dbxread.c
+(Used only in the Convex target.)
+
@item PC_IN_CALL_DUMMY
inferior.h
+
@item PC_LOAD_SEGMENT
-stack.c
+If defined, print information about the load segment for the program
+counter. (Defined only for the RS/6000.)
@item PC_REGNUM
-If the program counter is kept in a register, then define this macro
-to be the number of that register.
-This need be defined only if @code{TARGET_WRITE_PC} is not defined.
+If the program counter is kept in a register, then define this macro to
+be the number of that register. This need be defined only if
+@code{TARGET_WRITE_PC} is not defined.
@item NPC_REGNUM
The number of the ``next program counter'' register, if defined.
@@ -2217,101 +1471,106 @@ The number of the ``next program counter'' register, if defined.
The number of the ``next next program counter'' register, if defined.
Currently, this is only defined for the Motorola 88K.
-@item PRINT_RANDOM_SIGNAL
-infcmd.c
-@item PRINT_REGISTER_HOOK
-infcmd.c
+@item PRINT_REGISTER_HOOK (regno)
+If defined, this must be a function that prints the contents of the
+given register to standard output.
@item PRINT_TYPELESS_INTEGER
-This is an obscure substitute for @code{print_longest} that
-seems to have been defined for the Convex target.
+This is an obscure substitute for @code{print_longest} that seems to
+have been defined for the Convex target.
@item PROCESS_LINENUMBER_HOOK
-buildsym.c
+A hook defined for XCOFF reading.
+
@item PROLOGUE_FIRSTLINE_OVERLAP
-infrun.c
+(Only used in unsupported Convex configuration.)
+
@item PS_REGNUM
-parse.c
-@item PUSH_ARGUMENTS
-valops.c
+If defined, this is the number of the processor status register. (This
+definition is only used in generic code when parsing "$ps".)
+
+@item POP_FRAME
+Used in @samp{call_function_by_hand} to remove an artificial stack
+frame.
+
+@item PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr)
+Define this to push arguments onto the stack for inferior function call.
+
+@item PUSH_DUMMY_FRAME
+Used in @samp{call_function_by_hand} to create an artificial stack frame.
+
@item REGISTER_BYTES
-remote.c
+The total amount of space needed to store GDB's copy of the machine's
+register state.
-@item REGISTER_NAMES
-Define this to expand into an initializer of an array of strings.
-Each string is the name of a register.
-[more detail]
+@item REGISTER_NAME(i)
+Return the name of register @var{i} as a string. May return @var{NULL}
+or @var{NUL} to indicate that register @var{i} is not valid.
-@item REG_STACK_SEGMENT
-exec.c
-@item REG_STRUCT_HAS_ADDR
-findvar.c
-@item R_FP
-dwarfread.c
-@item R_OK
-xm-altos.h
+@item REG_STRUCT_HAS_ADDR (gcc_p, type)
+Define this to return 1 if the given type will be passed by pointer
+rather than directly.
@item SDB_REG_TO_REGNUM
-Define this to convert sdb register numbers
-into GDB regnums. If not defined, no conversion will be done.
+Define this to convert sdb register numbers into GDB regnums. If not
+defined, no conversion will be done.
-@item SEEK_END
-state.c
-@item SEEK_SET
-state.c
-@item SEM
-coffread.c
-@item SHELL_COMMAND_CONCAT
-infrun.c
-@item SHELL_FILE
-infrun.c
@item SHIFT_INST_REGS
-breakpoint.c
-@item SIGTRAP_STOP_AFTER_LOAD
-infrun.c
+(Only used for m88k targets.)
-@item SKIP_PROLOGUE
-A C statement that advances the PC across any function entry
+@item SKIP_PROLOGUE (pc)
+A C statement that advances the @var{pc} across any function entry
prologue instructions so as to reach ``real'' code.
@item SKIP_PROLOGUE_FRAMELESS_P
-A C statement that should behave similarly, but that can stop
-as soon as the function is known to have a frame.
-If not defined, @code{SKIP_PROLOGUE} will be used instead.
+A C statement that should behave similarly, but that can stop as soon as
+the function is known to have a frame. If not defined,
+@code{SKIP_PROLOGUE} will be used instead.
@item SKIP_TRAMPOLINE_CODE (pc)
-If the target machine has trampoline code that sits between callers
-and the functions being called, then define this macro to return
-a new PC that is at the start of the real function.
+If the target machine has trampoline code that sits between callers and
+the functions being called, then define this macro to return a new PC
+that is at the start of the real function.
@item SP_REGNUM
-parse.c
+Define this to be the number of the register that serves as the stack
+pointer.
@item STAB_REG_TO_REGNUM
-Define this to convert stab register numbers (as gotten from `r' declarations)
-into GDB regnums. If not defined, no conversion will be done.
+Define this to convert stab register numbers (as gotten from `r'
+declarations) into GDB regnums. If not defined, no conversion will be
+done.
-@item STACK_ALIGN
-valops.c
-@item STOP_SIGNAL
-main.c
+@item STACK_ALIGN (addr)
+Define this to adjust the address to the alignment required for the
+processor's stack.
+
+@item STEP_SKIPS_DELAY (addr)
+Define this to return true if the address is of an instruction with a
+delay slot. If a breakpoint has been placed in the instruction's delay
+slot, GDB will single-step over that instruction before resuming
+normally. Currently only defined for the Mips.
@item STORE_RETURN_VALUE (type, valbuf)
A C expression that stores a function return value of type @var{type},
where @var{valbuf} is the address of the value to be stored.
-@item SUN4_COMPILER_FEATURE
-infrun.c
@item SUN_FIXED_LBRAC_BUG
-dbxread.c
-@item SVR4_SHARED_LIBS
-solib.c
+(Used only for Sun-3 and Sun-4 targets.)
+
@item SYMBOL_RELOADING_DEFAULT
-symfile.c
+The default value of the `symbol-reloading' variable. (Never defined in
+current sources.)
+
+@item TARGET_BYTE_ORDER_DEFAULT
+The ordering of bytes in the target. This must be either
+@code{BIG_ENDIAN} or @code{LITTLE_ENDIAN}. This macro replaces
+@var{TARGET_BYTE_ORDER} which is deprecated.
-@item TARGET_BYTE_ORDER
-The ordering of bytes in the target.
-This must be defined to be either @code{BIG_ENDIAN} or @code{LITTLE_ENDIAN}.
+@item TARGET_BYTE_ORDER_SELECTABLE_P
+Non-zero if the target has both @code{BIG_ENDIAN} and
+@code{LITTLE_ENDIAN} variants. This macro replaces
+@var{TARGET_BYTE_ORDER_SELECTABLE} which is deprecated.
@item TARGET_CHAR_BIT
Number of bits in a char; defaults to 8.
@@ -2355,39 +1614,38 @@ Number of bits in a short integer; defaults to @code{2 * TARGET_CHAR_BIT}.
@item TARGET_WRITE_FP
These change the behavior of @code{read_pc}, @code{write_pc},
@code{read_sp}, @code{write_sp}, @code{read_fp} and @code{write_fp}.
-For most targets, these may be left undefined. GDB will call the
-read and write register functions with the relevant @code{_REGNUM} argument.
+For most targets, these may be left undefined. GDB will call the read
+and write register functions with the relevant @code{_REGNUM} argument.
These macros are useful when a target keeps one of these registers in a
-hard to get at place; for example, part in a segment register and part
+hard to get at place; for example, part in a segment register and part
in an ordinary register.
+@item TARGET_VIRTUAL_FRAME_POINTER(pc,regp,offsetp)
+Returns a @code{(register, offset)} pair representing the virtual
+frame pointer in use at the code address @code{"pc"}. If virtual
+frame pointers are not used, a default definition simply returns
+@code{FP_REGNUM}, with an offset of zero.
+
@item USE_STRUCT_CONVENTION (gcc_p, type)
-If defined, this must be an expression that is nonzero if a value
-of the given @var{type} being returned from a function must have
-space allocated for it on the stack. @var{gcc_p} is true if the
-function being considered is known to have been compiled by GCC;
-this is helpful for systems where GCC is known to use different calling
-convention than other compilers.
+If defined, this must be an expression that is nonzero if a value of the
+given @var{type} being returned from a function must have space
+allocated for it on the stack. @var{gcc_p} is true if the function
+being considered is known to have been compiled by GCC; this is helpful
+for systems where GCC is known to use different calling convention than
+other compilers.
@item VARIABLES_INSIDE_BLOCK (desc, gcc_p)
For dbx-style debugging information, if the compiler puts variable
-declarations inside LBRAC/RBRAC blocks, this should be defined
-to be nonzero. @var{desc} is the value of @code{n_desc} from the
-@code{N_RBRAC} symbol, and @var{gcc_p} is true if GDB has noticed
-the presence of either the @code{GCC_COMPILED_SYMBOL} or the
-@code{GCC2_COMPILED_SYMBOL}.
-By default, this is 0.
+declarations inside LBRAC/RBRAC blocks, this should be defined to be
+nonzero. @var{desc} is the value of @code{n_desc} from the
+@code{N_RBRAC} symbol, and @var{gcc_p} is true if GDB has noticed the
+presence of either the @code{GCC_COMPILED_SYMBOL} or the
+@code{GCC2_COMPILED_SYMBOL}. By default, this is 0.
@item OS9K_VARIABLES_INSIDE_BLOCK (desc, gcc_p)
Similarly, for OS/9000. Defaults to 1.
-@item WRS_ORIG
-remote-vx.c
-
-@item test
-(Define this to enable testing code in regex.c.)
-
@end table
Motorola M68K target conditionals.
@@ -2395,21 +1653,259 @@ Motorola M68K target conditionals.
@table @code
@item BPT_VECTOR
-Define this to be the 4-bit location of the breakpoint trap vector.
-If not defined, it will default to @code{0xf}.
+Define this to be the 4-bit location of the breakpoint trap vector. If
+not defined, it will default to @code{0xf}.
@item REMOTE_BPT_VECTOR
Defaults to @code{1}.
@end table
-@node Native Conditionals
-@chapter Native Conditionals
+@section Adding a New Target
+
+The following files define a target to GDB:
+
+@table @file
+
+@item gdb/config/@var{arch}/@var{ttt}.mt
+Contains a Makefile fragment specific to this target. Specifies what
+object files are needed for target @var{ttt}, by defining
+@samp{TDEPFILES=@dots{}}. Also specifies the header file which
+describes @var{ttt}, by defining @samp{TM_FILE= tm-@var{ttt}.h}. You
+can also define @samp{TM_CFLAGS}, @samp{TM_CLIBS}, @samp{TM_CDEPS}, but
+these are now deprecated and may go away in future versions of GDB.
+
+@item gdb/config/@var{arch}/tm-@var{ttt}.h
+(@file{tm.h} is a link to this file, created by configure). Contains
+macro definitions about the target machine's registers, stack frame
+format and instructions.
+
+@item gdb/@var{ttt}-tdep.c
+Contains any miscellaneous code required for this target machine. On
+some machines it doesn't exist at all. Sometimes the macros in
+@file{tm-@var{ttt}.h} become very complicated, so they are implemented
+as functions here instead, and the macro is simply defined to call the
+function. This is vastly preferable, since it is easier to understand
+and debug.
+
+@item gdb/config/@var{arch}/tm-@var{arch}.h
+This often exists to describe the basic layout of the target machine's
+processor chip (registers, stack, etc). If used, it is included by
+@file{tm-@var{ttt}.h}. It can be shared among many targets that use the
+same processor.
+
+@item gdb/@var{arch}-tdep.c
+Similarly, there are often common subroutines that are shared by all
+target machines that use this particular architecture.
+
+@end table
+
+If you are adding a new operating system for an existing CPU chip, add a
+@file{config/tm-@var{os}.h} file that describes the operating system
+facilities that are unusual (extra symbol table info; the breakpoint
+instruction needed; etc). Then write a @file{@var{arch}/tm-@var{os}.h}
+that just @code{#include}s @file{tm-@var{arch}.h} and
+@file{config/tm-@var{os}.h}.
+
+
+@node Target Vector Definition
+
+@chapter Target Vector Definition
+
+The target vector defines the interface between GDB's abstract handling
+of target systems, and the nitty-gritty code that actually exercises
+control over a process or a serial port. GDB includes some 30-40
+different target vectors; however, each configuration of GDB includes
+only a few of them.
+
+@section File Targets
+
+Both executables and core files have target vectors.
+
+@section Standard Protocol and Remote Stubs
+
+GDB's file @file{remote.c} talks a serial protocol to code that runs in
+the target system. GDB provides several sample ``stubs'' that can be
+integrated into target programs or operating systems for this purpose;
+they are named @file{*-stub.c}.
+
+The GDB user's manual describes how to put such a stub into your target
+code. What follows is a discussion of integrating the SPARC stub into a
+complicated operating system (rather than a simple program), by Stu
+Grossman, the author of this stub.
+
+The trap handling code in the stub assumes the following upon entry to
+trap_low:
+
+@enumerate
+
+@item %l1 and %l2 contain pc and npc respectively at the time of the trap
+
+@item traps are disabled
+
+@item you are in the correct trap window
+
+@end enumerate
+
+As long as your trap handler can guarantee those conditions, then there
+is no reason why you shouldn't be able to `share' traps with the stub.
+The stub has no requirement that it be jumped to directly from the
+hardware trap vector. That is why it calls @code{exceptionHandler()},
+which is provided by the external environment. For instance, this could
+setup the hardware traps to actually execute code which calls the stub
+first, and then transfers to its own trap handler.
+
+For the most point, there probably won't be much of an issue with
+`sharing' traps, as the traps we use are usually not used by the kernel,
+and often indicate unrecoverable error conditions. Anyway, this is all
+controlled by a table, and is trivial to modify. The most important
+trap for us is for @code{ta 1}. Without that, we can't single step or
+do breakpoints. Everything else is unnecessary for the proper operation
+of the debugger/stub.
+
+From reading the stub, it's probably not obvious how breakpoints work.
+They are simply done by deposit/examine operations from GDB.
+
+@section ROM Monitor Interface
+
+@section Custom Protocols
+
+@section Transport Layer
+
+@section Builtin Simulator
+
+
+@node Native Debugging
+
+@chapter Native Debugging
+
+Several files control GDB's configuration for native support:
+
+@table @file
+
+@item gdb/config/@var{arch}/@var{xyz}.mh
+Specifies Makefile fragments needed when hosting @emph{or native} on
+machine @var{xyz}. In particular, this lists the required
+native-dependent object files, by defining @samp{NATDEPFILES=@dots{}}.
+Also specifies the header file which describes native support on
+@var{xyz}, by defining @samp{NAT_FILE= nm-@var{xyz}.h}. You can also
+define @samp{NAT_CFLAGS}, @samp{NAT_ADD_FILES}, @samp{NAT_CLIBS},
+@samp{NAT_CDEPS}, etc.; see @file{Makefile.in}.
+
+@item gdb/config/@var{arch}/nm-@var{xyz}.h
+(@file{nm.h} is a link to this file, created by configure). Contains C
+macro definitions describing the native system environment, such as
+child process control and core file support.
+
+@item gdb/@var{xyz}-nat.c
+Contains any miscellaneous C code required for this native support of
+this machine. On some machines it doesn't exist at all.
+
+@end table
+
+There are some ``generic'' versions of routines that can be used by
+various systems. These can be customized in various ways by macros
+defined in your @file{nm-@var{xyz}.h} file. If these routines work for
+the @var{xyz} host, you can just include the generic file's name (with
+@samp{.o}, not @samp{.c}) in @code{NATDEPFILES}.
+
+Otherwise, if your machine needs custom support routines, you will need
+to write routines that perform the same functions as the generic file.
+Put them into @code{@var{xyz}-nat.c}, and put @code{@var{xyz}-nat.o}
+into @code{NATDEPFILES}.
+
+@table @file
+
+@item inftarg.c
+This contains the @emph{target_ops vector} that supports Unix child
+processes on systems which use ptrace and wait to control the child.
+
+@item procfs.c
+This contains the @emph{target_ops vector} that supports Unix child
+processes on systems which use /proc to control the child.
+
+@item fork-child.c
+This does the low-level grunge that uses Unix system calls to do a "fork
+and exec" to start up a child process.
+
+@item infptrace.c
+This is the low level interface to inferior processes for systems using
+the Unix @code{ptrace} call in a vanilla way.
+
+@end table
+
+@section Native core file Support
+
+@table @file
+
+@item core-aout.c::fetch_core_registers()
+Support for reading registers out of a core file. This routine calls
+@code{register_addr()}, see below. Now that BFD is used to read core
+files, virtually all machines should use @code{core-aout.c}, and should
+just provide @code{fetch_core_registers} in @code{@var{xyz}-nat.c} (or
+@code{REGISTER_U_ADDR} in @code{nm-@var{xyz}.h}).
+
+@item core-aout.c::register_addr()
+If your @code{nm-@var{xyz}.h} file defines the macro
+@code{REGISTER_U_ADDR(addr, blockend, regno)}, it should be defined to
+set @code{addr} to the offset within the @samp{user} struct of GDB
+register number @code{regno}. @code{blockend} is the offset within the
+``upage'' of @code{u.u_ar0}. If @code{REGISTER_U_ADDR} is defined,
+@file{core-aout.c} will define the @code{register_addr()} function and
+use the macro in it. If you do not define @code{REGISTER_U_ADDR}, but
+you are using the standard @code{fetch_core_registers()}, you will need
+to define your own version of @code{register_addr()}, put it into your
+@code{@var{xyz}-nat.c} file, and be sure @code{@var{xyz}-nat.o} is in
+the @code{NATDEPFILES} list. If you have your own
+@code{fetch_core_registers()}, you may not need a separate
+@code{register_addr()}. Many custom @code{fetch_core_registers()}
+implementations simply locate the registers themselves.@refill
+
+@end table
+
+When making GDB run native on a new operating system, to make it
+possible to debug core files, you will need to either write specific
+code for parsing your OS's core files, or customize
+@file{bfd/trad-core.c}. First, use whatever @code{#include} files your
+machine uses to define the struct of registers that is accessible
+(possibly in the u-area) in a core file (rather than
+@file{machine/reg.h}), and an include file that defines whatever header
+exists on a core file (e.g. the u-area or a @samp{struct core}). Then
+modify @code{trad_unix_core_file_p()} to use these values to set up the
+section information for the data segment, stack segment, any other
+segments in the core file (perhaps shared library contents or control
+information), ``registers'' segment, and if there are two discontiguous
+sets of registers (e.g. integer and float), the ``reg2'' segment. This
+section information basically delimits areas in the core file in a
+standard way, which the section-reading routines in BFD know how to seek
+around in.
+
+Then back in GDB, you need a matching routine called
+@code{fetch_core_registers()}. If you can use the generic one, it's in
+@file{core-aout.c}; if not, it's in your @file{@var{xyz}-nat.c} file.
+It will be passed a char pointer to the entire ``registers'' segment,
+its length, and a zero; or a char pointer to the entire ``regs2''
+segment, its length, and a 2. The routine should suck out the supplied
+register values and install them into GDB's ``registers'' array.
+
+If your system uses @file{/proc} to control processes, and uses ELF
+format core files, then you may be able to use the same routines for
+reading the registers out of processes and out of core files.
+
+@section ptrace
+
+@section /proc
+
+@section win32
+
+@section shared libraries
+
+@section Native Conditionals
When GDB is configured and compiled, various macros are defined or left
-undefined, to control compilation when the host and target systems
-are the same. These macros should be defined (or left undefined)
-in @file{nm-@var{system}.h}.
+undefined, to control compilation when the host and target systems are
+the same. These macros should be defined (or left undefined) in
+@file{nm-@var{system}.h}.
@table @code
@@ -2418,31 +1914,59 @@ If defined, then GDB will include support for the @code{attach} and
@code{detach} commands.
@item CHILD_PREPARE_TO_STORE
-If the machine stores all registers at once in the child process,
-then define this to ensure that all values are correct.
-This usually entails a read from the child.
+If the machine stores all registers at once in the child process, then
+define this to ensure that all values are correct. This usually entails
+a read from the child.
-[Note that this is incorrectly defined in @file{xm-@var{system}.h}
-files currently.]
+[Note that this is incorrectly defined in @file{xm-@var{system}.h} files
+currently.]
@item FETCH_INFERIOR_REGISTERS
-Define this if the native-dependent code will provide its
-own routines
+Define this if the native-dependent code will provide its own routines
@code{fetch_inferior_registers} and @code{store_inferior_registers} in
-@file{@var{HOST}-nat.c}.
-If this symbol is @emph{not} defined, and @file{infptrace.c}
-is included in this configuration, the default routines in
-@file{infptrace.c} are used for these functions.
+@file{@var{HOST}-nat.c}. If this symbol is @emph{not} defined, and
+@file{infptrace.c} is included in this configuration, the default
+routines in @file{infptrace.c} are used for these functions.
+
+@item FILES_INFO_HOOK
+(Only defined for Convex.)
+
+@item FP0_REGNUM
+This macro is normally defined to be the number of the first floating
+point register, if the machine has such registers. As such, it would
+appear only in target-specific code. However, /proc support uses this
+to decide whether floats are in use on this target.
@item GET_LONGJMP_TARGET
-For most machines, this is a target-dependent parameter. On the DECstation
-and the Iris, this is a native-dependent parameter, since <setjmp.h> is
-needed to define it.
+For most machines, this is a target-dependent parameter. On the
+DECstation and the Iris, this is a native-dependent parameter, since
+<setjmp.h> is needed to define it.
+
+This macro determines the target PC address that longjmp() will jump to,
+assuming that we have just stopped at a longjmp breakpoint. It takes a
+CORE_ADDR * as argument, and stores the target PC value through this
+pointer. It examines the current state of the machine as needed.
+
+@item KERNEL_U_ADDR
+Define this to the address of the @code{u} structure (the ``user
+struct'', also known as the ``u-page'') in kernel virtual memory. GDB
+needs to know this so that it can subtract this address from absolute
+addresses in the upage, that are obtained via ptrace or from core files.
+On systems that don't need this value, set it to zero.
-This macro determines the target PC address that longjmp() will jump
-to, assuming that we have just stopped at a longjmp breakpoint. It
-takes a CORE_ADDR * as argument, and stores the target PC value through
-this pointer. It examines the current state of the machine as needed.
+@item KERNEL_U_ADDR_BSD
+Define this to cause GDB to determine the address of @code{u} at
+runtime, by using Berkeley-style @code{nlist} on the kernel's image in
+the root directory.
+
+@item KERNEL_U_ADDR_HPUX
+Define this to cause GDB to determine the address of @code{u} at
+runtime, by using HP-style @code{nlist} on the kernel's image in the
+root directory.
+
+@item ONE_PROCESS_WRITETEXT
+Define this to be able to, when a breakpoint insertion fails, warn the
+user that another process may be running with the same executable.
@item PROC_NAME_FMT
Defines the format for the name of a @file{/proc} device. Should be
@@ -2453,43 +1977,53 @@ definition in @file{procfs.c}.
mach386-xdep.c
@item PTRACE_ARG3_TYPE
-The type of the third argument to the @code{ptrace} system call, if it exists
-and is different from @code{int}.
+The type of the third argument to the @code{ptrace} system call, if it
+exists and is different from @code{int}.
@item REGISTER_U_ADDR
-Defines the offset of the registers in the ``u area''; @pxref{Host}.
+Defines the offset of the registers in the ``u area''.
+
+@item SHELL_COMMAND_CONCAT
+If defined, is a string to prefix on the shell command used to start the
+inferior.
+
+@item SHELL_FILE
+If defined, this is the name of the shell to use to run the inferior.
+Defaults to @code{"/bin/sh"}.
@item SOLIB_ADD (filename, from_tty, targ)
-Define this to expand into an expression that will cause the symbols
-in @var{filename} to be added to GDB's symbol table.
+Define this to expand into an expression that will cause the symbols in
+@var{filename} to be added to GDB's symbol table.
@item SOLIB_CREATE_INFERIOR_HOOK
-Define this to expand into any shared-library-relocation code
-that you want to be run just after the child process has been forked.
+Define this to expand into any shared-library-relocation code that you
+want to be run just after the child process has been forked.
@item START_INFERIOR_TRAPS_EXPECTED
-When starting an inferior, GDB normally expects to trap twice;
-once when the shell execs, and once when the program itself execs.
-If the actual number of traps is something other than 2, then
-define this macro to expand into the number expected.
+When starting an inferior, GDB normally expects to trap twice; once when
+the shell execs, and once when the program itself execs. If the actual
+number of traps is something other than 2, then define this macro to
+expand into the number expected.
+
+@item SVR4_SHARED_LIBS
+Define this to indicate that SVR4-style shared libraries are in use.
@item USE_PROC_FS
This determines whether small routines in @file{*-tdep.c}, which
-translate register values
-between GDB's internal representation and the /proc representation,
-are compiled.
+translate register values between GDB's internal representation and the
+/proc representation, are compiled.
@item U_REGS_OFFSET
This is the offset of the registers in the upage. It need only be
defined if the generic ptrace register access routines in
-@file{infptrace.c} are being used (that is,
-@file{infptrace.c} is configured in, and
-@code{FETCH_INFERIOR_REGISTERS} is not defined). If the default value
-from @file{infptrace.c} is good enough, leave it undefined.
+@file{infptrace.c} are being used (that is, @file{infptrace.c} is
+configured in, and @code{FETCH_INFERIOR_REGISTERS} is not defined). If
+the default value from @file{infptrace.c} is good enough, leave it
+undefined.
-The default value means that u.u_ar0 @emph{points to} the location of the
-registers. I'm guessing that @code{#define U_REGS_OFFSET 0} means that
-u.u_ar0 @emph{is} the location of the registers.
+The default value means that u.u_ar0 @emph{points to} the location of
+the registers. I'm guessing that @code{#define U_REGS_OFFSET 0} means
+that u.u_ar0 @emph{is} the location of the registers.
@item CLEAR_SOLIB
objfiles.c
@@ -2499,13 +2033,653 @@ Define this to debug ptrace calls.
@end table
-@node Obsolete Conditionals
-@chapter Obsolete Conditionals
+
+@node Support Libraries
+
+@chapter Support Libraries
+
+@section BFD
+
+BFD provides support for GDB in several ways:
+
+@table @emph
+
+@item identifying executable and core files
+BFD will identify a variety of file types, including a.out, coff, and
+several variants thereof, as well as several kinds of core files.
+
+@item access to sections of files
+BFD parses the file headers to determine the names, virtual addresses,
+sizes, and file locations of all the various named sections in files
+(such as the text section or the data section). GDB simply calls BFD to
+read or write section X at byte offset Y for length Z.
+
+@item specialized core file support
+BFD provides routines to determine the failing command name stored in a
+core file, the signal with which the program failed, and whether a core
+file matches (i.e. could be a core dump of) a particular executable
+file.
+
+@item locating the symbol information
+GDB uses an internal interface of BFD to determine where to find the
+symbol information in an executable file or symbol-file. GDB itself
+handles the reading of symbols, since BFD does not ``understand'' debug
+symbols, but GDB uses BFD's cached information to find the symbols,
+string table, etc.
+
+@end table
+
+@section opcodes
+
+The opcodes library provides GDB's disassembler. (It's a separate
+library because it's also used in binutils, for @file{objdump}).
+
+@section readline
+
+@section mmalloc
+
+@section libiberty
+
+@section gnu-regex
+
+Regex conditionals.
+
+@table @code
+
+@item C_ALLOCA
+
+@item NFAILURES
+
+@item RE_NREGS
+
+@item SIGN_EXTEND_CHAR
+
+@item SWITCH_ENUM_BUG
+
+@item SYNTAX_TABLE
+
+@item Sword
+
+@item sparc
+
+@end table
+
+@section include
+
+@node Coding
+
+@chapter Coding
+
+This chapter covers topics that are lower-level than the major
+algorithms of GDB.
+
+@section Cleanups
+
+Cleanups are a structured way to deal with things that need to be done
+later. When your code does something (like @code{malloc} some memory,
+or open a file) that needs to be undone later (e.g. free the memory or
+close the file), it can make a cleanup. The cleanup will be done at
+some future point: when the command is finished, when an error occurs,
+or when your code decides it's time to do cleanups.
+
+You can also discard cleanups, that is, throw them away without doing
+what they say. This is only done if you ask that it be done.
+
+Syntax:
+
+@table @code
+
+@item struct cleanup *@var{old_chain};
+Declare a variable which will hold a cleanup chain handle.
+
+@item @var{old_chain} = make_cleanup (@var{function}, @var{arg});
+Make a cleanup which will cause @var{function} to be called with
+@var{arg} (a @code{char *}) later. The result, @var{old_chain}, is a
+handle that can be passed to @code{do_cleanups} or
+@code{discard_cleanups} later. Unless you are going to call
+@code{do_cleanups} or @code{discard_cleanups} yourself, you can ignore
+the result from @code{make_cleanup}.
+
+@item do_cleanups (@var{old_chain});
+Perform all cleanups done since @code{make_cleanup} returned
+@var{old_chain}. E.g.:
+@example
+make_cleanup (a, 0);
+old = make_cleanup (b, 0);
+do_cleanups (old);
+@end example
+@noindent
+will call @code{b()} but will not call @code{a()}. The cleanup that
+calls @code{a()} will remain in the cleanup chain, and will be done
+later unless otherwise discarded.@refill
+
+@item discard_cleanups (@var{old_chain});
+Same as @code{do_cleanups} except that it just removes the cleanups from
+the chain and does not call the specified functions.
+
+@end table
+
+Some functions, e.g. @code{fputs_filtered()} or @code{error()}, specify
+that they ``should not be called when cleanups are not in place''. This
+means that any actions you need to reverse in the case of an error or
+interruption must be on the cleanup chain before you call these
+functions, since they might never return to your code (they
+@samp{longjmp} instead).
+
+@section Wrapping Output Lines
+
+Output that goes through @code{printf_filtered} or @code{fputs_filtered}
+or @code{fputs_demangled} needs only to have calls to @code{wrap_here}
+added in places that would be good breaking points. The utility
+routines will take care of actually wrapping if the line width is
+exceeded.
+
+The argument to @code{wrap_here} is an indentation string which is
+printed @emph{only} if the line breaks there. This argument is saved
+away and used later. It must remain valid until the next call to
+@code{wrap_here} or until a newline has been printed through the
+@code{*_filtered} functions. Don't pass in a local variable and then
+return!
+
+It is usually best to call @code{wrap_here()} after printing a comma or
+space. If you call it before printing a space, make sure that your
+indentation properly accounts for the leading space that will print if
+the line wraps there.
+
+Any function or set of functions that produce filtered output must
+finish by printing a newline, to flush the wrap buffer, before switching
+to unfiltered (``@code{printf}'') output. Symbol reading routines that
+print warnings are a good example.
+
+@section GDB Coding Standards
+
+GDB follows the GNU coding standards, as described in
+@file{etc/standards.texi}. This file is also available for anonymous
+FTP from GNU archive sites. GDB takes a strict interpretation of the
+standard; in general, when the GNU standard recommends a practice but
+does not require it, GDB requires it.
+
+GDB follows an additional set of coding standards specific to GDB,
+as described in the following sections.
+
+You can configure with @samp{--enable-build-warnings} to get GCC to
+check on a number of these rules. GDB sources ought not to engender any
+complaints, unless they are caused by bogus host systems. (The exact
+set of enabled warnings is currently @samp{-Wall -Wpointer-arith
+-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations}.
+
+@subsection Formatting
+
+The standard GNU recommendations for formatting must be followed
+strictly.
+
+Note that while in a definition, the function's name must be in column
+zero; in a function declaration, the name must be on the same line as
+the return type.
+
+In addition, there must be a space between a function or macro name and
+the opening parenthesis of its argument list (except for macro
+definitions, as required by C). There must not be a space after an open
+paren/bracket or before a close paren/bracket.
+
+While additional whitespace is generally helpful for reading, do not use
+more than one blank line to separate blocks, and avoid adding whitespace
+after the end of a program line (as of 1/99, some 600 lines had whitespace
+after the semicolon). Excess whitespace causes difficulties for diff and
+patch.
+
+@subsection Comments
+
+The standard GNU requirements on comments must be followed strictly.
+
+Block comments must appear in the following form, with no `/*'- or
+'*/'-only lines, and no leading `*':
+
+@example @code
+/* 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. */
+@end example
+
+(Note that this format is encouraged by Emacs; tabbing for a multi-line
+comment works correctly, and M-Q fills the block consistently.)
+
+Put a blank line between the block comments preceding function or
+variable definitions, and the definition itself.
+
+In general, put function-body comments on lines by themselves, rather
+than trying to fit them into the 20 characters left at the end of a
+line, since either the comment or the code will inevitably get longer
+than will fit, and then somebody will have to move it anyhow.
+
+@subsection C Usage
+
+Code must not depend on the sizes of C data types, the format of the
+host's floating point numbers, the alignment of anything, or the order
+of evaluation of expressions.
+
+Use functions freely. There are only a handful of compute-bound areas
+in GDB that might be affected by the overhead of a function call, mainly
+in symbol reading. Most of GDB's performance is limited by the target
+interface (whether serial line or system call).
+
+However, use functions with moderation. A thousand one-line functions
+are just as hard to understand as a single thousand-line function.
+
+@subsection Function Prototypes
+
+Prototypes must be used to @emph{declare} functions but never to
+@emph{define} them. Prototypes for GDB functions must include both the
+argument type and name, with the name matching that used in the actual
+function definition.
+
+For the sake of compatibility with pre-ANSI compilers, define prototypes
+with the @code{PARAMS} macro:
+
+@example @code
+extern int memory_remove_breakpoint PARAMS ((CORE_ADDR addr,
+ char *contents_cache));
+@end example
+
+Note the double parentheses around the parameter types. This allows an
+arbitrary number of parameters to be described, without freaking out the
+C preprocessor. When the function has no parameters, it should be
+described like:
+
+@example @code
+extern void noprocess PARAMS ((void));
+@end example
+
+The @code{PARAMS} macro expands to its argument in ANSI C, or to a
+simple @code{()} in traditional C.
+
+All external functions should have a @code{PARAMS} declaration in a
+header file that callers include, except for @code{_initialize_*}
+functions, which must be external so that @file{init.c} construction
+works, but shouldn't be visible to random source files.
+
+All static functions must be declared in a block near the top of the
+source file.
+
+@subsection Clean Design
+
+In addition to getting the syntax right, there's the little question of
+semantics. Some things are done in certain ways in GDB because long
+experience has shown that the more obvious ways caused various kinds of
+trouble.
+
+You can't assume the byte order of anything that comes from a target
+(including @var{value}s, object files, and instructions). Such things
+must be byte-swapped using @code{SWAP_TARGET_AND_HOST} in GDB, or one of
+the swap routines defined in @file{bfd.h}, such as @code{bfd_get_32}.
+
+You can't assume that you know what interface is being used to talk to
+the target system. All references to the target must go through the
+current @code{target_ops} vector.
+
+You can't assume that the host and target machines are the same machine
+(except in the ``native'' support modules). In particular, you can't
+assume that the target machine's header files will be available on the
+host machine. Target code must bring along its own header files --
+written from scratch or explicitly donated by their owner, to avoid
+copyright problems.
+
+Insertion of new @code{#ifdef}'s will be frowned upon. It's much better
+to write the code portably than to conditionalize it for various
+systems.
+
+New @code{#ifdef}'s which test for specific compilers or manufacturers
+or operating systems are unacceptable. All @code{#ifdef}'s should test
+for features. The information about which configurations contain which
+features should be segregated into the configuration files. Experience
+has proven far too often that a feature unique to one particular system
+often creeps into other systems; and that a conditional based on some
+predefined macro for your current system will become worthless over
+time, as new versions of your system come out that behave differently
+with regard to this feature.
+
+Adding code that handles specific architectures, operating systems,
+target interfaces, or hosts, is not acceptable in generic code. If a
+hook is needed at that point, invent a generic hook and define it for
+your configuration, with something like:
+
+@example
+#ifdef WRANGLE_SIGNALS
+ WRANGLE_SIGNALS (signo);
+#endif
+@end example
+
+In your host, target, or native configuration file, as appropriate,
+define @code{WRANGLE_SIGNALS} to do the machine-dependent thing. Take a
+bit of care in defining the hook, so that it can be used by other ports
+in the future, if they need a hook in the same place.
+
+If the hook is not defined, the code should do whatever "most" machines
+want. Using @code{#ifdef}, as above, is the preferred way to do this,
+but sometimes that gets convoluted, in which case use
+
+@example
+#ifndef SPECIAL_FOO_HANDLING
+#define SPECIAL_FOO_HANDLING(pc, sp) (0)
+#endif
+@end example
+
+where the macro is used or in an appropriate header file.
+
+Whether to include a @dfn{small} hook, a hook around the exact pieces of
+code which are system-dependent, or whether to replace a whole function
+with a hook depends on the case. A good example of this dilemma can be
+found in @code{get_saved_register}. All machines that GDB 2.8 ran on
+just needed the @code{FRAME_FIND_SAVED_REGS} hook to find the saved
+registers. Then the SPARC and Pyramid came along, and
+@code{HAVE_REGISTER_WINDOWS} and @code{REGISTER_IN_WINDOW_P} were
+introduced. Then the 29k and 88k required the @code{GET_SAVED_REGISTER}
+hook. The first three are examples of small hooks; the latter replaces
+a whole function. In this specific case, it is useful to have both
+kinds; it would be a bad idea to replace all the uses of the small hooks
+with @code{GET_SAVED_REGISTER}, since that would result in much
+duplicated code. Other times, duplicating a few lines of code here or
+there is much cleaner than introducing a large number of small hooks.
+
+Another way to generalize GDB along a particular interface is with an
+attribute struct. For example, GDB has been generalized to handle
+multiple kinds of remote interfaces -- not by #ifdef's everywhere, but
+by defining the "target_ops" structure and having a current target (as
+well as a stack of targets below it, for memory references). Whenever
+something needs to be done that depends on which remote interface we are
+using, a flag in the current target_ops structure is tested (e.g.
+`target_has_stack'), or a function is called through a pointer in the
+current target_ops structure. In this way, when a new remote interface
+is added, only one module needs to be touched -- the one that actually
+implements the new remote interface. Other examples of
+attribute-structs are BFD access to multiple kinds of object file
+formats, or GDB's access to multiple source languages.
+
+Please avoid duplicating code. For example, in GDB 3.x all the code
+interfacing between @code{ptrace} and the rest of GDB was duplicated in
+@file{*-dep.c}, and so changing something was very painful. In GDB 4.x,
+these have all been consolidated into @file{infptrace.c}.
+@file{infptrace.c} can deal with variations between systems the same way
+any system-independent file would (hooks, #if defined, etc.), and
+machines which are radically different don't need to use infptrace.c at
+all.
+
+
+@node Porting GDB
+
+@chapter Porting GDB
+
+Most of the work in making GDB compile on a new machine is in specifying
+the configuration of the machine. This is done in a dizzying variety of
+header files and configuration scripts, which we hope to make more
+sensible soon. Let's say your new host is called an @var{xyz} (e.g.
+@samp{sun4}), and its full three-part configuration name is
+@code{@var{arch}-@var{xvend}-@var{xos}} (e.g. @samp{sparc-sun-sunos4}).
+In particular:
+
+In the top level directory, edit @file{config.sub} and add @var{arch},
+@var{xvend}, and @var{xos} to the lists of supported architectures,
+vendors, and operating systems near the bottom of the file. Also, add
+@var{xyz} as an alias that maps to
+@code{@var{arch}-@var{xvend}-@var{xos}}. You can test your changes by
+running
+
+@example
+./config.sub @var{xyz}
+@end example
+@noindent
+and
+@example
+./config.sub @code{@var{arch}-@var{xvend}-@var{xos}}
+@end example
+@noindent
+which should both respond with @code{@var{arch}-@var{xvend}-@var{xos}}
+and no error messages.
+
+You need to port BFD, if that hasn't been done already. Porting BFD is
+beyond the scope of this manual.
+
+To configure GDB itself, edit @file{gdb/configure.host} to recognize
+your system and set @code{gdb_host} to @var{xyz}, and (unless your
+desired target is already available) also edit @file{gdb/configure.tgt},
+setting @code{gdb_target} to something appropriate (for instance,
+@var{xyz}).
+
+Finally, you'll need to specify and define GDB's host-, native-, and
+target-dependent @file{.h} and @file{.c} files used for your
+configuration.
+
+@section Configuring GDB for Release
+
+From the top level directory (containing @file{gdb}, @file{bfd},
+@file{libiberty}, and so on):
+@example
+make -f Makefile.in gdb.tar.gz
+@end example
+
+This will properly configure, clean, rebuild any files that are
+distributed pre-built (e.g. @file{c-exp.tab.c} or @file{refcard.ps}),
+and will then make a tarfile. (If the top level directory has already
+been configured, you can just do @code{make gdb.tar.gz} instead.)
+
+This procedure requires:
+@itemize @bullet
+@item symbolic links
+@item @code{makeinfo} (texinfo2 level)
+@item @TeX{}
+@item @code{dvips}
+@item @code{yacc} or @code{bison}
+@end itemize
+@noindent
+@dots{} and the usual slew of utilities (@code{sed}, @code{tar}, etc.).
+
+@subheading TEMPORARY RELEASE PROCEDURE FOR DOCUMENTATION
+
+@file{gdb.texinfo} is currently marked up using the texinfo-2 macros,
+which are not yet a default for anything (but we have to start using
+them sometime).
+
+For making paper, the only thing this implies is the right generation of
+@file{texinfo.tex} needs to be included in the distribution.
+
+For making info files, however, rather than duplicating the texinfo2
+distribution, generate @file{gdb-all.texinfo} locally, and include the
+files @file{gdb.info*} in the distribution. Note the plural;
+@code{makeinfo} will split the document into one overall file and five
+or so included files.
+
+@node Hints
+
+@chapter Hints
+
+Check the @file{README} file, it often has useful information that does not
+appear anywhere else in the directory.
+
+@menu
+* Getting Started:: Getting started working on GDB
+* Debugging GDB:: Debugging GDB with itself
+@end menu
+
+@node Getting Started,,, Hints
+
+@section Getting Started
+
+GDB is a large and complicated program, and if you first starting to
+work on it, it can be hard to know where to start. Fortunately, if you
+know how to go about it, there are ways to figure out what is going on.
+
+This manual, the GDB Internals manual, has information which applies
+generally to many parts of GDB.
+
+Information about particular functions or data structures are located in
+comments with those functions or data structures. If you run across a
+function or a global variable which does not have a comment correctly
+explaining what is does, this can be thought of as a bug in GDB; feel
+free to submit a bug report, with a suggested comment if you can figure
+out what the comment should say. If you find a comment which is
+actually wrong, be especially sure to report that.
+
+Comments explaining the function of macros defined in host, target, or
+native dependent files can be in several places. Sometimes they are
+repeated every place the macro is defined. Sometimes they are where the
+macro is used. Sometimes there is a header file which supplies a
+default definition of the macro, and the comment is there. This manual
+also documents all the available macros.
+@c (@pxref{Host Conditionals}, @pxref{Target
+@c Conditionals}, @pxref{Native Conditionals}, and @pxref{Obsolete
+@c Conditionals})
+
+Start with the header files. Once you some idea of how GDB's internal
+symbol tables are stored (see @file{symtab.h}, @file{gdbtypes.h}), you
+will find it much easier to understand the code which uses and creates
+those symbol tables.
+
+You may wish to process the information you are getting somehow, to
+enhance your understanding of it. Summarize it, translate it to another
+language, add some (perhaps trivial or non-useful) feature to GDB, use
+the code to predict what a test case would do and write the test case
+and verify your prediction, etc. If you are reading code and your eyes
+are starting to glaze over, this is a sign you need to use a more active
+approach.
+
+Once you have a part of GDB to start with, you can find more
+specifically the part you are looking for by stepping through each
+function with the @code{next} command. Do not use @code{step} or you
+will quickly get distracted; when the function you are stepping through
+calls another function try only to get a big-picture understanding
+(perhaps using the comment at the beginning of the function being
+called) of what it does. This way you can identify which of the
+functions being called by the function you are stepping through is the
+one which you are interested in. You may need to examine the data
+structures generated at each stage, with reference to the comments in
+the header files explaining what the data structures are supposed to
+look like.
+
+Of course, this same technique can be used if you are just reading the
+code, rather than actually stepping through it. The same general
+principle applies---when the code you are looking at calls something
+else, just try to understand generally what the code being called does,
+rather than worrying about all its details.
+
+A good place to start when tracking down some particular area is with a
+command which invokes that feature. Suppose you want to know how
+single-stepping works. As a GDB user, you know that the @code{step}
+command invokes single-stepping. The command is invoked via command
+tables (see @file{command.h}); by convention the function which actually
+performs the command is formed by taking the name of the command and
+adding @samp{_command}, or in the case of an @code{info} subcommand,
+@samp{_info}. For example, the @code{step} command invokes the
+@code{step_command} function and the @code{info display} command invokes
+@code{display_info}. When this convention is not followed, you might
+have to use @code{grep} or @kbd{M-x tags-search} in emacs, or run GDB on
+itself and set a breakpoint in @code{execute_command}.
+
+If all of the above fail, it may be appropriate to ask for information
+on @code{bug-gdb}. But @emph{never} post a generic question like ``I was
+wondering if anyone could give me some tips about understanding
+GDB''---if we had some magic secret we would put it in this manual.
+Suggestions for improving the manual are always welcome, of course.
+
+@node Debugging GDB,,,Hints
+
+@section Debugging GDB with itself
+
+If GDB is limping on your machine, this is the preferred way to get it
+fully functional. Be warned that in some ancient Unix systems, like
+Ultrix 4.2, a program can't be running in one process while it is being
+debugged in another. Rather than typing the command @code{@w{./gdb
+./gdb}}, which works on Suns and such, you can copy @file{gdb} to
+@file{gdb2} and then type @code{@w{./gdb ./gdb2}}.
+
+When you run GDB in the GDB source directory, it will read a
+@file{.gdbinit} file that sets up some simple things to make debugging
+gdb easier. The @code{info} command, when executed without a subcommand
+in a GDB being debugged by gdb, will pop you back up to the top level
+gdb. See @file{.gdbinit} for details.
+
+If you use emacs, you will probably want to do a @code{make TAGS} after
+you configure your distribution; this will put the machine dependent
+routines for your local machine where they will be accessed first by
+@kbd{M-.}
+
+Also, make sure that you've either compiled GDB with your local cc, or
+have run @code{fixincludes} if you are compiling with gcc.
+
+@section Submitting Patches
+
+Thanks for thinking of offering your changes back to the community of
+GDB users. In general we like to get well designed enhancements.
+Thanks also for checking in advance about the best way to transfer the
+changes.
+
+The GDB maintainers will only install ``cleanly designed'' patches. You
+may not always agree on what is clean design.
+@c @pxref{Coding Style}, @pxref{Clean Design}.
+
+If the maintainers don't have time to put the patch in when it arrives,
+or if there is any question about a patch, it goes into a large queue
+with everyone else's patches and bug reports.
+
+The legal issue is that to incorporate substantial changes requires a
+copyright assignment from you and/or your employer, granting ownership
+of the changes to the Free Software Foundation. You can get the
+standard document for doing this by sending mail to
+@code{gnu@@prep.ai.mit.edu} and asking for it. I recommend that people
+write in "All programs owned by the Free Software Foundation" as "NAME
+OF PROGRAM", so that changes in many programs (not just GDB, but GAS,
+Emacs, GCC, etc) can be contributed with only one piece of legalese
+pushed through the bureacracy and filed with the FSF. I can't start
+merging changes until this paperwork is received by the FSF (their
+rules, which I follow since I maintain it for them).
+
+Technically, the easiest way to receive changes is to receive each
+feature as a small context diff or unidiff, suitable for "patch".
+Each message sent to me should include the changes to C code and
+header files for a single feature, plus ChangeLog entries for each
+directory where files were modified, and diffs for any changes needed
+to the manuals (gdb/doc/gdb.texi or gdb/doc/gdbint.texi). If there
+are a lot of changes for a single feature, they can be split down
+into multiple messages.
+
+In this way, if I read and like the feature, I can add it to the
+sources with a single patch command, do some testing, and check it in.
+If you leave out the ChangeLog, I have to write one. If you leave
+out the doc, I have to puzzle out what needs documenting. Etc.
+
+The reason to send each change in a separate message is that I will
+not install some of the changes. They'll be returned to you with
+questions or comments. If I'm doing my job, my message back to you
+will say what you have to fix in order to make the change acceptable.
+The reason to have separate messages for separate features is so
+that other changes (which I @emph{am} willing to accept) can be installed
+while one or more changes are being reworked. If multiple features
+are sent in a single message, I tend to not put in the effort to sort
+out the acceptable changes from the unacceptable, so none of the
+features get installed until all are acceptable.
+
+If this sounds painful or authoritarian, well, it is. But I get a lot
+of bug reports and a lot of patches, and most of them don't get
+installed because I don't have the time to finish the job that the bug
+reporter or the contributor could have done. Patches that arrive
+complete, working, and well designed, tend to get installed on the day
+they arrive. The others go into a queue and get installed if and when
+I scan back over the queue -- which can literally take months
+sometimes. It's in both our interests to make patch installation easy
+-- you get your changes installed, and I make some forward progress on
+GDB in a normal 12-hour day (instead of them having to wait until I
+have a 14-hour or 16-hour day to spend cleaning up patches before I
+can install them).
+
+Please send patches directly to the GDB maintainers at
+@code{gdb-patches@@cygnus.com}.
+
+@section Obsolete Conditionals
Fragments of old code in GDB sometimes reference or set the following
-configuration macros. They should not be used by new code, and
-old uses should be removed as those parts of the debugger are
-otherwise touched.
+configuration macros. They should not be used by new code, and old uses
+should be removed as those parts of the debugger are otherwise touched.
@table @code
@@ -2520,24 +2694,18 @@ and deleted from all of GDB's config files.
Any @file{@var{foo}-xdep.c} file that references STACK_END_ADDR
is so old that it has never been converted to use BFD. Now that's old!
-@end table
+@item PYRAMID_CONTROL_FRAME_DEBUGGING
+pyr-xdep.c
+@item PYRAMID_CORE
+pyr-xdep.c
+@item PYRAMID_PTRACE
+pyr-xdep.c
-@node XCOFF
-@chapter The XCOFF Object File Format
+@item REG_STACK_SEGMENT
+exec.c
-The IBM RS/6000 running AIX uses an object file format called xcoff.
-The COFF sections, symbols, and line numbers are used, but debugging
-symbols are dbx-style stabs whose strings are located in the
-@samp{.debug} section (rather than the string table). For more
-information, @xref{Top,,,stabs,The Stabs Debugging Format}, and search
-for XCOFF.
+@end table
-The shared library scheme has a nice clean interface for figuring out
-what shared libraries are in use, but the catch is that everything which
-refers to addresses (symbol tables and breakpoints at least) needs to be
-relocated for both shared libraries and the main executable. At least
-using the standard mechanism this can only be done once the program has
-been run (or the core file has been read).
@contents
@bye
diff --git a/contrib/gdb/gdb/doc/refcard.tex b/contrib/gdb/gdb/doc/refcard.tex
index c57c2d8..d2b72de 100644
--- a/contrib/gdb/gdb/doc/refcard.tex
+++ b/contrib/gdb/gdb/doc/refcard.tex
@@ -1,7 +1,7 @@
%%%%%%%%%%%%%%%% gdb-refcard.tex %%%%%%%%%%%%%%%%
%This file is TeX source for a reference card describing GDB, the GNU debugger.
-%Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+%Copyright (C) 1991, 1992, 1993, 1998 Free Software Foundation, Inc.
%Permission is granted to make and distribute verbatim copies of
%this reference provided the copyright notices and permission notices
%are preserved on all copies.
@@ -11,7 +11,7 @@
%
%This program is free software; you can redistribute it and/or modify
%it under the terms of the GNU General Public License as published by
-%the Free Software Foundation; either version 1, or (at your option)
+%the Free Software Foundation; either version 2, or (at your option)
%any later version.
%
%This program is distributed in the hope that it will be useful, but
@@ -19,18 +19,18 @@
%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%General Public License for more details.
%
-%You can find a copy of the GNU General Public License in the GDB
-%manual; or write to the Free Software Foundation, Inc.,
-%59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+%You can find a copy of the GNU General Public License at the URL
+%http://www.gnu.org/copyleft/gpl.html; or write to the Free Software
+%Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
%
-%You can contact the author at: doc@cygnus.com
+%You can contact the maintainer at: doc@cygnus.com
%
% Documentation Department
-% Cygnus Support
-% 1937 Landings Drive
-% Mountain View, CA 94043 USA
+% Cygnus Solutions
+% 1325 Chesapeake Terrace
+% Sunnyvale, CA 94089 USA
%
-% +1 415 903 1400
+% +1 800 CYGNUS-1
%
%
%
@@ -304,7 +304,7 @@ shell {\it cmd}&execute arbitrary shell command string\cr
\line{\smrm \opt{ } surround optional arguments \hfill $\ldots$ show
one or more arguments}
\vskip\baselineskip
-\centerline{\smrm \copyright 1991, 1992, 1993 Free Software Foundation, Inc.\qquad Permissions on back}
+\centerline{\smrm \copyright 1998 Free Software Foundation, Inc.\qquad Permissions on back}
\eject
\sec Breakpoints and Watchpoints;
break \opt{\it file\tt:}{\it line}\par
@@ -322,7 +322,8 @@ cond {\it n} \opt{\it expr}&new conditional expression on breakpoint
tbreak $\ldots$&temporary break; disable when reached\cr
rbreak {\it regex}&break on all functions matching {\it regex}\cr
watch {\it expr}&set a watchpoint for expression {\it expr}\cr
-catch {\it x}&break at C++ handler for exception {\it x}\cr
+catch {\it event}&break at {\it event}, which may be {\tt catch}, {\tt throw},
+{\tt exec}, {\tt fork}, {\tt vfork}, {\tt load}, or {\tt unload}.\cr
\cr
info break&show defined breakpoints\cr
info watch&show defined watchpoints\cr
@@ -371,7 +372,6 @@ info locals&local variables of selected frame\cr
info reg \opt{\it rn}$\ldots$\par
info all-reg \opt{\it rn}&register values \opt{for regs {\it rn\/}} in
selected frame; {\tt all-reg} includes floating point\cr
-info catch&exception handlers active in selected frame\cr
\endsec
\vfill\eject
@@ -628,15 +628,15 @@ statement.\cr
\vfill
{\smrm\parskip=6pt
-\centerline{Copyright \copyright 1991, 1992, 1993 Free Software Foundation, Inc.}
-\centerline{Cygnus Support (doc@cygnus.com)}
+\centerline{Copyright \copyright 1991, '92, '93, '98 Free Software Foundation, Inc.}
+\centerline{Roland H. Pesch}
\centerline{The author assumes no responsibility for any errors on this card.}
This card may be freely distributed under the terms of the GNU
General Public License.
\centerline{Please contribute to development of this card by
-annotating it.}
+annotating it. Improvements can be sent to bug-gdb@gnu.org.}
GDB itself is free software; you are welcome to distribute copies of
it under the terms of the GNU General Public License. There is
diff --git a/contrib/gdb/gdb/doc/remote.texi b/contrib/gdb/gdb/doc/remote.texi
index b878e19..816b658 100644
--- a/contrib/gdb/gdb/doc/remote.texi
+++ b/contrib/gdb/gdb/doc/remote.texi
@@ -62,9 +62,12 @@ machine; for example, use @file{sparc-stub.c} to debug programs on
These working remote stubs are distributed with @value{GDBN}:
@table @code
-@item sparc-stub.c
-@kindex sparc-stub.c
-For @sc{sparc} architectures.
+
+@item i386-stub.c
+@kindex i386-stub.c
+@cindex Intel
+@cindex i386
+For Intel 386 and compatible architectures.
@item m68k-stub.c
@kindex m68k-stub.c
@@ -72,11 +75,23 @@ For @sc{sparc} architectures.
@cindex m680x0
For Motorola 680x0 architectures.
-@item i386-stub.c
-@kindex i386-stub.c
-@cindex Intel
-@cindex i386
-For Intel 386 and compatible architectures.
+@item sh-stub.c
+@kindex sh-stub.c
+@cindex Hitachi
+@cindex SH
+For Hitachi SH architectures.
+
+@item sparc-stub.c
+@kindex sparc-stub.c
+@cindex Sparc
+For @sc{sparc} architectures.
+
+@item sparcl-stub.c
+@kindex sparcl-stub.c
+@cindex Fujitsu
+@cindex SparcLite
+For Fujitsu @sc{sparclite} architectures.
+
@end table
The @file{README} file in the @value{GDBN} distribution may list other
@@ -430,9 +445,8 @@ to make a quick decision about single-stepping or conditional breakpoints.
This eliminates the need to fetch the entire register set for each instruction
being stepped through.
-The @value{GDBN} remote serial protocol now implements a write-through
-cache for registers. @value{GDBN} only re-reads the registers if the
-target has run.
+@value{GDBN} now implements a write-through cache for registers and only
+re-reads the registers if the target has run.
@end table
@kindex set remotedebug
@@ -1129,6 +1143,157 @@ or suspended when you attach to it. Running tasks are suspended at
the time of attachment.
@end ifset
+@ifset SPARCLET
+@node Sparclet Remote
+@subsection @value{GDBN} and Sparclet
+@cindex Sparclet
+
+@value{GDBN} enables developers to debug tasks running on
+Sparclet targets from a Unix host.
+@value{GDBN} uses code that runs on
+both the Unix host and on the Sparclet target. The program
+@code{gdb} is installed and executed on the Unix host.
+
+@table @code
+@item timeout @var{args}
+@kindex remotetimeout
+@value{GDBN} now supports the option @code{remotetimeout}.
+This option is set by the user, and @var{args} represents the number of
+seconds @value{GDBN} waits for responses.
+@end table
+
+@kindex Compiling
+When compiling for debugging, include the options "-g" to get debug
+information and "-Ttext" to relocate the program to where you wish to
+load it on the target. You may also want to add the options "-n" or
+"-N" in order to reduce the size of the sections.
+
+@example
+sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N
+@end example
+
+You can use objdump to verify that the addresses are what you intended.
+
+@example
+sparclet-aout-objdump --headers --syms prog
+@end example
+
+@kindex Running
+Once you have set
+your Unix execution search path to find @value{GDBN}, you are ready to
+run @value{GDBN}. From your Unix host, run @code{gdb}
+(or @code{sparclet-aout-gdb}, depending on your installation).
+
+@value{GDBN} comes up showing the prompt:
+
+@example
+(gdbslet)
+@end example
+
+@menu
+* Sparclet File:: Setting the file to debug
+* Sparclet Connection:: Connecting to Sparclet
+* Sparclet Download:: Sparclet download
+* Sparclet Execution:: Running and debugging
+@end menu
+
+@node Sparclet File
+@subsubsection Setting file to debug
+
+The @value{GDBN} command @code{file} lets you choose with program to debug.
+
+@example
+(gdbslet) file prog
+@end example
+
+@need 1000
+@value{GDBN} then attempts to read the symbol table of @file{prog}.
+@value{GDBN} locates
+the file by searching the directories listed in the command search
+path.
+If the file was compiled with debug information (option "-g"), source
+files will be searched as well.
+@value{GDBN} locates
+the source files by searching the directories listed in the directory search
+path (@pxref{Environment, ,Your program's environment}).
+If it fails
+to find a file, it displays a message such as:
+
+@example
+prog: No such file or directory.
+@end example
+
+When this happens, add the appropriate directories to the search paths with
+the @value{GDBN} commands @code{path} and @code{dir}, and execute the
+@code{target} command again.
+
+@node Sparclet Connection
+@subsubsection Connecting to Sparclet
+
+The @value{GDBN} command @code{target} lets you connect to a Sparclet target.
+To connect to a target on serial port ``@code{ttya}'', type:
+
+@example
+(gdbslet) target sparclet /dev/ttya
+Remote target sparclet connected to /dev/ttya
+main () at ../prog.c:3
+@end example
+
+@need 750
+@value{GDBN} displays messages like these:
+
+@smallexample
+Connected to ttya.
+@end smallexample
+
+@node Sparclet Download
+@subsubsection Sparclet download
+
+@cindex download to Sparclet
+Once connected to the Sparclet target,
+you can use the @value{GDBN}
+@code{load} command to download the file from the host to the target.
+The file name and load offset should be given as arguments to the @code{load}
+command.
+Since the file format is aout, the program must be loaded to the starting
+address. You can use objdump to find out what this value is. The load
+offset is an offset which is added to the VMA (virtual memory address)
+of each of the file's sections.
+For instance, if the program
+@file{prog} was linked to text address 0x1201000, with data at 0x12010160
+and bss at 0x12010170, in @value{GDBN}, type:
+
+@example
+(gdbslet) load prog 0x12010000
+Loading section .text, size 0xdb0 vma 0x12010000
+@end example
+
+If the code is loaded at a different address then what the program was linked
+to, you may need to use the @code{section} and @code{add-symbol-file} commands
+to tell @value{GDBN} where to map the symbol table.
+
+@node Sparclet Execution
+@subsubsection Running and debugging
+
+@cindex running and debugging Sparclet programs
+You can now begin debugging the task using @value{GDBN}'s execution control
+commands, @code{b}, @code{step}, @code{run}, etc. See the @value{GDBN}
+manual for the list of commands.
+
+@example
+(gdbslet) b main
+Breakpoint 1 at 0x12010000: file prog.c, line 3.
+(gdbslet) run
+Starting program: prog
+Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3
+3 char *symarg = 0;
+(gdbslet) step
+4 char *execarg = "hello!";
+(gdbslet)
+@end example
+
+@end ifset
+
@ifset H8
@node Hitachi Remote
@subsection @value{GDBN} and Hitachi microprocessors
@@ -1363,8 +1528,19 @@ On some @value{GDBN} host configurations, you can specify a TCP
connection (for instance, to a serial line managed by a terminal
concentrator) instead of a serial port, using the syntax
@samp{@var{hostname}:@var{portnumber}}.
+
+@item target pmon @var{port}
+@kindex target pmon @var{port}
+
+@item target ddb @var{port}
+@kindex target ddb @var{port}
+
+@item target lsi @var{port}
+@kindex target lsi @var{port}
+
@end table
+
@noindent
@value{GDBN} also supports these special commands for MIPS targets:
@@ -1462,9 +1638,10 @@ to run before stopping.
@cindex Hitachi SH simulator
@cindex CPU simulator
For some configurations, @value{GDBN} includes a CPU simulator that you
-can use instead of a hardware CPU to debug your programs. Currently,
-a simulator is available when @value{GDBN} is configured to debug Zilog
-Z8000 or Hitachi microprocessor targets.
+can use instead of a hardware CPU to debug your programs.
+Currently, simulators are available for ARM, D10V, D30V, FR30, H8/300,
+H8/500, i960, M32R, MIPS, MN10200, MN10300, PowerPC, SH, Sparc, V850,
+W65, and Z8000.
@end ifset
@ifclear GENERIC
@@ -1494,13 +1671,11 @@ appropriate by inspecting the object code.
@end ifset
@table @code
-@item target sim
+@item target sim @var{args}
@kindex sim
@kindex target sim
-Debug programs on a simulated CPU
-@ifset GENERIC
-(which CPU depends on the @value{GDBN} configuration)
-@end ifset
+Debug programs on a simulated CPU. If the simulator supports setup
+options, specify them via @var{args}.
@end table
@noindent
@@ -1510,7 +1685,7 @@ CPU in the same style as programs for your host computer; use the
to run your program, and so on.
As well as making available all the usual machine registers (see
-@code{info reg}), this debugging target provides three additional items
+@code{info reg}), the Z8000 simulator provides three additional items
of information as specially named registers:
@table @code
@@ -1529,3 +1704,5 @@ conventions; for example, @w{@samp{b fputc if $cycles>5000}} sets a
conditional breakpoint that suspends only after at least 5000
simulated clock ticks.
@end ifset
+
+@c need to add much more detail about sims!
diff --git a/contrib/gdb/gdb/doc/stabs.texinfo b/contrib/gdb/gdb/doc/stabs.texinfo
index b0d26c3..1eb9d15 100644
--- a/contrib/gdb/gdb/doc/stabs.texinfo
+++ b/contrib/gdb/gdb/doc/stabs.texinfo
@@ -14,7 +14,7 @@ END-INFO-DIR-ENTRY
@ifinfo
This document describes the stabs debugging symbol tables.
-Copyright 1992, 1993 Free Software Foundation, Inc.
+Copyright 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Julia Menapace, Jim Kingdon,
and David MacKenzie.
@@ -43,7 +43,7 @@ regarded as a program in the language TeX).
@page
@tex
\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
-\xdef\manvers{\$Revision: 2.125 $} % For use in headers, footers too
+\xdef\manvers{\$Revision: 2.128 $} % For use in headers, footers too
{\parskip=0pt
\hfill Cygnus Support\par
\hfill \manvers\par
@@ -52,7 +52,7 @@ regarded as a program in the language TeX).
@end tex
@vskip 0pt plus 1filll
-Copyright @copyright{} 1992, 1993 Free Software Foundation, Inc.
+Copyright @copyright{} 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support.
Permission is granted to make and distribute verbatim copies of
@@ -80,8 +80,6 @@ This document describes the stabs debugging format.
* Type Descriptors:: Table of type descriptors
* Expanded Reference:: Reference information by stab type
* Questions:: Questions and anomolies
-* Sun Differences:: Differences between GNU stabs and Sun
- native stabs
* Stab Sections:: In some object file formats, stabs are
in sections.
* Symbol Types Index:: Index of symbolic stab symbol type names.
@@ -240,6 +238,18 @@ type is about to be defined. Any other values following the
a number follows the @samp{=} then the number is a @var{type-reference}.
For a full description of types, @ref{Types}.
+A @var{type-number} is often a single number. The GNU and Sun tools
+additionally permit a @var{type-number} to be a pair
+(@var{file-number},@var{filetype-number}) (the parentheses appear in the
+string, and serve to distinguish the two cases). The @var{file-number}
+is a number starting with 1 which is incremented for each seperate
+source file in the compilation (e.g., in C, each header file gets a
+different number). The @var{filetype-number} is a number starting with
+1 which is incremented for each new type defined in the file.
+(Separating the file number and the type number permits the
+@code{N_BINCL} optimization to succeed more often; see @ref{Include
+Files}).
+
There is an AIX extension for type attributes. Following the @samp{=}
are any number of type attributes. Each one starts with @samp{@@} and
ends with @samp{;}. Debuggers, including AIX's dbx and GDB 4.10, skip
@@ -463,7 +473,7 @@ the start of this one. To specify the main source file again, use an
@findex N_EXCL
The @code{N_BINCL} approach works as follows. An @code{N_BINCL} symbol
specifies the start of an include file. In an object file, only the
-string is significant; the Sun linker puts data into some of the other
+string is significant; the linker puts data into some of the other
fields. The end of the include file is marked by an @code{N_EINCL}
symbol (which has no string field). In an object file, there is no
significant data in the @code{N_EINCL} symbol. @code{N_BINCL} and
@@ -473,16 +483,17 @@ If the linker detects that two source files have identical stabs between
an @code{N_BINCL} and @code{N_EINCL} pair (as will generally be the case
for a header file), then it only puts out the stabs once. Each
additional occurance is replaced by an @code{N_EXCL} symbol. I believe
-the Sun (SunOS4, not sure about Solaris) linker is the only one which
-supports this feature.
-
-The SunOS4 linker sets the value of a @code{N_BINCL} symbol to the total
-of all the characters in the stabs strings included in the header file,
-omitting the file number. The value of an @code{N_EXCL} symbol is the
-same as the value of the @code{N_BINCL} symbol it replaces. I do not
-know if this information is used by anything. The @code{N_EINCL} value,
-and the values of the other and description fields for all three, appear
-to always be zero.
+the GNU linker and the Sun (both SunOS4 and Solaris) linker are the only
+ones which supports this feature.
+
+A linker which supports this feature will set the value of a
+@code{N_BINCL} symbol to the total of all the characters in the stabs
+strings included in the header file, omitting any file numbers. The
+value of an @code{N_EXCL} symbol is the same as the value of the
+@code{N_BINCL} symbol it replaces. This information can be used to
+match up @code{N_EXCL} and @code{N_BINCL} symbols which have the same
+filename. The @code{N_EINCL} value, and the values of the other and
+description fields for all three, appear to always be zero.
@findex C_BINCL
@findex C_EINCL
@@ -632,6 +643,15 @@ group of other stabs describing elements of the procedure. These other
stabs describe the procedure's parameters, its block local variables, and
its block structure.
+If functions can appear in different sections, then the debugger may not
+be able to find the end of a function. Recent versions of GCC will mark
+the end of a function with an @code{N_FUN} symbol with an empty string
+for the name. The value is the address of the end of the current
+function. Without such a symbol, there is no indication of the address
+of the end of a function, and you must assume that it ended at the
+starting address of the next function or at the end of the text section
+for the program.
+
@node Nested Procedures
@section Nested Procedures
@@ -2060,7 +2080,8 @@ For example,
@end example
specifies that @code{s_typedef} refers to type number 16. Such stabs
-have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF).
+have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF). (The Sun
+documentation mentions using @code{N_GSYM} in some cases).
If you are specifying the tag name for a structure, union, or
enumeration, use the @samp{T} symbol descriptor instead. I believe C is
@@ -2669,16 +2690,21 @@ pointer.
@node Method Type Descriptor
@section The @samp{#} Type Descriptor
-This is like the @samp{f} type descriptor for functions (@pxref{Function
-Types}), except that a function which uses the @samp{#} type descriptor
-takes an extra argument as its first argument, for the @code{this}
-pointer. The @samp{#} type descriptor is optionally followed by the
-types of the arguments, then another @samp{#}. If the types of the
-arguments are omitted, so that the second @samp{#} immediately follows
-the @samp{#} which is the type descriptor, the arguments are being
-omitted (to save space) and can be deduced from the mangled name of the
-method. After the second @samp{#} there is type information for the
-return type of the method and a semicolon.
+This is used to describe a class method. This is a function which takes
+an extra argument as its first argument, for the @code{this} pointer.
+
+If the @samp{#} is immediately followed by another @samp{#}, the second
+one will be followed by the return type and a semicolon. The class and
+argument types are not specified, and must be determined by demangling
+the name of the method if it is available.
+
+Otherwise, the single @samp{#} is followed by the class type, a comma,
+the return type, a comma, and zero or more parameter types separated by
+commas. The list of arguments is terminated by a semicolon. In the
+debugging output generated by gcc, a final argument type of @code{void}
+indicates a method which does not take a variable number of arguments.
+If the final argument type of @code{void} does not appear, the method
+was declared with an ellipsis.
Note that although such a type will normally be used to describe fields
in structures, unions, or classes, for at least some versions of the
@@ -3841,25 +3867,6 @@ What ends the procedure scope? Is it the proc block's @code{N_RBRAC} or the
next @code{N_FUN}? (I believe its the first.)
@end itemize
-@node Sun Differences
-@appendix Differences Between GNU Stabs and Sun Native Stabs
-
-@c FIXME: Merge all this stuff into the main body of the document.
-
-@itemize @bullet
-@item
-GNU C stabs define @emph{all} types, file or procedure scope, as
-@code{N_LSYM}. Sun doc talks about using @code{N_GSYM} too.
-
-@item
-Sun C stabs use type number pairs in the format
-(@var{file-number},@var{type-number}) where @var{file-number} is a
-number starting with 1 and incremented for each sub-source file in the
-compilation. @var{type-number} is a number starting with 1 and
-incremented for each new type defined in the compilation. GNU C stabs
-use the type number alone, with no source file number.
-@end itemize
-
@node Stab Sections
@appendix Using Stabs in Their Own Sections
@@ -3928,17 +3935,25 @@ header @code{sh_type} member set to @code{SHT_STRTAB} to mark it as a
string table. SOM and COFF have no way of linking the sections together
or marking them as string tables.
-For COFF, the @code{.stab} and @code{.stabstr} sections are simply
+For COFF, the @code{.stab} and @code{.stabstr} sections may be simply
concatenated by the linker. GDB then uses the @code{n_desc} fields to
figure out the extent of the original sections. Similarly, the
@code{n_value} fields of the header symbols are added together in order
to get the actual position of the strings in a desired @code{.stabstr}
-section. Although this design obviates any need for the linker to relocate
-or otherwise manipulate @code{.stab} and @code{.stabstr} sections, it also
-requires some care to ensure that the offsets are calculated correctly.
-For instance, if the linker were to pad in between the @code{.stabstr}
-sections before concatenating, then the offsets to strings in the middle
-of the executable's @code{.stabstr} section would be wrong.
+section. Although this design obviates any need for the linker to
+relocate or otherwise manipulate @code{.stab} and @code{.stabstr}
+sections, it also requires some care to ensure that the offsets are
+calculated correctly. For instance, if the linker were to pad in
+between the @code{.stabstr} sections before concatenating, then the
+offsets to strings in the middle of the executable's @code{.stabstr}
+section would be wrong.
+
+The GNU linker is able to optimize stabs information by merging
+duplicate strings and removing duplicate header file information
+(@pxref{Include Files}). When some versions of the GNU linker optimize
+stabs in sections, they remove the leading @code{N_UNDF} symbol and
+arranges for all the @code{n_strx} fields to be relative to the start of
+the @code{.stabstr} section.
@node ELF Linker Relocation
@appendixsec Having the Linker Relocate Stabs in ELF
diff --git a/contrib/gdb/gdb/dwarf2read.c b/contrib/gdb/gdb/dwarf2read.c
new file mode 100644
index 0000000..cf52066
--- /dev/null
+++ b/contrib/gdb/gdb/dwarf2read.c
@@ -0,0 +1,5865 @@
+/* DWARF 2 debugging format support for GDB.
+ Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support in dwarfread.c
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "bfd.h"
+#include "elf-bfd.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "elf/dwarf2.h"
+#include "buildsym.h"
+#include "demangle.h"
+#include "expression.h"
+#include "language.h"
+#include "complaints.h"
+
+#include <fcntl.h>
+#include "gdb_string.h"
+#include <sys/types.h>
+
+/* .debug_info header for a compilation unit
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct comp_unit_header
+ {
+ unsigned int length; /* length of the .debug_info
+ contribution */
+ unsigned short version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int abbrev_offset; /* offset into .debug_abbrev section */
+ unsigned char addr_size; /* byte size of an address -- 4 */
+ }
+_COMP_UNIT_HEADER;
+#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11
+
+/* .debug_pubnames header
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct pubnames_header
+ {
+ unsigned int length; /* length of the .debug_pubnames
+ contribution */
+ unsigned char version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int info_offset; /* offset into .debug_info section */
+ unsigned int info_size; /* byte size of .debug_info section
+ portion */
+ }
+_PUBNAMES_HEADER;
+#define _ACTUAL_PUBNAMES_HEADER_SIZE 13
+
+/* .debug_pubnames header
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct aranges_header
+ {
+ unsigned int length; /* byte len of the .debug_aranges
+ contribution */
+ unsigned short version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int info_offset; /* offset into .debug_info section */
+ unsigned char addr_size; /* byte size of an address */
+ unsigned char seg_size; /* byte size of segment descriptor */
+ }
+_ARANGES_HEADER;
+#define _ACTUAL_ARANGES_HEADER_SIZE 12
+
+/* .debug_line statement program prologue
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct statement_prologue
+ {
+ unsigned int total_length; /* byte length of the statement
+ information */
+ unsigned short version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int prologue_length; /* # bytes between prologue &
+ stmt program */
+ unsigned char minimum_instruction_length; /* byte size of
+ smallest instr */
+ unsigned char default_is_stmt; /* initial value of is_stmt
+ register */
+ char line_base;
+ unsigned char line_range;
+ unsigned char opcode_base; /* number assigned to first special
+ opcode */
+ unsigned char *standard_opcode_lengths;
+ }
+_STATEMENT_PROLOGUE;
+
+/* offsets and sizes of debugging sections */
+
+static file_ptr dwarf_info_offset;
+static file_ptr dwarf_abbrev_offset;
+static file_ptr dwarf_line_offset;
+static file_ptr dwarf_pubnames_offset;
+static file_ptr dwarf_aranges_offset;
+static file_ptr dwarf_loc_offset;
+static file_ptr dwarf_macinfo_offset;
+static file_ptr dwarf_str_offset;
+
+static unsigned int dwarf_info_size;
+static unsigned int dwarf_abbrev_size;
+static unsigned int dwarf_line_size;
+static unsigned int dwarf_pubnames_size;
+static unsigned int dwarf_aranges_size;
+static unsigned int dwarf_loc_size;
+static unsigned int dwarf_macinfo_size;
+static unsigned int dwarf_str_size;
+
+/* names of the debugging sections */
+
+#define INFO_SECTION ".debug_info"
+#define ABBREV_SECTION ".debug_abbrev"
+#define LINE_SECTION ".debug_line"
+#define PUBNAMES_SECTION ".debug_pubnames"
+#define ARANGES_SECTION ".debug_aranges"
+#define LOC_SECTION ".debug_loc"
+#define MACINFO_SECTION ".debug_macinfo"
+#define STR_SECTION ".debug_str"
+
+/* local data types */
+
+/* The data in a compilation unit header looks like this. */
+struct comp_unit_head
+ {
+ unsigned int length;
+ short version;
+ unsigned int abbrev_offset;
+ unsigned char addr_size;
+ };
+
+/* The data in the .debug_line statement prologue looks like this. */
+struct line_head
+ {
+ unsigned int total_length;
+ unsigned short version;
+ unsigned int prologue_length;
+ unsigned char minimum_instruction_length;
+ unsigned char default_is_stmt;
+ int line_base;
+ unsigned char line_range;
+ unsigned char opcode_base;
+ unsigned char *standard_opcode_lengths;
+ };
+
+/* When we construct a partial symbol table entry we only
+ need this much information. */
+struct partial_die_info
+ {
+ enum dwarf_tag tag;
+ unsigned char has_children;
+ unsigned char is_external;
+ unsigned char is_declaration;
+ unsigned char has_type;
+ unsigned int offset;
+ unsigned int abbrev;
+ char *name;
+ CORE_ADDR lowpc;
+ CORE_ADDR highpc;
+ struct dwarf_block *locdesc;
+ unsigned int language;
+ char *sibling;
+ };
+
+/* This data structure holds the information of an abbrev. */
+struct abbrev_info
+ {
+ unsigned int number; /* number identifying abbrev */
+ enum dwarf_tag tag; /* dwarf tag */
+ int has_children; /* boolean */
+ unsigned int num_attrs; /* number of attributes */
+ struct attr_abbrev *attrs; /* an array of attribute descriptions */
+ struct abbrev_info *next; /* next in chain */
+ };
+
+struct attr_abbrev
+ {
+ enum dwarf_attribute name;
+ enum dwarf_form form;
+ };
+
+/* This data structure holds a complete die structure. */
+struct die_info
+ {
+ enum dwarf_tag tag; /* Tag indicating type of die */
+ unsigned short has_children; /* Does the die have children */
+ unsigned int abbrev; /* Abbrev number */
+ unsigned int offset; /* Offset in .debug_info section */
+ unsigned int num_attrs; /* Number of attributes */
+ struct attribute *attrs; /* An array of attributes */
+ struct die_info *next_ref; /* Next die in ref hash table */
+ struct die_info *next; /* Next die in linked list */
+ struct type *type; /* Cached type information */
+ };
+
+/* Attributes have a name and a value */
+struct attribute
+ {
+ enum dwarf_attribute name;
+ enum dwarf_form form;
+ union
+ {
+ char *str;
+ struct dwarf_block *blk;
+ unsigned int unsnd;
+ int snd;
+ CORE_ADDR addr;
+ }
+ u;
+ };
+
+/* Get at parts of an attribute structure */
+
+#define DW_STRING(attr) ((attr)->u.str)
+#define DW_UNSND(attr) ((attr)->u.unsnd)
+#define DW_BLOCK(attr) ((attr)->u.blk)
+#define DW_SND(attr) ((attr)->u.snd)
+#define DW_ADDR(attr) ((attr)->u.addr)
+
+/* Blocks are a bunch of untyped bytes. */
+struct dwarf_block
+ {
+ unsigned int size;
+ char *data;
+ };
+
+/* We only hold one compilation unit's abbrevs in
+ memory at any one time. */
+#ifndef ABBREV_HASH_SIZE
+#define ABBREV_HASH_SIZE 121
+#endif
+#ifndef ATTR_ALLOC_CHUNK
+#define ATTR_ALLOC_CHUNK 4
+#endif
+
+static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
+
+/* A hash table of die offsets for following references. */
+#ifndef REF_HASH_SIZE
+#define REF_HASH_SIZE 1021
+#endif
+
+static struct die_info *die_ref_table[REF_HASH_SIZE];
+
+/* Obstack for allocating temporary storage used during symbol reading. */
+static struct obstack dwarf2_tmp_obstack;
+
+/* Offset to the first byte of the current compilation unit header,
+ for resolving relative reference dies. */
+static unsigned int cu_header_offset;
+
+/* Allocate fields for structs, unions and enums in this size. */
+#ifndef DW_FIELD_ALLOC_CHUNK
+#define DW_FIELD_ALLOC_CHUNK 4
+#endif
+
+/* The language we are debugging. */
+static enum language cu_language;
+static const struct language_defn *cu_language_defn;
+
+/* Actually data from the sections. */
+static char *dwarf_info_buffer;
+static char *dwarf_abbrev_buffer;
+static char *dwarf_line_buffer;
+
+/* A zeroed version of a partial die for initialization purposes. */
+static struct partial_die_info zeroed_partial_die;
+
+/* The generic symbol table building routines have separate lists for
+ file scope symbols and all all other scopes (local scopes). So
+ we need to select the right one to pass to add_symbol_to_list().
+ We do it by keeping a pointer to the correct list in list_in_scope.
+
+ FIXME: The original dwarf code just treated the file scope as the first
+ local scope, and all other local scopes as nested local scopes, and worked
+ fine. Check to see if we really need to distinguish these
+ in buildsym.c. */
+static struct pending **list_in_scope = &file_symbols;
+
+/* FIXME: The following variables pass additional information from
+ decode_locdesc to the caller. */
+static int optimized_out; /* Kludge to identify optimized out variables */
+static int isreg; /* Kludge to identify register variables */
+static int offreg; /* Kludge to identify basereg references */
+static int basereg; /* Which base register is it relative to? */
+static int islocal; /* Kludge to identify local variables */
+
+/* DW_AT_frame_base values for the current function.
+ frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
+ contains the register number for the frame register.
+ frame_base_offset is the offset from the frame register to the
+ virtual stack frame. */
+static int frame_base_reg;
+static CORE_ADDR frame_base_offset;
+
+/* This value is added to each symbol value. FIXME: Generalize to
+ the section_offsets structure used by dbxread (once this is done,
+ pass the appropriate section number to end_symtab). */
+static CORE_ADDR baseaddr; /* Add to each symbol value */
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab.
+ The complete dwarf information for an objfile is kept in the
+ psymbol_obstack, so that absolute die references can be handled.
+ Most of the information in this structure is related to an entire
+ object file and could be passed via the sym_private field of the objfile.
+ It is however conceivable that dwarf2 might not be the only type
+ of symbols read from an object file. */
+
+struct dwarf2_pinfo
+{
+ /* Pointer to start of dwarf info buffer for the objfile. */
+
+ char *dwarf_info_buffer;
+
+ /* Offset in dwarf_info_buffer for this compilation unit. */
+
+ unsigned long dwarf_info_offset;
+
+ /* Pointer to start of dwarf abbreviation buffer for the objfile. */
+
+ char *dwarf_abbrev_buffer;
+
+ /* Size of dwarf abbreviation section for the objfile. */
+
+ unsigned int dwarf_abbrev_size;
+
+ /* Pointer to start of dwarf line buffer for the objfile. */
+
+ char *dwarf_line_buffer;
+};
+
+#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
+#define DWARF_INFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_info_buffer)
+#define DWARF_INFO_OFFSET(p) (PST_PRIVATE(p)->dwarf_info_offset)
+#define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer)
+#define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size)
+#define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer)
+
+/* Maintain an array of referenced fundamental types for the current
+ compilation unit being read. For DWARF version 1, we have to construct
+ the fundamental types on the fly, since no information about the
+ fundamental types is supplied. Each such fundamental type is created by
+ calling a language dependent routine to create the type, and then a
+ pointer to that type is then placed in the array at the index specified
+ by it's FT_<TYPENAME> value. The array has a fixed size set by the
+ FT_NUM_MEMBERS compile time constant, which is the number of predefined
+ fundamental types gdb knows how to construct. */
+static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
+
+/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
+ but this would require a corresponding change in unpack_field_as_long
+ and friends. */
+static int bits_per_byte = 8;
+
+/* The routines that read and process dies for a C struct or C++ class
+ pass lists of data member fields and lists of member function fields
+ in an instance of a field_info structure, as defined below. */
+struct field_info
+{
+ /* List of data member and baseclasses fields. */
+ struct nextfield
+ {
+ struct nextfield *next;
+ int accessibility;
+ int virtuality;
+ struct field field;
+ } *fields;
+
+ /* Number of fields. */
+ int nfields;
+
+ /* Number of baseclasses. */
+ int nbaseclasses;
+
+ /* Set if the accesibility of one of the fields is not public. */
+ int non_public_fields;
+
+ /* Member function fields array, entries are allocated in the order they
+ are encountered in the object file. */
+ struct nextfnfield
+ {
+ struct nextfnfield *next;
+ struct fn_field fnfield;
+ } *fnfields;
+
+ /* Member function fieldlist array, contains name of possibly overloaded
+ member function, number of overloaded member functions and a pointer
+ to the head of the member function field chain. */
+ struct fnfieldlist
+ {
+ char *name;
+ int length;
+ struct nextfnfield *head;
+ } *fnfieldlists;
+
+ /* Number of entries in the fnfieldlists array. */
+ int nfnfields;
+};
+
+/* FIXME: Kludge to mark a varargs function type for C++ member function
+ argument processing. */
+#define TYPE_FLAG_VARARGS (1 << 10)
+
+/* Dwarf2 has no clean way to discern C++ static and non-static member
+ functions. G++ helps GDB by marking the first parameter for non-static
+ member functions (which is the this pointer) as artificial.
+ We pass this information between dwarf2_add_member_fn and
+ read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */
+#define TYPE_FIELD_ARTIFICIAL TYPE_FIELD_BITPOS
+
+/* Various complaints about symbol reading that don't abort the process */
+
+static struct complaint dwarf2_const_ignored =
+{
+ "type qualifier 'const' ignored", 0, 0
+};
+static struct complaint dwarf2_volatile_ignored =
+{
+ "type qualifier 'volatile' ignored", 0, 0
+};
+static struct complaint dwarf2_non_const_array_bound_ignored =
+{
+ "non-constant array bounds form '%s' ignored", 0, 0
+};
+static struct complaint dwarf2_missing_line_number_section =
+{
+ "missing .debug_line section", 0, 0
+};
+static struct complaint dwarf2_mangled_line_number_section =
+{
+ "mangled .debug_line section", 0, 0
+};
+static struct complaint dwarf2_unsupported_die_ref_attr =
+{
+ "unsupported die ref attribute form: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_stack_op =
+{
+ "unsupported stack op: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_tag =
+{
+ "unsupported tag: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_at_encoding =
+{
+ "unsupported DW_AT_encoding: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_at_frame_base =
+{
+ "unsupported DW_AT_frame_base for function '%s'", 0, 0
+};
+static struct complaint dwarf2_unexpected_tag =
+{
+ "unexepected tag in read_type_die: '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_at_frame_base =
+{
+ "DW_AT_frame_base missing for DW_OP_fbreg", 0, 0
+};
+static struct complaint dwarf2_bad_static_member_name =
+{
+ "unrecognized static data member name '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_accessibility =
+{
+ "unsupported accessibility %d", 0, 0
+};
+static struct complaint dwarf2_bad_member_name_complaint =
+{
+ "cannot extract member name from '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_member_fn_type_complaint =
+{
+ "member function type missing for '%s'", 0, 0
+};
+static struct complaint dwarf2_vtbl_not_found_complaint =
+{
+ "virtual function table pointer not found when defining class '%s'", 0, 0
+};
+static struct complaint dwarf2_absolute_sibling_complaint =
+{
+ "ignoring absolute DW_AT_sibling", 0, 0
+};
+static struct complaint dwarf2_const_value_length_mismatch =
+{
+ "const value length mismatch for '%s', got %d, expected %d", 0, 0
+};
+static struct complaint dwarf2_unsupported_const_value_attr =
+{
+ "unsupported const value attribute form: '%s'", 0, 0
+};
+
+/* Remember the addr_size read from the dwarf.
+ If a target expects to link compilation units with differing address
+ sizes, gdb needs to be sure that the appropriate size is here for
+ whatever scope is currently getting read. */
+static int address_size;
+
+/* Some elf32 object file formats while linked for a 32 bit address
+ space contain debug information that has assumed 64 bit
+ addresses. Eg 64 bit MIPS target produced by GCC/GAS/LD where the
+ symbol table contains 32bit address values while its .debug_info
+ section contains 64 bit address values.
+ ADDRESS_SIGNIFICANT_SIZE specifies the number significant bits in
+ the ADDRESS_SIZE bytes read from the file */
+static int address_significant_size;
+
+/* Externals references. */
+extern int info_verbose; /* From main.c; nonzero => verbose */
+
+/* local function prototypes */
+
+static void dwarf2_locate_sections PARAMS ((bfd *, asection *, PTR));
+
+#if 0
+static void dwarf2_build_psymtabs_easy PARAMS ((struct objfile *,
+ struct section_offsets *,
+ int));
+#endif
+
+static void dwarf2_build_psymtabs_hard PARAMS ((struct objfile *,
+ struct section_offsets *,
+ int));
+
+static char *scan_partial_symbols PARAMS ((char *, struct objfile *,
+ CORE_ADDR *, CORE_ADDR *));
+
+static void add_partial_symbol PARAMS ((struct partial_die_info *,
+ struct objfile *));
+
+static void dwarf2_psymtab_to_symtab PARAMS ((struct partial_symtab *));
+
+static void psymtab_to_symtab_1 PARAMS ((struct partial_symtab *));
+
+static char *dwarf2_read_section PARAMS ((struct objfile *, file_ptr,
+ unsigned int));
+
+static void dwarf2_read_abbrevs PARAMS ((bfd *, unsigned int));
+
+static void dwarf2_empty_abbrev_table PARAMS ((PTR));
+
+static struct abbrev_info *dwarf2_lookup_abbrev PARAMS ((unsigned int));
+
+static char *read_partial_die PARAMS ((struct partial_die_info *,
+ bfd *, char *, int *));
+
+static char *read_full_die PARAMS ((struct die_info **, bfd *, char *));
+
+static char *read_attribute PARAMS ((struct attribute *, struct attr_abbrev *,
+ bfd *, char *));
+
+static unsigned int read_1_byte PARAMS ((bfd *, char *));
+
+static int read_1_signed_byte PARAMS ((bfd *, char *));
+
+static unsigned int read_2_bytes PARAMS ((bfd *, char *));
+
+static unsigned int read_4_bytes PARAMS ((bfd *, char *));
+
+static unsigned int read_8_bytes PARAMS ((bfd *, char *));
+
+static CORE_ADDR read_address PARAMS ((bfd *, char *));
+
+static char *read_n_bytes PARAMS ((bfd *, char *, unsigned int));
+
+static char *read_string PARAMS ((bfd *, char *, unsigned int *));
+
+static unsigned int read_unsigned_leb128 PARAMS ((bfd *, char *,
+ unsigned int *));
+
+static int read_signed_leb128 PARAMS ((bfd *, char *, unsigned int *));
+
+static void set_cu_language PARAMS ((unsigned int));
+
+static struct attribute *dwarf_attr PARAMS ((struct die_info *,
+ unsigned int));
+
+static void dwarf_decode_lines PARAMS ((unsigned int, char *, bfd *));
+
+static void dwarf2_start_subfile PARAMS ((char *, char *));
+
+static struct symbol *new_symbol PARAMS ((struct die_info *, struct type *,
+ struct objfile *));
+
+static void dwarf2_const_value PARAMS ((struct attribute *, struct symbol *,
+ struct objfile *));
+
+static struct type *die_type PARAMS ((struct die_info *, struct objfile *));
+
+static struct type *die_containing_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+#if 0
+static struct type *type_at_offset PARAMS ((unsigned int, struct objfile *));
+#endif
+
+static struct type *tag_type_to_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+static void read_type_die PARAMS ((struct die_info *, struct objfile *));
+
+static void read_typedef PARAMS ((struct die_info *, struct objfile *));
+
+static void read_base_type PARAMS ((struct die_info *, struct objfile *));
+
+static void read_file_scope PARAMS ((struct die_info *, struct objfile *));
+
+static void read_func_scope PARAMS ((struct die_info *, struct objfile *));
+
+static void read_lexical_block_scope PARAMS ((struct die_info *,
+ struct objfile *));
+
+static int dwarf2_get_pc_bounds PARAMS ((struct die_info *,
+ CORE_ADDR *, CORE_ADDR *,
+ struct objfile *));
+
+static void dwarf2_add_field PARAMS ((struct field_info *, struct die_info *,
+ struct objfile *));
+
+static void dwarf2_attach_fields_to_type PARAMS ((struct field_info *,
+ struct type *,
+ struct objfile *));
+
+static char *skip_member_fn_name PARAMS ((char *));
+
+static void dwarf2_add_member_fn PARAMS ((struct field_info *,
+ struct die_info *, struct type *,
+ struct objfile *objfile));
+
+static void dwarf2_attach_fn_fields_to_type PARAMS ((struct field_info *,
+ struct type *,
+ struct objfile *));
+
+static void read_structure_scope PARAMS ((struct die_info *, struct objfile *));
+
+static void read_common_block PARAMS ((struct die_info *, struct objfile *));
+
+static void read_enumeration PARAMS ((struct die_info *, struct objfile *));
+
+static struct type *dwarf_base_type PARAMS ((int, int, struct objfile *));
+
+static CORE_ADDR decode_locdesc PARAMS ((struct dwarf_block *,
+ struct objfile *));
+
+static void read_array_type PARAMS ((struct die_info *, struct objfile *));
+
+static void read_tag_pointer_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+static void read_tag_ptr_to_member_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+static void read_tag_reference_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+static void read_tag_const_type PARAMS ((struct die_info *, struct objfile *));
+
+static void read_tag_volatile_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+static void read_tag_string_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+static void read_subroutine_type PARAMS ((struct die_info *,
+ struct objfile *));
+
+struct die_info *read_comp_unit PARAMS ((char *, bfd *));
+
+static void free_die_list PARAMS ((struct die_info *));
+
+static void process_die PARAMS ((struct die_info *, struct objfile *));
+
+static char *dwarf2_linkage_name PARAMS ((struct die_info *));
+
+static char *dwarf_tag_name PARAMS ((unsigned int));
+
+static char *dwarf_attr_name PARAMS ((unsigned int));
+
+static char *dwarf_form_name PARAMS ((unsigned int));
+
+static char *dwarf_stack_op_name PARAMS ((unsigned int));
+
+static char *dwarf_bool_name PARAMS ((unsigned int));
+
+static char *dwarf_type_encoding_name PARAMS ((unsigned int));
+
+#if 0
+static char *dwarf_cfi_name PARAMS ((unsigned int));
+
+struct die_info *copy_die PARAMS ((struct die_info *));
+#endif
+
+struct die_info *sibling_die PARAMS ((struct die_info *));
+
+void dump_die PARAMS ((struct die_info *));
+
+void dump_die_list PARAMS ((struct die_info *));
+
+void store_in_ref_table PARAMS ((unsigned int, struct die_info *));
+
+static void dwarf2_empty_die_ref_table PARAMS ((void));
+
+static unsigned int dwarf2_get_ref_die_offset PARAMS ((struct attribute *));
+
+struct die_info *follow_die_ref PARAMS ((unsigned int));
+
+static struct type *dwarf2_fundamental_type PARAMS ((struct objfile *, int));
+
+/* memory allocation interface */
+
+static void dwarf2_free_tmp_obstack PARAMS ((PTR));
+
+static struct dwarf_block *dwarf_alloc_block PARAMS ((void));
+
+static struct abbrev_info *dwarf_alloc_abbrev PARAMS ((void));
+
+static struct die_info *dwarf_alloc_die PARAMS ((void));
+
+/* Try to locate the sections we need for DWARF 2 debugging
+ information and return true if we have enough to do something. */
+
+int
+dwarf2_has_info (abfd)
+ bfd *abfd;
+{
+ dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0;
+ bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
+ if (dwarf_info_offset && dwarf_abbrev_offset)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* This function is mapped across the sections and remembers the
+ offset and size of each of the debugging sections we are interested
+ in. */
+
+static void
+dwarf2_locate_sections (ignore_abfd, sectp, ignore_ptr)
+ bfd *ignore_abfd;
+ asection *sectp;
+ PTR ignore_ptr;
+{
+ if (STREQ (sectp->name, INFO_SECTION))
+ {
+ dwarf_info_offset = sectp->filepos;
+ dwarf_info_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, ABBREV_SECTION))
+ {
+ dwarf_abbrev_offset = sectp->filepos;
+ dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, LINE_SECTION))
+ {
+ dwarf_line_offset = sectp->filepos;
+ dwarf_line_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, PUBNAMES_SECTION))
+ {
+ dwarf_pubnames_offset = sectp->filepos;
+ dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, ARANGES_SECTION))
+ {
+ dwarf_aranges_offset = sectp->filepos;
+ dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, LOC_SECTION))
+ {
+ dwarf_loc_offset = sectp->filepos;
+ dwarf_loc_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, MACINFO_SECTION))
+ {
+ dwarf_macinfo_offset = sectp->filepos;
+ dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, STR_SECTION))
+ {
+ dwarf_str_offset = sectp->filepos;
+ dwarf_str_size = bfd_get_section_size_before_reloc (sectp);
+ }
+}
+
+/* Build a partial symbol table. */
+
+void
+dwarf2_build_psymtabs (objfile, section_offsets, mainline)
+ struct objfile *objfile;
+ struct section_offsets *section_offsets;
+ int mainline;
+{
+
+ /* We definitely need the .debug_info and .debug_abbrev sections */
+
+ dwarf_info_buffer = dwarf2_read_section (objfile,
+ dwarf_info_offset,
+ dwarf_info_size);
+ dwarf_abbrev_buffer = dwarf2_read_section (objfile,
+ dwarf_abbrev_offset,
+ dwarf_abbrev_size);
+ dwarf_line_buffer = dwarf2_read_section (objfile,
+ dwarf_line_offset,
+ dwarf_line_size);
+
+ if (mainline || objfile->global_psymbols.size == 0 ||
+ objfile->static_psymbols.size == 0)
+ {
+ init_psymbol_list (objfile, 1024);
+ }
+
+#if 0
+ if (dwarf_aranges_offset && dwarf_pubnames_offset)
+ {
+ /* Things are significanlty easier if we have .debug_aranges and
+ .debug_pubnames sections */
+
+ dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline);
+ }
+ else
+#endif
+ /* only test this case for now */
+ {
+ /* In this case we have to work a bit harder */
+ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline);
+ }
+}
+
+#if 0
+/* Build the partial symbol table from the information in the
+ .debug_pubnames and .debug_aranges sections. */
+
+static void
+dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline)
+ struct objfile *objfile;
+ struct section_offsets *section_offsets;
+ int mainline;
+{
+ bfd *abfd = objfile->obfd;
+ char *aranges_buffer, *pubnames_buffer;
+ char *aranges_ptr, *pubnames_ptr;
+ unsigned int entry_length, version, info_offset, info_size;
+
+ pubnames_buffer = dwarf2_read_section (objfile,
+ dwarf_pubnames_offset,
+ dwarf_pubnames_size);
+ pubnames_ptr = pubnames_buffer;
+ while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
+ {
+ entry_length = read_4_bytes (abfd, pubnames_ptr);
+ pubnames_ptr += 4;
+ version = read_1_byte (abfd, pubnames_ptr);
+ pubnames_ptr += 1;
+ info_offset = read_4_bytes (abfd, pubnames_ptr);
+ pubnames_ptr += 4;
+ info_size = read_4_bytes (abfd, pubnames_ptr);
+ pubnames_ptr += 4;
+ }
+
+ aranges_buffer = dwarf2_read_section (objfile,
+ dwarf_aranges_offset,
+ dwarf_aranges_size);
+
+}
+#endif
+
+/* Build the partial symbol table by doing a quick pass through the
+ .debug_info and .debug_abbrev sections. */
+
+static void
+dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
+ struct objfile *objfile;
+ struct section_offsets *section_offsets;
+ int mainline;
+{
+ /* Instead of reading this into a big buffer, we should probably use
+ mmap() on architectures that support it. (FIXME) */
+ bfd *abfd = objfile->obfd;
+ char *info_ptr, *abbrev_ptr;
+ char *beg_of_comp_unit;
+ struct comp_unit_head cu_header;
+ struct partial_die_info comp_unit_die;
+ struct partial_symtab *pst;
+ struct cleanup *back_to;
+ int comp_unit_has_pc_info;
+ CORE_ADDR lowpc, highpc;
+
+ /* Number of bytes of any addresses that are signficant */
+ address_significant_size = get_elf_backend_data (abfd)->s->arch_size / 8;
+
+ info_ptr = dwarf_info_buffer;
+ abbrev_ptr = dwarf_abbrev_buffer;
+
+ obstack_init (&dwarf2_tmp_obstack);
+ back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+ while ((unsigned int) (info_ptr - dwarf_info_buffer)
+ + ((info_ptr - dwarf_info_buffer) % 4) < dwarf_info_size)
+ {
+ beg_of_comp_unit = info_ptr;
+ cu_header.length = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ cu_header.version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ cu_header.abbrev_offset = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ cu_header.addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ address_size = cu_header.addr_size;
+
+ if (cu_header.version != 2)
+ {
+ error ("Dwarf Error: wrong version in compilation unit header.");
+ return;
+ }
+ if (cu_header.abbrev_offset >= dwarf_abbrev_size)
+ {
+ error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).",
+ (long) cu_header.abbrev_offset,
+ (long) (beg_of_comp_unit - dwarf_info_buffer));
+ return;
+ }
+ if (beg_of_comp_unit + cu_header.length + 4
+ > dwarf_info_buffer + dwarf_info_size)
+ {
+ error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
+ (long) cu_header.length,
+ (long) (beg_of_comp_unit - dwarf_info_buffer));
+ return;
+ }
+ if (address_size < address_significant_size)
+ {
+ error ("Dwarf Error: bad address size (%ld) in compilation unit header (offset 0x%lx + 11).",
+ (long) cu_header.addr_size,
+ (long) (beg_of_comp_unit - dwarf_info_buffer));
+ }
+
+ /* Read the abbrevs for this compilation unit into a table */
+ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
+ make_cleanup (dwarf2_empty_abbrev_table, NULL);
+
+ /* Read the compilation unit die */
+ info_ptr = read_partial_die (&comp_unit_die, abfd,
+ info_ptr, &comp_unit_has_pc_info);
+
+ /* Set the language we're debugging */
+ set_cu_language (comp_unit_die.language);
+
+ /* Allocate a new partial symbol table structure */
+ pst = start_psymtab_common (objfile, section_offsets,
+ comp_unit_die.name ? comp_unit_die.name : "",
+ comp_unit_die.lowpc,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+
+ pst->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
+ cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+ DWARF_INFO_BUFFER(pst) = dwarf_info_buffer;
+ DWARF_INFO_OFFSET(pst) = beg_of_comp_unit - dwarf_info_buffer;
+ DWARF_ABBREV_BUFFER(pst) = dwarf_abbrev_buffer;
+ DWARF_ABBREV_SIZE(pst) = dwarf_abbrev_size;
+ DWARF_LINE_BUFFER(pst) = dwarf_line_buffer;
+ baseaddr = ANOFFSET (section_offsets, 0);
+
+ /* Store the function that reads in the rest of the symbol table */
+ pst->read_symtab = dwarf2_psymtab_to_symtab;
+
+ /* Check if comp unit has_children.
+ If so, read the rest of the partial symbols from this comp unit.
+ If not, there's no more debug_info for this comp unit. */
+ if (comp_unit_die.has_children)
+ {
+ info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc);
+
+ /* If the compilation unit didn't have an explicit address range,
+ then use the information extracted from its child dies. */
+ if (!comp_unit_has_pc_info)
+ {
+ comp_unit_die.lowpc = lowpc;
+ comp_unit_die.highpc = highpc;
+ }
+ }
+ pst->textlow = comp_unit_die.lowpc + baseaddr;
+ pst->texthigh = comp_unit_die.highpc + baseaddr;
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this
+ name, remove it. (If there is a symtab, more drastic things
+ also happen.) This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ info_ptr = beg_of_comp_unit + cu_header.length + 4;
+ }
+ do_cleanups (back_to);
+}
+
+/* Read in all interesting dies to the end of the compilation unit. */
+
+static char *
+scan_partial_symbols (info_ptr, objfile, lowpc, highpc)
+ char *info_ptr;
+ struct objfile *objfile;
+ CORE_ADDR *lowpc;
+ CORE_ADDR *highpc;
+{
+ bfd *abfd = objfile->obfd;
+ struct partial_die_info pdi;
+
+ /* This function is called after we've read in the comp_unit_die in
+ order to read its children. We start the nesting level at 1 since
+ we have pushed 1 level down in order to read the comp unit's children.
+ The comp unit itself is at level 0, so we stop reading when we pop
+ back to that level. */
+
+ int nesting_level = 1;
+ int has_pc_info;
+
+ *lowpc = ((CORE_ADDR) -1);
+ *highpc = ((CORE_ADDR) 0);
+
+ while (nesting_level)
+ {
+ info_ptr = read_partial_die (&pdi, abfd, info_ptr, &has_pc_info);
+
+ if (pdi.name)
+ {
+ switch (pdi.tag)
+ {
+ case DW_TAG_subprogram:
+ if (has_pc_info)
+ {
+ if (pdi.lowpc < *lowpc)
+ {
+ *lowpc = pdi.lowpc;
+ }
+ if (pdi.highpc > *highpc)
+ {
+ *highpc = pdi.highpc;
+ }
+ if ((pdi.is_external || nesting_level == 1)
+ && !pdi.is_declaration)
+ {
+ add_partial_symbol (&pdi, objfile);
+ }
+ }
+ break;
+ case DW_TAG_variable:
+ case DW_TAG_typedef:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ if ((pdi.is_external || nesting_level == 1)
+ && !pdi.is_declaration)
+ {
+ add_partial_symbol (&pdi, objfile);
+ }
+ break;
+ case DW_TAG_enumerator:
+ /* File scope enumerators are added to the partial symbol
+ table. */
+ if (nesting_level == 2)
+ add_partial_symbol (&pdi, objfile);
+ break;
+ case DW_TAG_base_type:
+ /* File scope base type definitions are added to the partial
+ symbol table. */
+ if (nesting_level == 1)
+ add_partial_symbol (&pdi, objfile);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If the die has a sibling, skip to the sibling.
+ Do not skip enumeration types, we want to record their
+ enumerators. */
+ if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type)
+ {
+ info_ptr = pdi.sibling;
+ }
+ else if (pdi.has_children)
+ {
+ /* Die has children, but the optional DW_AT_sibling attribute
+ is missing. */
+ nesting_level++;
+ }
+
+ if (pdi.tag == 0)
+ {
+ nesting_level--;
+ }
+ }
+
+ /* If we didn't find a lowpc, set it to highpc to avoid complaints
+ from `maint check'. */
+ if (*lowpc == ((CORE_ADDR) -1))
+ *lowpc = *highpc;
+ return info_ptr;
+}
+
+static void
+add_partial_symbol (pdi, objfile)
+ struct partial_die_info *pdi;
+ struct objfile *objfile;
+{
+ CORE_ADDR addr = 0;
+
+ switch (pdi->tag)
+ {
+ case DW_TAG_subprogram:
+ if (pdi->is_external)
+ {
+ /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+ mst_text, objfile);*/
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, pdi->lowpc + baseaddr, cu_language, objfile);
+ }
+ else
+ {
+ /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+ mst_file_text, objfile);*/
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, pdi->lowpc + baseaddr, cu_language, objfile);
+ }
+ break;
+ case DW_TAG_variable:
+ if (pdi->is_external)
+ {
+ /* Global Variable.
+ Don't enter into the minimal symbol tables as there is
+ a minimal symbol table entry from the ELF symbols already.
+ Enter into partial symbol table if it has a location
+ descriptor or a type.
+ If the location descriptor is missing, new_symbol will create
+ a LOC_UNRESOLVED symbol, the address of the variable will then
+ be determined from the minimal symbol table whenever the variable
+ is referenced.
+ The address for the partial symbol table entry is not
+ used by GDB, but it comes in handy for debugging partial symbol
+ table building. */
+
+ if (pdi->locdesc)
+ addr = decode_locdesc (pdi->locdesc, objfile);
+ if (pdi->locdesc || pdi->has_type)
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, addr + baseaddr, cu_language, objfile);
+ }
+ else
+ {
+ /* Static Variable. Skip symbols without location descriptors. */
+ if (pdi->locdesc == NULL)
+ return;
+ addr = decode_locdesc (pdi->locdesc, objfile);
+ /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+ mst_file_data, objfile);*/
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, addr + baseaddr, cu_language, objfile);
+ }
+ break;
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ /* Skip aggregate types without children, these are external
+ references. */
+ if (pdi->has_children == 0)
+ return;
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+
+ if (cu_language == language_cplus)
+ {
+ /* For C++, these implicitly act as typedefs as well. */
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+ }
+ break;
+ case DW_TAG_enumerator:
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Expand this partial symbol table into a full symbol table. */
+
+static void
+dwarf2_psymtab_to_symtab (pst)
+ struct partial_symtab *pst;
+{
+ /* FIXME: This is barely more than a stub. */
+ if (pst != NULL)
+ {
+ if (pst->readin)
+ {
+ warning ("bug: psymtab for %s is already read in.", pst->filename);
+ }
+ else
+ {
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ psymtab_to_symtab_1 (pst);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+ }
+}
+
+static void
+psymtab_to_symtab_1 (pst)
+ struct partial_symtab *pst;
+{
+ struct objfile *objfile = pst->objfile;
+ bfd *abfd = objfile->obfd;
+ struct comp_unit_head cu_header;
+ struct die_info *dies;
+ unsigned long offset;
+ CORE_ADDR lowpc, highpc;
+ struct die_info *child_die;
+ char *info_ptr;
+ struct symtab *symtab;
+ struct cleanup *back_to;
+
+ /* Set local variables from the partial symbol table info. */
+ offset = DWARF_INFO_OFFSET(pst);
+ dwarf_info_buffer = DWARF_INFO_BUFFER(pst);
+ dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER(pst);
+ dwarf_abbrev_size = DWARF_ABBREV_SIZE(pst);
+ dwarf_line_buffer = DWARF_LINE_BUFFER(pst);
+ baseaddr = ANOFFSET (pst->section_offsets, 0);
+ cu_header_offset = offset;
+ info_ptr = dwarf_info_buffer + offset;
+
+ obstack_init (&dwarf2_tmp_obstack);
+ back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+ buildsym_init ();
+ make_cleanup ((make_cleanup_func) really_free_pendings, NULL);
+
+ /* read in the comp_unit header */
+ cu_header.length = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ cu_header.version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ cu_header.abbrev_offset = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ cu_header.addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+
+ /* Read the abbrevs for this compilation unit */
+ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
+ make_cleanup (dwarf2_empty_abbrev_table, NULL);
+
+ dies = read_comp_unit (info_ptr, abfd);
+
+ make_cleanup ((make_cleanup_func) free_die_list, dies);
+
+ /* Do line number decoding in read_file_scope () */
+ process_die (dies, objfile);
+
+ if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile))
+ {
+ /* Some compilers don't define a DW_AT_high_pc attribute for
+ the compilation unit. If the DW_AT_high_pc is missing,
+ synthesize it, by scanning the DIE's below the compilation unit. */
+ highpc = 0;
+ if (dies->has_children)
+ {
+ child_die = dies->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_subprogram)
+ {
+ CORE_ADDR low, high;
+
+ if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+ {
+ highpc = max (highpc, high);
+ }
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+ }
+ symtab = end_symtab (highpc + baseaddr, objfile, 0);
+
+ /* Set symtab language to language from DW_AT_language.
+ If the compilation is from a C file generated by language preprocessors,
+ do not set the language if it was already deduced by start_subfile. */
+ if (symtab != NULL
+ && !(cu_language == language_c && symtab->language != language_c))
+ {
+ symtab->language = cu_language;
+ }
+ pst->symtab = symtab;
+ pst->readin = 1;
+ sort_symtab_syms (pst->symtab);
+
+ do_cleanups (back_to);
+}
+
+/* Process a die and its children. */
+
+static void
+process_die (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ switch (die->tag)
+ {
+ case DW_TAG_padding:
+ break;
+ case DW_TAG_compile_unit:
+ read_file_scope (die, objfile);
+ break;
+ case DW_TAG_subprogram:
+ read_subroutine_type (die, objfile);
+ read_func_scope (die, objfile);
+ break;
+ case DW_TAG_inlined_subroutine:
+ /* FIXME: These are ignored for now.
+ They could be used to set breakpoints on all inlined instances
+ of a function and make GDB `next' properly over inlined functions. */
+ break;
+ case DW_TAG_lexical_block:
+ read_lexical_block_scope (die, objfile);
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ read_structure_scope (die, objfile);
+ break;
+ case DW_TAG_enumeration_type:
+ read_enumeration (die, objfile);
+ break;
+ case DW_TAG_subroutine_type:
+ read_subroutine_type (die, objfile);
+ break;
+ case DW_TAG_array_type:
+ read_array_type (die, objfile);
+ break;
+ case DW_TAG_pointer_type:
+ read_tag_pointer_type (die, objfile);
+ break;
+ case DW_TAG_ptr_to_member_type:
+ read_tag_ptr_to_member_type (die, objfile);
+ break;
+ case DW_TAG_reference_type:
+ read_tag_reference_type (die, objfile);
+ break;
+ case DW_TAG_string_type:
+ read_tag_string_type (die, objfile);
+ break;
+ case DW_TAG_base_type:
+ read_base_type (die, objfile);
+ if (dwarf_attr (die, DW_AT_name))
+ {
+ /* Add a typedef symbol for the base type definition. */
+ new_symbol (die, die->type, objfile);
+ }
+ break;
+ case DW_TAG_common_block:
+ read_common_block (die, objfile);
+ break;
+ case DW_TAG_common_inclusion:
+ break;
+ default:
+ new_symbol (die, NULL, objfile);
+ break;
+ }
+}
+
+static void
+read_file_scope (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ unsigned int line_offset = 0;
+ CORE_ADDR lowpc = ((CORE_ADDR) -1);
+ CORE_ADDR highpc = ((CORE_ADDR) 0);
+ struct attribute *attr;
+ char *name = "<unknown>";
+ char *comp_dir = NULL;
+ struct die_info *child_die;
+ bfd *abfd = objfile->obfd;
+
+ if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+ {
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_subprogram)
+ {
+ CORE_ADDR low, high;
+
+ if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+ {
+ lowpc = min (lowpc, low);
+ highpc = max (highpc, high);
+ }
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+ }
+
+ /* If we didn't find a lowpc, set it to highpc to avoid complaints
+ from finish_block. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+ lowpc += baseaddr;
+ highpc += baseaddr;
+
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr)
+ {
+ name = DW_STRING (attr);
+ }
+ attr = dwarf_attr (die, DW_AT_comp_dir);
+ if (attr)
+ {
+ comp_dir = DW_STRING (attr);
+ if (comp_dir)
+ {
+ /* Irix 6.2 native cc prepends <machine>.: to the compilation
+ directory, get rid of it. */
+ char *cp = strchr (comp_dir, ':');
+
+ if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+ comp_dir = cp + 1;
+ }
+ }
+
+ if (objfile->ei.entry_point >= lowpc &&
+ objfile->ei.entry_point < highpc)
+ {
+ objfile->ei.entry_file_lowpc = lowpc;
+ objfile->ei.entry_file_highpc = highpc;
+ }
+
+ attr = dwarf_attr (die, DW_AT_language);
+ if (attr)
+ {
+ set_cu_language (DW_UNSND (attr));
+ }
+
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
+#if 0
+ /* FIXME:Do something here. */
+ if (dip->at_producer != NULL)
+ {
+ handle_producer (dip->at_producer);
+ }
+#endif
+
+ /* The compilation unit may be in a different language or objfile,
+ zero out all remembered fundamental types. */
+ memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+
+ start_symtab (name, comp_dir, lowpc);
+ record_debugformat ("DWARF 2");
+
+ /* Decode line number information if present. */
+ attr = dwarf_attr (die, DW_AT_stmt_list);
+ if (attr)
+ {
+ line_offset = DW_UNSND (attr);
+ dwarf_decode_lines (line_offset, comp_dir, abfd);
+ }
+
+ /* Process all dies in compilation unit. */
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, objfile);
+ child_die = sibling_die (child_die);
+ }
+ }
+}
+
+static void
+read_func_scope (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ register struct context_stack *new;
+ CORE_ADDR lowpc;
+ CORE_ADDR highpc;
+ struct die_info *child_die;
+ struct attribute *attr;
+ char *name;
+
+ name = dwarf2_linkage_name (die);
+
+ /* Ignore functions with missing or empty names and functions with
+ missing or invalid low and high pc attributes. */
+ if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+ return;
+
+ lowpc += baseaddr;
+ highpc += baseaddr;
+
+ if (objfile->ei.entry_point >= lowpc &&
+ objfile->ei.entry_point < highpc)
+ {
+ objfile->ei.entry_func_lowpc = lowpc;
+ objfile->ei.entry_func_highpc = highpc;
+ }
+
+ if (STREQ (name, "main")) /* FIXME: hardwired name */
+ {
+ objfile->ei.main_func_lowpc = lowpc;
+ objfile->ei.main_func_highpc = highpc;
+ }
+
+ /* Decode DW_AT_frame_base location descriptor if present, keep result
+ for DW_OP_fbreg operands in decode_locdesc. */
+ frame_base_reg = -1;
+ frame_base_offset = 0;
+ attr = dwarf_attr (die, DW_AT_frame_base);
+ if (attr)
+ {
+ CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile);
+ if (isreg)
+ frame_base_reg = addr;
+ else if (offreg)
+ {
+ frame_base_reg = basereg;
+ frame_base_offset = addr;
+ }
+ else
+ complain (&dwarf2_unsupported_at_frame_base, name);
+ }
+
+ new = push_context (0, lowpc);
+ new->name = new_symbol (die, die->type, objfile);
+ list_in_scope = &local_symbols;
+
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, objfile);
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ new = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ lowpc, highpc, objfile);
+ list_in_scope = &file_symbols;
+}
+
+/* Process all the DIES contained within a lexical block scope. Start
+ a new scope, process the dies, and then close the scope. */
+
+static void
+read_lexical_block_scope (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ register struct context_stack *new;
+ CORE_ADDR lowpc, highpc;
+ struct die_info *child_die;
+
+ /* Ignore blocks with missing or invalid low and high pc attributes. */
+ if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+ return;
+ lowpc += baseaddr;
+ highpc += baseaddr;
+
+ push_context (0, lowpc);
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, objfile);
+ child_die = sibling_die (child_die);
+ }
+ }
+ new = pop_context ();
+
+ if (local_symbols != NULL)
+ {
+ finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
+ highpc, objfile);
+ }
+ local_symbols = new->locals;
+}
+
+/* Get low and high pc attributes from a die.
+ Return 1 if the attributes are present and valid, otherwise, return 0. */
+
+static int
+dwarf2_get_pc_bounds (die, lowpc, highpc, objfile)
+ struct die_info *die;
+ CORE_ADDR *lowpc;
+ CORE_ADDR *highpc;
+ struct objfile *objfile;
+{
+ struct attribute *attr;
+ CORE_ADDR low;
+ CORE_ADDR high;
+
+ attr = dwarf_attr (die, DW_AT_low_pc);
+ if (attr)
+ low = DW_ADDR (attr);
+ else
+ return 0;
+ attr = dwarf_attr (die, DW_AT_high_pc);
+ if (attr)
+ high = DW_ADDR (attr);
+ else
+ return 0;
+
+ if (high < low)
+ return 0;
+
+ /* When using the GNU linker, .gnu.linkonce. sections are used to
+ eliminate duplicate copies of functions and vtables and such.
+ The linker will arbitrarily choose one and discard the others.
+ The AT_*_pc values for such functions refer to local labels in
+ these sections. If the section from that file was discarded, the
+ labels are not in the output, so the relocs get a value of 0.
+ If this is a discarded function, mark the pc bounds as invalid,
+ so that GDB will ignore it. */
+ if (low == 0 && (bfd_get_file_flags (objfile->obfd) & HAS_RELOC) == 0)
+ return 0;
+
+ *lowpc = low;
+ *highpc = high;
+ return 1;
+}
+
+/* Add an aggregate field to the field list. */
+
+static void
+dwarf2_add_field (fip, die, objfile)
+ struct field_info *fip;
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct nextfield *new_field;
+ struct attribute *attr;
+ struct field *fp;
+ char *fieldname = "";
+
+ /* Allocate a new field list entry and link it in. */
+ new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (free, new_field);
+ memset (new_field, 0, sizeof (struct nextfield));
+ new_field->next = fip->fields;
+ fip->fields = new_field;
+ fip->nfields++;
+
+ /* Handle accessibility and virtuality of field.
+ The default accessibility for members is public, the default
+ accessibility for inheritance is private. */
+ if (die->tag != DW_TAG_inheritance)
+ new_field->accessibility = DW_ACCESS_public;
+ else
+ new_field->accessibility = DW_ACCESS_private;
+ new_field->virtuality = DW_VIRTUALITY_none;
+
+ attr = dwarf_attr (die, DW_AT_accessibility);
+ if (attr)
+ new_field->accessibility = DW_UNSND (attr);
+ if (new_field->accessibility != DW_ACCESS_public)
+ fip->non_public_fields = 1;
+ attr = dwarf_attr (die, DW_AT_virtuality);
+ if (attr)
+ new_field->virtuality = DW_UNSND (attr);
+
+ fp = &new_field->field;
+ if (die->tag == DW_TAG_member)
+ {
+ /* Get type of field. */
+ fp->type = die_type (die, objfile);
+
+ /* Get bit size of field (zero if none). */
+ attr = dwarf_attr (die, DW_AT_bit_size);
+ if (attr)
+ {
+ FIELD_BITSIZE (*fp) = DW_UNSND (attr);
+ }
+ else
+ {
+ FIELD_BITSIZE (*fp) = 0;
+ }
+
+ /* Get bit offset of field. */
+ attr = dwarf_attr (die, DW_AT_data_member_location);
+ if (attr)
+ {
+ FIELD_BITPOS (*fp) =
+ decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
+ }
+ else
+ FIELD_BITPOS (*fp) = 0;
+ attr = dwarf_attr (die, DW_AT_bit_offset);
+ if (attr)
+ {
+ if (BITS_BIG_ENDIAN)
+ {
+ /* For big endian bits, the DW_AT_bit_offset gives the
+ additional bit offset from the MSB of the containing
+ anonymous object to the MSB of the field. We don't
+ have to do anything special since we don't need to
+ know the size of the anonymous object. */
+ FIELD_BITPOS (*fp) += DW_UNSND (attr);
+ }
+ else
+ {
+ /* For little endian bits, compute the bit offset to the
+ MSB of the anonymous object, subtract off the number of
+ bits from the MSB of the field to the MSB of the
+ object, and then subtract off the number of bits of
+ the field itself. The result is the bit offset of
+ the LSB of the field. */
+ int anonymous_size;
+ int bit_offset = DW_UNSND (attr);
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ /* The size of the anonymous object containing
+ the bit field is explicit, so use the
+ indicated size (in bytes). */
+ anonymous_size = DW_UNSND (attr);
+ }
+ else
+ {
+ /* The size of the anonymous object containing
+ the bit field must be inferred from the type
+ attribute of the data member containing the
+ bit field. */
+ anonymous_size = TYPE_LENGTH (fp->type);
+ }
+ FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte
+ - bit_offset - FIELD_BITSIZE (*fp);
+ }
+ }
+
+ /* Get name of field. */
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ fieldname = DW_STRING (attr);
+ fp->name = obsavestring (fieldname, strlen (fieldname),
+ &objfile->type_obstack);
+
+ /* Change accessibility for artificial fields (e.g. virtual table
+ pointer or virtual base class pointer) to private. */
+ if (dwarf_attr (die, DW_AT_artificial))
+ {
+ new_field->accessibility = DW_ACCESS_private;
+ fip->non_public_fields = 1;
+ }
+ }
+ else if (die->tag == DW_TAG_variable)
+ {
+ char *physname;
+ char *cp;
+
+ /* C++ static member.
+ Get physical name, extract field name from physical name. */
+ physname = dwarf2_linkage_name (die);
+ if (physname == NULL)
+ return;
+
+ cp = physname;
+ while (*cp && !is_cplus_marker (*cp))
+ cp++;
+ if (*cp)
+ fieldname = cp + 1;
+ if (*fieldname == '\0')
+ {
+ complain (&dwarf2_bad_static_member_name, physname);
+ }
+
+ SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
+ &objfile->type_obstack));
+ FIELD_TYPE (*fp) = die_type (die, objfile);
+ FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
+ &objfile->type_obstack);
+ }
+ else if (die->tag == DW_TAG_inheritance)
+ {
+ /* C++ base class field. */
+ attr = dwarf_attr (die, DW_AT_data_member_location);
+ if (attr)
+ FIELD_BITPOS (*fp) = decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
+ FIELD_BITSIZE (*fp) = 0;
+ FIELD_TYPE (*fp) = die_type (die, objfile);
+ FIELD_NAME (*fp) = type_name_no_tag (fp->type);
+ fip->nbaseclasses++;
+ }
+}
+
+/* Create the vector of fields, and attach it to the type. */
+
+static void
+dwarf2_attach_fields_to_type (fip, type, objfile)
+ struct field_info *fip;
+ struct type *type;
+ struct objfile *objfile;
+{
+ int nfields = fip->nfields;
+
+ /* Record the field count, allocate space for the array of fields,
+ and create blank accessibility bitfields if necessary. */
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+ memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+ if (fip->non_public_fields)
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+ }
+
+ /* If the type has baseclasses, allocate and clear a bit vector for
+ TYPE_FIELD_VIRTUAL_BITS. */
+ if (fip->nbaseclasses)
+ {
+ int num_bytes = B_BYTES (fip->nbaseclasses);
+ char *pointer;
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ pointer = (char *) TYPE_ALLOC (type, num_bytes);
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
+ TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
+ }
+
+ /* Copy the saved-up fields into the field vector. Start from the head
+ of the list, adding to the tail of the field array, so that they end
+ up in the same order in the array in which they were added to the list. */
+ while (nfields-- > 0)
+ {
+ TYPE_FIELD (type, nfields) = fip->fields->field;
+ switch (fip->fields->accessibility)
+ {
+ case DW_ACCESS_private:
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+ break;
+
+ case DW_ACCESS_protected:
+ SET_TYPE_FIELD_PROTECTED (type, nfields);
+ break;
+
+ case DW_ACCESS_public:
+ break;
+
+ default:
+ /* Unknown accessibility. Complain and treat it as public. */
+ {
+ complain (&dwarf2_unsupported_accessibility,
+ fip->fields->accessibility);
+ }
+ break;
+ }
+ if (nfields < fip->nbaseclasses)
+ {
+ switch (fip->fields->virtuality)
+ {
+ case DW_VIRTUALITY_virtual:
+ case DW_VIRTUALITY_pure_virtual:
+ SET_TYPE_FIELD_VIRTUAL (type, nfields);
+ break;
+ }
+ }
+ fip->fields = fip->fields->next;
+ }
+}
+
+/* Skip to the end of a member function name in a mangled name. */
+
+static char *
+skip_member_fn_name (physname)
+ char *physname;
+{
+ char *endname = physname;
+
+ /* Skip over leading underscores. */
+ while (*endname == '_')
+ endname++;
+
+ /* Find two succesive underscores. */
+ do
+ endname = strchr (endname, '_');
+ while (endname != NULL && *++endname != '_');
+
+ if (endname == NULL)
+ {
+ complain (&dwarf2_bad_member_name_complaint, physname);
+ endname = physname;
+ }
+ else
+ {
+ /* Take care of trailing underscores. */
+ if (endname[1] != '_')
+ endname--;
+ }
+ return endname;
+}
+
+/* Add a member function to the proper fieldlist. */
+
+static void
+dwarf2_add_member_fn (fip, die, type, objfile)
+ struct field_info *fip;
+ struct die_info *die;
+ struct type *type;
+ struct objfile *objfile;
+{
+ struct attribute *attr;
+ struct fnfieldlist *flp;
+ int i;
+ struct fn_field *fnp;
+ char *fieldname;
+ char *physname;
+ struct nextfnfield *new_fnfield;
+
+ /* Extract member function name from mangled name. */
+ physname = dwarf2_linkage_name (die);
+ if (physname == NULL)
+ return;
+ if ((physname[0] == '_' && physname[1] == '_'
+ && strchr ("0123456789Qt", physname[2]))
+ || DESTRUCTOR_PREFIX_P (physname))
+ {
+ /* Constructor and destructor field names are set to the name
+ of the class, but without template parameter lists.
+ The name might be missing for anonymous aggregates. */
+ if (TYPE_TAG_NAME (type))
+ {
+ char *p = strchr (TYPE_TAG_NAME (type), '<');
+
+ if (p == NULL)
+ fieldname = TYPE_TAG_NAME (type);
+ else
+ fieldname = obsavestring (TYPE_TAG_NAME (type),
+ p - TYPE_TAG_NAME (type),
+ &objfile->type_obstack);
+ }
+ else
+ {
+ char *anon_name = "";
+ fieldname = obsavestring (anon_name, strlen (anon_name),
+ &objfile->type_obstack);
+ }
+ }
+ else
+ {
+ char *endname = skip_member_fn_name (physname);
+
+ /* Ignore member function if we were unable not extract the member
+ function name. */
+ if (endname == physname)
+ return;
+ fieldname = obsavestring (physname, endname - physname,
+ &objfile->type_obstack);
+ }
+
+ /* Look up member function name in fieldlist. */
+ for (i = 0; i < fip->nfnfields; i++)
+ {
+ if (STREQ (fip->fnfieldlists[i].name, fieldname))
+ break;
+ }
+
+ /* Create new list element if necessary. */
+ if (i < fip->nfnfields)
+ flp = &fip->fnfieldlists[i];
+ else
+ {
+ if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ fip->fnfieldlists = (struct fnfieldlist *)
+ xrealloc (fip->fnfieldlists,
+ (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct fnfieldlist));
+ if (fip->nfnfields == 0)
+ make_cleanup ((make_cleanup_func) free_current_contents,
+ &fip->fnfieldlists);
+ }
+ flp = &fip->fnfieldlists[fip->nfnfields];
+ flp->name = fieldname;
+ flp->length = 0;
+ flp->head = NULL;
+ fip->nfnfields++;
+ }
+
+ /* Create a new member function field and chain it to the field list
+ entry. */
+ new_fnfield = (struct nextfnfield *) xmalloc (sizeof (struct nextfnfield));
+ make_cleanup (free, new_fnfield);
+ memset (new_fnfield, 0, sizeof (struct nextfnfield));
+ new_fnfield->next = flp->head;
+ flp->head = new_fnfield;
+ flp->length++;
+
+ /* Fill in the member function field info. */
+ fnp = &new_fnfield->fnfield;
+ fnp->physname = obsavestring (physname, strlen (physname),
+ &objfile->type_obstack);
+ fnp->type = alloc_type (objfile);
+ if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
+ {
+ struct type *return_type = TYPE_TARGET_TYPE (die->type);
+ struct type **arg_types;
+ int nparams = TYPE_NFIELDS (die->type);
+ int iparams;
+
+ /* Copy argument types from the subroutine type. */
+ arg_types = (struct type **)
+ TYPE_ALLOC (fnp->type, (nparams + 1) * sizeof (struct type *));
+ for (iparams = 0; iparams < nparams; iparams++)
+ arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams);
+
+ /* Set last entry in argument type vector. */
+ if (TYPE_FLAGS (die->type) & TYPE_FLAG_VARARGS)
+ arg_types[nparams] = NULL;
+ else
+ arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID);
+
+ smash_to_method_type (fnp->type, type, return_type, arg_types);
+
+ /* Handle static member functions.
+ Dwarf2 has no clean way to discern C++ static and non-static
+ member functions. G++ helps GDB by marking the first
+ parameter for non-static member functions (which is the
+ this pointer) as artificial. We obtain this information
+ from read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */
+ if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0)
+ fnp->voffset = VOFFSET_STATIC;
+ }
+ else
+ complain (&dwarf2_missing_member_fn_type_complaint, physname);
+
+ /* Get fcontext from DW_AT_containing_type if present. */
+ if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+ fnp->fcontext = die_containing_type (die, objfile);
+
+ /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
+ and is_volatile is irrelevant, as it is needed by gdb_mangle_name only. */
+
+ /* Get accessibility. */
+ attr = dwarf_attr (die, DW_AT_accessibility);
+ if (attr)
+ {
+ switch (DW_UNSND (attr))
+ {
+ case DW_ACCESS_private:
+ fnp->is_private = 1;
+ break;
+ case DW_ACCESS_protected:
+ fnp->is_protected = 1;
+ break;
+ }
+ }
+
+ /* Get index in virtual function table if it is a virtual member function. */
+ attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+ if (attr)
+ fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile) + 2;
+}
+
+/* Create the vector of member function fields, and attach it to the type. */
+
+static void
+dwarf2_attach_fn_fields_to_type (fip, type, objfile)
+ struct field_info *fip;
+ struct type *type;
+ struct objfile *objfile;
+{
+ struct fnfieldlist *flp;
+ int total_length = 0;
+ int i;
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields);
+
+ for (i = 0, flp = fip->fnfieldlists; i < fip->nfnfields; i++, flp++)
+ {
+ struct nextfnfield *nfp = flp->head;
+ struct fn_fieldlist *fn_flp = &TYPE_FN_FIELDLIST (type, i);
+ int k;
+
+ TYPE_FN_FIELDLIST_NAME (type, i) = flp->name;
+ TYPE_FN_FIELDLIST_LENGTH (type, i) = flp->length;
+ fn_flp->fn_fields = (struct fn_field *)
+ TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length);
+ for (k = flp->length; (k--, nfp); nfp = nfp->next)
+ fn_flp->fn_fields[k] = nfp->fnfield;
+
+ total_length += flp->length;
+ }
+
+ TYPE_NFN_FIELDS (type) = fip->nfnfields;
+ TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+}
+
+/* Called when we find the DIE that starts a structure or union scope
+ (definition) to process all dies that define the members of the
+ structure or union.
+
+ NOTE: we need to call struct_type regardless of whether or not the
+ DIE has an at_name attribute, since it might be an anonymous
+ structure or union. This gets the type entered into our set of
+ user defined types.
+
+ However, if the structure is incomplete (an opaque struct/union)
+ then suppress creating a symbol table entry for it since gdb only
+ wants to find the one with the complete definition. Note that if
+ it is complete, we just call new_symbol, which does it's own
+ checking about whether the struct/union is anonymous or not (and
+ suppresses creating a symbol table entry itself). */
+
+static void
+read_structure_scope (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct attribute *attr;
+
+ type = alloc_type (objfile);
+
+ INIT_CPLUS_SPECIFIC (type);
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
+ strlen (DW_STRING (attr)),
+ &objfile->type_obstack);
+ }
+
+ if (die->tag == DW_TAG_structure_type)
+ {
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ }
+ else if (die->tag == DW_TAG_union_type)
+ {
+ TYPE_CODE (type) = TYPE_CODE_UNION;
+ }
+ else
+ {
+ /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT
+ in gdbtypes.h. */
+ TYPE_CODE (type) = TYPE_CODE_CLASS;
+ }
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = 0;
+ }
+
+ /* We need to add the type field to the die immediately so we don't
+ infinitely recurse when dealing with pointers to the structure
+ type within the structure itself. */
+ die->type = type;
+
+ if (die->has_children)
+ {
+ struct field_info fi;
+ struct die_info *child_die;
+ struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+
+ memset (&fi, 0, sizeof (struct field_info));
+
+ child_die = die->next;
+
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_member)
+ {
+ dwarf2_add_field (&fi, child_die, objfile);
+ }
+ else if (child_die->tag == DW_TAG_variable)
+ {
+ /* C++ static member. */
+ dwarf2_add_field (&fi, child_die, objfile);
+ }
+ else if (child_die->tag == DW_TAG_subprogram)
+ {
+ /* C++ member function. */
+ process_die (child_die, objfile);
+ dwarf2_add_member_fn (&fi, child_die, type, objfile);
+ }
+ else if (child_die->tag == DW_TAG_inheritance)
+ {
+ /* C++ base class field. */
+ dwarf2_add_field (&fi, child_die, objfile);
+ }
+ else
+ {
+ process_die (child_die, objfile);
+ }
+ child_die = sibling_die (child_die);
+ }
+
+ /* Attach fields and member functions to the type. */
+ if (fi.nfields)
+ dwarf2_attach_fields_to_type (&fi, type, objfile);
+ if (fi.nfnfields)
+ {
+ dwarf2_attach_fn_fields_to_type (&fi, type, objfile);
+
+ /* Get the type which refers to the base class (possibly this
+ class itself) which contains the vtable pointer for the current
+ class from the DW_AT_containing_type attribute. */
+
+ if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+ {
+ struct type *t = die_containing_type (die, objfile);
+
+ TYPE_VPTR_BASETYPE (type) = t;
+ if (type == t)
+ {
+ static const char vptr_name[] = { '_','v','p','t','r','\0' };
+ int i;
+
+ /* Our own class provides vtbl ptr. */
+ for (i = TYPE_NFIELDS (t) - 1;
+ i >= TYPE_N_BASECLASSES (t);
+ --i)
+ {
+ char *fieldname = TYPE_FIELD_NAME (t, i);
+
+ if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+ && is_cplus_marker (fieldname[strlen (vptr_name)]))
+ {
+ TYPE_VPTR_FIELDNO (type) = i;
+ break;
+ }
+ }
+
+ /* Complain if virtual function table field not found. */
+ if (i < TYPE_N_BASECLASSES (t))
+ complain (&dwarf2_vtbl_not_found_complaint,
+ TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "");
+ }
+ else
+ {
+ TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+ }
+ }
+ }
+
+ new_symbol (die, type, objfile);
+
+ do_cleanups (back_to);
+ }
+ else
+ {
+ /* No children, must be stub. */
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+ }
+
+ die->type = type;
+}
+
+/* Given a pointer to a die which begins an enumeration, process all
+ the dies that define the members of the enumeration.
+
+ This will be much nicer in draft 6 of the DWARF spec when our
+ members will be dies instead squished into the DW_AT_element_list
+ attribute.
+
+ NOTE: We reverse the order of the element list. */
+
+static void
+read_enumeration (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct die_info *child_die;
+ struct type *type;
+ struct field *fields;
+ struct attribute *attr;
+ struct symbol *sym;
+ int num_fields;
+ int unsigned_enum = 1;
+
+ type = alloc_type (objfile);
+
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
+ strlen (DW_STRING (attr)),
+ &objfile->type_obstack);
+ }
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = 0;
+ }
+
+ num_fields = 0;
+ fields = NULL;
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag != DW_TAG_enumerator)
+ {
+ process_die (child_die, objfile);
+ }
+ else
+ {
+ attr = dwarf_attr (child_die, DW_AT_name);
+ if (attr)
+ {
+ sym = new_symbol (child_die, type, objfile);
+ if (SYMBOL_VALUE (sym) < 0)
+ unsigned_enum = 0;
+
+ if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ fields = (struct field *)
+ xrealloc (fields,
+ (num_fields + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct field));
+ }
+
+ FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+ FIELD_TYPE (fields[num_fields]) = NULL;
+ FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
+ FIELD_BITSIZE (fields[num_fields]) = 0;
+
+ num_fields++;
+ }
+ }
+
+ child_die = sibling_die (child_die);
+ }
+
+ if (num_fields)
+ {
+ TYPE_NFIELDS (type) = num_fields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * num_fields);
+ memcpy (TYPE_FIELDS (type), fields,
+ sizeof (struct field) * num_fields);
+ free (fields);
+ }
+ if (unsigned_enum)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ }
+ die->type = type;
+ new_symbol (die, type, objfile);
+}
+
+/* Extract all information from a DW_TAG_array_type DIE and put it in
+ the DIE's type field. For now, this only handles one dimensional
+ arrays. */
+
+static void
+read_array_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct die_info *child_die;
+ struct type *type = NULL;
+ struct type *element_type, *range_type, *index_type;
+ struct type **range_types = NULL;
+ struct attribute *attr;
+ int ndim = 0;
+ struct cleanup *back_to;
+
+ /* Return if we've already decoded this type. */
+ if (die->type)
+ {
+ return;
+ }
+
+ element_type = die_type (die, objfile);
+
+ /* Irix 6.2 native cc creates array types without children for
+ arrays with unspecified length. */
+ if (die->has_children == 0)
+ {
+ index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+ range_type = create_range_type (NULL, index_type, 0, -1);
+ die->type = create_array_type (NULL, element_type, range_type);
+ return;
+ }
+
+ back_to = make_cleanup (null_cleanup, NULL);
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_subrange_type)
+ {
+ unsigned int low, high;
+
+ /* Default bounds to an array with unspecified length. */
+ low = 0;
+ high = -1;
+ if (cu_language == language_fortran)
+ {
+ /* FORTRAN implies a lower bound of 1, if not given. */
+ low = 1;
+ }
+
+ index_type = die_type (child_die, objfile);
+ attr = dwarf_attr (child_die, DW_AT_lower_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_sdata)
+ {
+ low = DW_SND (attr);
+ }
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4)
+ {
+ low = DW_UNSND (attr);
+ }
+ else
+ {
+ complain (&dwarf2_non_const_array_bound_ignored,
+ dwarf_form_name (attr->form));
+#ifdef FORTRAN_HACK
+ die->type = lookup_pointer_type (element_type);
+ return;
+#else
+ low = 0;
+#endif
+ }
+ }
+ attr = dwarf_attr (child_die, DW_AT_upper_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_sdata)
+ {
+ high = DW_SND (attr);
+ }
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4)
+ {
+ high = DW_UNSND (attr);
+ }
+ else if (attr->form == DW_FORM_block1)
+ {
+ /* GCC encodes arrays with unspecified or dynamic length
+ with a DW_FORM_block1 attribute.
+ FIXME: GDB does not yet know how to handle dynamic
+ arrays properly, treat them as arrays with unspecified
+ length for now. */
+ high = -1;
+ }
+ else
+ {
+ complain (&dwarf2_non_const_array_bound_ignored,
+ dwarf_form_name (attr->form));
+#ifdef FORTRAN_HACK
+ die->type = lookup_pointer_type (element_type);
+ return;
+#else
+ high = 1;
+#endif
+ }
+ }
+
+ /* Create a range type and save it for array type creation. */
+ if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ range_types = (struct type **)
+ xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct type *));
+ if (ndim == 0)
+ make_cleanup ((make_cleanup_func) free_current_contents,
+ &range_types);
+ }
+ range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+ }
+ child_die = sibling_die (child_die);
+ }
+
+ /* Dwarf2 dimensions are output from left to right, create the
+ necessary array types in backwards order. */
+ type = element_type;
+ while (ndim-- > 0)
+ type = create_array_type (NULL, type, range_types[ndim]);
+
+ do_cleanups (back_to);
+
+ /* Install the type in the die. */
+ die->type = type;
+}
+
+/* First cut: install each common block member as a global variable. */
+
+static void
+read_common_block (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct die_info *child_die;
+ struct attribute *attr;
+ struct symbol *sym;
+ CORE_ADDR base = (CORE_ADDR) 0;
+
+ attr = dwarf_attr (die, DW_AT_location);
+ if (attr)
+ {
+ base = decode_locdesc (DW_BLOCK (attr), objfile);
+ }
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ sym = new_symbol (child_die, NULL, objfile);
+ attr = dwarf_attr (child_die, DW_AT_data_member_location);
+ if (attr)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) =
+ base + decode_locdesc (DW_BLOCK (attr), objfile);
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+}
+
+/* Extract all information from a DW_TAG_pointer_type DIE and add to
+ the user defined type vector. */
+
+static void
+read_tag_pointer_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct attribute *attr;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ type = lookup_pointer_type (die_type (die, objfile));
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = address_size;
+ }
+ die->type = type;
+}
+
+/* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
+ the user defined type vector. */
+
+static void
+read_tag_ptr_to_member_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct type *to_type;
+ struct type *domain;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ type = alloc_type (objfile);
+ to_type = die_type (die, objfile);
+ domain = die_containing_type (die, objfile);
+ smash_to_member_type (type, domain, to_type);
+
+ die->type = type;
+}
+
+/* Extract all information from a DW_TAG_reference_type DIE and add to
+ the user defined type vector. */
+
+static void
+read_tag_reference_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct attribute *attr;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ type = lookup_reference_type (die_type (die, objfile));
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = address_size;
+ }
+ die->type = type;
+}
+
+static void
+read_tag_const_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ if (die->type)
+ {
+ return;
+ }
+
+ complain (&dwarf2_const_ignored);
+ die->type = die_type (die, objfile);
+}
+
+static void
+read_tag_volatile_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ if (die->type)
+ {
+ return;
+ }
+
+ complain (&dwarf2_volatile_ignored);
+ die->type = die_type (die, objfile);
+}
+
+/* Extract all information from a DW_TAG_string_type DIE and add to
+ the user defined type vector. It isn't really a user defined type,
+ but it behaves like one, with other DIE's using an AT_user_def_type
+ attribute to reference it. */
+
+static void
+read_tag_string_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type, *range_type, *index_type, *char_type;
+ struct attribute *attr;
+ unsigned int length;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ attr = dwarf_attr (die, DW_AT_string_length);
+ if (attr)
+ {
+ length = DW_UNSND (attr);
+ }
+ else
+ {
+ length = 1;
+ }
+ index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+ range_type = create_range_type (NULL, index_type, 1, length);
+ char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+ type = create_string_type (char_type, range_type);
+ die->type = type;
+}
+
+/* Handle DIES due to C code like:
+
+ struct foo
+ {
+ int (*funcp)(int a, long l);
+ int b;
+ };
+
+ ('funcp' generates a DW_TAG_subroutine_type DIE)
+*/
+
+static void
+read_subroutine_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type; /* Type that this function returns */
+ struct type *ftype; /* Function that returns above type */
+ struct attribute *attr;
+
+ /* Decode the type that this subroutine returns */
+ if (die->type)
+ {
+ return;
+ }
+ type = die_type (die, objfile);
+ ftype = lookup_function_type (type);
+
+ /* All functions in C++ have prototypes. */
+ attr = dwarf_attr (die, DW_AT_prototyped);
+ if ((attr && (DW_UNSND (attr) != 0))
+ || cu_language == language_cplus)
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+
+ if (die->has_children)
+ {
+ struct die_info *child_die;
+ int nparams = 0;
+ int iparams = 0;
+
+ /* Count the number of parameters.
+ FIXME: GDB currently ignores vararg functions, but knows about
+ vararg member functions. */
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_formal_parameter)
+ nparams++;
+ else if (child_die->tag == DW_TAG_unspecified_parameters)
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_VARARGS;
+ child_die = sibling_die (child_die);
+ }
+
+ /* Allocate storage for parameters and fill them in. */
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_formal_parameter)
+ {
+ /* Dwarf2 has no clean way to discern C++ static and non-static
+ member functions. G++ helps GDB by marking the first
+ parameter for non-static member functions (which is the
+ this pointer) as artificial. We pass this information
+ to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL. */
+ attr = dwarf_attr (child_die, DW_AT_artificial);
+ if (attr)
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
+ else
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+ TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile);
+ iparams++;
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ die->type = ftype;
+}
+
+static void
+read_typedef (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+
+ if (!die->type)
+ {
+ struct attribute *attr;
+ struct type *xtype;
+
+ xtype = die_type (die, objfile);
+
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
+ TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
+ TYPE_TARGET_TYPE (type) = xtype;
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ TYPE_NAME (type) = obsavestring (DW_STRING (attr),
+ strlen (DW_STRING (attr)),
+ &objfile->type_obstack);
+
+ die->type = type;
+ }
+}
+
+/* Find a representation of a given base type and install
+ it in the TYPE field of the die. */
+
+static void
+read_base_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct attribute *attr;
+ int encoding = 0, size = 0;
+
+ /* If we've already decoded this die, this is a no-op. */
+ if (die->type)
+ {
+ return;
+ }
+
+ attr = dwarf_attr (die, DW_AT_encoding);
+ if (attr)
+ {
+ encoding = DW_UNSND (attr);
+ }
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ size = DW_UNSND (attr);
+ }
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ enum type_code code = TYPE_CODE_INT;
+ int is_unsigned = 0;
+
+ switch (encoding)
+ {
+ case DW_ATE_address:
+ /* Turn DW_ATE_address into a void * pointer. */
+ code = TYPE_CODE_PTR;
+ is_unsigned = 1;
+ break;
+ case DW_ATE_boolean:
+ code = TYPE_CODE_BOOL;
+ is_unsigned = 1;
+ break;
+ case DW_ATE_complex_float:
+ code = TYPE_CODE_COMPLEX;
+ break;
+ case DW_ATE_float:
+ code = TYPE_CODE_FLT;
+ break;
+ case DW_ATE_signed:
+ case DW_ATE_signed_char:
+ break;
+ case DW_ATE_unsigned:
+ case DW_ATE_unsigned_char:
+ is_unsigned = 1;
+ break;
+ default:
+ complain (&dwarf2_unsupported_at_encoding,
+ dwarf_type_encoding_name (encoding));
+ break;
+ }
+ type = init_type (code, size, is_unsigned, DW_STRING (attr), objfile);
+ if (encoding == DW_ATE_address)
+ TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+ }
+ else
+ {
+ type = dwarf_base_type (encoding, size, objfile);
+ }
+ die->type = type;
+}
+
+/* Read a whole compilation unit into a linked list of dies. */
+
+struct die_info *
+read_comp_unit (info_ptr, abfd)
+ char *info_ptr;
+ bfd *abfd;
+{
+ struct die_info *first_die, *last_die, *die;
+ char *cur_ptr;
+ int nesting_level;
+
+ /* Reset die reference table, we are building a new one now. */
+ dwarf2_empty_die_ref_table ();
+
+ cur_ptr = info_ptr;
+ nesting_level = 0;
+ first_die = last_die = NULL;
+ do
+ {
+ cur_ptr = read_full_die (&die, abfd, cur_ptr);
+ if (die->has_children)
+ {
+ nesting_level++;
+ }
+ if (die->tag == 0)
+ {
+ nesting_level--;
+ }
+
+ die->next = NULL;
+
+ /* Enter die in reference hash table */
+ store_in_ref_table (die->offset, die);
+
+ if (!first_die)
+ {
+ first_die = last_die = die;
+ }
+ else
+ {
+ last_die->next = die;
+ last_die = die;
+ }
+ }
+ while (nesting_level > 0);
+ return first_die;
+}
+
+/* Free a linked list of dies. */
+
+static void
+free_die_list (dies)
+ struct die_info *dies;
+{
+ struct die_info *die, *next;
+
+ die = dies;
+ while (die)
+ {
+ next = die->next;
+ free (die->attrs);
+ free (die);
+ die = next;
+ }
+}
+
+/* Read the contents of the section at OFFSET and of size SIZE from the
+ object file specified by OBJFILE into the psymbol_obstack and return it. */
+
+static char *
+dwarf2_read_section (objfile, offset, size)
+ struct objfile *objfile;
+ file_ptr offset;
+ unsigned int size;
+{
+ bfd *abfd = objfile->obfd;
+ char *buf;
+
+ if (size == 0)
+ return NULL;
+
+ buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+ if ((bfd_seek (abfd, offset, SEEK_SET) != 0) ||
+ (bfd_read (buf, size, 1, abfd) != size))
+ {
+ buf = NULL;
+ error ("Dwarf Error: Can't read DWARF data from '%s'",
+ bfd_get_filename (abfd));
+ }
+ return buf;
+}
+
+/* In DWARF version 2, the description of the debugging information is
+ stored in a separate .debug_abbrev section. Before we read any
+ dies from a section we read in all abbreviations and install them
+ in a hash table. */
+
+static void
+dwarf2_read_abbrevs (abfd, offset)
+ bfd * abfd;
+ unsigned int offset;
+{
+ char *abbrev_ptr;
+ struct abbrev_info *cur_abbrev;
+ unsigned int abbrev_number, bytes_read, abbrev_name;
+ unsigned int abbrev_form, hash_number;
+
+ /* empty the table */
+ dwarf2_empty_abbrev_table (NULL);
+
+ abbrev_ptr = dwarf_abbrev_buffer + offset;
+ abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+
+ /* loop until we reach an abbrev number of 0 */
+ while (abbrev_number)
+ {
+ cur_abbrev = dwarf_alloc_abbrev ();
+
+ /* read in abbrev header */
+ cur_abbrev->number = abbrev_number;
+ cur_abbrev->tag = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
+ abbrev_ptr += 1;
+
+ /* now read in declarations */
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ while (abbrev_name)
+ {
+ if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
+ {
+ cur_abbrev->attrs = (struct attr_abbrev *)
+ xrealloc (cur_abbrev->attrs,
+ (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
+ * sizeof (struct attr_abbrev));
+ }
+ cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
+ cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ }
+
+ hash_number = abbrev_number % ABBREV_HASH_SIZE;
+ cur_abbrev->next = dwarf2_abbrevs[hash_number];
+ dwarf2_abbrevs[hash_number] = cur_abbrev;
+
+ /* Get next abbreviation.
+ Under Irix6 the abbreviations for a compilation unit are not
+ always properly terminated with an abbrev number of 0.
+ Exit loop if we encounter an abbreviation which we have
+ already read (which means we are about to read the abbreviations
+ for the next compile unit) or if the end of the abbreviation
+ table is reached. */
+ if ((unsigned int) (abbrev_ptr - dwarf_abbrev_buffer)
+ >= dwarf_abbrev_size)
+ break;
+ abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ if (dwarf2_lookup_abbrev (abbrev_number) != NULL)
+ break;
+ }
+}
+
+/* Empty the abbrev table for a new compilation unit. */
+
+/* ARGSUSED */
+static void
+dwarf2_empty_abbrev_table (ignore)
+ PTR ignore;
+{
+ int i;
+ struct abbrev_info *abbrev, *next;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; ++i)
+ {
+ next = NULL;
+ abbrev = dwarf2_abbrevs[i];
+ while (abbrev)
+ {
+ next = abbrev->next;
+ free (abbrev->attrs);
+ free (abbrev);
+ abbrev = next;
+ }
+ dwarf2_abbrevs[i] = NULL;
+ }
+}
+
+/* Lookup an abbrev_info structure in the abbrev hash table. */
+
+static struct abbrev_info *
+dwarf2_lookup_abbrev (number)
+ unsigned int number;
+{
+ unsigned int hash_number;
+ struct abbrev_info *abbrev;
+
+ hash_number = number % ABBREV_HASH_SIZE;
+ abbrev = dwarf2_abbrevs[hash_number];
+
+ while (abbrev)
+ {
+ if (abbrev->number == number)
+ return abbrev;
+ else
+ abbrev = abbrev->next;
+ }
+ return NULL;
+}
+
+/* Read a minimal amount of information into the minimal die structure. */
+
+static char *
+read_partial_die (part_die, abfd, info_ptr, has_pc_info)
+ struct partial_die_info *part_die;
+ bfd * abfd;
+ char *info_ptr;
+ int *has_pc_info;
+{
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ struct attribute attr;
+ struct attribute spec_attr;
+ int found_spec_attr = 0;
+ int has_low_pc_attr = 0;
+ int has_high_pc_attr = 0;
+
+ *part_die = zeroed_partial_die;
+ *has_pc_info = 0;
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ if (!abbrev_number)
+ return info_ptr;
+
+ abbrev = dwarf2_lookup_abbrev (abbrev_number);
+ if (!abbrev)
+ {
+ error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
+ }
+ part_die->offset = info_ptr - dwarf_info_buffer;
+ part_die->tag = abbrev->tag;
+ part_die->has_children = abbrev->has_children;
+ part_die->abbrev = abbrev_number;
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr);
+
+ /* Store the data if it is of an attribute we want to keep in a
+ partial symbol table. */
+ switch (attr.name)
+ {
+ case DW_AT_name:
+
+ /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */
+ if (part_die->name == NULL)
+ part_die->name = DW_STRING (&attr);
+ break;
+ case DW_AT_MIPS_linkage_name:
+ part_die->name = DW_STRING (&attr);
+ break;
+ case DW_AT_low_pc:
+ has_low_pc_attr = 1;
+ part_die->lowpc = DW_ADDR (&attr);
+ break;
+ case DW_AT_high_pc:
+ has_high_pc_attr = 1;
+ part_die->highpc = DW_ADDR (&attr);
+ break;
+ case DW_AT_location:
+ part_die->locdesc = DW_BLOCK (&attr);
+ break;
+ case DW_AT_language:
+ part_die->language = DW_UNSND (&attr);
+ break;
+ case DW_AT_external:
+ part_die->is_external = DW_UNSND (&attr);
+ break;
+ case DW_AT_declaration:
+ part_die->is_declaration = DW_UNSND (&attr);
+ break;
+ case DW_AT_type:
+ part_die->has_type = 1;
+ break;
+ case DW_AT_abstract_origin:
+ case DW_AT_specification:
+ found_spec_attr = 1;
+ spec_attr = attr;
+ break;
+ case DW_AT_sibling:
+ /* Ignore absolute siblings, they might point outside of
+ the current compile unit. */
+ if (attr.form == DW_FORM_ref_addr)
+ complain(&dwarf2_absolute_sibling_complaint);
+ else
+ part_die->sibling =
+ dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If we found a reference attribute and the die has no name, try
+ to find a name in the referred to die. */
+
+ if (found_spec_attr && part_die->name == NULL)
+ {
+ struct partial_die_info spec_die;
+ char *spec_ptr;
+ int dummy;
+
+ spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
+ read_partial_die (&spec_die, abfd, spec_ptr, &dummy);
+ if (spec_die.name)
+ {
+ part_die->name = spec_die.name;
+
+ /* Copy DW_AT_external attribute if it is set. */
+ if (spec_die.is_external)
+ part_die->is_external = spec_die.is_external;
+ }
+ }
+
+ /* When using the GNU linker, .gnu.linkonce. sections are used to
+ eliminate duplicate copies of functions and vtables and such.
+ The linker will arbitrarily choose one and discard the others.
+ The AT_*_pc values for such functions refer to local labels in
+ these sections. If the section from that file was discarded, the
+ labels are not in the output, so the relocs get a value of 0.
+ If this is a discarded function, mark the pc bounds as invalid,
+ so that GDB will ignore it. */
+ if (has_low_pc_attr && has_high_pc_attr
+ && part_die->lowpc < part_die->highpc
+ && (part_die->lowpc != 0
+ || (bfd_get_file_flags (abfd) & HAS_RELOC)))
+ *has_pc_info = 1;
+ return info_ptr;
+}
+
+/* Read the die from the .debug_info section buffer. And set diep to
+ point to a newly allocated die with its information. */
+
+static char *
+read_full_die (diep, abfd, info_ptr)
+ struct die_info **diep;
+ bfd *abfd;
+ char *info_ptr;
+{
+ unsigned int abbrev_number, bytes_read, i, offset;
+ struct abbrev_info *abbrev;
+ struct die_info *die;
+
+ offset = info_ptr - dwarf_info_buffer;
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ if (!abbrev_number)
+ {
+ die = dwarf_alloc_die ();
+ die->tag = 0;
+ die->abbrev = abbrev_number;
+ die->type = NULL;
+ *diep = die;
+ return info_ptr;
+ }
+
+ abbrev = dwarf2_lookup_abbrev (abbrev_number);
+ if (!abbrev)
+ {
+ error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
+ }
+ die = dwarf_alloc_die ();
+ die->offset = offset;
+ die->tag = abbrev->tag;
+ die->has_children = abbrev->has_children;
+ die->abbrev = abbrev_number;
+ die->type = NULL;
+
+ die->num_attrs = abbrev->num_attrs;
+ die->attrs = (struct attribute *)
+ xmalloc (die->num_attrs * sizeof (struct attribute));
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
+ abfd, info_ptr);
+ }
+
+ *diep = die;
+ return info_ptr;
+}
+
+/* Read an attribute described by an abbreviated attribute. */
+
+static char *
+read_attribute (attr, abbrev, abfd, info_ptr)
+ struct attribute *attr;
+ struct attr_abbrev *abbrev;
+ bfd *abfd;
+ char *info_ptr;
+{
+ unsigned int bytes_read;
+ struct dwarf_block *blk;
+
+ attr->name = abbrev->name;
+ attr->form = abbrev->form;
+ switch (abbrev->form)
+ {
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ DW_ADDR (attr) = read_address (abfd, info_ptr);
+ info_ptr += address_size;
+ break;
+ case DW_FORM_block2:
+ blk = dwarf_alloc_block ();
+ blk->size = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_block4:
+ blk = dwarf_alloc_block ();
+ blk->size = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_data2:
+ DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_data4:
+ DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_data8:
+ DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_string:
+ DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_block:
+ blk = dwarf_alloc_block ();
+ blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_block1:
+ blk = dwarf_alloc_block ();
+ blk->size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_data1:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_flag:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_sdata:
+ DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_udata:
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_ref1:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_ref2:
+ DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_ref4:
+ DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_ref_udata:
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_strp:
+ case DW_FORM_indirect:
+ default:
+ error ("Dwarf Error: Cannot handle %s in DWARF reader.",
+ dwarf_form_name (abbrev->form));
+ }
+ return info_ptr;
+}
+
+/* read dwarf information from a buffer */
+
+static unsigned int
+read_1_byte (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_8 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_1_signed_byte (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_signed_8 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_2_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_16 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_2_signed_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_4_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_32 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_4_signed_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_8_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_64 (abfd, (bfd_byte *) buf);
+}
+
+static CORE_ADDR
+read_address (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ CORE_ADDR retval = 0;
+
+ switch (address_size)
+ {
+ case 4:
+ retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+ break;
+ case 8:
+ retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+ break;
+ default:
+ /* *THE* alternative is 8, right? */
+ abort ();
+ }
+ /* If the address being read is larger than the address that is
+ applicable for the object file format then mask it down to the
+ correct size. Take care to avoid unnecessary shift or shift
+ overflow */
+ if (address_size > address_significant_size
+ && address_significant_size < sizeof (CORE_ADDR))
+ {
+ CORE_ADDR mask = ((CORE_ADDR) 0) - 1;
+ retval &= ~(mask << (address_significant_size * 8));
+ }
+ return retval;
+}
+
+static char *
+read_n_bytes (abfd, buf, size)
+ bfd * abfd;
+ char *buf;
+ unsigned int size;
+{
+ /* If the size of a host char is 8 bits, we can return a pointer
+ to the buffer, otherwise we have to copy the data to a buffer
+ allocated on the temporary obstack. */
+#if HOST_CHAR_BIT == 8
+ return buf;
+#else
+ char *ret;
+ unsigned int i;
+
+ ret = obstack_alloc (&dwarf2_tmp_obstack, size);
+ for (i = 0; i < size; ++i)
+ {
+ ret[i] = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf++;
+ }
+ return ret;
+#endif
+}
+
+static char *
+read_string (abfd, buf, bytes_read_ptr)
+ bfd *abfd;
+ char *buf;
+ unsigned int *bytes_read_ptr;
+{
+ /* If the size of a host char is 8 bits, we can return a pointer
+ to the string, otherwise we have to copy the string to a buffer
+ allocated on the temporary obstack. */
+#if HOST_CHAR_BIT == 8
+ if (*buf == '\0')
+ {
+ *bytes_read_ptr = 1;
+ return NULL;
+ }
+ *bytes_read_ptr = strlen (buf) + 1;
+ return buf;
+#else
+ int byte;
+ unsigned int i = 0;
+
+ while ((byte = bfd_get_8 (abfd, (bfd_byte *) buf)) != 0)
+ {
+ obstack_1grow (&dwarf2_tmp_obstack, byte);
+ i++;
+ buf++;
+ }
+ if (i == 0)
+ {
+ *bytes_read_ptr = 1;
+ return NULL;
+ }
+ obstack_1grow (&dwarf2_tmp_obstack, '\0');
+ *bytes_read_ptr = i + 1;
+ return obstack_finish (&dwarf2_tmp_obstack);
+#endif
+}
+
+static unsigned int
+read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
+ bfd *abfd;
+ char *buf;
+ unsigned int *bytes_read_ptr;
+{
+ unsigned int result, num_read;
+ int i, shift;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ num_read = 0;
+ i = 0;
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf++;
+ num_read++;
+ result |= ((byte & 127) << shift);
+ if ((byte & 128) == 0)
+ {
+ break;
+ }
+ shift += 7;
+ }
+ *bytes_read_ptr = num_read;
+ return result;
+}
+
+static int
+read_signed_leb128 (abfd, buf, bytes_read_ptr)
+ bfd *abfd;
+ char *buf;
+ unsigned int *bytes_read_ptr;
+{
+ int result;
+ int i, shift, size, num_read;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ size = 32;
+ num_read = 0;
+ i = 0;
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf++;
+ num_read++;
+ result |= ((byte & 127) << shift);
+ shift += 7;
+ if ((byte & 128) == 0)
+ {
+ break;
+ }
+ }
+ if ((shift < size) && (byte & 0x40))
+ {
+ result |= -(1 << shift);
+ }
+ *bytes_read_ptr = num_read;
+ return result;
+}
+
+static void
+set_cu_language (lang)
+ unsigned int lang;
+{
+ switch (lang)
+ {
+ case DW_LANG_C89:
+ case DW_LANG_C:
+ cu_language = language_c;
+ break;
+ case DW_LANG_C_plus_plus:
+ cu_language = language_cplus;
+ break;
+ case DW_LANG_Fortran77:
+ case DW_LANG_Fortran90:
+ cu_language = language_fortran;
+ break;
+ case DW_LANG_Mips_Assembler:
+ cu_language = language_asm;
+ break;
+ case DW_LANG_Ada83:
+ case DW_LANG_Cobol74:
+ case DW_LANG_Cobol85:
+ case DW_LANG_Pascal83:
+ case DW_LANG_Modula2:
+ default:
+ cu_language = language_unknown;
+ break;
+ }
+ cu_language_defn = language_def (cu_language);
+}
+
+/* Return the named attribute or NULL if not there. */
+
+static struct attribute *
+dwarf_attr (die, name)
+ struct die_info *die;
+ unsigned int name;
+{
+ unsigned int i;
+ struct attribute *spec = NULL;
+
+ for (i = 0; i < die->num_attrs; ++i)
+ {
+ if (die->attrs[i].name == name)
+ {
+ return &die->attrs[i];
+ }
+ if (die->attrs[i].name == DW_AT_specification
+ || die->attrs[i].name == DW_AT_abstract_origin)
+ spec = &die->attrs[i];
+ }
+ if (spec)
+ {
+ struct die_info *ref_die =
+ follow_die_ref (dwarf2_get_ref_die_offset (spec));
+
+ if (ref_die)
+ return dwarf_attr (ref_die, name);
+ }
+
+ return NULL;
+}
+
+/* Decode the line number information for the compilation unit whose
+ line number info is at OFFSET in the .debug_line section.
+ The compilation directory of the file is passed in COMP_DIR. */
+
+struct filenames
+{
+ unsigned int num_files;
+ struct fileinfo
+ {
+ char *name;
+ unsigned int dir;
+ unsigned int time;
+ unsigned int size;
+ }
+ *files;
+};
+
+struct directories
+{
+ unsigned int num_dirs;
+ char **dirs;
+};
+
+static void
+dwarf_decode_lines (offset, comp_dir, abfd)
+ unsigned int offset;
+ char *comp_dir;
+ bfd *abfd;
+{
+ char *line_ptr;
+ char *line_end;
+ struct line_head lh;
+ struct cleanup *back_to;
+ unsigned int i, bytes_read;
+ char *cur_file, *cur_dir;
+ unsigned char op_code, extended_op, adj_opcode;
+
+#define FILE_ALLOC_CHUNK 5
+#define DIR_ALLOC_CHUNK 5
+
+ struct filenames files;
+ struct directories dirs;
+
+ if (dwarf_line_buffer == NULL)
+ {
+ complain (&dwarf2_missing_line_number_section);
+ return;
+ }
+
+ files.num_files = 0;
+ files.files = NULL;
+
+ dirs.num_dirs = 0;
+ dirs.dirs = NULL;
+
+ line_ptr = dwarf_line_buffer + offset;
+
+ /* read in the prologue */
+ lh.total_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ line_end = line_ptr + lh.total_length;
+ lh.version = read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ lh.prologue_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.default_is_stmt = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.line_base = read_1_signed_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.line_range = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.opcode_base = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.standard_opcode_lengths = (unsigned char *)
+ xmalloc (lh.opcode_base * sizeof (unsigned char));
+ back_to = make_cleanup ((make_cleanup_func) free_current_contents,
+ &lh.standard_opcode_lengths);
+
+ lh.standard_opcode_lengths[0] = 1;
+ for (i = 1; i < lh.opcode_base; ++i)
+ {
+ lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+
+ /* Read directory table */
+ while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ if ((dirs.num_dirs % DIR_ALLOC_CHUNK) == 0)
+ {
+ dirs.dirs = (char **)
+ xrealloc (dirs.dirs,
+ (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
+ if (dirs.num_dirs == 0)
+ make_cleanup ((make_cleanup_func) free_current_contents, &dirs.dirs);
+ }
+ dirs.dirs[dirs.num_dirs++] = cur_dir;
+ }
+ line_ptr += bytes_read;
+
+ /* Read file name table */
+ while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
+ {
+ files.files = (struct fileinfo *)
+ xrealloc (files.files,
+ (files.num_files + FILE_ALLOC_CHUNK)
+ * sizeof (struct fileinfo));
+ if (files.num_files == 0)
+ make_cleanup ((make_cleanup_func) free_current_contents,
+ &files.files);
+ }
+ files.files[files.num_files].name = cur_file;
+ files.files[files.num_files].dir =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ files.files[files.num_files].time =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ files.files[files.num_files].size =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ files.num_files++;
+ }
+ line_ptr += bytes_read;
+
+ /* Read the statement sequences until there's nothing left. */
+ while (line_ptr < line_end)
+ {
+ /* state machine registers */
+ CORE_ADDR address = 0;
+ unsigned int file = 1;
+ unsigned int line = 1;
+ unsigned int column = 0;
+ int is_stmt = lh.default_is_stmt;
+ int basic_block = 0;
+ int end_sequence = 0;
+
+ /* Start a subfile for the current file of the state machine. */
+ if (files.num_files >= file)
+ {
+ /* The file and directory tables are 0 based, the references
+ are 1 based. */
+ dwarf2_start_subfile (files.files[file - 1].name,
+ (files.files[file - 1].dir
+ ? dirs.dirs[files.files[file - 1].dir - 1]
+ : comp_dir));
+ }
+
+ /* Decode the table. */
+ while (! end_sequence)
+ {
+ op_code = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ line_ptr += 1; /* ignore length */
+ extended_op = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ switch (extended_op)
+ {
+ case DW_LNE_end_sequence:
+ end_sequence = 1;
+ record_line (current_subfile, line, address);
+ break;
+ case DW_LNE_set_address:
+ address = read_address (abfd, line_ptr) + baseaddr;
+ line_ptr += address_size;
+ break;
+ case DW_LNE_define_file:
+ cur_file = read_string (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
+ {
+ files.files = (struct fileinfo *)
+ xrealloc (files.files,
+ (files.num_files + FILE_ALLOC_CHUNK)
+ * sizeof (struct fileinfo));
+ if (files.num_files == 0)
+ make_cleanup ((make_cleanup_func) free_current_contents,
+ &files.files);
+ }
+ files.files[files.num_files].name = cur_file;
+ files.files[files.num_files].dir =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ files.files[files.num_files].time =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ files.files[files.num_files].size =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ files.num_files++;
+ break;
+ default:
+ complain (&dwarf2_mangled_line_number_section);
+ goto done;
+ }
+ break;
+ case DW_LNS_copy:
+ record_line (current_subfile, line, address);
+ basic_block = 0;
+ break;
+ case DW_LNS_advance_pc:
+ address += lh.minimum_instruction_length
+ * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_advance_line:
+ line += read_signed_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_set_file:
+ /* The file and directory tables are 0 based, the references
+ are 1 based. */
+ file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ dwarf2_start_subfile
+ (files.files[file - 1].name,
+ (files.files[file - 1].dir
+ ? dirs.dirs[files.files[file - 1].dir - 1]
+ : comp_dir));
+ break;
+ case DW_LNS_set_column:
+ column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_negate_stmt:
+ is_stmt = (!is_stmt);
+ break;
+ case DW_LNS_set_basic_block:
+ basic_block = 1;
+ break;
+ case DW_LNS_const_add_pc:
+ address += (255 - lh.opcode_base) / lh.line_range;
+ break;
+ case DW_LNS_fixed_advance_pc:
+ address += read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ break;
+ default: /* special operand */
+ adj_opcode = op_code - lh.opcode_base;
+ address += (adj_opcode / lh.line_range)
+ * lh.minimum_instruction_length;
+ line += lh.line_base + (adj_opcode % lh.line_range);
+ /* append row to matrix using current values */
+ record_line (current_subfile, line, address);
+ basic_block = 1;
+ }
+ }
+ }
+done:
+ do_cleanups (back_to);
+}
+
+/* Start a subfile for DWARF. FILENAME is the name of the file and
+ DIRNAME the name of the source directory which contains FILENAME
+ or NULL if not known.
+ This routine tries to keep line numbers from identical absolute and
+ relative file names in a common subfile.
+
+ Using the `list' example from the GDB testsuite, which resides in
+ /srcdir and compiling it with Irix6.2 cc in /compdir using a filename
+ of /srcdir/list0.c yields the following debugging information for list0.c:
+
+ DW_AT_name: /srcdir/list0.c
+ DW_AT_comp_dir: /compdir
+ files.files[0].name: list0.h
+ files.files[0].dir: /srcdir
+ files.files[1].name: list0.c
+ files.files[1].dir: /srcdir
+
+ The line number information for list0.c has to end up in a single
+ subfile, so that `break /srcdir/list0.c:1' works as expected. */
+
+static void
+dwarf2_start_subfile (filename, dirname)
+ char *filename;
+ char *dirname;
+{
+ /* If the filename isn't absolute, try to match an existing subfile
+ with the full pathname. */
+
+ if (*filename != '/' && dirname != NULL)
+ {
+ struct subfile *subfile;
+ char *fullname = concat (dirname, "/", filename, NULL);
+
+ for (subfile = subfiles; subfile; subfile = subfile->next)
+ {
+ if (STREQ (subfile->name, fullname))
+ {
+ current_subfile = subfile;
+ free (fullname);
+ return;
+ }
+ }
+ free (fullname);
+ }
+ start_subfile (filename, dirname);
+}
+
+/* Given a pointer to a DWARF information entry, figure out if we need
+ to make a symbol table entry for it, and if so, create a new entry
+ and return a pointer to it.
+ If TYPE is NULL, determine symbol type from the die, otherwise
+ used the passed type.
+ */
+
+static struct symbol *
+new_symbol (die, type, objfile)
+ struct die_info *die;
+ struct type *type;
+ struct objfile *objfile;
+{
+ struct symbol *sym = NULL;
+ char *name;
+ struct attribute *attr = NULL;
+ struct attribute *attr2 = NULL;
+ CORE_ADDR addr;
+
+ name = dwarf2_linkage_name (die);
+ if (name)
+ {
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ OBJSTAT (objfile, n_syms++);
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+
+ /* Default assumptions.
+ Use the passed type or decode it from the die. */
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ if (type != NULL)
+ SYMBOL_TYPE (sym) = type;
+ else
+ SYMBOL_TYPE (sym) = die_type (die, objfile);
+ attr = dwarf_attr (die, DW_AT_decl_line);
+ if (attr)
+ {
+ SYMBOL_LINE (sym) = DW_UNSND (attr);
+ }
+
+ /* If this symbol is from a C++ compilation, then attempt to
+ cache the demangled form for future reference. This is a
+ typical time versus space tradeoff, that was decided in favor
+ of time because it sped up C++ symbol lookups by a factor of
+ about 20. */
+
+ SYMBOL_LANGUAGE (sym) = cu_language;
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ switch (die->tag)
+ {
+ case DW_TAG_label:
+ attr = dwarf_attr (die, DW_AT_low_pc);
+ if (attr)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
+ }
+ SYMBOL_CLASS (sym) = LOC_LABEL;
+ break;
+ case DW_TAG_subprogram:
+ /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+ finish_block. */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0))
+ {
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ else
+ {
+ add_symbol_to_list (sym, list_in_scope);
+ }
+ break;
+ case DW_TAG_variable:
+ /* Compilation with minimal debug info may result in variables
+ with missing type entries. Change the misleading `void' type
+ to something sensible. */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+ SYMBOL_TYPE (sym) = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<variable, no debug info>",
+ objfile);
+ attr = dwarf_attr (die, DW_AT_const_value);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, objfile);
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0))
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ }
+ attr = dwarf_attr (die, DW_AT_location);
+ if (attr)
+ {
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0))
+ {
+ SYMBOL_VALUE_ADDRESS (sym) =
+ decode_locdesc (DW_BLOCK (attr), objfile);
+ add_symbol_to_list (sym, &global_symbols);
+
+ /* In shared libraries the address of the variable
+ in the location descriptor might still be relocatable,
+ so its value could be zero.
+ Enter the symbol as a LOC_UNRESOLVED symbol, if its
+ value is zero, the address of the variable will then
+ be determined from the minimal symbol table whenever
+ the variable is referenced. */
+ if (SYMBOL_VALUE_ADDRESS (sym))
+ {
+ SYMBOL_VALUE_ADDRESS (sym) += baseaddr;
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ }
+ else
+ SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+ }
+ else
+ {
+ SYMBOL_VALUE (sym) = addr =
+ decode_locdesc (DW_BLOCK (attr), objfile);
+ add_symbol_to_list (sym, list_in_scope);
+ if (optimized_out)
+ {
+ SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ }
+ else if (isreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ }
+ else if (offreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG;
+ SYMBOL_BASEREG (sym) = basereg;
+ }
+ else if (islocal)
+ {
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ }
+ else
+ {
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE_ADDRESS (sym) = addr + baseaddr;
+ }
+ }
+ }
+ else
+ {
+ /* We do not know the address of this symbol.
+ If it is an external symbol and we have type information
+ for it, enter the symbol as a LOC_UNRESOLVED symbol.
+ The address of the variable will then be determined from
+ the minimal symbol table whenever the variable is
+ referenced. */
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0)
+ && dwarf_attr (die, DW_AT_type) != NULL)
+ {
+ SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ }
+ break;
+ case DW_TAG_formal_parameter:
+ attr = dwarf_attr (die, DW_AT_location);
+ if (attr)
+ {
+ SYMBOL_VALUE (sym) = decode_locdesc (DW_BLOCK (attr), objfile);
+ if (isreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ }
+ else if (offreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+ SYMBOL_BASEREG (sym) = basereg;
+ }
+ else
+ {
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ }
+ }
+ attr = dwarf_attr (die, DW_AT_const_value);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, objfile);
+ }
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ case DW_TAG_unspecified_parameters:
+ /* From varargs functions; gdb doesn't seem to have any
+ interest in this information, so just ignore it for now.
+ (FIXME?) */
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+
+ /* The semantics of C++ state that "struct foo { ... }" also
+ defines a typedef for "foo". Synthesize a typedef symbol so
+ that "ptype foo" works as expected. */
+ if (cu_language == language_cplus)
+ {
+ struct symbol *typedef_sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ *typedef_sym = *sym;
+ SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+ TYPE_NAME (SYMBOL_TYPE (sym)) =
+ obsavestring (SYMBOL_NAME (sym),
+ strlen (SYMBOL_NAME (sym)),
+ &objfile->type_obstack);
+ add_symbol_to_list (typedef_sym, list_in_scope);
+ }
+ break;
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ case DW_TAG_enumerator:
+ attr = dwarf_attr (die, DW_AT_const_value);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, objfile);
+ }
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ default:
+ /* Not a tag we recognize. Hopefully we aren't processing
+ trash data, but since we must specifically ignore things
+ we don't recognize, there is nothing else we should do at
+ this point. */
+ complain (&dwarf2_unsupported_tag, dwarf_tag_name (die->tag));
+ break;
+ }
+ }
+ return (sym);
+}
+
+/* Copy constant value from an attribute to a symbol. */
+
+static void
+dwarf2_const_value (attr, sym, objfile)
+ struct attribute *attr;
+ struct symbol *sym;
+ struct objfile *objfile;
+{
+ struct dwarf_block *blk;
+
+ switch (attr->form)
+ {
+ case DW_FORM_addr:
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != (unsigned int) address_size)
+ complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+ address_size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+ SYMBOL_VALUE_BYTES (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, address_size);
+ store_address (SYMBOL_VALUE_BYTES (sym), address_size, DW_ADDR (attr));
+ SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ break;
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_block:
+ blk = DW_BLOCK (attr);
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
+ complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+ blk->size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+ SYMBOL_VALUE_BYTES (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, blk->size);
+ memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
+ SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ break;
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_data1:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ SYMBOL_VALUE (sym) = DW_UNSND (attr);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ break;
+ default:
+ complain (&dwarf2_unsupported_const_value_attr,
+ dwarf_form_name (attr->form));
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ break;
+ }
+}
+
+/* Return the type of the die in question using its DW_AT_type attribute. */
+
+static struct type *
+die_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct attribute *type_attr;
+ struct die_info *type_die;
+ unsigned int ref;
+
+ type_attr = dwarf_attr (die, DW_AT_type);
+ if (!type_attr)
+ {
+ /* A missing DW_AT_type represents a void type. */
+ return dwarf2_fundamental_type (objfile, FT_VOID);
+ }
+ else
+ {
+ ref = dwarf2_get_ref_die_offset (type_attr);
+ type_die = follow_die_ref (ref);
+ if (!type_die)
+ {
+ error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+ return NULL;
+ }
+ }
+ type = tag_type_to_type (type_die, objfile);
+ if (!type)
+ {
+ dump_die (type_die);
+ error ("Dwarf Error: Problem turning type die at offset into gdb type.");
+ }
+ return type;
+}
+
+/* Return the containing type of the die in question using its
+ DW_AT_containing_type attribute. */
+
+static struct type *
+die_containing_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ struct type *type = NULL;
+ struct attribute *type_attr;
+ struct die_info *type_die = NULL;
+ unsigned int ref;
+
+ type_attr = dwarf_attr (die, DW_AT_containing_type);
+ if (type_attr)
+ {
+ ref = dwarf2_get_ref_die_offset (type_attr);
+ type_die = follow_die_ref (ref);
+ if (!type_die)
+ {
+ error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+ return NULL;
+ }
+ type = tag_type_to_type (type_die, objfile);
+ }
+ if (!type)
+ {
+ if (type_die)
+ dump_die (type_die);
+ error ("Dwarf Error: Problem turning containing type into gdb type.");
+ }
+ return type;
+}
+
+#if 0
+static struct type *
+type_at_offset (offset, objfile)
+ unsigned int offset;
+ struct objfile *objfile;
+{
+ struct die_info *die;
+ struct type *type;
+
+ die = follow_die_ref (offset);
+ if (!die)
+ {
+ error ("Dwarf Error: Cannot find type referent at offset %d.", offset);
+ return NULL;
+ }
+ type = tag_type_to_type (die, objfile);
+ return type;
+}
+#endif
+
+static struct type *
+tag_type_to_type (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ if (die->type)
+ {
+ return die->type;
+ }
+ else
+ {
+ read_type_die (die, objfile);
+ if (!die->type)
+ {
+ dump_die (die);
+ error ("Dwarf Error: Cannot find type of die.");
+ }
+ return die->type;
+ }
+}
+
+static void
+read_type_die (die, objfile)
+ struct die_info *die;
+ struct objfile *objfile;
+{
+ switch (die->tag)
+ {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ read_structure_scope (die, objfile);
+ break;
+ case DW_TAG_enumeration_type:
+ read_enumeration (die, objfile);
+ break;
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
+ read_subroutine_type (die, objfile);
+ break;
+ case DW_TAG_array_type:
+ read_array_type (die, objfile);
+ break;
+ case DW_TAG_pointer_type:
+ read_tag_pointer_type (die, objfile);
+ break;
+ case DW_TAG_ptr_to_member_type:
+ read_tag_ptr_to_member_type (die, objfile);
+ break;
+ case DW_TAG_reference_type:
+ read_tag_reference_type (die, objfile);
+ break;
+ case DW_TAG_const_type:
+ read_tag_const_type (die, objfile);
+ break;
+ case DW_TAG_volatile_type:
+ read_tag_volatile_type (die, objfile);
+ break;
+ case DW_TAG_string_type:
+ read_tag_string_type (die, objfile);
+ break;
+ case DW_TAG_typedef:
+ read_typedef (die, objfile);
+ break;
+ case DW_TAG_base_type:
+ read_base_type (die, objfile);
+ break;
+ default:
+ complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
+ break;
+ }
+}
+
+static struct type *
+dwarf_base_type (encoding, size, objfile)
+ int encoding;
+ int size;
+ struct objfile *objfile;
+{
+ /* FIXME - this should not produce a new (struct type *)
+ every time. It should cache base types. */
+ struct type *type;
+ switch (encoding)
+ {
+ case DW_ATE_address:
+ type = dwarf2_fundamental_type (objfile, FT_VOID);
+ return type;
+ case DW_ATE_boolean:
+ type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+ return type;
+ case DW_ATE_complex_float:
+ if (size == 16)
+ {
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+ }
+ else
+ {
+ type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+ }
+ return type;
+ case DW_ATE_float:
+ if (size == 8)
+ {
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+ }
+ else
+ {
+ type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+ }
+ return type;
+ case DW_ATE_signed:
+ switch (size)
+ {
+ case 1:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+ break;
+ case 2:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+ break;
+ default:
+ case 4:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+ break;
+ }
+ return type;
+ case DW_ATE_signed_char:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+ return type;
+ case DW_ATE_unsigned:
+ switch (size)
+ {
+ case 1:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+ break;
+ case 2:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+ break;
+ default:
+ case 4:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+ break;
+ }
+ return type;
+ case DW_ATE_unsigned_char:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+ return type;
+ default:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+ return type;
+ }
+}
+
+#if 0
+struct die_info *
+copy_die (old_die)
+ struct die_info *old_die;
+{
+ struct die_info *new_die;
+ int i, num_attrs;
+
+ new_die = (struct die_info *) xmalloc (sizeof (struct die_info));
+ memset (new_die, 0, sizeof (struct die_info));
+
+ new_die->tag = old_die->tag;
+ new_die->has_children = old_die->has_children;
+ new_die->abbrev = old_die->abbrev;
+ new_die->offset = old_die->offset;
+ new_die->type = NULL;
+
+ num_attrs = old_die->num_attrs;
+ new_die->num_attrs = num_attrs;
+ new_die->attrs = (struct attribute *)
+ xmalloc (num_attrs * sizeof (struct attribute));
+
+ for (i = 0; i < old_die->num_attrs; ++i)
+ {
+ new_die->attrs[i].name = old_die->attrs[i].name;
+ new_die->attrs[i].form = old_die->attrs[i].form;
+ new_die->attrs[i].u.addr = old_die->attrs[i].u.addr;
+ }
+
+ new_die->next = NULL;
+ return new_die;
+}
+#endif
+
+/* Return sibling of die, NULL if no sibling. */
+
+struct die_info *
+sibling_die (die)
+ struct die_info *die;
+{
+ int nesting_level = 0;
+
+ if (!die->has_children)
+ {
+ if (die->next && (die->next->tag == 0))
+ {
+ return NULL;
+ }
+ else
+ {
+ return die->next;
+ }
+ }
+ else
+ {
+ do
+ {
+ if (die->has_children)
+ {
+ nesting_level++;
+ }
+ if (die->tag == 0)
+ {
+ nesting_level--;
+ }
+ die = die->next;
+ }
+ while (nesting_level);
+ if (die && (die->tag == 0))
+ {
+ return NULL;
+ }
+ else
+ {
+ return die;
+ }
+ }
+}
+
+/* Get linkage name of a die, return NULL if not found. */
+
+static char *
+dwarf2_linkage_name (die)
+ struct die_info *die;
+{
+ struct attribute *attr;
+
+ attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+ if (attr && DW_STRING (attr))
+ return DW_STRING (attr);
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ return DW_STRING (attr);
+ return NULL;
+}
+
+/* Convert a DIE tag into its string name. */
+
+static char *
+dwarf_tag_name (tag)
+ register unsigned tag;
+{
+ switch (tag)
+ {
+ case DW_TAG_padding:
+ return "DW_TAG_padding";
+ case DW_TAG_array_type:
+ return "DW_TAG_array_type";
+ case DW_TAG_class_type:
+ return "DW_TAG_class_type";
+ case DW_TAG_entry_point:
+ return "DW_TAG_entry_point";
+ case DW_TAG_enumeration_type:
+ return "DW_TAG_enumeration_type";
+ case DW_TAG_formal_parameter:
+ return "DW_TAG_formal_parameter";
+ case DW_TAG_imported_declaration:
+ return "DW_TAG_imported_declaration";
+ case DW_TAG_label:
+ return "DW_TAG_label";
+ case DW_TAG_lexical_block:
+ return "DW_TAG_lexical_block";
+ case DW_TAG_member:
+ return "DW_TAG_member";
+ case DW_TAG_pointer_type:
+ return "DW_TAG_pointer_type";
+ case DW_TAG_reference_type:
+ return "DW_TAG_reference_type";
+ case DW_TAG_compile_unit:
+ return "DW_TAG_compile_unit";
+ case DW_TAG_string_type:
+ return "DW_TAG_string_type";
+ case DW_TAG_structure_type:
+ return "DW_TAG_structure_type";
+ case DW_TAG_subroutine_type:
+ return "DW_TAG_subroutine_type";
+ case DW_TAG_typedef:
+ return "DW_TAG_typedef";
+ case DW_TAG_union_type:
+ return "DW_TAG_union_type";
+ case DW_TAG_unspecified_parameters:
+ return "DW_TAG_unspecified_parameters";
+ case DW_TAG_variant:
+ return "DW_TAG_variant";
+ case DW_TAG_common_block:
+ return "DW_TAG_common_block";
+ case DW_TAG_common_inclusion:
+ return "DW_TAG_common_inclusion";
+ case DW_TAG_inheritance:
+ return "DW_TAG_inheritance";
+ case DW_TAG_inlined_subroutine:
+ return "DW_TAG_inlined_subroutine";
+ case DW_TAG_module:
+ return "DW_TAG_module";
+ case DW_TAG_ptr_to_member_type:
+ return "DW_TAG_ptr_to_member_type";
+ case DW_TAG_set_type:
+ return "DW_TAG_set_type";
+ case DW_TAG_subrange_type:
+ return "DW_TAG_subrange_type";
+ case DW_TAG_with_stmt:
+ return "DW_TAG_with_stmt";
+ case DW_TAG_access_declaration:
+ return "DW_TAG_access_declaration";
+ case DW_TAG_base_type:
+ return "DW_TAG_base_type";
+ case DW_TAG_catch_block:
+ return "DW_TAG_catch_block";
+ case DW_TAG_const_type:
+ return "DW_TAG_const_type";
+ case DW_TAG_constant:
+ return "DW_TAG_constant";
+ case DW_TAG_enumerator:
+ return "DW_TAG_enumerator";
+ case DW_TAG_file_type:
+ return "DW_TAG_file_type";
+ case DW_TAG_friend:
+ return "DW_TAG_friend";
+ case DW_TAG_namelist:
+ return "DW_TAG_namelist";
+ case DW_TAG_namelist_item:
+ return "DW_TAG_namelist_item";
+ case DW_TAG_packed_type:
+ return "DW_TAG_packed_type";
+ case DW_TAG_subprogram:
+ return "DW_TAG_subprogram";
+ case DW_TAG_template_type_param:
+ return "DW_TAG_template_type_param";
+ case DW_TAG_template_value_param:
+ return "DW_TAG_template_value_param";
+ case DW_TAG_thrown_type:
+ return "DW_TAG_thrown_type";
+ case DW_TAG_try_block:
+ return "DW_TAG_try_block";
+ case DW_TAG_variant_part:
+ return "DW_TAG_variant_part";
+ case DW_TAG_variable:
+ return "DW_TAG_variable";
+ case DW_TAG_volatile_type:
+ return "DW_TAG_volatile_type";
+ case DW_TAG_MIPS_loop:
+ return "DW_TAG_MIPS_loop";
+ case DW_TAG_format_label:
+ return "DW_TAG_format_label";
+ case DW_TAG_function_template:
+ return "DW_TAG_function_template";
+ case DW_TAG_class_template:
+ return "DW_TAG_class_template";
+ default:
+ return "DW_TAG_<unknown>";
+ }
+}
+
+/* Convert a DWARF attribute code into its string name. */
+
+static char *
+dwarf_attr_name (attr)
+ register unsigned attr;
+{
+ switch (attr)
+ {
+ case DW_AT_sibling:
+ return "DW_AT_sibling";
+ case DW_AT_location:
+ return "DW_AT_location";
+ case DW_AT_name:
+ return "DW_AT_name";
+ case DW_AT_ordering:
+ return "DW_AT_ordering";
+ case DW_AT_subscr_data:
+ return "DW_AT_subscr_data";
+ case DW_AT_byte_size:
+ return "DW_AT_byte_size";
+ case DW_AT_bit_offset:
+ return "DW_AT_bit_offset";
+ case DW_AT_bit_size:
+ return "DW_AT_bit_size";
+ case DW_AT_element_list:
+ return "DW_AT_element_list";
+ case DW_AT_stmt_list:
+ return "DW_AT_stmt_list";
+ case DW_AT_low_pc:
+ return "DW_AT_low_pc";
+ case DW_AT_high_pc:
+ return "DW_AT_high_pc";
+ case DW_AT_language:
+ return "DW_AT_language";
+ case DW_AT_member:
+ return "DW_AT_member";
+ case DW_AT_discr:
+ return "DW_AT_discr";
+ case DW_AT_discr_value:
+ return "DW_AT_discr_value";
+ case DW_AT_visibility:
+ return "DW_AT_visibility";
+ case DW_AT_import:
+ return "DW_AT_import";
+ case DW_AT_string_length:
+ return "DW_AT_string_length";
+ case DW_AT_common_reference:
+ return "DW_AT_common_reference";
+ case DW_AT_comp_dir:
+ return "DW_AT_comp_dir";
+ case DW_AT_const_value:
+ return "DW_AT_const_value";
+ case DW_AT_containing_type:
+ return "DW_AT_containing_type";
+ case DW_AT_default_value:
+ return "DW_AT_default_value";
+ case DW_AT_inline:
+ return "DW_AT_inline";
+ case DW_AT_is_optional:
+ return "DW_AT_is_optional";
+ case DW_AT_lower_bound:
+ return "DW_AT_lower_bound";
+ case DW_AT_producer:
+ return "DW_AT_producer";
+ case DW_AT_prototyped:
+ return "DW_AT_prototyped";
+ case DW_AT_return_addr:
+ return "DW_AT_return_addr";
+ case DW_AT_start_scope:
+ return "DW_AT_start_scope";
+ case DW_AT_stride_size:
+ return "DW_AT_stride_size";
+ case DW_AT_upper_bound:
+ return "DW_AT_upper_bound";
+ case DW_AT_abstract_origin:
+ return "DW_AT_abstract_origin";
+ case DW_AT_accessibility:
+ return "DW_AT_accessibility";
+ case DW_AT_address_class:
+ return "DW_AT_address_class";
+ case DW_AT_artificial:
+ return "DW_AT_artificial";
+ case DW_AT_base_types:
+ return "DW_AT_base_types";
+ case DW_AT_calling_convention:
+ return "DW_AT_calling_convention";
+ case DW_AT_count:
+ return "DW_AT_count";
+ case DW_AT_data_member_location:
+ return "DW_AT_data_member_location";
+ case DW_AT_decl_column:
+ return "DW_AT_decl_column";
+ case DW_AT_decl_file:
+ return "DW_AT_decl_file";
+ case DW_AT_decl_line:
+ return "DW_AT_decl_line";
+ case DW_AT_declaration:
+ return "DW_AT_declaration";
+ case DW_AT_discr_list:
+ return "DW_AT_discr_list";
+ case DW_AT_encoding:
+ return "DW_AT_encoding";
+ case DW_AT_external:
+ return "DW_AT_external";
+ case DW_AT_frame_base:
+ return "DW_AT_frame_base";
+ case DW_AT_friend:
+ return "DW_AT_friend";
+ case DW_AT_identifier_case:
+ return "DW_AT_identifier_case";
+ case DW_AT_macro_info:
+ return "DW_AT_macro_info";
+ case DW_AT_namelist_items:
+ return "DW_AT_namelist_items";
+ case DW_AT_priority:
+ return "DW_AT_priority";
+ case DW_AT_segment:
+ return "DW_AT_segment";
+ case DW_AT_specification:
+ return "DW_AT_specification";
+ case DW_AT_static_link:
+ return "DW_AT_static_link";
+ case DW_AT_type:
+ return "DW_AT_type";
+ case DW_AT_use_location:
+ return "DW_AT_use_location";
+ case DW_AT_variable_parameter:
+ return "DW_AT_variable_parameter";
+ case DW_AT_virtuality:
+ return "DW_AT_virtuality";
+ case DW_AT_vtable_elem_location:
+ return "DW_AT_vtable_elem_location";
+
+#ifdef MIPS
+ case DW_AT_MIPS_fde:
+ return "DW_AT_MIPS_fde";
+ case DW_AT_MIPS_loop_begin:
+ return "DW_AT_MIPS_loop_begin";
+ case DW_AT_MIPS_tail_loop_begin:
+ return "DW_AT_MIPS_tail_loop_begin";
+ case DW_AT_MIPS_epilog_begin:
+ return "DW_AT_MIPS_epilog_begin";
+ case DW_AT_MIPS_loop_unroll_factor:
+ return "DW_AT_MIPS_loop_unroll_factor";
+ case DW_AT_MIPS_software_pipeline_depth:
+ return "DW_AT_MIPS_software_pipeline_depth";
+ case DW_AT_MIPS_linkage_name:
+ return "DW_AT_MIPS_linkage_name";
+#endif
+
+ case DW_AT_sf_names:
+ return "DW_AT_sf_names";
+ case DW_AT_src_info:
+ return "DW_AT_src_info";
+ case DW_AT_mac_info:
+ return "DW_AT_mac_info";
+ case DW_AT_src_coords:
+ return "DW_AT_src_coords";
+ case DW_AT_body_begin:
+ return "DW_AT_body_begin";
+ case DW_AT_body_end:
+ return "DW_AT_body_end";
+ default:
+ return "DW_AT_<unknown>";
+ }
+}
+
+/* Convert a DWARF value form code into its string name. */
+
+static char *
+dwarf_form_name (form)
+ register unsigned form;
+{
+ switch (form)
+ {
+ case DW_FORM_addr:
+ return "DW_FORM_addr";
+ case DW_FORM_block2:
+ return "DW_FORM_block2";
+ case DW_FORM_block4:
+ return "DW_FORM_block4";
+ case DW_FORM_data2:
+ return "DW_FORM_data2";
+ case DW_FORM_data4:
+ return "DW_FORM_data4";
+ case DW_FORM_data8:
+ return "DW_FORM_data8";
+ case DW_FORM_string:
+ return "DW_FORM_string";
+ case DW_FORM_block:
+ return "DW_FORM_block";
+ case DW_FORM_block1:
+ return "DW_FORM_block1";
+ case DW_FORM_data1:
+ return "DW_FORM_data1";
+ case DW_FORM_flag:
+ return "DW_FORM_flag";
+ case DW_FORM_sdata:
+ return "DW_FORM_sdata";
+ case DW_FORM_strp:
+ return "DW_FORM_strp";
+ case DW_FORM_udata:
+ return "DW_FORM_udata";
+ case DW_FORM_ref_addr:
+ return "DW_FORM_ref_addr";
+ case DW_FORM_ref1:
+ return "DW_FORM_ref1";
+ case DW_FORM_ref2:
+ return "DW_FORM_ref2";
+ case DW_FORM_ref4:
+ return "DW_FORM_ref4";
+ case DW_FORM_ref8:
+ return "DW_FORM_ref8";
+ case DW_FORM_ref_udata:
+ return "DW_FORM_ref_udata";
+ case DW_FORM_indirect:
+ return "DW_FORM_indirect";
+ default:
+ return "DW_FORM_<unknown>";
+ }
+}
+
+/* Convert a DWARF stack opcode into its string name. */
+
+static char *
+dwarf_stack_op_name (op)
+ register unsigned op;
+{
+ switch (op)
+ {
+ case DW_OP_addr:
+ return "DW_OP_addr";
+ case DW_OP_deref:
+ return "DW_OP_deref";
+ case DW_OP_const1u:
+ return "DW_OP_const1u";
+ case DW_OP_const1s:
+ return "DW_OP_const1s";
+ case DW_OP_const2u:
+ return "DW_OP_const2u";
+ case DW_OP_const2s:
+ return "DW_OP_const2s";
+ case DW_OP_const4u:
+ return "DW_OP_const4u";
+ case DW_OP_const4s:
+ return "DW_OP_const4s";
+ case DW_OP_const8u:
+ return "DW_OP_const8u";
+ case DW_OP_const8s:
+ return "DW_OP_const8s";
+ case DW_OP_constu:
+ return "DW_OP_constu";
+ case DW_OP_consts:
+ return "DW_OP_consts";
+ case DW_OP_dup:
+ return "DW_OP_dup";
+ case DW_OP_drop:
+ return "DW_OP_drop";
+ case DW_OP_over:
+ return "DW_OP_over";
+ case DW_OP_pick:
+ return "DW_OP_pick";
+ case DW_OP_swap:
+ return "DW_OP_swap";
+ case DW_OP_rot:
+ return "DW_OP_rot";
+ case DW_OP_xderef:
+ return "DW_OP_xderef";
+ case DW_OP_abs:
+ return "DW_OP_abs";
+ case DW_OP_and:
+ return "DW_OP_and";
+ case DW_OP_div:
+ return "DW_OP_div";
+ case DW_OP_minus:
+ return "DW_OP_minus";
+ case DW_OP_mod:
+ return "DW_OP_mod";
+ case DW_OP_mul:
+ return "DW_OP_mul";
+ case DW_OP_neg:
+ return "DW_OP_neg";
+ case DW_OP_not:
+ return "DW_OP_not";
+ case DW_OP_or:
+ return "DW_OP_or";
+ case DW_OP_plus:
+ return "DW_OP_plus";
+ case DW_OP_plus_uconst:
+ return "DW_OP_plus_uconst";
+ case DW_OP_shl:
+ return "DW_OP_shl";
+ case DW_OP_shr:
+ return "DW_OP_shr";
+ case DW_OP_shra:
+ return "DW_OP_shra";
+ case DW_OP_xor:
+ return "DW_OP_xor";
+ case DW_OP_bra:
+ return "DW_OP_bra";
+ case DW_OP_eq:
+ return "DW_OP_eq";
+ case DW_OP_ge:
+ return "DW_OP_ge";
+ case DW_OP_gt:
+ return "DW_OP_gt";
+ case DW_OP_le:
+ return "DW_OP_le";
+ case DW_OP_lt:
+ return "DW_OP_lt";
+ case DW_OP_ne:
+ return "DW_OP_ne";
+ case DW_OP_skip:
+ return "DW_OP_skip";
+ case DW_OP_lit0:
+ return "DW_OP_lit0";
+ case DW_OP_lit1:
+ return "DW_OP_lit1";
+ case DW_OP_lit2:
+ return "DW_OP_lit2";
+ case DW_OP_lit3:
+ return "DW_OP_lit3";
+ case DW_OP_lit4:
+ return "DW_OP_lit4";
+ case DW_OP_lit5:
+ return "DW_OP_lit5";
+ case DW_OP_lit6:
+ return "DW_OP_lit6";
+ case DW_OP_lit7:
+ return "DW_OP_lit7";
+ case DW_OP_lit8:
+ return "DW_OP_lit8";
+ case DW_OP_lit9:
+ return "DW_OP_lit9";
+ case DW_OP_lit10:
+ return "DW_OP_lit10";
+ case DW_OP_lit11:
+ return "DW_OP_lit11";
+ case DW_OP_lit12:
+ return "DW_OP_lit12";
+ case DW_OP_lit13:
+ return "DW_OP_lit13";
+ case DW_OP_lit14:
+ return "DW_OP_lit14";
+ case DW_OP_lit15:
+ return "DW_OP_lit15";
+ case DW_OP_lit16:
+ return "DW_OP_lit16";
+ case DW_OP_lit17:
+ return "DW_OP_lit17";
+ case DW_OP_lit18:
+ return "DW_OP_lit18";
+ case DW_OP_lit19:
+ return "DW_OP_lit19";
+ case DW_OP_lit20:
+ return "DW_OP_lit20";
+ case DW_OP_lit21:
+ return "DW_OP_lit21";
+ case DW_OP_lit22:
+ return "DW_OP_lit22";
+ case DW_OP_lit23:
+ return "DW_OP_lit23";
+ case DW_OP_lit24:
+ return "DW_OP_lit24";
+ case DW_OP_lit25:
+ return "DW_OP_lit25";
+ case DW_OP_lit26:
+ return "DW_OP_lit26";
+ case DW_OP_lit27:
+ return "DW_OP_lit27";
+ case DW_OP_lit28:
+ return "DW_OP_lit28";
+ case DW_OP_lit29:
+ return "DW_OP_lit29";
+ case DW_OP_lit30:
+ return "DW_OP_lit30";
+ case DW_OP_lit31:
+ return "DW_OP_lit31";
+ case DW_OP_reg0:
+ return "DW_OP_reg0";
+ case DW_OP_reg1:
+ return "DW_OP_reg1";
+ case DW_OP_reg2:
+ return "DW_OP_reg2";
+ case DW_OP_reg3:
+ return "DW_OP_reg3";
+ case DW_OP_reg4:
+ return "DW_OP_reg4";
+ case DW_OP_reg5:
+ return "DW_OP_reg5";
+ case DW_OP_reg6:
+ return "DW_OP_reg6";
+ case DW_OP_reg7:
+ return "DW_OP_reg7";
+ case DW_OP_reg8:
+ return "DW_OP_reg8";
+ case DW_OP_reg9:
+ return "DW_OP_reg9";
+ case DW_OP_reg10:
+ return "DW_OP_reg10";
+ case DW_OP_reg11:
+ return "DW_OP_reg11";
+ case DW_OP_reg12:
+ return "DW_OP_reg12";
+ case DW_OP_reg13:
+ return "DW_OP_reg13";
+ case DW_OP_reg14:
+ return "DW_OP_reg14";
+ case DW_OP_reg15:
+ return "DW_OP_reg15";
+ case DW_OP_reg16:
+ return "DW_OP_reg16";
+ case DW_OP_reg17:
+ return "DW_OP_reg17";
+ case DW_OP_reg18:
+ return "DW_OP_reg18";
+ case DW_OP_reg19:
+ return "DW_OP_reg19";
+ case DW_OP_reg20:
+ return "DW_OP_reg20";
+ case DW_OP_reg21:
+ return "DW_OP_reg21";
+ case DW_OP_reg22:
+ return "DW_OP_reg22";
+ case DW_OP_reg23:
+ return "DW_OP_reg23";
+ case DW_OP_reg24:
+ return "DW_OP_reg24";
+ case DW_OP_reg25:
+ return "DW_OP_reg25";
+ case DW_OP_reg26:
+ return "DW_OP_reg26";
+ case DW_OP_reg27:
+ return "DW_OP_reg27";
+ case DW_OP_reg28:
+ return "DW_OP_reg28";
+ case DW_OP_reg29:
+ return "DW_OP_reg29";
+ case DW_OP_reg30:
+ return "DW_OP_reg30";
+ case DW_OP_reg31:
+ return "DW_OP_reg31";
+ case DW_OP_breg0:
+ return "DW_OP_breg0";
+ case DW_OP_breg1:
+ return "DW_OP_breg1";
+ case DW_OP_breg2:
+ return "DW_OP_breg2";
+ case DW_OP_breg3:
+ return "DW_OP_breg3";
+ case DW_OP_breg4:
+ return "DW_OP_breg4";
+ case DW_OP_breg5:
+ return "DW_OP_breg5";
+ case DW_OP_breg6:
+ return "DW_OP_breg6";
+ case DW_OP_breg7:
+ return "DW_OP_breg7";
+ case DW_OP_breg8:
+ return "DW_OP_breg8";
+ case DW_OP_breg9:
+ return "DW_OP_breg9";
+ case DW_OP_breg10:
+ return "DW_OP_breg10";
+ case DW_OP_breg11:
+ return "DW_OP_breg11";
+ case DW_OP_breg12:
+ return "DW_OP_breg12";
+ case DW_OP_breg13:
+ return "DW_OP_breg13";
+ case DW_OP_breg14:
+ return "DW_OP_breg14";
+ case DW_OP_breg15:
+ return "DW_OP_breg15";
+ case DW_OP_breg16:
+ return "DW_OP_breg16";
+ case DW_OP_breg17:
+ return "DW_OP_breg17";
+ case DW_OP_breg18:
+ return "DW_OP_breg18";
+ case DW_OP_breg19:
+ return "DW_OP_breg19";
+ case DW_OP_breg20:
+ return "DW_OP_breg20";
+ case DW_OP_breg21:
+ return "DW_OP_breg21";
+ case DW_OP_breg22:
+ return "DW_OP_breg22";
+ case DW_OP_breg23:
+ return "DW_OP_breg23";
+ case DW_OP_breg24:
+ return "DW_OP_breg24";
+ case DW_OP_breg25:
+ return "DW_OP_breg25";
+ case DW_OP_breg26:
+ return "DW_OP_breg26";
+ case DW_OP_breg27:
+ return "DW_OP_breg27";
+ case DW_OP_breg28:
+ return "DW_OP_breg28";
+ case DW_OP_breg29:
+ return "DW_OP_breg29";
+ case DW_OP_breg30:
+ return "DW_OP_breg30";
+ case DW_OP_breg31:
+ return "DW_OP_breg31";
+ case DW_OP_regx:
+ return "DW_OP_regx";
+ case DW_OP_fbreg:
+ return "DW_OP_fbreg";
+ case DW_OP_bregx:
+ return "DW_OP_bregx";
+ case DW_OP_piece:
+ return "DW_OP_piece";
+ case DW_OP_deref_size:
+ return "DW_OP_deref_size";
+ case DW_OP_xderef_size:
+ return "DW_OP_xderef_size";
+ case DW_OP_nop:
+ return "DW_OP_nop";
+ default:
+ return "OP_<unknown>";
+ }
+}
+
+static char *
+dwarf_bool_name (mybool)
+ unsigned mybool;
+{
+ if (mybool)
+ return "TRUE";
+ else
+ return "FALSE";
+}
+
+/* Convert a DWARF type code into its string name. */
+
+static char *
+dwarf_type_encoding_name (enc)
+ register unsigned enc;
+{
+ switch (enc)
+ {
+ case DW_ATE_address:
+ return "DW_ATE_address";
+ case DW_ATE_boolean:
+ return "DW_ATE_boolean";
+ case DW_ATE_complex_float:
+ return "DW_ATE_complex_float";
+ case DW_ATE_float:
+ return "DW_ATE_float";
+ case DW_ATE_signed:
+ return "DW_ATE_signed";
+ case DW_ATE_signed_char:
+ return "DW_ATE_signed_char";
+ case DW_ATE_unsigned:
+ return "DW_ATE_unsigned";
+ case DW_ATE_unsigned_char:
+ return "DW_ATE_unsigned_char";
+ default:
+ return "DW_ATE_<unknown>";
+ }
+}
+
+/* Convert a DWARF call frame info operation to its string name. */
+
+#if 0
+static char *
+dwarf_cfi_name (cfi_opc)
+ register unsigned cfi_opc;
+{
+ switch (cfi_opc)
+ {
+ case DW_CFA_advance_loc:
+ return "DW_CFA_advance_loc";
+ case DW_CFA_offset:
+ return "DW_CFA_offset";
+ case DW_CFA_restore:
+ return "DW_CFA_restore";
+ case DW_CFA_nop:
+ return "DW_CFA_nop";
+ case DW_CFA_set_loc:
+ return "DW_CFA_set_loc";
+ case DW_CFA_advance_loc1:
+ return "DW_CFA_advance_loc1";
+ case DW_CFA_advance_loc2:
+ return "DW_CFA_advance_loc2";
+ case DW_CFA_advance_loc4:
+ return "DW_CFA_advance_loc4";
+ case DW_CFA_offset_extended:
+ return "DW_CFA_offset_extended";
+ case DW_CFA_restore_extended:
+ return "DW_CFA_restore_extended";
+ case DW_CFA_undefined:
+ return "DW_CFA_undefined";
+ case DW_CFA_same_value:
+ return "DW_CFA_same_value";
+ case DW_CFA_register:
+ return "DW_CFA_register";
+ case DW_CFA_remember_state:
+ return "DW_CFA_remember_state";
+ case DW_CFA_restore_state:
+ return "DW_CFA_restore_state";
+ case DW_CFA_def_cfa:
+ return "DW_CFA_def_cfa";
+ case DW_CFA_def_cfa_register:
+ return "DW_CFA_def_cfa_register";
+ case DW_CFA_def_cfa_offset:
+ return "DW_CFA_def_cfa_offset";
+ /* SGI/MIPS specific */
+ case DW_CFA_MIPS_advance_loc8:
+ return "DW_CFA_MIPS_advance_loc8";
+ default:
+ return "DW_CFA_<unknown>";
+ }
+}
+#endif
+
+void
+dump_die (die)
+ struct die_info *die;
+{
+ unsigned int i;
+
+ fprintf (stderr, "Die: %s (abbrev = %d, offset = %d)\n",
+ dwarf_tag_name (die->tag), die->abbrev, die->offset);
+ fprintf (stderr, "\thas children: %s\n",
+ dwarf_bool_name (die->has_children));
+
+ fprintf (stderr, "\tattributes:\n");
+ for (i = 0; i < die->num_attrs; ++i)
+ {
+ fprintf (stderr, "\t\t%s (%s) ",
+ dwarf_attr_name (die->attrs[i].name),
+ dwarf_form_name (die->attrs[i].form));
+ switch (die->attrs[i].form)
+ {
+ case DW_FORM_ref_addr:
+ case DW_FORM_addr:
+ fprintf (stderr, "address: ");
+ print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
+ break;
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ fprintf (stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
+ break;
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_udata:
+ case DW_FORM_sdata:
+ fprintf (stderr, "constant: %d", DW_UNSND (&die->attrs[i]));
+ break;
+ case DW_FORM_string:
+ fprintf (stderr, "string: \"%s\"",
+ DW_STRING (&die->attrs[i])
+ ? DW_STRING (&die->attrs[i]) : "");
+ break;
+ case DW_FORM_flag:
+ if (DW_UNSND (&die->attrs[i]))
+ fprintf (stderr, "flag: TRUE");
+ else
+ fprintf (stderr, "flag: FALSE");
+ break;
+ case DW_FORM_strp: /* we do not support separate string
+ section yet */
+ case DW_FORM_indirect: /* we do not handle indirect yet */
+ case DW_FORM_data8: /* we do not have 64 bit quantities */
+ default:
+ fprintf (stderr, "unsupported attribute form: %d.",
+ die->attrs[i].form);
+ }
+ fprintf (stderr, "\n");
+ }
+}
+
+void
+dump_die_list (die)
+ struct die_info *die;
+{
+ while (die)
+ {
+ dump_die (die);
+ die = die->next;
+ }
+}
+
+void
+store_in_ref_table (offset, die)
+ unsigned int offset;
+ struct die_info *die;
+{
+ int h;
+ struct die_info *old;
+
+ h = (offset % REF_HASH_SIZE);
+ old = die_ref_table[h];
+ die->next_ref = old;
+ die_ref_table[h] = die;
+}
+
+
+static void
+dwarf2_empty_die_ref_table ()
+{
+ memset (die_ref_table, 0, sizeof (die_ref_table));
+}
+
+static unsigned int
+dwarf2_get_ref_die_offset (attr)
+ struct attribute *attr;
+{
+ unsigned int result = 0;
+
+ switch (attr->form)
+ {
+ case DW_FORM_ref_addr:
+ result = DW_ADDR (attr);
+ break;
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref_udata:
+ result = cu_header_offset + DW_UNSND (attr);
+ break;
+ default:
+ complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form));
+ }
+ return result;
+}
+
+struct die_info *
+follow_die_ref (offset)
+ unsigned int offset;
+{
+ struct die_info *die;
+ int h;
+
+ h = (offset % REF_HASH_SIZE);
+ die = die_ref_table[h];
+ while (die)
+ {
+ if (die->offset == offset)
+ {
+ return die;
+ }
+ die = die->next_ref;
+ }
+ return NULL;
+}
+
+static struct type *
+dwarf2_fundamental_type (objfile, typeid)
+ struct objfile *objfile;
+ int typeid;
+{
+ if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
+ {
+ error ("Dwarf Error: internal error - invalid fundamental type id %d.",
+ typeid);
+ }
+
+ /* Look for this particular type in the fundamental type vector. If
+ one is not found, create and install one appropriate for the
+ current language and the current target machine. */
+
+ if (ftypes[typeid] == NULL)
+ {
+ ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+ }
+
+ return (ftypes[typeid]);
+}
+
+/* Decode simple location descriptions.
+ Given a pointer to a dwarf block that defines a location, compute
+ the location and return the value.
+
+ FIXME: This is a kludge until we figure out a better
+ way to handle the location descriptions.
+ Gdb's design does not mesh well with the DWARF2 notion of a location
+ computing interpreter, which is a shame because the flexibility goes unused.
+ FIXME: Implement more operations as necessary.
+
+ A location description containing no operations indicates that the
+ object is optimized out. The global optimized_out flag is set for
+ those, the return value is meaningless.
+
+ When the result is a register number, the global isreg flag is set,
+ otherwise it is cleared.
+
+ When the result is a base register offset, the global offreg flag is set
+ and the register number is returned in basereg, otherwise it is cleared.
+
+ When the DW_OP_fbreg operation is encountered without a corresponding
+ DW_AT_frame_base attribute, the global islocal flag is set.
+ Hopefully the machine dependent code knows how to set up a virtual
+ frame pointer for the local references.
+
+ Note that stack[0] is unused except as a default error return.
+ Note that stack overflow is not yet handled. */
+
+static CORE_ADDR
+decode_locdesc (blk, objfile)
+ struct dwarf_block *blk;
+ struct objfile *objfile;
+{
+ int i;
+ int size = blk->size;
+ char *data = blk->data;
+ CORE_ADDR stack[64];
+ int stacki;
+ unsigned int bytes_read, unsnd;
+ unsigned char op;
+
+ i = 0;
+ stacki = 0;
+ stack[stacki] = 0;
+ isreg = 0;
+ offreg = 0;
+ islocal = 0;
+ optimized_out = 1;
+
+ while (i < size)
+ {
+ optimized_out = 0;
+ op = data[i++];
+ switch (op)
+ {
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ isreg = 1;
+ stack[++stacki] = op - DW_OP_reg0;
+ break;
+
+ case DW_OP_regx:
+ isreg = 1;
+ unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+#if defined(HARRIS_TARGET) && defined(_M88K)
+ /* The Harris 88110 gdb ports have long kept their special reg
+ numbers between their gp-regs and their x-regs. This is
+ not how our dwarf is generated. Punt. */
+ unsnd += 6;
+#endif
+ stack[++stacki] = unsnd;
+ break;
+
+ case DW_OP_breg0:
+ case DW_OP_breg1:
+ case DW_OP_breg2:
+ case DW_OP_breg3:
+ case DW_OP_breg4:
+ case DW_OP_breg5:
+ case DW_OP_breg6:
+ case DW_OP_breg7:
+ case DW_OP_breg8:
+ case DW_OP_breg9:
+ case DW_OP_breg10:
+ case DW_OP_breg11:
+ case DW_OP_breg12:
+ case DW_OP_breg13:
+ case DW_OP_breg14:
+ case DW_OP_breg15:
+ case DW_OP_breg16:
+ case DW_OP_breg17:
+ case DW_OP_breg18:
+ case DW_OP_breg19:
+ case DW_OP_breg20:
+ case DW_OP_breg21:
+ case DW_OP_breg22:
+ case DW_OP_breg23:
+ case DW_OP_breg24:
+ case DW_OP_breg25:
+ case DW_OP_breg26:
+ case DW_OP_breg27:
+ case DW_OP_breg28:
+ case DW_OP_breg29:
+ case DW_OP_breg30:
+ case DW_OP_breg31:
+ offreg = 1;
+ basereg = op - DW_OP_breg0;
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_fbreg:
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ if (frame_base_reg >= 0)
+ {
+ offreg = 1;
+ basereg = frame_base_reg;
+ stack[stacki] += frame_base_offset;
+ }
+ else
+ {
+ complain (&dwarf2_missing_at_frame_base);
+ islocal = 1;
+ }
+ break;
+
+ case DW_OP_addr:
+ stack[++stacki] = read_address (objfile->obfd, &data[i]);
+ i += address_size;
+ break;
+
+ case DW_OP_const1u:
+ stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const1s:
+ stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const2u:
+ stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const2s:
+ stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const4u:
+ stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_const4s:
+ stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_constu:
+ stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
+ &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_consts:
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_plus:
+ stack[stacki - 1] += stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_plus_uconst:
+ stack[stacki] += read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_minus:
+ stack[stacki - 1] = stack[stacki] - stack[stacki - 1];
+ stacki--;
+ break;
+
+ default:
+ complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name(op));
+ return (stack[stacki]);
+ }
+ }
+ return (stack[stacki]);
+}
+
+/* memory allocation interface */
+
+/* ARGSUSED */
+static void
+dwarf2_free_tmp_obstack (ignore)
+ PTR ignore;
+{
+ obstack_free (&dwarf2_tmp_obstack, NULL);
+}
+
+static struct dwarf_block *
+dwarf_alloc_block ()
+{
+ struct dwarf_block *blk;
+
+ blk = (struct dwarf_block *)
+ obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct dwarf_block));
+ return (blk);
+}
+
+static struct abbrev_info *
+dwarf_alloc_abbrev ()
+{
+ struct abbrev_info *abbrev;
+
+ abbrev = (struct abbrev_info *) xmalloc (sizeof (struct abbrev_info));
+ memset (abbrev, 0, sizeof (struct abbrev_info));
+ return (abbrev);
+}
+
+static struct die_info *
+dwarf_alloc_die ()
+{
+ struct die_info *die;
+
+ die = (struct die_info *) xmalloc (sizeof (struct die_info));
+ memset (die, 0, sizeof (struct die_info));
+ return (die);
+}
diff --git a/contrib/gdb/gdb/dwarfread.c b/contrib/gdb/gdb/dwarfread.c
index ed82009..9de0312 100644
--- a/contrib/gdb/gdb/dwarfread.c
+++ b/contrib/gdb/gdb/dwarfread.c
@@ -1,5 +1,5 @@
/* DWARF debugging format support for GDB.
- Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1998
Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support. Portions based on dbxread.c,
mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.
@@ -54,10 +54,6 @@ other things to work on, if you get bored. :-)
#include <fcntl.h>
#include "gdb_string.h"
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
-
/* Some macros to provide DIE info for complaints. */
#define DIE_ID (curdie!=NULL ? curdie->die_ref : 0)
@@ -318,6 +314,23 @@ struct dieinfo {
unsigned int has_at_stmt_list:1;
unsigned int has_at_byte_size:1;
unsigned int short_element_list:1;
+
+ /* Kludge to identify register variables */
+
+ unsigned int isreg;
+
+ /* Kludge to identify optimized out variables */
+
+ unsigned int optimized_out;
+
+ /* Kludge to identify basereg references.
+ Nonzero if we have an offset relative to a basereg. */
+
+ unsigned int offreg;
+
+ /* Kludge to identify which base register is it relative to. */
+
+ unsigned int basereg;
};
static int diecount; /* Approximate count of dies for compilation unit */
@@ -327,13 +340,6 @@ static char *dbbase; /* Base pointer to dwarf info */
static int dbsize; /* Size of dwarf info in bytes */
static int dbroff; /* Relative offset from start of .debug section */
static char *lnbase; /* Base pointer to line section */
-static int isreg; /* Kludge to identify register variables */
-static int optimized_out; /* Kludge to identify optimized out variables */
-/* Kludge to identify basereg references. Nonzero if we have an offset
- relative to a basereg. */
-static int offreg;
-/* Which base register is it relative to? */
-static int basereg;
/* This value is added to each symbol value. FIXME: Generalize to
the section_offsets structure used by dbxread (once this is done,
@@ -442,6 +448,9 @@ static const struct language_defn *cu_language_defn;
/* Forward declarations of static functions so we don't have to worry
about ordering within this file. */
+static void
+free_utypes PARAMS ((PTR));
+
static int
attribute_size PARAMS ((unsigned int));
@@ -558,7 +567,7 @@ synthesize_typedef PARAMS ((struct dieinfo *, struct objfile *,
struct type *));
static int
-locval PARAMS ((char *));
+locval PARAMS ((struct dieinfo *));
static void
set_cu_language PARAMS ((struct dieinfo *));
@@ -665,11 +674,13 @@ set_cu_language (dip)
case LANG_MODULA2:
cu_language = language_m2;
break;
+ case LANG_FORTRAN77:
+ case LANG_FORTRAN90:
+ cu_language = language_fortran;
+ break;
case LANG_ADA83:
case LANG_COBOL74:
case LANG_COBOL85:
- case LANG_FORTRAN77:
- case LANG_FORTRAN90:
case LANG_PASCAL83:
/* We don't know anything special about these yet. */
cu_language = language_unknown;
@@ -965,7 +976,7 @@ decode_die_type (dip)
}
else
{
- type = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ type = dwarf_fundamental_type (current_objfile, FT_VOID);
}
return (type);
}
@@ -1077,10 +1088,10 @@ struct_type (dip, thisdie, enddie, objfile)
list -> field.name =
obsavestring (mbr.at_name, strlen (mbr.at_name),
&objfile -> type_obstack);
- list -> field.type = decode_die_type (&mbr);
- list -> field.bitpos = 8 * locval (mbr.at_location);
+ FIELD_TYPE (list->field) = decode_die_type (&mbr);
+ FIELD_BITPOS (list->field) = 8 * locval (&mbr);
/* Handle bit fields. */
- list -> field.bitsize = mbr.at_bit_size;
+ FIELD_BITSIZE (list->field) = mbr.at_bit_size;
if (BITS_BIG_ENDIAN)
{
/* For big endian bits, the at_bit_offset gives the
@@ -1088,7 +1099,7 @@ struct_type (dip, thisdie, enddie, objfile)
anonymous object to the MSB of the field. We don't
have to do anything special since we don't need to
know the size of the anonymous object. */
- list -> field.bitpos += mbr.at_bit_offset;
+ FIELD_BITPOS (list->field) += mbr.at_bit_offset;
}
else
{
@@ -1118,7 +1129,7 @@ struct_type (dip, thisdie, enddie, objfile)
a debug information size optimization. */
anonymous_size = TYPE_LENGTH (list -> field.type);
}
- list -> field.bitpos +=
+ FIELD_BITPOS (list->field) +=
anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size;
}
}
@@ -1492,10 +1503,8 @@ read_tag_pointer_type (dip)
TYPE_POINTER_TYPE (type) = utype;
/* We assume the machine has only one representation for pointers! */
- /* FIXME: This confuses host<->target data representations, and is a
- poor assumption besides. */
-
- TYPE_LENGTH (utype) = sizeof (char *);
+ /* FIXME: Possably a poor assumption */
+ TYPE_LENGTH (utype) = TARGET_PTR_BIT / TARGET_CHAR_BIT ;
TYPE_CODE (utype) = TYPE_CODE_PTR;
}
}
@@ -1762,9 +1771,9 @@ enum_type (dip, objfile)
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new -> next = list;
list = new;
- list -> field.type = NULL;
- list -> field.bitsize = 0;
- list -> field.bitpos =
+ FIELD_TYPE (list->field) = NULL;
+ FIELD_BITSIZE (list->field) = 0;
+ FIELD_BITPOS (list->field) =
target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
objfile);
scan += TARGET_FT_LONG_SIZE (objfile);
@@ -1782,7 +1791,7 @@ enum_type (dip, objfile)
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
SYMBOL_CLASS (sym) = LOC_CONST;
SYMBOL_TYPE (sym) = type;
- SYMBOL_VALUE (sym) = list -> field.bitpos;
+ SYMBOL_VALUE (sym) = FIELD_BITPOS (list->field);
if (SYMBOL_VALUE (sym) < 0)
unsigned_enum = 0;
add_symbol_to_list (sym, list_in_scope);
@@ -1893,10 +1902,17 @@ handle_producer (producer)
/* If this compilation unit was compiled with g++ or gcc, then set the
processing_gcc_compilation flag. */
- processing_gcc_compilation =
- STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
- || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER))
- || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+ if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
+ {
+ char version = producer[strlen (GCC_PRODUCER)];
+ processing_gcc_compilation = (version == '2' ? 2 : 1);
+ }
+ else
+ {
+ processing_gcc_compilation =
+ STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
+ || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER));
+ }
/* Select a demangling style if we can identify the producer and if
the current style is auto. We leave the current style alone if it
@@ -1966,6 +1982,7 @@ read_file_scope (dip, thisdie, enddie, objfile)
memset (utypes, 0, numutypes * sizeof (struct type *));
memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
start_symtab (dip -> at_name, dip -> at_comp_dir, dip -> at_low_pc);
+ record_debugformat ("DWARF 1");
decode_line_numbers (lnbase);
process_dies (thisdie + dip -> die_length, enddie, objfile);
@@ -2187,23 +2204,23 @@ LOCAL FUNCTION
SYNOPSIS
- static int locval (char *loc)
+ static int locval (struct dieinfo *dip)
DESCRIPTION
Given pointer to a string of bytes that define a location, compute
the location and return the value.
A location description containing no atoms indicates that the
- object is optimized out. The global optimized_out flag is set for
- those, the return value is meaningless.
+ object is optimized out. The optimized_out flag is set for those,
+ the return value is meaningless.
When computing values involving the current value of the frame pointer,
the value zero is used, which results in a value relative to the frame
pointer, rather than the absolute value. This is what GDB wants
anyway.
- When the result is a register number, the global isreg flag is set,
- otherwise it is cleared. This is a kludge until we figure out a better
+ When the result is a register number, the isreg flag is set, otherwise
+ it is cleared. This is a kludge until we figure out a better
way to handle the problem. Gdb's design does not mesh well with the
DWARF notion of a location computing interpreter, which is a shame
because the flexibility goes unused.
@@ -2215,30 +2232,32 @@ NOTES
*/
static int
-locval (loc)
- char *loc;
+locval (dip)
+ struct dieinfo *dip;
{
unsigned short nbytes;
unsigned short locsize;
auto long stack[64];
int stacki;
+ char *loc;
char *end;
int loc_atom_code;
int loc_value_size;
+ loc = dip -> at_location;
nbytes = attribute_size (AT_location);
locsize = target_to_host (loc, nbytes, GET_UNSIGNED, current_objfile);
loc += nbytes;
end = loc + locsize;
stacki = 0;
stack[stacki] = 0;
- isreg = 0;
- offreg = 0;
- optimized_out = 1;
+ dip -> isreg = 0;
+ dip -> offreg = 0;
+ dip -> optimized_out = 1;
loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
while (loc < end)
{
- optimized_out = 0;
+ dip -> optimized_out = 0;
loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
current_objfile);
loc += SIZEOF_LOC_ATOM_CODE;
@@ -2255,15 +2274,15 @@ locval (loc)
GET_UNSIGNED,
current_objfile));
loc += loc_value_size;
- isreg = 1;
+ dip -> isreg = 1;
break;
case OP_BASEREG:
/* push value of register (number) */
/* Actually, we compute the value as if register has 0, so the
value ends up being the offset from that register. */
- offreg = 1;
- basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
- current_objfile);
+ dip -> offreg = 1;
+ dip -> basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
+ current_objfile);
loc += loc_value_size;
stack[++stacki] = 0;
break;
@@ -2433,7 +2452,8 @@ psymtab_to_symtab_1 (pst)
if (DBLENGTH (pst)) /* Otherwise it's a dummy */
{
buildsym_init ();
- old_chain = make_cleanup (really_free_pendings, 0);
+ old_chain = make_cleanup ((make_cleanup_func)
+ really_free_pendings, 0);
read_ofile_symtab (pst);
if (info_verbose)
{
@@ -2958,6 +2978,8 @@ new_symbol (dip, objfile)
case TAG_subroutine:
SYMBOL_VALUE_ADDRESS (sym) = dip -> at_low_pc;
SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+ if (dip -> at_prototyped)
+ TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
SYMBOL_CLASS (sym) = LOC_BLOCK;
if (dip -> die_tag == TAG_global_subroutine)
{
@@ -2971,7 +2993,7 @@ new_symbol (dip, objfile)
case TAG_global_variable:
if (dip -> at_location != NULL)
{
- SYMBOL_VALUE (sym) = locval (dip -> at_location);
+ SYMBOL_VALUE_ADDRESS (sym) = locval (dip);
add_symbol_to_list (sym, &global_symbols);
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE (sym) += baseaddr;
@@ -2980,42 +3002,52 @@ new_symbol (dip, objfile)
case TAG_local_variable:
if (dip -> at_location != NULL)
{
- SYMBOL_VALUE (sym) = locval (dip -> at_location);
- add_symbol_to_list (sym, list_in_scope);
- if (optimized_out)
+ int loc = locval (dip);
+ if (dip -> optimized_out)
{
SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
}
- else if (isreg)
+ else if (dip -> isreg)
{
SYMBOL_CLASS (sym) = LOC_REGISTER;
}
- else if (offreg)
+ else if (dip -> offreg)
{
SYMBOL_CLASS (sym) = LOC_BASEREG;
- SYMBOL_BASEREG (sym) = basereg;
+ SYMBOL_BASEREG (sym) = dip -> basereg;
}
else
{
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE (sym) += baseaddr;
}
+ if (SYMBOL_CLASS (sym) == LOC_STATIC)
+ {
+ /* LOC_STATIC address class MUST use SYMBOL_VALUE_ADDRESS,
+ which may store to a bigger location than SYMBOL_VALUE. */
+ SYMBOL_VALUE_ADDRESS (sym) = loc;
+ }
+ else
+ {
+ SYMBOL_VALUE (sym) = loc;
+ }
+ add_symbol_to_list (sym, list_in_scope);
}
break;
case TAG_formal_parameter:
if (dip -> at_location != NULL)
{
- SYMBOL_VALUE (sym) = locval (dip -> at_location);
+ SYMBOL_VALUE (sym) = locval (dip);
}
add_symbol_to_list (sym, list_in_scope);
- if (isreg)
+ if (dip -> isreg)
{
SYMBOL_CLASS (sym) = LOC_REGPARM;
}
- else if (offreg)
+ else if (dip -> offreg)
{
SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
- SYMBOL_BASEREG (sym) = basereg;
+ SYMBOL_BASEREG (sym) = dip -> basereg;
}
else
{
diff --git a/contrib/gdb/gdb/elfread.c b/contrib/gdb/gdb/elfread.c
index 9a7a0fe..417039e 100644
--- a/contrib/gdb/gdb/elfread.c
+++ b/contrib/gdb/gdb/elfread.c
@@ -1,5 +1,5 @@
/* Read ELF (Executable and Linking Format) object files for GDB.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1991, 92, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
This file is part of GDB.
@@ -78,12 +78,10 @@ elf_symtab_read PARAMS ((bfd *, CORE_ADDR, struct objfile *, int));
static void
free_elfinfo PARAMS ((void *));
-static struct section_offsets *
-elf_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
-
static struct minimal_symbol *
record_minimal_symbol_and_info PARAMS ((char *, CORE_ADDR,
enum minimal_symbol_type, char *,
+ asection *bfd_section,
struct objfile *));
static void
@@ -172,11 +170,13 @@ elf_interpreter (abfd)
#endif
static struct minimal_symbol *
-record_minimal_symbol_and_info (name, address, ms_type, info, objfile)
+record_minimal_symbol_and_info (name, address, ms_type, info, bfd_section,
+ objfile)
char *name;
CORE_ADDR address;
enum minimal_symbol_type ms_type;
char *info; /* FIXME, is this really char *? */
+ asection *bfd_section;
struct objfile *objfile;
{
int section;
@@ -205,9 +205,8 @@ record_minimal_symbol_and_info (name, address, ms_type, info, objfile)
break;
}
- name = obsavestring (name, strlen (name), &objfile -> symbol_obstack);
return prim_record_minimal_symbol_and_info
- (name, address, ms_type, info, section, objfile);
+ (name, address, ms_type, info, section, bfd_section, objfile);
}
/*
@@ -262,8 +261,7 @@ elf_symtab_read (abfd, addr, objfile, dynamic)
/* Name of filesym, as saved on the symbol_obstack. */
char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack);
#endif
- struct dbx_symfile_info *dbx = (struct dbx_symfile_info *)
- objfile->sym_stab_info;
+ struct dbx_symfile_info *dbx = objfile->sym_stab_info;
unsigned long size;
int stripped = (bfd_get_symcount (abfd) == 0);
@@ -324,7 +322,7 @@ elf_symtab_read (abfd, addr, objfile, dynamic)
symaddr += addr;
msym = record_minimal_symbol_and_info
((char *) sym -> name, symaddr,
- mst_solib_trampoline, NULL, objfile);
+ mst_solib_trampoline, NULL, sym -> section, objfile);
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (msym != NULL)
msym->filename = filesymname;
@@ -393,6 +391,15 @@ elf_symtab_read (abfd, addr, objfile, dynamic)
default:
ms_type = mst_abs;
}
+
+ /* If it is an Irix dynamic symbol, skip section name
+ symbols, relocate all others. */
+ if (ms_type != mst_abs)
+ {
+ if (sym->name[0] == '.')
+ continue;
+ symaddr += addr;
+ }
}
else if (sym -> section -> flags & SEC_CODE)
{
@@ -411,6 +418,17 @@ elf_symtab_read (abfd, addr, objfile, dynamic)
should be harmless (but I encourage people to fix this
in the assembler instead of adding checks here). */
continue;
+#ifdef HARRIS_TARGET
+ else if (sym->name[0] == '.' && sym->name[1] == '.')
+ {
+ /* Looks like a Harris compiler generated label for the
+ purpose of marking instructions that are relevant to
+ DWARF dies. The assembler can't get rid of these
+ because they are relocatable addresses that the
+ linker needs to resolve. */
+ continue;
+ }
+#endif
else
{
ms_type = mst_file_text;
@@ -515,11 +533,14 @@ elf_symtab_read (abfd, addr, objfile, dynamic)
size = ((elf_symbol_type *) sym) -> internal_elf_sym.st_size;
msym = record_minimal_symbol_and_info
((char *) sym -> name, symaddr,
- ms_type, (PTR) size, objfile);
+ ms_type, (PTR) size, sym -> section, objfile);
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (msym != NULL)
msym->filename = filesymname;
#endif
+#ifdef ELF_MAKE_MSYMBOL_SPECIAL
+ ELF_MAKE_MSYMBOL_SPECIAL(sym,msym);
+#endif
}
}
do_cleanups (back_to);
@@ -570,12 +591,12 @@ elf_symfile_read (objfile, section_offsets, mainline)
CORE_ADDR offset;
init_minimal_symbol_collection ();
- back_to = make_cleanup (discard_minimal_symbols, 0);
+ back_to = make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
memset ((char *) &ei, 0, sizeof (ei));
/* Allocate struct to keep track of the symfile */
- objfile->sym_stab_info = (PTR)
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
memset ((char *) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
make_cleanup (free_elfinfo, (PTR) objfile);
@@ -593,16 +614,42 @@ elf_symfile_read (objfile, section_offsets, mainline)
elf_symtab_read (abfd, offset, objfile, 1);
/* Now process debugging information, which is contained in
- special ELF sections. We first have to find them... */
+ special ELF sections. */
+ /* If we are reinitializing, or if we have never loaded syms yet,
+ set table to empty. MAINLINE is cleared so that *_read_psymtab
+ functions do not all also re-initialize the psymbol table. */
+ if (mainline)
+ {
+ init_psymbol_list (objfile, 0);
+ mainline = 0;
+ }
+
+ /* We first have to find them... */
bfd_map_over_sections (abfd, elf_locate_sections, (PTR) &ei);
- if (ei.dboffset && ei.lnoffset)
+
+ /* ELF debugging information is inserted into the psymtab in the
+ order of least informative first - most informative last. Since
+ the psymtab table is searched `most recent insertion first' this
+ increases the probability that more detailed debug information
+ for a section is found.
+
+ For instance, an object file might contain both .mdebug (XCOFF)
+ and .debug_info (DWARF2) sections then .mdebug is inserted first
+ (searched last) and DWARF2 is inserted last (searched first). If
+ we don't do this then the XCOFF info is found first - for code in
+ an included file XCOFF info is useless. */
+
+ if (ei.mdebugsect)
{
- /* DWARF sections */
- dwarf_build_psymtabs (objfile,
- section_offsets, mainline,
- ei.dboffset, ei.dbsize,
- ei.lnoffset, ei.lnsize);
+ const struct ecoff_debug_swap *swap;
+
+ /* .mdebug section, presumably holding ECOFF debugging
+ information. */
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ if (swap)
+ elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect,
+ section_offsets);
}
if (ei.stabsect)
{
@@ -622,16 +669,18 @@ elf_symfile_read (objfile, section_offsets, mainline)
str_sect->filepos,
bfd_section_size (abfd, str_sect));
}
- if (ei.mdebugsect)
+ if (dwarf2_has_info (abfd))
{
- const struct ecoff_debug_swap *swap;
-
- /* .mdebug section, presumably holding ECOFF debugging
- information. */
- swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
- if (swap)
- elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect,
- section_offsets);
+ /* DWARF 2 sections */
+ dwarf2_build_psymtabs (objfile, section_offsets, mainline);
+ }
+ else if (ei.dboffset && ei.lnoffset)
+ {
+ /* DWARF sections */
+ dwarf_build_psymtabs (objfile,
+ section_offsets, mainline,
+ ei.dboffset, ei.dbsize,
+ ei.lnoffset, ei.lnsize);
}
/* Install any minimal symbols that have been collected as the current
@@ -650,8 +699,7 @@ free_elfinfo (objp)
PTR objp;
{
struct objfile *objfile = (struct objfile *)objp;
- struct dbx_symfile_info *dbxinfo = (struct dbx_symfile_info *)
- objfile->sym_stab_info;
+ struct dbx_symfile_info *dbxinfo = objfile->sym_stab_info;
struct stab_section_info *ssi, *nssi;
ssi = dbxinfo->stab_section_info;
@@ -714,31 +762,6 @@ elf_symfile_init (objfile)
objfile->flags |= OBJF_REORDERED;
}
-/* ELF specific parsing routine for section offsets.
-
- Plain and simple for now. */
-
-static
-struct section_offsets *
-elf_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets)
- + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- ANOFFSET (section_offsets, i) = addr;
-
- return section_offsets;
-}
-
/* When handling an ELF file that contains Sun STABS debug info,
some of the debug info is relative to the particular chunk of the
section that was generated in its individual .o file. E.g.
@@ -753,8 +776,7 @@ elfstab_offset_sections (objfile, pst)
struct partial_symtab *pst;
{
char *filename = pst->filename;
- struct dbx_symfile_info *dbx = (struct dbx_symfile_info *)
- objfile->sym_stab_info;
+ struct dbx_symfile_info *dbx = objfile->sym_stab_info;
struct stab_section_info *maybe = dbx->stab_section_info;
struct stab_section_info *questionable = 0;
int i;
@@ -815,7 +837,8 @@ static struct sym_fns elf_sym_fns =
elf_symfile_init, /* sym_init: read initial info, setup for sym_read() */
elf_symfile_read, /* sym_read: read a symbol file into symtab */
elf_symfile_finish, /* sym_finish: finished with file, cleanup */
- elf_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_symfile_offsets,
+ /* sym_offsets: Translate ext. to int. relocation */
NULL /* next: pointer to next struct sym_fns */
};
diff --git a/contrib/gdb/gdb/eval.c b/contrib/gdb/gdb/eval.c
index ed9fd53..d3c3465 100644
--- a/contrib/gdb/gdb/eval.c
+++ b/contrib/gdb/gdb/eval.c
@@ -1,5 +1,5 @@
/* Evaluate expressions for GDB.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,6 +30,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h" /* For CAST_IS_CONVERSION */
#include "f-lang.h" /* for array bound stuff */
+/* Defined in symtab.c */
+extern int hp_som_som_object_present;
+
+/* This is defined in valops.c */
+extern int overload_resolution;
+
+
/* Prototypes for local functions. */
static value_ptr evaluate_subexp_for_sizeof PARAMS ((struct expression *,
@@ -38,6 +45,19 @@ static value_ptr evaluate_subexp_for_sizeof PARAMS ((struct expression *,
static value_ptr evaluate_subexp_for_address PARAMS ((struct expression *,
int *, enum noside));
+static value_ptr evaluate_subexp PARAMS ((struct type *, struct expression *,
+ int *, enum noside));
+
+static char *get_label PARAMS ((struct expression *, int *));
+
+static value_ptr
+evaluate_struct_tuple PARAMS ((value_ptr, struct expression *, int *,
+ enum noside, int));
+
+static LONGEST
+init_array_element PARAMS ((value_ptr, value_ptr, struct expression *,
+ int *, enum noside, LONGEST, LONGEST));
+
#ifdef __GNUC__
inline
#endif
@@ -61,7 +81,7 @@ parse_and_eval_address (exp)
struct expression *expr = parse_expression (exp);
register CORE_ADDR addr;
register struct cleanup *old_chain =
- make_cleanup (free_current_contents, &expr);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expr);
addr = value_as_pointer (evaluate_expression (expr));
do_cleanups (old_chain);
@@ -78,7 +98,7 @@ parse_and_eval_address_1 (expptr)
struct expression *expr = parse_exp_1 (expptr, (struct block *)0, 0);
register CORE_ADDR addr;
register struct cleanup *old_chain =
- make_cleanup (free_current_contents, &expr);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expr);
addr = value_as_pointer (evaluate_expression (expr));
do_cleanups (old_chain);
@@ -92,7 +112,7 @@ parse_and_eval (exp)
struct expression *expr = parse_expression (exp);
register value_ptr val;
register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
+ = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
val = evaluate_expression (expr);
do_cleanups (old_chain);
@@ -110,7 +130,7 @@ parse_to_comma_and_eval (expp)
struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);
register value_ptr val;
register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
+ = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
val = evaluate_expression (expr);
do_cleanups (old_chain);
@@ -316,6 +336,7 @@ init_array_element (array, element, exp, pos, noside, low_bound, high_bound)
register struct expression *exp;
register int *pos;
enum noside noside;
+ LONGEST low_bound, high_bound;
{
LONGEST index;
int element_size = TYPE_LENGTH (VALUE_TYPE (element));
@@ -369,6 +390,11 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
value_ptr *argvec;
int upper, lower, retcode;
int code;
+ int ix;
+ long mem_offset;
+ struct symbol * sym;
+ struct type ** arg_types;
+ int save_pos1;
/* This expect_type crap should not be used for C. C expressions do
not have any notion of expected types, never has and (goddess
@@ -449,9 +475,16 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
access_value_history (longest_to_int (exp->elts[pc + 1].longconst));
case OP_REGISTER:
- (*pos) += 2;
- return value_of_register (longest_to_int (exp->elts[pc + 1].longconst));
-
+ {
+ int regno = longest_to_int (exp->elts[pc + 1].longconst);
+ value_ptr val = value_of_register (regno);
+
+ (*pos) += 2;
+ if (val == NULL)
+ error ("Value of register %s not available.", REGISTER_NAME (regno));
+ else
+ return val;
+ }
case OP_BOOL:
(*pos) += 2;
return value_from_longest (LA_BOOL_TYPE,
@@ -529,6 +562,9 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
}
else
{
+ if (index > high_bound)
+ /* to avoid memory corruption */
+ error ("Too many array elements");
memcpy (VALUE_CONTENTS_RAW (array)
+ (index - low_bound) * element_size,
VALUE_CONTENTS (element),
@@ -545,27 +581,54 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
value_ptr set = allocate_value (expect_type);
char *valaddr = VALUE_CONTENTS_RAW (set);
struct type *element_type = TYPE_INDEX_TYPE (type);
+ struct type *check_type = element_type;
LONGEST low_bound, high_bound;
+
+ /* get targettype of elementtype */
+ while (TYPE_CODE (check_type) == TYPE_CODE_RANGE ||
+ TYPE_CODE (check_type) == TYPE_CODE_TYPEDEF)
+ check_type = TYPE_TARGET_TYPE (check_type);
+
if (get_discrete_bounds (element_type, &low_bound, &high_bound) < 0)
error ("(power)set type with unknown size");
memset (valaddr, '\0', TYPE_LENGTH (type));
for (tem = 0; tem < nargs; tem++)
{
LONGEST range_low, range_high;
+ struct type *range_low_type, *range_high_type;
value_ptr elem_val;
if (exp->elts[*pos].opcode == BINOP_RANGE)
{
(*pos)++;
elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_low_type = VALUE_TYPE (elem_val);
range_low = value_as_long (elem_val);
elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_high_type = VALUE_TYPE (elem_val);
range_high = value_as_long (elem_val);
}
else
{
elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_low_type = range_high_type = VALUE_TYPE (elem_val);
range_low = range_high = value_as_long (elem_val);
}
+ /* check types of elements to avoid mixture of elements from
+ different types. Also check if type of element is "compatible"
+ with element type of powerset */
+ if (TYPE_CODE (range_low_type) == TYPE_CODE_RANGE)
+ range_low_type = TYPE_TARGET_TYPE (range_low_type);
+ if (TYPE_CODE (range_high_type) == TYPE_CODE_RANGE)
+ range_high_type = TYPE_TARGET_TYPE (range_high_type);
+ if ((TYPE_CODE (range_low_type) != TYPE_CODE (range_high_type)) ||
+ (TYPE_CODE (range_low_type) == TYPE_CODE_ENUM &&
+ (range_low_type != range_high_type)))
+ /* different element modes */
+ error ("POWERSET tuple elements of different mode");
+ if ((TYPE_CODE (check_type) != TYPE_CODE (range_low_type)) ||
+ (TYPE_CODE (check_type) == TYPE_CODE_ENUM &&
+ range_low_type != check_type))
+ error ("incompatible POWERSET tuple elements");
if (range_low > range_high)
{
warning ("empty POWERSET tuple range");
@@ -645,6 +708,14 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
{
LONGEST fnptr;
+ /* 1997-08-01 Currently we do not support function invocation
+ via pointers-to-methods with HP aCC. Pointer does not point
+ to the function, but possibly to some thunk. */
+ if (hp_som_som_object_present)
+ {
+ error ("Not implemented: function invocation through pointer to method with HP aCC");
+ }
+
nargs++;
/* First, evaluate the structure into arg2 */
pc2 = (*pos)++;
@@ -748,6 +819,8 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
}
else
{
+ /* Non-method function call */
+ save_pos1 = *pos;
argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
tem = 1;
type = VALUE_TYPE (argvec[0]);
@@ -757,16 +830,18 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
{
for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
{
+ /* pai: FIXME This seems to be coercing arguments before
+ * overload resolution has been done! */
argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type, tem-1),
exp, pos, noside);
}
}
}
+ /* Evaluate arguments */
for (; tem <= nargs; tem++)
{
/* Ensure that array expressions are coerced into pointer objects. */
-
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
}
@@ -777,23 +852,48 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
{
int static_memfuncp;
value_ptr temp = arg2;
- char tstr[64];
-
- argvec[1] = arg2;
- argvec[0] = 0;
- strcpy(tstr, &exp->elts[pc2+2].string);
- if (!argvec[0])
- {
- temp = arg2;
- argvec[0] =
- value_struct_elt (&temp, argvec+1, tstr,
- &static_memfuncp,
- op == STRUCTOP_STRUCT
- ? "structure" : "structure pointer");
- }
- arg2 = value_from_longest (lookup_pointer_type(VALUE_TYPE (temp)),
- VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
- argvec[1] = arg2;
+ char tstr[256];
+ struct fn_field * fns_ptr;
+ int num_fns;
+ struct type * basetype;
+ int boffset;
+
+ /* Method invocation : stuff "this" as first parameter */
+ /* pai: this used to have lookup_pointer_type for some reason,
+ * but temp is already a pointer to the object */
+ argvec[1] = value_from_longest (VALUE_TYPE (temp),
+ VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
+ /* Name of method from expression */
+ strcpy(tstr, &exp->elts[pc2+2].string);
+
+ if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+ {
+ /* Language is C++, do some overload resolution before evaluation */
+ value_ptr valp = NULL;
+
+ /* Prepare list of argument types for overload resolution */
+ arg_types = (struct type **) xmalloc (nargs * (sizeof (struct type *)));
+ for (ix=1; ix <= nargs; ix++)
+ arg_types[ix-1] = VALUE_TYPE (argvec[ix]);
+
+ (void) find_overload_match (arg_types, nargs, tstr,
+ 1 /* method */, 0 /* strict match */,
+ arg2 /* the object */, NULL,
+ &valp, NULL, &static_memfuncp);
+
+
+ argvec[1] = arg2; /* the ``this'' pointer */
+ argvec[0] = valp; /* use the method found after overload resolution */
+ }
+ else /* Non-C++ case -- or no overload resolution */
+ {
+ temp = arg2;
+ argvec[0] = value_struct_elt (&temp, argvec+1, tstr,
+ &static_memfuncp,
+ op == STRUCTOP_STRUCT
+ ? "structure" : "structure pointer");
+ argvec[1] = arg2; /* the ``this'' pointer */
+ }
if (static_memfuncp)
{
@@ -807,6 +907,35 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
argvec[1] = arg2;
argvec[0] = arg1;
}
+ else
+ {
+ /* Non-member function being called */
+
+ if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+ {
+ /* Language is C++, do some overload resolution before evaluation */
+ struct symbol * symp;
+
+ /* Prepare list of argument types for overload resolution */
+ arg_types = (struct type **) xmalloc (nargs * (sizeof (struct type *)));
+ for (ix=1; ix <= nargs; ix++)
+ arg_types[ix-1] = VALUE_TYPE (argvec[ix]);
+
+ (void) find_overload_match (arg_types, nargs, NULL /* no need for name */,
+ 0 /* not method */, 0 /* strict match */,
+ NULL, exp->elts[5].symbol /* the function */,
+ NULL, &symp, NULL);
+
+ /* Now fix the expression being evaluated */
+ exp->elts[5].symbol = symp;
+ argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
+ }
+ else
+ {
+ /* Not C++, or no overload resolution allowed */
+ /* nothing to be done; argvec already correctly set up */
+ }
+ }
do_call_it:
@@ -829,7 +958,10 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
else
error ("Expression of type other than \"Function returning ...\" used as function");
}
+ if (argvec[0] == NULL)
+ error ("Cannot evaluate function -- may be inlined");
return call_function_by_hand (argvec[0], nargs, argvec + 1);
+ /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve */
case OP_F77_UNDETERMINED_ARGLIST:
@@ -938,14 +1070,40 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
NULL, "structure pointer");
}
-
case STRUCTOP_MEMBER:
arg1 = evaluate_subexp_for_address (exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* With HP aCC, pointers to methods do not point to the function code */
+ if (hp_som_som_object_present &&
+ (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_METHOD))
+ error ("Pointers to methods not supported with HP aCC"); /* 1997-08-19 */
+
+ mem_offset = value_as_long (arg2);
goto handle_pointer_to_member;
+
case STRUCTOP_MPTR:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- handle_pointer_to_member:
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* With HP aCC, pointers to methods do not point to the function code */
+ if (hp_som_som_object_present &&
+ (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_METHOD))
+ error ("Pointers to methods not supported with HP aCC"); /* 1997-08-19 */
+
+ mem_offset = value_as_long (arg2);
+
+handle_pointer_to_member:
+ /* HP aCC generates offsets that have bit #29 set; turn it off to get
+ a real offset to the member. */
+ if (hp_som_som_object_present)
+ {
+ if (!mem_offset) /* no bias -> really null */
+ error ("Attempted dereference of null pointer-to-member");
+ mem_offset &= ~0x20000000;
+ }
if (noside == EVAL_SKIP)
goto nosideret;
type = check_typedef (VALUE_TYPE (arg2));
@@ -960,9 +1118,9 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
arg1);
arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
- value_as_long (arg1) + value_as_long (arg2));
+ value_as_long (arg1) + mem_offset);
return value_ind (arg3);
- bad_pointer_to_member:
+bad_pointer_to_member:
error("non-pointer-to-member value used in pointer-to-member construct");
case BINOP_CONCAT:
@@ -971,17 +1129,38 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
return value_concat (arg1, arg2);
case BINOP_ASSIGN:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+
+ /* Do special stuff for HP aCC pointers to members */
+ if (hp_som_som_object_present)
+ {
+ /* 1997-08-19 Can't assign HP aCC pointers to methods. No details of
+ the implementation yet; but the pointer appears to point to a code
+ sequence (thunk) in memory -- in any case it is *not* the address
+ of the function as it would be in a naive implementation. */
+ if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_METHOD))
+ error ("Assignment to pointers to methods not implemented with HP aCC");
+
+ /* HP aCC pointers to data members require a constant bias */
+ if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_MEMBER))
+ {
+ unsigned int * ptr = (unsigned int *) VALUE_CONTENTS (arg2); /* forces evaluation */
+ *ptr |= 0x20000000; /* set 29th bit */
+ }
+ }
+
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
return value_assign (arg1, arg2);
@@ -993,7 +1172,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
return arg1;
op = exp->elts[pc + 1].opcode;
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op);
+ return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside);
else if (op == BINOP_ADD)
arg2 = value_add (arg1, arg2);
else if (op == BINOP_SUB)
@@ -1008,7 +1187,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
return value_add (arg1, arg2);
@@ -1018,7 +1197,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
return value_sub (arg1, arg2);
@@ -1036,7 +1215,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
if (noside == EVAL_AVOID_SIDE_EFFECTS
&& (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD))
@@ -1056,24 +1235,31 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- /* If the user attempts to subscript something that has no target
- type (like a plain int variable for example), then report this
- as an error. */
-
- type = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (arg1)));
- if (type)
- return value_zero (type, VALUE_LVAL (arg1));
- else
- error ("cannot subscript something of type `%s'",
- TYPE_NAME (VALUE_TYPE (arg1)));
- }
-
if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
- return value_subscript (arg1, arg2);
+ {
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
+
+ COERCE_REF (arg1);
+ type = check_typedef (VALUE_TYPE (arg1));
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_PTR)
+ {
+ if (TYPE_NAME (type))
+ error ("cannot subscript something of type `%s'",
+ TYPE_NAME (type));
+ else
+ error ("cannot subscript requested type");
+ }
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
+ else
+ return value_subscript (arg1, arg2);
+ }
case BINOP_IN:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
@@ -1124,7 +1310,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (binop_user_defined_p (op, arg1, arg2))
{
- arg1 = value_x_binop (arg1, arg2, op, OP_NULL);
+ arg1 = value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1228,7 +1414,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (binop_user_defined_p (op, arg1, arg2))
{
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1254,7 +1440,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (binop_user_defined_p (op, arg1, arg2))
{
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1272,7 +1458,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
{
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1287,7 +1473,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
{
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1302,7 +1488,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
{
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1317,7 +1503,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
{
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1332,7 +1518,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
{
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1347,7 +1533,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
goto nosideret;
if (binop_user_defined_p (op, arg1, arg2))
{
- return value_x_binop (arg1, arg2, op, OP_NULL);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
@@ -1360,7 +1546,8 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
- if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT)
+ type = check_typedef (VALUE_TYPE (arg2));
+ if (TYPE_CODE (type) != TYPE_CODE_INT)
error ("Non-integral right operand for \"@\" operator.");
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
@@ -1379,7 +1566,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op);
+ return value_x_unop (arg1, op, noside);
else
return value_neg (arg1);
@@ -1391,7 +1578,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_user_defined_p (UNOP_COMPLEMENT, arg1))
- return value_x_unop (arg1, UNOP_COMPLEMENT);
+ return value_x_unop (arg1, UNOP_COMPLEMENT, noside);
else
return value_complement (arg1);
@@ -1400,18 +1587,24 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op);
+ return value_x_unop (arg1, op, noside);
else
- return value_from_longest (builtin_type_int,
+ return value_from_longest (LA_BOOL_TYPE,
(LONGEST) value_logical_not (arg1));
case UNOP_IND:
if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if ((TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) &&
+ ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_METHOD) ||
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_MEMBER)))
+ error ("Attempt to dereference pointer to member without an object");
if (noside == EVAL_SKIP)
goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ if (unop_user_defined_p (op, arg1))
+ return value_x_unop (arg1, op, noside);
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
type = check_typedef (VALUE_TYPE (arg1));
if (TYPE_CODE (type) == TYPE_CODE_PTR
@@ -1445,9 +1638,20 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
evaluate_subexp (expect_type, exp, pos, EVAL_SKIP);
goto nosideret;
}
-
- return evaluate_subexp_for_address (exp, pos, noside);
-
+ else
+ {
+ value_ptr retvalp = evaluate_subexp_for_address (exp, pos, noside);
+ /* If HP aCC object, use bias for pointers to members */
+ if (hp_som_som_object_present &&
+ (TYPE_CODE (VALUE_TYPE (retvalp)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (retvalp))) == TYPE_CODE_MEMBER))
+ {
+ unsigned int * ptr = (unsigned int *) VALUE_CONTENTS (retvalp); /* forces evaluation */
+ *ptr |= 0x20000000; /* set 29th bit */
+ }
+ return retvalp;
+ }
+
case UNOP_SIZEOF:
if (noside == EVAL_SKIP)
{
@@ -1475,7 +1679,8 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
return value_zero (exp->elts[pc + 1].type, lval_memory);
else
return value_at_lazy (exp->elts[pc + 1].type,
- value_as_pointer (arg1));
+ value_as_pointer (arg1),
+ NULL);
case UNOP_PREINCREMENT:
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
@@ -1483,7 +1688,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
- return value_x_unop (arg1, op);
+ return value_x_unop (arg1, op, noside);
}
else
{
@@ -1498,7 +1703,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
- return value_x_unop (arg1, op);
+ return value_x_unop (arg1, op, noside);
}
else
{
@@ -1513,7 +1718,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
- return value_x_unop (arg1, op);
+ return value_x_unop (arg1, op, noside);
}
else
{
@@ -1529,7 +1734,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
- return value_x_unop (arg1, op);
+ return value_x_unop (arg1, op, noside);
}
else
{
@@ -1716,6 +1921,10 @@ evaluate_subexp_for_sizeof (exp, pos)
(*pos)++;
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
type = check_typedef (VALUE_TYPE (val));
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF
+ && TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ error ("Attempt to take contents of a non-pointer value.");
type = check_typedef (TYPE_TARGET_TYPE (type));
return value_from_longest (builtin_type_int, (LONGEST)
TYPE_LENGTH (type));
diff --git a/contrib/gdb/gdb/exec.c b/contrib/gdb/gdb/exec.c
index dc71a49..87aed01 100644
--- a/contrib/gdb/gdb/exec.c
+++ b/contrib/gdb/gdb/exec.c
@@ -1,5 +1,6 @@
/* Work with executable files, for GDB.
- Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,7 +31,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/types.h>
#endif
-#include <sys/param.h>
#include <fcntl.h>
#include "gdb_string.h"
@@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
struct vmap *map_vmap PARAMS ((bfd *, bfd *));
+void (*file_changed_hook) PARAMS ((char *));
+
/* Prototypes for local functions */
static void add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
@@ -58,8 +60,20 @@ static void set_section_command PARAMS ((char *, int));
static void exec_files_info PARAMS ((struct target_ops *));
+static void bfdsec_to_vmap PARAMS ((bfd *, sec_ptr, PTR));
+
+static int ignore PARAMS ((CORE_ADDR, char *));
+
+static void init_exec_ops PARAMS ((void));
+
+void _initialize_exec PARAMS ((void));
+
extern int info_verbose;
+/* The target vector for executable files. */
+
+struct target_ops exec_ops;
+
/* The Binary File Descriptor handle for the executable file. */
bfd *exec_bfd = NULL;
@@ -70,17 +84,14 @@ int write_files = 0;
/* Text start and end addresses (KLUDGE) if needed */
-#ifdef NEED_TEXT_START_END
+#ifndef NEED_TEXT_START_END
+#define NEED_TEXT_START_END (0)
+#endif
CORE_ADDR text_start = 0;
CORE_ADDR text_end = 0;
-#endif
struct vmap *vmap;
-/* Forward decl */
-
-extern struct target_ops exec_ops;
-
/* ARGSUSED */
static void
exec_close (quitting)
@@ -140,20 +151,29 @@ exec_close (quitting)
/* Process the first arg in ARGS as the new exec file.
- Note that we have to explicitly ignore additional args, since we can
- be called from file_command(), which also calls symbol_file_command()
- which can take multiple args. */
+ This function is intended to be behave essentially the same
+ as exec_file_command, except that the latter will detect when
+ a target is being debugged, and will ask the user whether it
+ should be shut down first. (If the answer is "no", then the
+ new file is ignored.)
+
+ This file is used by exec_file_command, to do the work of opening
+ and processing the exec file after any prompting has happened.
+
+ And, it is used by child_attach, when the attach command was
+ given a pid but not a exec pathname, and the attach command could
+ figure out the pathname from the pid. (In this case, we shouldn't
+ ask the user whether the current target should be shut down --
+ we're supplying the exec pathname late for good reason.) */
void
-exec_file_command (args, from_tty)
+exec_file_attach (args, from_tty)
char *args;
int from_tty;
{
char **argv;
char *filename;
- target_preopen (from_tty);
-
/* Remove any previous exec file. */
unpush_target (&exec_ops);
@@ -171,7 +191,7 @@ exec_file_command (args, from_tty)
if (argv == NULL)
nomem (0);
- make_cleanup (freeargv, (char *) argv);
+ make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
for (; (*argv != NULL) && (**argv == '-'); argv++) {;}
if (*argv == NULL)
@@ -183,6 +203,15 @@ exec_file_command (args, from_tty)
scratch_chan = openp (getenv ("PATH"), 1, filename,
write_files? O_RDWR|O_BINARY: O_RDONLY|O_BINARY, 0,
&scratch_pathname);
+#if defined(__GO32__) || defined(_WIN32)
+ if (scratch_chan < 0)
+ {
+ char *exename = alloca (strlen (filename) + 5);
+ strcat (strcpy (exename, filename), ".exe");
+ scratch_chan = openp (getenv ("PATH"), 1, exename, write_files ?
+ O_RDWR|O_BINARY : O_RDONLY|O_BINARY, 0, &scratch_pathname);
+ }
+#endif
if (scratch_chan < 0)
perror_with_name (filename);
exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
@@ -233,37 +262,34 @@ exec_file_command (args, from_tty)
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
-#ifdef NEED_TEXT_START_END
-
/* text_end is sometimes used for where to put call dummies. A
few ports use these for other purposes too. */
-
- {
- struct section_table *p;
-
- /* 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;
- for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
- if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
- & (SEC_CODE | SEC_READONLY))
- {
- if (text_start > p->addr)
- text_start = p->addr;
- if (text_end < p->endaddr)
- text_end = p->endaddr;
- }
- }
-#endif
+ if (NEED_TEXT_START_END)
+ {
+ struct section_table *p;
+
+ /* 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;
+ for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+ if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
+ & (SEC_CODE | SEC_READONLY))
+ {
+ if (text_start > p->addr)
+ text_start = p->addr;
+ if (text_end < p->endaddr)
+ text_end = p->endaddr;
+ }
+ }
validate_files ();
- set_endian_from_file (exec_bfd);
+ set_gdbarch_from_file (exec_bfd);
push_target (&exec_ops);
@@ -272,7 +298,26 @@ exec_file_command (args, from_tty)
(*exec_file_display_hook) (filename);
}
else if (from_tty)
- printf_unfiltered ("No exec file now.\n");
+ printf_unfiltered ("No executable file now.\n");
+}
+
+/* Process the first arg in ARGS as the new exec file.
+
+ Note that we have to explicitly ignore additional args, since we can
+ be called from file_command(), which also calls symbol_file_command()
+ which can take multiple args. */
+
+void
+exec_file_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char **argv;
+ char *filename;
+
+ target_preopen (from_tty);
+
+ exec_file_attach (args, from_tty);
}
/* Set both the exec file and the symbol file, in one command.
@@ -288,6 +333,8 @@ file_command (arg, from_tty)
the exec file, but that's rough. */
exec_file_command (arg, from_tty);
symbol_file_command (arg, from_tty);
+ if (file_changed_hook)
+ file_changed_hook (arg);
}
@@ -354,20 +401,16 @@ bfdsec_to_vmap(abfd, sect, arg3)
if (STREQ (bfd_section_name (abfd, sect), ".text"))
{
- vp->tstart = 0;
+ vp->tstart = bfd_section_vma (abfd, sect);
vp->tend = vp->tstart + bfd_section_size (abfd, sect);
-
- /* When it comes to this adjustment value, in contrast to our previous
- belief shared objects should behave the same as the main load segment.
- This is the offset from the beginning of text section to the first
- real instruction. */
-
- vp->tadj = sect->filepos - bfd_section_vma (abfd, sect);
+ vp->tvma = bfd_section_vma (abfd, sect);
+ vp->toffs = sect->filepos;
}
else if (STREQ (bfd_section_name (abfd, sect), ".data"))
{
- vp->dstart = 0;
+ vp->dstart = bfd_section_vma (abfd, sect);
vp->dend = vp->dstart + bfd_section_size (abfd, sect);
+ vp->dvma = bfd_section_vma (abfd, sect);
}
/* Silently ignore other types of sections. (FIXME?) */
}
@@ -432,25 +475,79 @@ xfer_memory (memaddr, myaddr, len, write, target)
struct section_table *p;
CORE_ADDR nextsectaddr, memend;
boolean (*xfer_fn) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+ asection *section;
if (len <= 0)
abort();
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (memaddr);
+ if (pc_in_unmapped_range (memaddr, section))
+ memaddr = overlay_mapped_address (memaddr, section);
+ }
+
memend = memaddr + len;
xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents;
nextsectaddr = memend;
+#if 0 /* Stu's implementation */
+/* If a section has been specified, try to use it. Note that we cannot use the
+ specified section directly. This is because it usually comes from the
+ symbol file, which may be different from the exec or core file. Instead, we
+ have to lookup the specified section by name in the bfd associated with
+ to_sections. */
+
+ if (target_memory_bfd_section)
+ {
+ asection *s;
+ bfd *abfd;
+ asection *target_section;
+ bfd *target_bfd;
+
+ s = target_memory_bfd_section;
+ abfd = s->owner;
+
+ target_bfd = target->to_sections->bfd;
+ target_section = bfd_get_section_by_name (target_bfd, bfd_section_name (abfd, s));
+
+ if (target_section)
+ {
+ bfd_vma sec_addr;
+ bfd_size_type sec_size;
+
+ sec_addr = bfd_section_vma (target_bfd, target_section);
+ sec_size = target_section->_raw_size;
+
+ /* Make sure the requested memory starts inside the section. */
+
+ if (memaddr >= sec_addr
+ && memaddr < sec_addr + sec_size)
+ {
+ /* Cut back length in case request overflows the end of the section. */
+ len = min (len, sec_addr + sec_size - memaddr);
+
+ res = xfer_fn (target_bfd, target_section, myaddr, memaddr - sec_addr, len);
+
+ return res ? len : 0;
+ }
+ }
+ }
+#endif /* 0, Stu's implementation */
for (p = target->to_sections; p < target->to_sections_end; p++)
{
- if (p->addr <= memaddr)
- if (p->endaddr >= memend)
+ if (overlay_debugging && section && p->the_bfd_section &&
+ strcmp (section->name, p->the_bfd_section->name) != 0)
+ continue; /* not the section we need */
+ if (memaddr >= p->addr)
+ if (memend <= p->endaddr)
{
/* Entire transfer is within this section. */
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
- else if (p->endaddr <= memaddr)
+ else if (memaddr >= p->endaddr)
{
/* This section ends before the transfer starts. */
continue;
@@ -463,8 +560,8 @@ xfer_memory (memaddr, myaddr, len, write, target)
memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
- else if (p->addr < nextsectaddr)
- nextsectaddr = p->addr;
+ else
+ nextsectaddr = min (nextsectaddr, p->addr);
}
if (nextsectaddr >= memend)
@@ -585,7 +682,8 @@ set_section_command (args, from_tty)
}
/* If mourn is being called in all the right places, this could be say
- `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
+ `gdb internal error' (since generic_mourn calls
+ breakpoint_init_inferior). */
static int
ignore (addr, contents)
@@ -595,63 +693,50 @@ ignore (addr, contents)
return 0;
}
-struct target_ops exec_ops = {
- "exec", /* to_shortname */
- "Local exec file", /* to_longname */
- "Use an executable file as a target.\n\
-Specify the filename of the executable file.", /* to_doc */
- exec_file_command, /* to_open */
- exec_close, /* to_close */
- find_default_attach, /* to_attach */
- 0, /* to_detach */
- 0, /* to_resume */
- 0, /* to_wait */
- 0, /* to_fetch_registers */
- 0, /* to_store_registers */
- 0, /* to_prepare_to_store */
- xfer_memory, /* to_xfer_memory */
- exec_files_info, /* to_files_info */
- ignore, /* to_insert_breakpoint */
- ignore, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- 0, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- find_default_create_inferior, /* to_create_inferior */
- 0, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- file_stratum, /* to_stratum */
- 0, /* to_next */
- 0, /* to_has_all_memory */
- 1, /* to_has_memory */
- 0, /* to_has_stack */
- 0, /* to_has_registers */
- 0, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC, /* to_magic */
-};
+/* Fill in the exec file target vector. Very few entries need to be
+ defined. */
+
+void
+init_exec_ops ()
+{
+ exec_ops.to_shortname = "exec";
+ exec_ops.to_longname = "Local exec file";
+ exec_ops.to_doc = "Use an executable file as a target.\n\
+Specify the filename of the executable file.";
+ exec_ops.to_open = exec_file_command;
+ exec_ops.to_close = exec_close;
+ exec_ops.to_attach = find_default_attach;
+ exec_ops.to_require_attach = find_default_require_attach;
+ exec_ops.to_require_detach = find_default_require_detach;
+ exec_ops.to_xfer_memory = xfer_memory;
+ exec_ops.to_files_info = exec_files_info;
+ exec_ops.to_insert_breakpoint = ignore;
+ exec_ops.to_remove_breakpoint = ignore;
+ exec_ops.to_create_inferior = find_default_create_inferior;
+ exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ exec_ops.to_stratum = file_stratum;
+ exec_ops.to_has_memory = 1;
+ exec_ops.to_magic = OPS_MAGIC;
+}
void
-_initialize_exec()
+_initialize_exec ()
{
struct cmd_list_element *c;
- c = add_cmd ("file", class_files, file_command,
- "Use FILE as program to be debugged.\n\
+ init_exec_ops ();
+
+ if (!dbx_commands)
+ {
+ c = add_cmd ("file", class_files, file_command,
+ "Use FILE as program to be debugged.\n\
It is read for its symbols, for getting the contents of pure memory,\n\
and it is the program executed when you use the `run' command.\n\
If FILE cannot be found as specified, your execution directory path\n\
($PATH) is searched for a command of that name.\n\
No arg means to have no executable file and no symbols.", &cmdlist);
- c->completer = filename_completer;
+ c->completer = filename_completer;
+ }
c = add_cmd ("exec-file", class_files, exec_file_command,
"Use FILE as program for getting contents of pure memory.\n\
diff --git a/contrib/gdb/gdb/expprint.c b/contrib/gdb/gdb/expprint.c
index b44ada2..939919a 100644
--- a/contrib/gdb/gdb/expprint.c
+++ b/contrib/gdb/gdb/expprint.c
@@ -25,6 +25,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h"
#include "parser-defs.h"
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
/* Prototypes for local functions */
static void
@@ -120,7 +124,7 @@ print_subexp (exp, pos, stream, prec)
case OP_REGISTER:
(*pos) += 2;
fprintf_filtered (stream, "$%s",
- reg_names[longest_to_int (exp->elts[pc + 1].longconst)]);
+ REGISTER_NAME (longest_to_int (exp->elts[pc + 1].longconst)));
return;
case OP_BOOL:
@@ -163,14 +167,14 @@ print_subexp (exp, pos, stream, prec)
/* LA_PRINT_STRING will print using the current repeat count threshold.
If necessary, we can temporarily set it to zero, or pass it as an
additional parameter to LA_PRINT_STRING. -fnf */
- LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 0);
+ LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0);
return;
case OP_BITSTRING:
nargs = longest_to_int (exp -> elts[pc + 1].longconst);
(*pos)
+= 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
- fprintf (stream, "B'<unimplemented>'");
+ fprintf_unfiltered (stream, "B'<unimplemented>'");
return;
case OP_ARRAY:
@@ -211,7 +215,7 @@ print_subexp (exp, pos, stream, prec)
}
if (tem > 0)
{
- LA_PRINT_STRING (stream, tempstr, nargs - 1, 0);
+ LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0);
(*pos) = pc;
}
else
@@ -300,7 +304,6 @@ print_subexp (exp, pos, stream, prec)
fputs_filtered (&exp->elts[pc + 2].string, stream);
return;
-
case BINOP_SUBSCRIPT:
print_subexp (exp, pos, stream, PREC_SUFFIX);
fputs_filtered ("[", stream);
@@ -342,7 +345,8 @@ print_subexp (exp, pos, stream, prec)
its type; print the value in the type of the MEMVAL. */
(*pos) += 4;
val = value_at_lazy (exp->elts[pc + 1].type,
- (CORE_ADDR) exp->elts[pc + 5].longconst);
+ (CORE_ADDR) exp->elts[pc + 5].longconst,
+ NULL);
value_print (val, stream, 0, Val_no_prettyprint);
} else {
fputs_filtered ("{", stream);
@@ -493,13 +497,117 @@ op_string(op)
return NULL;
}
-#ifdef DEBUG_EXPRESSIONS
+#ifdef MAINTENANCE_CMDS
/* Support for dumping the raw data from expressions in a human readable
form. */
+static char * op_name PARAMS ((int opcode));
+
+static char *
+op_name (opcode)
+ int opcode;
+{
+ switch (opcode)
+ {
+ default:
+ {
+ static char buf[30];
+
+ sprintf (buf, "<unknown %d>", opcode);
+ return buf;
+ }
+ case OP_NULL: return "OP_NULL";
+ case BINOP_ADD: return "BINOP_ADD";
+ case BINOP_SUB: return "BINOP_SUB";
+ case BINOP_MUL: return "BINOP_MUL";
+ case BINOP_DIV: return "BINOP_DIV";
+ case BINOP_REM: return "BINOP_REM";
+ case BINOP_MOD: return "BINOP_MOD";
+ case BINOP_LSH: return "BINOP_LSH";
+ case BINOP_RSH: return "BINOP_RSH";
+ case BINOP_LOGICAL_AND: return "BINOP_LOGICAL_AND";
+ case BINOP_LOGICAL_OR: return "BINOP_LOGICAL_OR";
+ case BINOP_BITWISE_AND: return "BINOP_BITWISE_AND";
+ case BINOP_BITWISE_IOR: return "BINOP_BITWISE_IOR";
+ case BINOP_BITWISE_XOR: return "BINOP_BITWISE_XOR";
+ case BINOP_EQUAL: return "BINOP_EQUAL";
+ case BINOP_NOTEQUAL: return "BINOP_NOTEQUAL";
+ case BINOP_LESS: return "BINOP_LESS";
+ case BINOP_GTR: return "BINOP_GTR";
+ case BINOP_LEQ: return "BINOP_LEQ";
+ case BINOP_GEQ: return "BINOP_GEQ";
+ case BINOP_REPEAT: return "BINOP_REPEAT";
+ case BINOP_ASSIGN: return "BINOP_ASSIGN";
+ case BINOP_COMMA: return "BINOP_COMMA";
+ case BINOP_SUBSCRIPT: return "BINOP_SUBSCRIPT";
+ case MULTI_SUBSCRIPT: return "MULTI_SUBSCRIPT";
+ case BINOP_EXP: return "BINOP_EXP";
+ case BINOP_MIN: return "BINOP_MIN";
+ case BINOP_MAX: return "BINOP_MAX";
+ case BINOP_SCOPE: return "BINOP_SCOPE";
+ case STRUCTOP_MEMBER: return "STRUCTOP_MEMBER";
+ case STRUCTOP_MPTR: return "STRUCTOP_MPTR";
+ case BINOP_INTDIV: return "BINOP_INTDIV";
+ case BINOP_ASSIGN_MODIFY: return "BINOP_ASSIGN_MODIFY";
+ case BINOP_VAL: return "BINOP_VAL";
+ case BINOP_INCL: return "BINOP_INCL";
+ case BINOP_EXCL: return "BINOP_EXCL";
+ case BINOP_CONCAT: return "BINOP_CONCAT";
+ case BINOP_RANGE: return "BINOP_RANGE";
+ case BINOP_END: return "BINOP_END";
+ case TERNOP_COND: return "TERNOP_COND";
+ case TERNOP_SLICE: return "TERNOP_SLICE";
+ case TERNOP_SLICE_COUNT: return "TERNOP_SLICE_COUNT";
+ case OP_LONG: return "OP_LONG";
+ case OP_DOUBLE: return "OP_DOUBLE";
+ case OP_VAR_VALUE: return "OP_VAR_VALUE";
+ case OP_LAST: return "OP_LAST";
+ case OP_REGISTER: return "OP_REGISTER";
+ case OP_INTERNALVAR: return "OP_INTERNALVAR";
+ case OP_FUNCALL: return "OP_FUNCALL";
+ case OP_STRING: return "OP_STRING";
+ case OP_BITSTRING: return "OP_BITSTRING";
+ case OP_ARRAY: return "OP_ARRAY";
+ case UNOP_CAST: return "UNOP_CAST";
+ case UNOP_MEMVAL: return "UNOP_MEMVAL";
+ case UNOP_NEG: return "UNOP_NEG";
+ case UNOP_LOGICAL_NOT: return "UNOP_LOGICAL_NOT";
+ case UNOP_COMPLEMENT: return "UNOP_COMPLEMENT";
+ case UNOP_IND: return "UNOP_IND";
+ case UNOP_ADDR: return "UNOP_ADDR";
+ case UNOP_PREINCREMENT: return "UNOP_PREINCREMENT";
+ case UNOP_POSTINCREMENT: return "UNOP_POSTINCREMENT";
+ case UNOP_PREDECREMENT: return "UNOP_PREDECREMENT";
+ case UNOP_POSTDECREMENT: return "UNOP_POSTDECREMENT";
+ case UNOP_SIZEOF: return "UNOP_SIZEOF";
+ case UNOP_LOWER: return "UNOP_LOWER";
+ case UNOP_UPPER: return "UNOP_UPPER";
+ case UNOP_LENGTH: return "UNOP_LENGTH";
+ case UNOP_PLUS: return "UNOP_PLUS";
+ case UNOP_CAP: return "UNOP_CAP";
+ case UNOP_CHR: return "UNOP_CHR";
+ case UNOP_ORD: return "UNOP_ORD";
+ case UNOP_ABS: return "UNOP_ABS";
+ case UNOP_FLOAT: return "UNOP_FLOAT";
+ case UNOP_HIGH: return "UNOP_HIGH";
+ case UNOP_MAX: return "UNOP_MAX";
+ case UNOP_MIN: return "UNOP_MIN";
+ case UNOP_ODD: return "UNOP_ODD";
+ case UNOP_TRUNC: return "UNOP_TRUNC";
+ case OP_BOOL: return "OP_BOOL";
+ case OP_M2_STRING: return "OP_M2_STRING";
+ case STRUCTOP_STRUCT: return "STRUCTOP_STRUCT";
+ case STRUCTOP_PTR: return "STRUCTOP_PTR";
+ case OP_THIS: return "OP_THIS";
+ case OP_SCOPE: return "OP_SCOPE";
+ case OP_TYPE: return "OP_TYPE";
+ case OP_LABELED: return "OP_LABELED";
+ }
+}
+
void
-dump_expression (exp, stream, note)
+dump_prefix_expression (exp, stream, note)
struct expression *exp;
GDB_FILE *stream;
char *note;
@@ -511,8 +619,12 @@ dump_expression (exp, stream, note)
fprintf_filtered (stream, "Dump of expression @ ");
gdb_print_address (exp, stream);
- fprintf_filtered (stream, ", %s:\n", note);
- fprintf_filtered (stream, "\tLanguage %s, %d elements, %d bytes each.\n",
+ fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ if (exp->elts[0].opcode != OP_TYPE)
+ print_expression (exp, stream);
+ else
+ fprintf_filtered (stream, "Type printing not yet supported....");
+ fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %d bytes each.\n",
exp->language_defn->la_name, exp -> nelts,
sizeof (union exp_element));
fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode",
@@ -520,104 +632,11 @@ dump_expression (exp, stream, note)
for (elt = 0; elt < exp -> nelts; elt++)
{
fprintf_filtered (stream, "\t%5d ", elt);
- switch (exp -> elts[elt].opcode)
- {
- default: opcode_name = "<unknown>"; break;
- case OP_NULL: opcode_name = "OP_NULL"; break;
- case BINOP_ADD: opcode_name = "BINOP_ADD"; break;
- case BINOP_SUB: opcode_name = "BINOP_SUB"; break;
- case BINOP_MUL: opcode_name = "BINOP_MUL"; break;
- case BINOP_DIV: opcode_name = "BINOP_DIV"; break;
- case BINOP_REM: opcode_name = "BINOP_REM"; break;
- case BINOP_MOD: opcode_name = "BINOP_MOD"; break;
- case BINOP_LSH: opcode_name = "BINOP_LSH"; break;
- case BINOP_RSH: opcode_name = "BINOP_RSH"; break;
- case BINOP_LOGICAL_AND: opcode_name = "BINOP_LOGICAL_AND"; break;
- case BINOP_LOGICAL_OR: opcode_name = "BINOP_LOGICAL_OR"; break;
- case BINOP_BITWISE_AND: opcode_name = "BINOP_BITWISE_AND"; break;
- case BINOP_BITWISE_IOR: opcode_name = "BINOP_BITWISE_IOR"; break;
- case BINOP_BITWISE_XOR: opcode_name = "BINOP_BITWISE_XOR"; break;
- case BINOP_EQUAL: opcode_name = "BINOP_EQUAL"; break;
- case BINOP_NOTEQUAL: opcode_name = "BINOP_NOTEQUAL"; break;
- case BINOP_LESS: opcode_name = "BINOP_LESS"; break;
- case BINOP_GTR: opcode_name = "BINOP_GTR"; break;
- case BINOP_LEQ: opcode_name = "BINOP_LEQ"; break;
- case BINOP_GEQ: opcode_name = "BINOP_GEQ"; break;
- case BINOP_REPEAT: opcode_name = "BINOP_REPEAT"; break;
- case BINOP_ASSIGN: opcode_name = "BINOP_ASSIGN"; break;
- case BINOP_COMMA: opcode_name = "BINOP_COMMA"; break;
- case BINOP_SUBSCRIPT: opcode_name = "BINOP_SUBSCRIPT"; break;
- case MULTI_SUBSCRIPT: opcode_name = "MULTI_SUBSCRIPT"; break;
- case BINOP_EXP: opcode_name = "BINOP_EXP"; break;
- case BINOP_MIN: opcode_name = "BINOP_MIN"; break;
- case BINOP_MAX: opcode_name = "BINOP_MAX"; break;
- case BINOP_SCOPE: opcode_name = "BINOP_SCOPE"; break;
- case STRUCTOP_MEMBER: opcode_name = "STRUCTOP_MEMBER"; break;
- case STRUCTOP_MPTR: opcode_name = "STRUCTOP_MPTR"; break;
- case BINOP_INTDIV: opcode_name = "BINOP_INTDIV"; break;
- case BINOP_ASSIGN_MODIFY: opcode_name = "BINOP_ASSIGN_MODIFY"; break;
- case BINOP_VAL: opcode_name = "BINOP_VAL"; break;
- case BINOP_INCL: opcode_name = "BINOP_INCL"; break;
- case BINOP_EXCL: opcode_name = "BINOP_EXCL"; break;
- case BINOP_CONCAT: opcode_name = "BINOP_CONCAT"; break;
- case BINOP_RANGE: opcode_name = "BINOP_RANGE"; break;
- case BINOP_END: opcode_name = "BINOP_END"; break;
- case TERNOP_COND: opcode_name = "TERNOP_COND"; break;
- case TERNOP_SLICE: opcode_name = "TERNOP_SLICE"; break;
- case TERNOP_SLICE_COUNT: opcode_name = "TERNOP_SLICE_COUNT"; break;
- case OP_LONG: opcode_name = "OP_LONG"; break;
- case OP_DOUBLE: opcode_name = "OP_DOUBLE"; break;
- case OP_VAR_VALUE: opcode_name = "OP_VAR_VALUE"; break;
- case OP_LAST: opcode_name = "OP_LAST"; break;
- case OP_REGISTER: opcode_name = "OP_REGISTER"; break;
- case OP_INTERNALVAR: opcode_name = "OP_INTERNALVAR"; break;
- case OP_FUNCALL: opcode_name = "OP_FUNCALL"; break;
- case OP_STRING: opcode_name = "OP_STRING"; break;
- case OP_BITSTRING: opcode_name = "OP_BITSTRING"; break;
- case OP_ARRAY: opcode_name = "OP_ARRAY"; break;
- case UNOP_CAST: opcode_name = "UNOP_CAST"; break;
- case UNOP_MEMVAL: opcode_name = "UNOP_MEMVAL"; break;
- case UNOP_NEG: opcode_name = "UNOP_NEG"; break;
- case UNOP_LOGICAL_NOT: opcode_name = "UNOP_LOGICAL_NOT"; break;
- case UNOP_COMPLEMENT: opcode_name = "UNOP_COMPLEMENT"; break;
- case UNOP_IND: opcode_name = "UNOP_IND"; break;
- case UNOP_ADDR: opcode_name = "UNOP_ADDR"; break;
- case UNOP_PREINCREMENT: opcode_name = "UNOP_PREINCREMENT"; break;
- case UNOP_POSTINCREMENT: opcode_name = "UNOP_POSTINCREMENT"; break;
- case UNOP_PREDECREMENT: opcode_name = "UNOP_PREDECREMENT"; break;
- case UNOP_POSTDECREMENT: opcode_name = "UNOP_POSTDECREMENT"; break;
- case UNOP_SIZEOF: opcode_name = "UNOP_SIZEOF"; break;
- case UNOP_LOWER: opcode_name = "UNOP_LOWER"; break;
- case UNOP_UPPER: opcode_name = "UNOP_UPPER"; break;
- case UNOP_LENGTH: opcode_name = "UNOP_LENGTH"; break;
- case UNOP_PLUS: opcode_name = "UNOP_PLUS"; break;
- case UNOP_CAP: opcode_name = "UNOP_CAP"; break;
- case UNOP_CHR: opcode_name = "UNOP_CHR"; break;
- case UNOP_ORD: opcode_name = "UNOP_ORD"; break;
- case UNOP_ABS: opcode_name = "UNOP_ABS"; break;
- case UNOP_FLOAT: opcode_name = "UNOP_FLOAT"; break;
- case UNOP_HIGH: opcode_name = "UNOP_HIGH"; break;
- case UNOP_MAX: opcode_name = "UNOP_MAX"; break;
- case UNOP_MIN: opcode_name = "UNOP_MIN"; break;
- case UNOP_ODD: opcode_name = "UNOP_ODD"; break;
- case UNOP_TRUNC: opcode_name = "UNOP_TRUNC"; break;
- case OP_BOOL: opcode_name = "OP_BOOL"; break;
- case OP_M2_STRING: opcode_name = "OP_M2_STRING"; break;
- case STRUCTOP_STRUCT: opcode_name = "STRUCTOP_STRUCT"; break;
- case STRUCTOP_PTR: opcode_name = "STRUCTOP_PTR"; break;
- case OP_THIS: opcode_name = "OP_THIS"; break;
- case OP_SCOPE: opcode_name = "OP_SCOPE"; break;
- case OP_TYPE: opcode_name = "OP_TYPE"; break;
- case OP_LABELED: opcode_name = "OP_LABELED"; break;
- }
+ opcode_name = op_name (exp -> elts[elt].opcode);
+
fprintf_filtered (stream, "%20s ", opcode_name);
- fprintf_filtered (stream,
-#if defined (PRINTF_HAS_LONG_LONG)
- "%ll16x ",
-#else
- "%l16x ",
-#endif
- exp -> elts[elt].longconst);
+ print_longest (stream, 'd', 0, exp -> elts[elt].longconst);
+ fprintf_filtered (stream, " ");
for (eltscan = (char *) &exp->elts[elt],
eltsize = sizeof (union exp_element) ;
@@ -631,4 +650,254 @@ dump_expression (exp, stream, note)
}
}
-#endif /* DEBUG_EXPRESSIONS */
+static int dump_subexp PARAMS ((struct expression *exp, GDB_FILE *stream, int elt));
+
+static int
+dump_subexp (exp, stream, elt)
+ struct expression *exp;
+ GDB_FILE *stream;
+ int elt;
+{
+ static int indent = 0;
+ int i;
+
+ fprintf_filtered (stream, "\n");
+ fprintf_filtered (stream, "\t%5d ", elt);
+
+ for (i = 1; i <= indent; i++)
+ fprintf_filtered (stream, " ");
+ indent += 2;
+
+ fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode));
+
+ switch (exp -> elts[elt++].opcode)
+ {
+ case TERNOP_COND:
+ case TERNOP_SLICE:
+ case TERNOP_SLICE_COUNT:
+ elt = dump_subexp (exp, stream, elt);
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_MOD:
+ case BINOP_LSH:
+ case BINOP_RSH:
+ case BINOP_LOGICAL_AND:
+ case BINOP_LOGICAL_OR:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
+ case BINOP_REPEAT:
+ case BINOP_ASSIGN:
+ case BINOP_COMMA:
+ case BINOP_SUBSCRIPT:
+ case BINOP_EXP:
+ case BINOP_MIN:
+ case BINOP_MAX:
+ case BINOP_SCOPE:
+ case BINOP_INTDIV:
+ case BINOP_ASSIGN_MODIFY:
+ case BINOP_VAL:
+ case BINOP_INCL:
+ case BINOP_EXCL:
+ case BINOP_CONCAT:
+ case BINOP_IN:
+ case BINOP_RANGE:
+ case BINOP_END:
+ elt = dump_subexp (exp, stream, elt);
+ case UNOP_NEG:
+ case UNOP_LOGICAL_NOT:
+ case UNOP_COMPLEMENT:
+ case UNOP_IND:
+ case UNOP_ADDR:
+ case UNOP_PREINCREMENT:
+ case UNOP_POSTINCREMENT:
+ case UNOP_PREDECREMENT:
+ case UNOP_POSTDECREMENT:
+ case UNOP_SIZEOF:
+ case UNOP_PLUS:
+ case UNOP_CAP:
+ case UNOP_CHR:
+ case UNOP_ORD:
+ case UNOP_ABS:
+ case UNOP_FLOAT:
+ case UNOP_HIGH:
+ case UNOP_MAX:
+ case UNOP_MIN:
+ case UNOP_ODD:
+ case UNOP_TRUNC:
+ case UNOP_LOWER:
+ case UNOP_UPPER:
+ case UNOP_LENGTH:
+ case UNOP_CARD:
+ case UNOP_CHMAX:
+ case UNOP_CHMIN:
+ elt = dump_subexp (exp, stream, elt);
+ break;
+ case OP_LONG:
+ fprintf_filtered (stream, "Type @0x%x (", exp->elts[elt].type);
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, "), value %ld (0x%lx)",
+ (long)exp->elts[elt+1].longconst,
+ (long)exp->elts[elt+1].longconst);
+ elt += 3;
+ break;
+ case OP_DOUBLE:
+ fprintf_filtered (stream, "Type @0x%x (", exp->elts[elt].type);
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, "), value %g",
+ (double)exp->elts[elt+1].doubleconst);
+ elt += 3;
+ break;
+ case OP_VAR_VALUE:
+ fprintf_filtered (stream, "Block @0x%x, symbol @0x%x (%s)",
+ exp->elts[elt].block,
+ exp->elts[elt+1].symbol,
+ SYMBOL_NAME (exp->elts[elt+1].symbol));
+ elt += 3;
+ break;
+ case OP_LAST:
+ fprintf_filtered (stream, "History element %ld",
+ (long)exp->elts[elt].longconst);
+ elt += 2;
+ break;
+ case OP_REGISTER:
+ fprintf_filtered (stream, "Register %ld",
+ (long)exp->elts[elt].longconst);
+ elt += 2;
+ break;
+ case OP_INTERNALVAR:
+ fprintf_filtered (stream, "Internal var @0x%x (%s)",
+ exp->elts[elt].internalvar,
+ exp->elts[elt].internalvar->name);
+ elt += 2;
+ break;
+ case OP_FUNCALL:
+ {
+ int nargs;
+
+ nargs = longest_to_int (exp->elts[elt].longconst);
+
+ fprintf_filtered (stream, "Number of args: %d", nargs);
+ elt += 2;
+
+ for (i = 1; i <= nargs + 1; i++)
+ elt = dump_subexp (exp, stream, elt);
+ }
+ break;
+ case OP_ARRAY:
+ {
+ int lower, upper;
+ int i;
+
+ lower = longest_to_int (exp->elts[elt].longconst);
+ upper = longest_to_int (exp->elts[elt + 1].longconst);
+
+ fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper);
+ elt += 3;
+
+ for (i = 1; i <= upper - lower + 1; i++)
+ elt = dump_subexp (exp, stream, elt);
+ }
+ break;
+ case UNOP_MEMVAL:
+ case UNOP_CAST:
+ fprintf_filtered (stream, "Type @0x%x (",
+ exp->elts[elt].type);
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ")");
+ elt = dump_subexp (exp, stream, elt + 2);
+ break;
+ case OP_TYPE:
+ fprintf_filtered (stream, "Type @0x%x (",
+ exp->elts[elt].type);
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ")");
+ elt += 2;
+ break;
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ {
+ char *elem_name;
+ int len;
+
+ len = longest_to_int (exp->elts[elt].longconst);
+ elem_name = &exp->elts[elt + 1].string;
+
+ fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name);
+ elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1));
+ }
+ break;
+ case OP_SCOPE:
+ {
+ char *elem_name;
+ int len;
+
+ fprintf_filtered (stream, "Type @0x%x (", exp->elts[elt].type);
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ") ");
+
+ len = longest_to_int (exp->elts[elt + 1].longconst);
+ elem_name = &exp->elts[elt + 2].string;
+
+ fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name);
+ elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
+ }
+ break;
+ default:
+ case OP_NULL:
+ case STRUCTOP_MEMBER:
+ case STRUCTOP_MPTR:
+ case MULTI_SUBSCRIPT:
+ case OP_F77_UNDETERMINED_ARGLIST:
+ case OP_COMPLEX:
+ case OP_STRING:
+ case OP_BITSTRING:
+ case OP_BOOL:
+ case OP_M2_STRING:
+ case OP_THIS:
+ case OP_LABELED:
+ case OP_NAME:
+ case OP_EXPRSTRING:
+ fprintf_filtered (stream, "Unknown format");
+ }
+
+ indent -= 2;
+
+ return elt;
+}
+
+void
+dump_postfix_expression (exp, stream, note)
+ struct expression *exp;
+ GDB_FILE *stream;
+ char *note;
+{
+ int elt;
+
+ fprintf_filtered (stream, "Dump of expression @ ");
+ gdb_print_address (exp, stream);
+ fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ if (exp->elts[0].opcode != OP_TYPE)
+ print_expression (exp, stream);
+ else
+ fputs_filtered ("Type printing not yet supported....", stream);
+ fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %d bytes each.\n",
+ exp->language_defn->la_name, exp -> nelts,
+ sizeof (union exp_element));
+ fputs_filtered ("\n", stream);
+
+ for (elt = 0; elt < exp -> nelts;)
+ elt = dump_subexp (exp, stream, elt);
+ fputs_filtered ("\n", stream);
+}
+
+#endif /* MAINTENANCE_CMDS */
diff --git a/contrib/gdb/gdb/expression.h b/contrib/gdb/gdb/expression.h
index 6526db1..310b2e2 100644
--- a/contrib/gdb/gdb/expression.h
+++ b/contrib/gdb/gdb/expression.h
@@ -20,9 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if !defined (EXPRESSION_H)
#define EXPRESSION_H 1
-#ifdef __STDC__
-struct block; /* Forward declaration for prototypes */
-#endif
+
+#include "symtab.h" /* Needed for "struct block" type. */
+
/* Definitions for saved C expressions. */
@@ -270,7 +270,6 @@ enum exp_opcode
STRUCTOP_STRUCT,
STRUCTOP_PTR,
-
/* C++ */
/* OP_THIS is just a placeholder for the class instance variable.
It just comes in a tight (OP_THIS, OP_THIS) pair. */
@@ -371,16 +370,13 @@ extern void print_expression PARAMS ((struct expression *, GDB_FILE *));
extern char *op_string PARAMS ((enum exp_opcode));
-/* To enable dumping of all parsed expressions in a human readable
- form, define DEBUG_EXPRESSIONS. This is a compile time constant
- at the moment, since it's not clear that this feature is important
- enough to include by default. */
-
-#ifdef DEBUG_EXPRESSIONS
-extern void dump_expression PARAMS ((struct expression *, GDB_FILE *, char *));
-#define DUMP_EXPRESSION(exp,file,note) dump_expression ((exp), (file), (note))
-#else
-#define DUMP_EXPRESSION(exp,file,note) /* Null expansion */
-#endif /* DEBUG_EXPRESSIONS */
+#ifdef MAINTENANCE_CMDS
+extern void dump_prefix_expression PARAMS ((struct expression *,
+ GDB_FILE *,
+ char *));
+extern void dump_postfix_expression PARAMS ((struct expression *,
+ GDB_FILE *,
+ char *));
+#endif /* MAINTENANCE_CMDS */
#endif /* !defined (EXPRESSION_H) */
diff --git a/contrib/gdb/gdb/f-exp.tab.c b/contrib/gdb/gdb/f-exp.tab.c
index 5ba51da..ef7d25e 100644
--- a/contrib/gdb/gdb/f-exp.tab.c
+++ b/contrib/gdb/gdb/f-exp.tab.c
@@ -1,5 +1,6 @@
-/* A Bison parser, made from ./f-exp.y with Bison version GNU Bison version 1.24
+/* A Bison parser, made from f-exp.y
+ by GNU Bison version 1.25
*/
#define YYBISON 1 /* Identify Bison output. */
@@ -41,7 +42,7 @@
#define RSH 292
#define UNARY 293
-#line 43 "./f-exp.y"
+#line 43 "f-exp.y"
#include "defs.h"
@@ -111,8 +112,12 @@ static int yylex PARAMS ((void));
void yyerror PARAMS ((char *));
+static void growbuf_by_size PARAMS ((int));
-#line 118 "./f-exp.y"
+static int match_string_literal PARAMS ((void));
+
+
+#line 122 "f-exp.y"
typedef union
{
LONGEST lval;
@@ -134,27 +139,10 @@ typedef union
struct type **tvec;
int *ivec;
} YYSTYPE;
-#line 140 "./f-exp.y"
+#line 144 "f-exp.y"
/* YYSTYPE gets defined by %union */
static int parse_number PARAMS ((char *, int, int, YYSTYPE *));
-
-#ifndef YYLTYPE
-typedef
- struct yyltype
- {
- int timestamp;
- int first_line;
- int first_column;
- int last_line;
- int last_column;
- char *text;
- }
- yyltype;
-
-#define YYLTYPE yyltype
-#endif
-
#include <stdio.h>
#ifndef __cplusplus
@@ -249,16 +237,20 @@ static const short yyrhs[] = { 57,
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 217, 218, 221, 227, 232, 235, 238, 242, 246, 250,
- 259, 261, 267, 270, 274, 277, 281, 286, 290, 294,
- 302, 306, 310, 314, 318, 322, 326, 330, 334, 338,
- 342, 346, 350, 354, 358, 362, 366, 370, 375, 379,
- 383, 389, 396, 405, 412, 415, 418, 426, 433, 441,
- 485, 488, 489, 532, 534, 536, 538, 540, 543, 545,
- 547, 551, 553, 558, 560, 562, 564, 566, 568, 570,
- 572, 574, 576, 578, 580, 582, 586, 590, 595, 602,
- 604, 606, 610
+ 221, 222, 225, 231, 236, 239, 242, 246, 250, 254,
+ 263, 265, 271, 274, 278, 281, 285, 290, 294, 298,
+ 306, 310, 314, 318, 322, 326, 330, 334, 338, 342,
+ 346, 350, 354, 358, 362, 366, 370, 374, 379, 383,
+ 387, 393, 400, 409, 416, 419, 422, 430, 437, 445,
+ 489, 492, 493, 536, 538, 540, 542, 544, 547, 549,
+ 551, 555, 557, 562, 564, 566, 568, 570, 572, 574,
+ 576, 578, 580, 582, 584, 586, 590, 594, 599, 606,
+ 608, 610, 614
};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
static const char * const yytname[] = { "$","error","$undefined.","INT","FLOAT",
"STRING_LITERAL","BOOLEAN_LITERAL","NAME","TYPENAME","NAME_OR_INT","SIZEOF",
@@ -269,8 +261,7 @@ static const char * const yytname[] = { "$","error","$undefined.","INT","FLOAT
"'^'","'&'","EQUAL","NOTEQUAL","LESSTHAN","GREATERTHAN","LEQ","GEQ","LSH","RSH",
"'@'","'+'","'-'","'*'","'/'","'%'","UNARY","'('","')'","'~'","':'","start",
"type_exp","exp","@1","arglist","substring","complexnum","variable","type","ptype",
-"abs_decl","direct_abs_decl","func_mod","typebase","nonempty_typelist","name_not_typename",
-""
+"abs_decl","direct_abs_decl","func_mod","typebase","nonempty_typelist","name_not_typename", NULL
};
#endif
@@ -442,7 +433,7 @@ static const short yycheck[] = { 0,
44, 45, 46, 47, 48, 49, -1, 51
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/unsupported/share/bison.simple"
+#line 3 "/stone/jimb/main-98r2/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -595,16 +586,16 @@ int yyparse (void);
#endif
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
-#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
#ifndef __cplusplus
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (from, to, count)
- char *from;
+__yy_memcpy (to, from, count)
char *to;
+ char *from;
int count;
{
register char *f = from;
@@ -620,7 +611,7 @@ __yy_memcpy (from, to, count)
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (char *from, char *to, int count)
+__yy_memcpy (char *to, char *from, int count)
{
register char *f = from;
register char *t = to;
@@ -633,7 +624,7 @@ __yy_memcpy (char *from, char *to, int count)
#endif
#endif
-#line 192 "/usr/unsupported/share/bison.simple"
+#line 196 "/stone/jimb/main-98r2/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -642,14 +633,20 @@ __yy_memcpy (char *from, char *to, int count)
to the proper pointer type. */
#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#else
-#define YYPARSE_PARAM
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
#define YYPARSE_PARAM_DECL
-#endif
+#endif /* not YYPARSE_PARAM */
int
-yyparse(YYPARSE_PARAM)
+yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
register int yystate;
@@ -766,12 +763,12 @@ yynewstate:
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
@@ -932,174 +929,174 @@ yyreduce:
switch (yyn) {
case 3:
-#line 222 "./f-exp.y"
+#line 226 "f-exp.y"
{ write_exp_elt_opcode(OP_TYPE);
write_exp_elt_type(yyvsp[0].tval);
write_exp_elt_opcode(OP_TYPE); ;
break;}
case 4:
-#line 228 "./f-exp.y"
+#line 232 "f-exp.y"
{ ;
break;}
case 5:
-#line 233 "./f-exp.y"
+#line 237 "f-exp.y"
{ write_exp_elt_opcode (UNOP_IND); ;
break;}
case 6:
-#line 236 "./f-exp.y"
+#line 240 "f-exp.y"
{ write_exp_elt_opcode (UNOP_ADDR); ;
break;}
case 7:
-#line 239 "./f-exp.y"
+#line 243 "f-exp.y"
{ write_exp_elt_opcode (UNOP_NEG); ;
break;}
case 8:
-#line 243 "./f-exp.y"
+#line 247 "f-exp.y"
{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ;
break;}
case 9:
-#line 247 "./f-exp.y"
+#line 251 "f-exp.y"
{ write_exp_elt_opcode (UNOP_COMPLEMENT); ;
break;}
case 10:
-#line 251 "./f-exp.y"
+#line 255 "f-exp.y"
{ write_exp_elt_opcode (UNOP_SIZEOF); ;
break;}
case 11:
-#line 260 "./f-exp.y"
+#line 264 "f-exp.y"
{ start_arglist (); ;
break;}
case 12:
-#line 262 "./f-exp.y"
+#line 266 "f-exp.y"
{ write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST);
write_exp_elt_longcst ((LONGEST) end_arglist ());
write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); ;
break;}
case 14:
-#line 271 "./f-exp.y"
+#line 275 "f-exp.y"
{ arglist_len = 1; ;
break;}
case 15:
-#line 275 "./f-exp.y"
+#line 279 "f-exp.y"
{ arglist_len = 2;;
break;}
case 16:
-#line 278 "./f-exp.y"
+#line 282 "f-exp.y"
{ arglist_len++; ;
break;}
case 17:
-#line 282 "./f-exp.y"
+#line 286 "f-exp.y"
{ ;
break;}
case 18:
-#line 287 "./f-exp.y"
+#line 291 "f-exp.y"
{ ;
break;}
case 19:
-#line 291 "./f-exp.y"
+#line 295 "f-exp.y"
{ write_exp_elt_opcode(OP_COMPLEX); ;
break;}
case 20:
-#line 295 "./f-exp.y"
+#line 299 "f-exp.y"
{ write_exp_elt_opcode (UNOP_CAST);
write_exp_elt_type (yyvsp[-2].tval);
write_exp_elt_opcode (UNOP_CAST); ;
break;}
case 21:
-#line 303 "./f-exp.y"
+#line 307 "f-exp.y"
{ write_exp_elt_opcode (BINOP_REPEAT); ;
break;}
case 22:
-#line 307 "./f-exp.y"
+#line 311 "f-exp.y"
{ write_exp_elt_opcode (BINOP_MUL); ;
break;}
case 23:
-#line 311 "./f-exp.y"
+#line 315 "f-exp.y"
{ write_exp_elt_opcode (BINOP_DIV); ;
break;}
case 24:
-#line 315 "./f-exp.y"
+#line 319 "f-exp.y"
{ write_exp_elt_opcode (BINOP_REM); ;
break;}
case 25:
-#line 319 "./f-exp.y"
+#line 323 "f-exp.y"
{ write_exp_elt_opcode (BINOP_ADD); ;
break;}
case 26:
-#line 323 "./f-exp.y"
+#line 327 "f-exp.y"
{ write_exp_elt_opcode (BINOP_SUB); ;
break;}
case 27:
-#line 327 "./f-exp.y"
+#line 331 "f-exp.y"
{ write_exp_elt_opcode (BINOP_LSH); ;
break;}
case 28:
-#line 331 "./f-exp.y"
+#line 335 "f-exp.y"
{ write_exp_elt_opcode (BINOP_RSH); ;
break;}
case 29:
-#line 335 "./f-exp.y"
+#line 339 "f-exp.y"
{ write_exp_elt_opcode (BINOP_EQUAL); ;
break;}
case 30:
-#line 339 "./f-exp.y"
+#line 343 "f-exp.y"
{ write_exp_elt_opcode (BINOP_NOTEQUAL); ;
break;}
case 31:
-#line 343 "./f-exp.y"
+#line 347 "f-exp.y"
{ write_exp_elt_opcode (BINOP_LEQ); ;
break;}
case 32:
-#line 347 "./f-exp.y"
+#line 351 "f-exp.y"
{ write_exp_elt_opcode (BINOP_GEQ); ;
break;}
case 33:
-#line 351 "./f-exp.y"
+#line 355 "f-exp.y"
{ write_exp_elt_opcode (BINOP_LESS); ;
break;}
case 34:
-#line 355 "./f-exp.y"
+#line 359 "f-exp.y"
{ write_exp_elt_opcode (BINOP_GTR); ;
break;}
case 35:
-#line 359 "./f-exp.y"
+#line 363 "f-exp.y"
{ write_exp_elt_opcode (BINOP_BITWISE_AND); ;
break;}
case 36:
-#line 363 "./f-exp.y"
+#line 367 "f-exp.y"
{ write_exp_elt_opcode (BINOP_BITWISE_XOR); ;
break;}
case 37:
-#line 367 "./f-exp.y"
+#line 371 "f-exp.y"
{ write_exp_elt_opcode (BINOP_BITWISE_IOR); ;
break;}
case 38:
-#line 371 "./f-exp.y"
+#line 375 "f-exp.y"
{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ;
break;}
case 39:
-#line 376 "./f-exp.y"
+#line 380 "f-exp.y"
{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ;
break;}
case 40:
-#line 380 "./f-exp.y"
+#line 384 "f-exp.y"
{ write_exp_elt_opcode (BINOP_ASSIGN); ;
break;}
case 41:
-#line 384 "./f-exp.y"
+#line 388 "f-exp.y"
{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
write_exp_elt_opcode (yyvsp[-1].opcode);
write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ;
break;}
case 42:
-#line 390 "./f-exp.y"
+#line 394 "f-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (yyvsp[0].typed_val.type);
write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val.val));
write_exp_elt_opcode (OP_LONG); ;
break;}
case 43:
-#line 397 "./f-exp.y"
+#line 401 "f-exp.y"
{ YYSTYPE val;
parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val);
write_exp_elt_opcode (OP_LONG);
@@ -1108,14 +1105,14 @@ case 43:
write_exp_elt_opcode (OP_LONG); ;
break;}
case 44:
-#line 406 "./f-exp.y"
+#line 410 "f-exp.y"
{ write_exp_elt_opcode (OP_DOUBLE);
write_exp_elt_type (builtin_type_f_real_s8);
write_exp_elt_dblcst (yyvsp[0].dval);
write_exp_elt_opcode (OP_DOUBLE); ;
break;}
case 47:
-#line 419 "./f-exp.y"
+#line 423 "f-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_f_integer);
CHECK_TYPEDEF (yyvsp[-1].tval);
@@ -1123,14 +1120,14 @@ case 47:
write_exp_elt_opcode (OP_LONG); ;
break;}
case 48:
-#line 427 "./f-exp.y"
+#line 431 "f-exp.y"
{ write_exp_elt_opcode (OP_BOOL);
write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
write_exp_elt_opcode (OP_BOOL);
;
break;}
case 49:
-#line 434 "./f-exp.y"
+#line 438 "f-exp.y"
{
write_exp_elt_opcode (OP_STRING);
write_exp_string (yyvsp[0].sval);
@@ -1138,7 +1135,7 @@ case 49:
;
break;}
case 50:
-#line 442 "./f-exp.y"
+#line 446 "f-exp.y"
{ struct symbol *sym = yyvsp[0].ssym.sym;
if (sym)
@@ -1181,7 +1178,7 @@ case 50:
;
break;}
case 53:
-#line 490 "./f-exp.y"
+#line 494 "f-exp.y"
{
/* This is where the interesting stuff happens. */
int done = 0;
@@ -1224,122 +1221,122 @@ case 53:
;
break;}
case 54:
-#line 533 "./f-exp.y"
+#line 537 "f-exp.y"
{ push_type (tp_pointer); yyval.voidval = 0; ;
break;}
case 55:
-#line 535 "./f-exp.y"
+#line 539 "f-exp.y"
{ push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; ;
break;}
case 56:
-#line 537 "./f-exp.y"
+#line 541 "f-exp.y"
{ push_type (tp_reference); yyval.voidval = 0; ;
break;}
case 57:
-#line 539 "./f-exp.y"
+#line 543 "f-exp.y"
{ push_type (tp_reference); yyval.voidval = yyvsp[0].voidval; ;
break;}
case 59:
-#line 544 "./f-exp.y"
+#line 548 "f-exp.y"
{ yyval.voidval = yyvsp[-1].voidval; ;
break;}
case 60:
-#line 546 "./f-exp.y"
+#line 550 "f-exp.y"
{ push_type (tp_function); ;
break;}
case 61:
-#line 548 "./f-exp.y"
+#line 552 "f-exp.y"
{ push_type (tp_function); ;
break;}
case 62:
-#line 552 "./f-exp.y"
+#line 556 "f-exp.y"
{ yyval.voidval = 0; ;
break;}
case 63:
-#line 554 "./f-exp.y"
+#line 558 "f-exp.y"
{ free ((PTR)yyvsp[-1].tvec); yyval.voidval = 0; ;
break;}
case 64:
-#line 559 "./f-exp.y"
+#line 563 "f-exp.y"
{ yyval.tval = yyvsp[0].tsym.type; ;
break;}
case 65:
-#line 561 "./f-exp.y"
+#line 565 "f-exp.y"
{ yyval.tval = builtin_type_f_integer; ;
break;}
case 66:
-#line 563 "./f-exp.y"
+#line 567 "f-exp.y"
{ yyval.tval = builtin_type_f_integer_s2; ;
break;}
case 67:
-#line 565 "./f-exp.y"
+#line 569 "f-exp.y"
{ yyval.tval = builtin_type_f_character; ;
break;}
case 68:
-#line 567 "./f-exp.y"
+#line 571 "f-exp.y"
{ yyval.tval = builtin_type_f_logical;;
break;}
case 69:
-#line 569 "./f-exp.y"
+#line 573 "f-exp.y"
{ yyval.tval = builtin_type_f_logical_s2;;
break;}
case 70:
-#line 571 "./f-exp.y"
+#line 575 "f-exp.y"
{ yyval.tval = builtin_type_f_logical_s1;;
break;}
case 71:
-#line 573 "./f-exp.y"
+#line 577 "f-exp.y"
{ yyval.tval = builtin_type_f_real;;
break;}
case 72:
-#line 575 "./f-exp.y"
+#line 579 "f-exp.y"
{ yyval.tval = builtin_type_f_real_s8;;
break;}
case 73:
-#line 577 "./f-exp.y"
+#line 581 "f-exp.y"
{ yyval.tval = builtin_type_f_real_s16;;
break;}
case 74:
-#line 579 "./f-exp.y"
+#line 583 "f-exp.y"
{ yyval.tval = builtin_type_f_complex_s8;;
break;}
case 75:
-#line 581 "./f-exp.y"
+#line 585 "f-exp.y"
{ yyval.tval = builtin_type_f_complex_s16;;
break;}
case 76:
-#line 583 "./f-exp.y"
+#line 587 "f-exp.y"
{ yyval.tval = builtin_type_f_complex_s32;;
break;}
case 78:
-#line 591 "./f-exp.y"
+#line 595 "f-exp.y"
{ yyval.tvec = (struct type **) xmalloc (sizeof (struct type *) * 2);
yyval.ivec[0] = 1; /* Number of types in vector */
yyval.tvec[1] = yyvsp[0].tval;
;
break;}
case 79:
-#line 596 "./f-exp.y"
+#line 600 "f-exp.y"
{ int len = sizeof (struct type *) * (++(yyvsp[-2].ivec[0]) + 1);
yyval.tvec = (struct type **) xrealloc ((char *) yyvsp[-2].tvec, len);
yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval;
;
break;}
case 80:
-#line 603 "./f-exp.y"
+#line 607 "f-exp.y"
{ yyval.sval = yyvsp[0].ssym.stoken; ;
break;}
case 81:
-#line 605 "./f-exp.y"
+#line 609 "f-exp.y"
{ yyval.sval = yyvsp[0].tsym.stoken; ;
break;}
case 82:
-#line 607 "./f-exp.y"
+#line 611 "f-exp.y"
{ yyval.sval = yyvsp[0].ssym.stoken; ;
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 487 "/usr/unsupported/share/bison.simple"
+#line 498 "/stone/jimb/main-98r2/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1535,7 +1532,7 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 620 "./f-exp.y"
+#line 624 "f-exp.y"
/* Take care of parsing a number (anything that starts with a digit).
@@ -1558,7 +1555,7 @@ parse_number (p, len, parsed_float, putithere)
register int base = input_radix;
int unsigned_p = 0;
int long_p = 0;
- unsigned LONGEST high_bit;
+ ULONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
@@ -1660,13 +1657,13 @@ parse_number (p, len, parsed_float, putithere)
&& ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */
|| long_p)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
unsigned_type = builtin_type_unsigned_long;
signed_type = builtin_type_long;
}
else
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
unsigned_type = builtin_type_unsigned_int;
signed_type = builtin_type_int;
}
diff --git a/contrib/gdb/gdb/f-exp.y b/contrib/gdb/gdb/f-exp.y
index 528d215..4a1f747 100644
--- a/contrib/gdb/gdb/f-exp.y
+++ b/contrib/gdb/gdb/f-exp.y
@@ -109,6 +109,10 @@ static int yylex PARAMS ((void));
void yyerror PARAMS ((char *));
+static void growbuf_by_size PARAMS ((int));
+
+static int match_string_literal PARAMS ((void));
+
%}
/* Although the yacc "value" of an expression is not used,
@@ -639,7 +643,7 @@ parse_number (p, len, parsed_float, putithere)
register int base = input_radix;
int unsigned_p = 0;
int long_p = 0;
- unsigned LONGEST high_bit;
+ ULONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
@@ -741,13 +745,13 @@ parse_number (p, len, parsed_float, putithere)
&& ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */
|| long_p)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
unsigned_type = builtin_type_unsigned_long;
signed_type = builtin_type_long;
}
else
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
unsigned_type = builtin_type_unsigned_int;
signed_type = builtin_type_int;
}
diff --git a/contrib/gdb/gdb/f-lang.c b/contrib/gdb/gdb/f-lang.c
index 57a6809..4ee66d5 100644
--- a/contrib/gdb/gdb/f-lang.c
+++ b/contrib/gdb/gdb/f-lang.c
@@ -45,6 +45,47 @@ struct type *builtin_type_f_complex_s16;
struct type *builtin_type_f_complex_s32;
struct type *builtin_type_f_void;
+/* Following is dubious stuff that had been in the xcoff reader. */
+
+struct saved_fcn
+{
+ long line_offset; /* Line offset for function */
+ struct saved_fcn *next;
+};
+
+
+struct saved_bf_symnum
+{
+ long symnum_fcn; /* Symnum of function (i.e. .function directive) */
+ long symnum_bf; /* Symnum of .bf for this function */
+ struct saved_bf_symnum *next;
+};
+
+typedef struct saved_fcn SAVED_FUNCTION, *SAVED_FUNCTION_PTR;
+typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR;
+
+/* Local functions */
+
+#if 0
+static void clear_function_list PARAMS ((void));
+static long get_bf_for_fcn PARAMS ((long));
+static void clear_bf_list PARAMS ((void));
+static void patch_all_commons_by_name PARAMS ((char *, CORE_ADDR, int));
+static SAVED_F77_COMMON_PTR find_first_common_named PARAMS ((char *));
+static void add_common_entry PARAMS ((struct symbol *));
+static void add_common_block PARAMS ((char *, CORE_ADDR, int, char *));
+static SAVED_FUNCTION *allocate_saved_function_node PARAMS ((void));
+static SAVED_BF_PTR allocate_saved_bf_node PARAMS ((void));
+static COMMON_ENTRY_PTR allocate_common_entry_node PARAMS ((void));
+static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node PARAMS ((void));
+static void patch_common_entries PARAMS ((SAVED_F77_COMMON_PTR, CORE_ADDR, int));
+#endif
+
+static struct type *f_create_fundamental_type PARAMS ((struct objfile *, int));
+static void f_printstr PARAMS ((GDB_FILE *stream, char *string, unsigned int length, int width, int force_ellipses));
+static void f_printchar PARAMS ((int c, GDB_FILE *stream));
+static void f_emit_char PARAMS ((int c, GDB_FILE *stream, int quoter));
+
/* Print the character C on STREAM as part of the contents of a literal
string whose delimiter is QUOTER. Note that that format for printing
characters and strings is language specific.
@@ -52,9 +93,9 @@ struct type *builtin_type_f_void;
be replaced with a true F77 version. */
static void
-emit_char (c, stream, quoter)
+f_emit_char (c, stream, quoter)
register int c;
- FILE *stream;
+ GDB_FILE *stream;
int quoter;
{
c &= 0xFF; /* Avoid sign bit follies */
@@ -103,10 +144,10 @@ emit_char (c, stream, quoter)
static void
f_printchar (c, stream)
int c;
- FILE *stream;
+ GDB_FILE *stream;
{
fputs_filtered ("'", stream);
- emit_char (c, stream, '\'');
+ LA_EMIT_CHAR (c, stream, '\'');
fputs_filtered ("'", stream);
}
@@ -118,10 +159,11 @@ f_printchar (c, stream)
be replaced with a true F77 version. */
static void
-f_printstr (stream, string, length, force_ellipses)
- FILE *stream;
+f_printstr (stream, string, length, width, force_ellipses)
+ GDB_FILE *stream;
char *string;
unsigned int length;
+ int width;
int force_ellipses;
{
register unsigned int i;
@@ -134,7 +176,7 @@ f_printstr (stream, string, length, force_ellipses)
if (length == 0)
{
- fputs_filtered ("''", stdout);
+ fputs_filtered ("''", gdb_stdout);
return;
}
@@ -188,7 +230,7 @@ f_printstr (stream, string, length, force_ellipses)
fputs_filtered ("'", stream);
in_quotes = 1;
}
- emit_char (string[i], stream, '"');
+ LA_EMIT_CHAR (string[i], stream, '"');
++things_printed;
}
}
@@ -393,7 +435,7 @@ static const struct op_print f_op_print_tab[] = {
{ NULL, 0, 0, 0 }
};
-struct type ** const (f_builtin_types[]) =
+struct type ** CONST_PTR (f_builtin_types[]) =
{
&builtin_type_f_character,
&builtin_type_f_logical,
@@ -413,7 +455,10 @@ struct type ** const (f_builtin_types[]) =
0
};
-int c_value_print();
+/* This is declared in c-lang.h but it is silly to import that file for what
+ is already just a hack. */
+extern int
+c_value_print PARAMS ((struct value *, GDB_FILE *, int, enum val_prettyprint));
const struct language_defn f_language_defn = {
"fortran",
@@ -426,6 +471,7 @@ const struct language_defn f_language_defn = {
evaluate_subexp_standard,
f_printchar, /* Print character constant */
f_printstr, /* function to print string constant */
+ f_emit_char, /* Function to print a single character */
f_create_fundamental_type, /* Create fundamental type in this language */
f_print_type, /* Print a type using appropriate syntax */
f_val_print, /* Print a value using appropriate syntax */
@@ -523,27 +569,9 @@ _initialize_f_language ()
add_language (&f_language_defn);
}
-/* Following is dubious stuff that had been in the xcoff reader. */
-
-struct saved_fcn
-{
- long line_offset; /* Line offset for function */
- struct saved_fcn *next;
-};
-
-
-struct saved_bf_symnum
-{
- long symnum_fcn; /* Symnum of function (i.e. .function directive) */
- long symnum_bf; /* Symnum of .bf for this function */
- struct saved_bf_symnum *next;
-};
-
-typedef struct saved_fcn SAVED_FUNCTION, *SAVED_FUNCTION_PTR;
-typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR;
-
-
-SAVED_BF_PTR allocate_saved_bf_node()
+#if 0
+static SAVED_BF_PTR
+allocate_saved_bf_node()
{
SAVED_BF_PTR new;
@@ -551,7 +579,8 @@ SAVED_BF_PTR allocate_saved_bf_node()
return(new);
}
-SAVED_FUNCTION *allocate_saved_function_node()
+static SAVED_FUNCTION *
+allocate_saved_function_node()
{
SAVED_FUNCTION *new;
@@ -559,7 +588,7 @@ SAVED_FUNCTION *allocate_saved_function_node()
return(new);
}
-SAVED_F77_COMMON_PTR allocate_saved_f77_common_node()
+static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node()
{
SAVED_F77_COMMON_PTR new;
@@ -567,41 +596,38 @@ SAVED_F77_COMMON_PTR allocate_saved_f77_common_node()
return(new);
}
-COMMON_ENTRY_PTR allocate_common_entry_node()
+static COMMON_ENTRY_PTR allocate_common_entry_node()
{
COMMON_ENTRY_PTR new;
new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY));
return(new);
}
-
+#endif
SAVED_F77_COMMON_PTR head_common_list=NULL; /* Ptr to 1st saved COMMON */
SAVED_F77_COMMON_PTR tail_common_list=NULL; /* Ptr to last saved COMMON */
SAVED_F77_COMMON_PTR current_common=NULL; /* Ptr to current COMMON */
+#if 0
static SAVED_BF_PTR saved_bf_list=NULL; /* Ptr to (.bf,function)
list*/
-#if 0
static SAVED_BF_PTR saved_bf_list_end=NULL; /* Ptr to above list's end */
-#endif
static SAVED_BF_PTR current_head_bf_list=NULL; /* Current head of above list
*/
-#if 0
static SAVED_BF_PTR tmp_bf_ptr; /* Generic temporary for use
in macros */
-#endif
/* The following function simply enters a given common block onto
the global common block chain */
-void add_common_block(name,offset,secnum,func_stab)
+static void
+add_common_block(name,offset,secnum,func_stab)
char *name;
CORE_ADDR offset;
int secnum;
char *func_stab;
-
{
SAVED_F77_COMMON_PTR tmp;
char *c,*local_copy_func_stab;
@@ -662,14 +688,15 @@ void add_common_block(name,offset,secnum,func_stab)
tail_common_list->next = tmp;
tail_common_list = tmp;
}
-
}
-
+#endif
/* The following function simply enters a given common entry onto
the "current_common" block that has been saved away. */
-void add_common_entry(entry_sym_ptr)
+#if 0
+static void
+add_common_entry(entry_sym_ptr)
struct symbol *entry_sym_ptr;
{
COMMON_ENTRY_PTR tmp;
@@ -700,13 +727,14 @@ void add_common_entry(entry_sym_ptr)
current_common->end_of_entries = tmp;
}
}
-
-
}
+#endif
/* This routine finds the first encountred COMMON block named "name" */
-SAVED_F77_COMMON_PTR find_first_common_named(name)
+#if 0
+static SAVED_F77_COMMON_PTR
+find_first_common_named(name)
char *name;
{
@@ -723,6 +751,7 @@ SAVED_F77_COMMON_PTR find_first_common_named(name)
}
return(NULL);
}
+#endif
/* This routine finds the first encountred COMMON block named "name"
that belongs to function funcname */
@@ -747,14 +776,14 @@ SAVED_F77_COMMON_PTR find_common_for_function(name, funcname)
}
-
+#if 0
/* The following function is called to patch up the offsets
for the statics contained in the COMMON block named
"name." */
-
-void patch_common_entries (blk, offset, secnum)
+static void
+patch_common_entries (blk, offset, secnum)
SAVED_F77_COMMON_PTR blk;
CORE_ADDR offset;
int secnum;
@@ -775,15 +804,14 @@ void patch_common_entries (blk, offset, secnum)
blk->secnum = secnum;
}
-
/* Patch all commons named "name" that need patching.Since COMMON
blocks occur with relative infrequency, we simply do a linear scan on
the name. Eventually, the best way to do this will be a
hashed-lookup. Secnum is the section number for the .bss section
(which is where common data lives). */
-
-void patch_all_commons_by_name (name, offset, secnum)
+static void
+patch_all_commons_by_name (name, offset, secnum)
char *name;
CORE_ADDR offset;
int secnum;
@@ -812,12 +840,8 @@ void patch_all_commons_by_name (name, offset, secnum)
tmp = tmp->next;
}
-
}
-
-
-
-
+#endif
/* This macro adds the symbol-number for the start of the function
(the symbol number of the .bf) referenced by symnum_fcn to a
@@ -856,7 +880,8 @@ else \
/* This function frees the entire (.bf,function) list */
-void
+#if 0
+static void
clear_bf_list()
{
@@ -871,10 +896,13 @@ void
}
saved_bf_list = NULL;
}
+#endif
int global_remote_debug;
-long
+#if 0
+
+static long
get_bf_for_fcn (the_function)
long the_function;
{
@@ -924,11 +952,10 @@ get_bf_for_fcn (the_function)
}
static SAVED_FUNCTION_PTR saved_function_list=NULL;
-#if 0 /* Currently unused */
static SAVED_FUNCTION_PTR saved_function_list_end=NULL;
-#endif
-void clear_function_list()
+static void
+clear_function_list()
{
SAVED_FUNCTION_PTR tmp = saved_function_list;
SAVED_FUNCTION_PTR next = NULL;
@@ -942,3 +969,5 @@ void clear_function_list()
saved_function_list = NULL;
}
+#endif
+
diff --git a/contrib/gdb/gdb/f-lang.h b/contrib/gdb/gdb/f-lang.h
index 226b399..c6b8f02 100644
--- a/contrib/gdb/gdb/f-lang.h
+++ b/contrib/gdb/gdb/f-lang.h
@@ -23,9 +23,11 @@ extern int f_parse PARAMS ((void));
extern void f_error PARAMS ((char *)); /* Defined in f-exp.y */
-extern void f_print_type PARAMS ((struct type *, char *, FILE *, int, int));
+extern void f_print_type PARAMS ((struct type *, char *,
+ GDB_FILE *, int, int));
-extern int f_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *,
+extern int f_val_print PARAMS ((struct type *, char *, int,
+ CORE_ADDR, GDB_FILE *,
int, int, int, enum val_prettyprint));
/* Language-specific data structures */
diff --git a/contrib/gdb/gdb/f-typeprint.c b/contrib/gdb/gdb/f-typeprint.c
index 3ab6237..09bb3eb 100644
--- a/contrib/gdb/gdb/f-typeprint.c
+++ b/contrib/gdb/gdb/f-typeprint.c
@@ -40,15 +40,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <errno.h>
#if 0 /* Currently unused */
-static void f_type_print_args PARAMS ((struct type *, FILE *));
+static void f_type_print_args PARAMS ((struct type *, GDB_FILE *));
#endif
-static void f_type_print_varspec_suffix PARAMS ((struct type *, FILE *,
+static void print_equivalent_f77_float_type PARAMS ((struct type *,
+ GDB_FILE *));
+
+static void f_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *,
int, int, int));
-void f_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
+void f_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *,
+ int, int));
-void f_type_print_base PARAMS ((struct type *, FILE *, int, int));
+void f_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
/* LEVEL is the depth to indent lines by. */
@@ -57,7 +61,7 @@ void
f_print_type (type, varstring, stream, show, level)
struct type *type;
char *varstring;
- FILE *stream;
+ GDB_FILE *stream;
int show;
int level;
{
@@ -100,7 +104,7 @@ f_print_type (type, varstring, stream, show, level)
void
f_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
struct type *type;
- FILE *stream;
+ GDB_FILE *stream;
int show;
int passed_a_ptr;
{
@@ -158,7 +162,7 @@ f_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
static void
f_type_print_args (type, stream)
struct type *type;
- FILE *stream;
+ GDB_FILE *stream;
{
int i;
struct type **args;
@@ -198,7 +202,7 @@ f_type_print_args (type, stream)
static void
f_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
struct type *type;
- FILE *stream;
+ GDB_FILE *stream;
int show;
int passed_a_ptr;
int demangled_args;
@@ -307,10 +311,10 @@ f_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
}
}
-void
+static void
print_equivalent_f77_float_type (type, stream)
struct type *type;
- FILE *stream;
+ GDB_FILE *stream;
{
/* Override type name "float" and make it the
appropriate real. XLC stupidly outputs -12 as a type
@@ -335,7 +339,7 @@ print_equivalent_f77_float_type (type, stream)
void
f_type_print_base (type, stream, show, level)
struct type *type;
- FILE *stream;
+ GDB_FILE *stream;
int show;
int level;
{
diff --git a/contrib/gdb/gdb/f-valprint.c b/contrib/gdb/gdb/f-valprint.c
index 1143b9d..bb0b1d0 100644
--- a/contrib/gdb/gdb/f-valprint.c
+++ b/contrib/gdb/gdb/f-valprint.c
@@ -33,9 +33,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#include "command.h"
-extern unsigned int print_max; /* No of array elements to print */
-
-extern int calc_f77_array_dims PARAMS ((struct type *));
+#if 0
+static int there_is_a_visible_common_named PARAMS ((char *));
+#endif
+
+static void info_common_command PARAMS ((char *, int));
+static void list_all_visible_commons PARAMS ((char *));
+static void f77_print_array PARAMS ((struct type *, char *, CORE_ADDR,
+ GDB_FILE *, int, int, int,
+ enum val_prettyprint));
+static void f77_print_array_1 PARAMS ((int, int, struct type *, char *,
+ CORE_ADDR, GDB_FILE *, int, int, int,
+ enum val_prettyprint));
+static void f77_create_arrayprint_offset_tbl PARAMS ((struct type *,
+ GDB_FILE *));
+static void f77_get_dynamic_length_of_aggregate PARAMS ((struct type *));
int f77_array_offset_tbl[MAX_FORTRAN_DIMS+1][2];
@@ -178,7 +190,7 @@ f77_get_dynamic_upperbound (type, upper_bound)
/* Obtain F77 adjustable array dimensions */
-void
+static void
f77_get_dynamic_length_of_aggregate (type)
struct type *type;
{
@@ -217,10 +229,10 @@ f77_get_dynamic_length_of_aggregate (type)
/* Function that sets up the array offset,size table for the array
type "type". */
-void
+static void
f77_create_arrayprint_offset_tbl (type, stream)
struct type *type;
- FILE *stream;
+ GDB_FILE *stream;
{
struct type *tmp_type;
int eltlen;
@@ -266,15 +278,15 @@ f77_create_arrayprint_offset_tbl (type, stream)
/* Actual function which prints out F77 arrays, Valaddr == address in
the superior. Address == the address in the inferior. */
-void
+static void
f77_print_array_1 (nss, ndimensions, type, valaddr, address,
stream, format, deref_ref, recurse, pretty)
int nss;
int ndimensions;
- char *valaddr;
struct type *type;
+ char *valaddr;
CORE_ADDR address;
- FILE *stream;
+ GDB_FILE *stream;
int format;
int deref_ref;
int recurse;
@@ -290,7 +302,7 @@ f77_print_array_1 (nss, ndimensions, type, valaddr, address,
f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type),
valaddr + i * F77_DIM_OFFSET (nss),
address + i * F77_DIM_OFFSET (nss),
- stream, format, deref_ref, recurse, pretty, i);
+ stream, format, deref_ref, recurse, pretty);
fprintf_filtered (stream, ") ");
}
}
@@ -300,6 +312,7 @@ f77_print_array_1 (nss, ndimensions, type, valaddr, address,
{
val_print (TYPE_TARGET_TYPE (type),
valaddr + i * F77_DIM_OFFSET (ndimensions),
+ 0,
address + i * F77_DIM_OFFSET (ndimensions),
stream, format, deref_ref, recurse, pretty);
@@ -315,13 +328,13 @@ f77_print_array_1 (nss, ndimensions, type, valaddr, address,
/* This function gets called to print an F77 array, we set up some
stuff and then immediately call f77_print_array_1() */
-void
+static void
f77_print_array (type, valaddr, address, stream, format, deref_ref, recurse,
pretty)
struct type *type;
char *valaddr;
CORE_ADDR address;
- FILE *stream;
+ GDB_FILE *stream;
int format;
int deref_ref;
int recurse;
@@ -360,12 +373,13 @@ f77_print_array (type, valaddr, address, stream, format, deref_ref, recurse,
The PRETTY parameter controls prettyprinting. */
int
-f_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
+f_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, recurse,
pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
- FILE *stream;
+ GDB_FILE *stream;
int format;
int deref_ref;
int recurse;
@@ -381,7 +395,7 @@ f_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
case TYPE_CODE_STRING:
f77_get_dynamic_length_of_aggregate (type);
- LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 0);
+ LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0);
break;
case TYPE_CODE_ARRAY:
@@ -423,7 +437,7 @@ f_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
&& TYPE_CODE (elttype) == TYPE_CODE_INT
&& (format == 0 || format == 's')
&& addr != 0)
- i = val_print_string (addr, 0, stream);
+ i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
@@ -523,7 +537,7 @@ f_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
/* Bash the type code temporarily. */
TYPE_CODE (type) = TYPE_CODE_INT;
- f_val_print (type, valaddr, address, stream, format,
+ f_val_print (type, valaddr, 0, address, stream, format,
deref_ref, recurse, pretty);
/* Restore the type code so later uses work as intended. */
TYPE_CODE (type) = TYPE_CODE_BOOL;
@@ -557,11 +571,11 @@ f_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
default:
error ("Invalid F77 type code %d in symbol table.", TYPE_CODE (type));
}
- fflush (stream);
+ gdb_flush (stream);
return 0;
}
-void
+static void
list_all_visible_commons (funname)
char *funname;
{
@@ -667,7 +681,7 @@ info_common_command (comname, from_tty)
while (entry != NULL)
{
printf_filtered ("%s = ",SYMBOL_NAME(entry->symbol));
- print_variable_value (entry->symbol,fi,stdout);
+ print_variable_value (entry->symbol, fi, gdb_stdout);
printf_filtered ("\n");
entry = entry->next;
}
@@ -680,7 +694,8 @@ info_common_command (comname, from_tty)
/* This function is used to determine whether there is a
F77 common block visible at the current scope called 'comname'. */
-int
+#if 0
+static int
there_is_a_visible_common_named (comname)
char *comname;
{
@@ -739,10 +754,14 @@ there_is_a_visible_common_named (comname)
return (the_common ? 1 : 0);
}
+#endif
void
_initialize_f_valprint ()
{
add_info ("common", info_common_command,
"Print out the values contained in a Fortran COMMON block.");
+ if (xdb_commands)
+ add_com("lc", class_info, info_common_command,
+ "Print out the values contained in a Fortran COMMON block.");
}
diff --git a/contrib/gdb/gdb/findvar.c b/contrib/gdb/gdb/findvar.c
index 1dce905..5bfecc2 100644
--- a/contrib/gdb/gdb/findvar.c
+++ b/contrib/gdb/gdb/findvar.c
@@ -1,5 +1,6 @@
/* Find a variable's value in memory, for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1986, 87, 89, 91, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -26,13 +27,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "inferior.h"
#include "target.h"
#include "gdb_string.h"
+#include "floatformat.h"
+#include "symfile.h" /* for overlay functions */
+
+/* This is used to indicate that we don't know the format of the floating point
+ number. Typically, this is useful for native ports, where the actual format
+ is irrelevant, since no conversions will be taking place. */
+
+const struct floatformat floatformat_unknown;
/* Registers we shouldn't try to store. */
#if !defined (CANNOT_STORE_REGISTER)
#define CANNOT_STORE_REGISTER(regno) 0
#endif
-static void write_register_pid PARAMS ((int regno, LONGEST val, int pid));
+static void write_register_gen PARAMS ((int, char *));
/* Basic byte-swapping routines. GDB has needed these for a long time...
All extract a target-format integer at ADDR which is LEN bytes long. */
@@ -81,20 +90,20 @@ That operation is not available on integers of more than %d bytes.",
return retval;
}
-unsigned LONGEST
+ULONGEST
extract_unsigned_integer (addr, len)
PTR addr;
int len;
{
- unsigned LONGEST retval;
+ ULONGEST retval;
unsigned char *p;
unsigned char *startaddr = (unsigned char *)addr;
unsigned char *endaddr = startaddr + len;
- if (len > (int) sizeof (unsigned LONGEST))
+ if (len > (int) sizeof (ULONGEST))
error ("\
That operation is not available on integers of more than %d bytes.",
- sizeof (unsigned LONGEST));
+ sizeof (ULONGEST));
/* Start at the most significant end of the integer, and work towards
the least significant. */
@@ -171,7 +180,7 @@ extract_address (addr, len)
{
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
- return extract_unsigned_integer (addr, len);
+ return (CORE_ADDR)extract_unsigned_integer (addr, len);
}
void
@@ -208,7 +217,7 @@ void
store_unsigned_integer (addr, len, val)
PTR addr;
int len;
- unsigned LONGEST val;
+ ULONGEST val;
{
unsigned char *p;
unsigned char *startaddr = (unsigned char *)addr;
@@ -234,15 +243,35 @@ store_unsigned_integer (addr, len, val)
}
}
+/* Store the literal address "val" into
+ gdb-local memory pointed to by "addr"
+ for "len" bytes. */
void
store_address (addr, len, val)
PTR addr;
int len;
- CORE_ADDR val;
+ LONGEST val;
{
- /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
- whether we want this to be true eventually. */
- store_unsigned_integer (addr, len, (LONGEST)val);
+ if( TARGET_BYTE_ORDER == BIG_ENDIAN
+ && len != sizeof( LONGEST )) {
+ /* On big-endian machines (e.g., HPPA 2.0, narrow mode)
+ * just letting this fall through to the call below will
+ * lead to the wrong bits being stored.
+ *
+ * Only the simplest case is fixed here, the others just
+ * get the old behavior.
+ */
+ if( (len == sizeof( CORE_ADDR ))
+ && (sizeof( LONGEST ) == 2 * sizeof( CORE_ADDR ))) {
+ /* Watch out! The high bits are garbage! */
+ CORE_ADDR coerce[2];
+ *(LONGEST*)&coerce = val;
+
+ store_unsigned_integer (addr, len, coerce[1] ); /* BIG_ENDIAN code! */
+ return;
+ }
+ }
+ store_unsigned_integer (addr, len, val);
}
/* Swap LEN bytes at BUFFER between target and host byte-order. */
@@ -264,52 +293,63 @@ store_address (addr, len, val)
} \
while (0)
-/* There are various problems with the extract_floating and store_floating
- routines.
+/* Extract a floating-point number from a target-order byte-stream at ADDR.
+ Returns the value as type DOUBLEST.
- 1. These routines only handle byte-swapping, not conversion of
- formats. So if host is IEEE floating and target is VAX floating,
- or vice-versa, it loses. This means that we can't (yet) use these
- routines for extendeds. Extendeds are handled by
- REGISTER_CONVERTIBLE. What we want is to use floatformat.h, but that
- doesn't yet handle VAX floating at all.
-
- 2. We can't deal with it if there is more than one floating point
- format in use. This has to be fixed at the unpack_double level.
-
- 3. We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever
- we want to call it which is long double where available. */
+ If the host and target formats agree, we just copy the raw data into the
+ appropriate type of variable and return, letting the host increase precision
+ as necessary. Otherwise, we call the conversion routine and let it do the
+ dirty work. */
DOUBLEST
extract_floating (addr, len)
PTR addr;
int len;
{
+ DOUBLEST dretval;
+
if (len == sizeof (float))
{
- float retval;
- memcpy (&retval, addr, sizeof (retval));
- SWAP_FLOATING (&retval, sizeof (retval));
- return retval;
+ if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
+ {
+ float retval;
+
+ memcpy (&retval, addr, sizeof (retval));
+ return retval;
+ }
+ else
+ floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval);
}
else if (len == sizeof (double))
{
- double retval;
- memcpy (&retval, addr, sizeof (retval));
- SWAP_FLOATING (&retval, sizeof (retval));
- return retval;
+ if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
+ {
+ double retval;
+
+ memcpy (&retval, addr, sizeof (retval));
+ return retval;
+ }
+ else
+ floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval);
}
else if (len == sizeof (DOUBLEST))
{
- DOUBLEST retval;
- memcpy (&retval, addr, sizeof (retval));
- SWAP_FLOATING (&retval, sizeof (retval));
- return retval;
+ if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
+ {
+ DOUBLEST retval;
+
+ memcpy (&retval, addr, sizeof (retval));
+ return retval;
+ }
+ else
+ floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
+
+ return dretval;
}
void
@@ -320,21 +360,32 @@ store_floating (addr, len, val)
{
if (len == sizeof (float))
{
- float floatval = val;
- SWAP_FLOATING (&floatval, sizeof (floatval));
- memcpy (addr, &floatval, sizeof (floatval));
+ if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
+ {
+ float floatval = val;
+
+ memcpy (addr, &floatval, sizeof (floatval));
+ }
+ else
+ floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr);
}
else if (len == sizeof (double))
{
- double doubleval = val;
+ if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
+ {
+ double doubleval = val;
- SWAP_FLOATING (&doubleval, sizeof (doubleval));
- memcpy (addr, &doubleval, sizeof (doubleval));
+ memcpy (addr, &doubleval, sizeof (doubleval));
+ }
+ else
+ floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr);
}
else if (len == sizeof (DOUBLEST))
{
- SWAP_FLOATING (&val, sizeof (val));
- memcpy (addr, &val, sizeof (val));
+ if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
+ memcpy (addr, &val, sizeof (val));
+ else
+ floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
}
else
{
@@ -354,8 +405,6 @@ find_saved_register (frame, regnum)
struct frame_info *frame;
int regnum;
{
- struct frame_saved_regs saved_regs;
-
register struct frame_info *frame1 = NULL;
register CORE_ADDR addr = 0;
@@ -389,8 +438,8 @@ find_saved_register (frame, regnum)
if (regnum != SP_REGNUM)
frame1 = frame;
- get_frame_saved_regs (frame1, &saved_regs);
- return saved_regs.regs[regnum]; /* ... which might be zero */
+ FRAME_INIT_SAVED_REGS (frame1);
+ return frame1->saved_regs[regnum]; /* ... which might be zero */
}
#endif /* HAVE_REGISTER_WINDOWS */
@@ -404,9 +453,9 @@ find_saved_register (frame, regnum)
frame1 = get_prev_frame (frame1);
if (frame1 == 0 || frame1 == frame)
break;
- get_frame_saved_regs (frame1, &saved_regs);
- if (saved_regs.regs[regnum])
- addr = saved_regs.regs[regnum];
+ FRAME_INIT_SAVED_REGS (frame1);
+ if (frame1->saved_regs[regnum])
+ addr = frame1->saved_regs[regnum];
}
return addr;
@@ -454,7 +503,7 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
if (raw_buffer != NULL)
{
/* Put it back in target format. */
- store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), addr);
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), (LONGEST)addr);
}
if (addrp != NULL)
*addrp = 0;
@@ -476,34 +525,58 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
}
#endif /* GET_SAVED_REGISTER. */
-/* Copy the bytes of register REGNUM, relative to the current stack frame,
+/* Copy the bytes of register REGNUM, relative to the input stack frame,
into our memory at MYADDR, in target byte order.
The number of bytes copied is REGISTER_RAW_SIZE (REGNUM).
Returns 1 if could not be read, 0 if could. */
int
-read_relative_register_raw_bytes (regnum, myaddr)
+read_relative_register_raw_bytes_for_frame (regnum, myaddr, frame)
int regnum;
char *myaddr;
+ struct frame_info *frame;
{
int optim;
- if (regnum == FP_REGNUM && selected_frame)
+ if (regnum == FP_REGNUM && frame)
{
- /* Put it back in target format. */
+ /* Put it back in target format. */
store_address (myaddr, REGISTER_RAW_SIZE(FP_REGNUM),
- FRAME_FP(selected_frame));
+ (LONGEST)FRAME_FP(frame));
+
return 0;
}
- get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, selected_frame,
+ get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, frame,
regnum, (enum lval_type *)NULL);
+
+ if (register_valid [regnum] < 0)
+ return 1; /* register value not available */
+
return optim;
}
+/* Copy the bytes of register REGNUM, relative to the current stack frame,
+ into our memory at MYADDR, in target byte order.
+ The number of bytes copied is REGISTER_RAW_SIZE (REGNUM).
+
+ Returns 1 if could not be read, 0 if could. */
+
+int
+read_relative_register_raw_bytes (regnum, myaddr)
+ int regnum;
+ char *myaddr;
+{
+ return read_relative_register_raw_bytes_for_frame (regnum, myaddr,
+ selected_frame);
+}
+
/* Return a `value' with the contents of register REGNUM
in its virtual format, with the type specified by
- REGISTER_VIRTUAL_TYPE. */
+ REGISTER_VIRTUAL_TYPE.
+
+ NOTE: returns NULL if register value is not available.
+ Caller will check return value or die! */
value_ptr
value_of_register (regnum)
@@ -518,6 +591,9 @@ value_of_register (regnum)
get_saved_register (raw_buffer, &optim, &addr,
selected_frame, regnum, &lval);
+ if (register_valid[regnum] < 0)
+ return NULL; /* register value not available */
+
reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
/* Convert raw data to virtual format if necessary. */
@@ -530,8 +606,13 @@ value_of_register (regnum)
}
else
#endif
- memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer,
- REGISTER_RAW_SIZE (regnum));
+ if (REGISTER_RAW_SIZE (regnum) == REGISTER_VIRTUAL_SIZE (regnum))
+ memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer,
+ REGISTER_RAW_SIZE (regnum));
+ else
+ fatal ("Register \"%s\" (%d) has conflicting raw (%d) and virtual (%d) size",
+ REGISTER_NAME (regnum), regnum,
+ REGISTER_RAW_SIZE (regnum), REGISTER_VIRTUAL_SIZE (regnum));
VALUE_LVAL (reg_val) = lval;
VALUE_ADDRESS (reg_val) = addr;
VALUE_REGNO (reg_val) = regnum;
@@ -547,12 +628,14 @@ value_of_register (regnum)
the caller got the value from the last stop). */
/* Contents of the registers in target byte order.
- We allocate some extra slop since we do a lot of memcpy's around `registers',
- and failing-soft is better than failing hard. */
+ We allocate some extra slop since we do a lot of memcpy's around
+ `registers', and failing-soft is better than failing hard. */
+
char registers[REGISTER_BYTES + /* SLOP */ 256];
-/* Nonzero if that register has been fetched. */
-char register_valid[NUM_REGS];
+/* Nonzero if that register has been fetched,
+ -1 if register value not available. */
+SIGNED char register_valid[NUM_REGS];
/* The thread/process associated with the current set of registers. For now,
-1 is special, and means `no current process'. */
@@ -568,6 +651,13 @@ registers_changed ()
registers_pid = -1;
+ /* Force cleanup of any alloca areas if using C alloca instead of
+ a builtin alloca. This particular call is used to clean up
+ areas allocated by low level target code which may build up
+ during lengthy interactions between gdb and the target before
+ gdb gives control to the user (ie watchpoints). */
+ alloca (0);
+
for (i = 0; i < numregs; i++)
register_valid[i] = 0;
@@ -630,6 +720,9 @@ read_register_bytes (inregbyte, myaddr, inlen)
if (register_valid[regno])
continue;
+ if (REGISTER_NAME (regno) == NULL || *REGISTER_NAME (regno) == '\0')
+ continue;
+
regstart = REGISTER_BYTE (regno);
regend = regstart + REGISTER_RAW_SIZE (regno);
@@ -676,7 +769,7 @@ read_register_gen (regno, myaddr)
/* Write register REGNO at MYADDR to the target. MYADDR points at
REGISTER_RAW_BYTES(REGNO), which must be in target byte-order. */
-void
+static void
write_register_gen (regno, myaddr)
int regno;
char *myaddr;
@@ -784,8 +877,8 @@ read_register (regno)
if (!register_valid[regno])
target_fetch_registers (regno);
- return extract_address (&registers[REGISTER_BYTE (regno)],
- REGISTER_RAW_SIZE(regno));
+ return (CORE_ADDR)extract_address (&registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE(regno));
}
CORE_ADDR
@@ -809,7 +902,8 @@ read_register_pid (regno, pid)
return retval;
}
-/* Store VALUE, into the raw contents of register number REGNO. */
+/* Store VALUE, into the raw contents of register number REGNO.
+ This should probably write a LONGEST rather than a CORE_ADDR */
void
write_register (regno, val)
@@ -832,7 +926,7 @@ write_register (regno, val)
size = REGISTER_RAW_SIZE(regno);
buf = alloca (size);
- store_signed_integer (buf, size, (LONGEST) val);
+ store_signed_integer (buf, size, (LONGEST)val);
/* If we have a valid copy of the register, and new value == old value,
then don't bother doing the actual store. */
@@ -850,10 +944,10 @@ write_register (regno, val)
target_store_registers (regno);
}
-static void
+void
write_register_pid (regno, val, pid)
int regno;
- LONGEST val;
+ CORE_ADDR val;
int pid;
{
int save_pid;
@@ -875,21 +969,31 @@ write_register_pid (regno, val, pid)
/* Record that register REGNO contains VAL.
This is used when the value is obtained from the inferior or core dump,
- so there is no need to store the value there. */
+ so there is no need to store the value there.
+
+ If VAL is a NULL pointer, then it's probably an unsupported register. We
+ just set it's value to all zeros. We might want to record this fact, and
+ report it to the users of read_register and friends.
+*/
void
supply_register (regno, val)
int regno;
char *val;
{
+#if 1
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
+#endif
register_valid[regno] = 1;
- memcpy (&registers[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
+ if (val)
+ memcpy (&registers[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
+ else
+ memset (&registers[REGISTER_BYTE (regno)], '\000', REGISTER_RAW_SIZE (regno));
/* On some architectures, e.g. HPPA, there are a few stray bits in some
registers, that the rest of the code would like to ignore. */
@@ -904,59 +1008,63 @@ supply_register (regno, val)
Ditto for write_pc. */
CORE_ADDR
-read_pc ()
+read_pc_pid (pid)
+ int pid;
{
+ int saved_inferior_pid;
+ CORE_ADDR pc_val;
+
+ /* In case pid != inferior_pid. */
+ saved_inferior_pid = inferior_pid;
+ inferior_pid = pid;
+
#ifdef TARGET_READ_PC
- return TARGET_READ_PC (inferior_pid);
+ pc_val = TARGET_READ_PC (pid);
#else
- return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, inferior_pid));
+ pc_val = ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid));
#endif
+
+ inferior_pid = saved_inferior_pid;
+ return pc_val;
}
CORE_ADDR
-read_pc_pid (pid)
- int pid;
+read_pc ()
{
-#ifdef TARGET_READ_PC
- return TARGET_READ_PC (pid);
-#else
- return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid));
-#endif
+ return read_pc_pid (inferior_pid);
}
void
-write_pc (val)
- CORE_ADDR val;
+write_pc_pid (pc, pid)
+ CORE_ADDR pc;
+ int pid;
{
+ int saved_inferior_pid;
+
+ /* In case pid != inferior_pid. */
+ saved_inferior_pid = inferior_pid;
+ inferior_pid = pid;
+
#ifdef TARGET_WRITE_PC
- TARGET_WRITE_PC (val, inferior_pid);
+ TARGET_WRITE_PC (pc, pid);
#else
- write_register_pid (PC_REGNUM, val, inferior_pid);
+ write_register_pid (PC_REGNUM, pc, pid);
#ifdef NPC_REGNUM
- write_register_pid (NPC_REGNUM, val + 4, inferior_pid);
+ write_register_pid (NPC_REGNUM, pc + 4, pid);
#ifdef NNPC_REGNUM
- write_register_pid (NNPC_REGNUM, val + 8, inferior_pid);
+ write_register_pid (NNPC_REGNUM, pc + 8, pid);
#endif
#endif
#endif
+
+ inferior_pid = saved_inferior_pid;
}
void
-write_pc_pid (val, pid)
- CORE_ADDR val;
- int pid;
+write_pc (pc)
+ CORE_ADDR pc;
{
-#ifdef TARGET_WRITE_PC
- TARGET_WRITE_PC (val, pid);
-#else
- write_register_pid (PC_REGNUM, val, pid);
-#ifdef NPC_REGNUM
- write_register_pid (NPC_REGNUM, val + 4, pid);
-#ifdef NNPC_REGNUM
- write_register_pid (NNPC_REGNUM, val + 8, pid);
-#endif
-#endif
-#endif
+ write_pc_pid (pc, inferior_pid);
}
/* Cope with strage ways of getting to the stack and frame pointers */
@@ -1023,11 +1131,13 @@ symbol_read_needs_frame (sym)
case LOC_LOCAL_ARG:
case LOC_BASEREG:
case LOC_BASEREG_ARG:
+ case LOC_THREAD_LOCAL_STATIC:
return 1;
case LOC_UNDEF:
case LOC_CONST:
case LOC_STATIC:
+ case LOC_INDIRECT:
case LOC_TYPEDEF:
case LOC_LABEL:
@@ -1062,6 +1172,8 @@ read_var_value (var, frame)
v = allocate_value (type);
VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
+ VALUE_BFD_SECTION (v) = SYMBOL_BFD_SECTION (var);
+
len = TYPE_LENGTH (type);
if (frame == NULL) frame = selected_frame;
@@ -1077,7 +1189,13 @@ read_var_value (var, frame)
case LOC_LABEL:
/* Put the constant back in target format. */
- store_address (VALUE_CONTENTS_RAW (v), len, SYMBOL_VALUE_ADDRESS (var));
+ if (overlay_debugging)
+ store_address (VALUE_CONTENTS_RAW (v), len,
+ (LONGEST)symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
+ SYMBOL_BFD_SECTION (var)));
+ else
+ store_address (VALUE_CONTENTS_RAW (v), len,
+ (LONGEST)SYMBOL_VALUE_ADDRESS (var));
VALUE_LVAL (v) = not_lval;
return v;
@@ -1091,7 +1209,25 @@ read_var_value (var, frame)
}
case LOC_STATIC:
+ if (overlay_debugging)
+ addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
+ SYMBOL_BFD_SECTION (var));
+ else
+ addr = SYMBOL_VALUE_ADDRESS (var);
+ break;
+
+ case LOC_INDIRECT:
+ /* The import slot does not have a real address in it from the
+ dynamic loader (dld.sl on HP-UX), if the target hasn't begun
+ execution yet, so check for that. */
+ if (!target_has_execution)
+ error ("\
+Attempt to access variable defined in different shared object or load module when\n\
+addresses have not been bound by the dynamic loader. Try again when executable is running.");
+
addr = SYMBOL_VALUE_ADDRESS (var);
+ addr = read_memory_unsigned_integer
+ (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
break;
case LOC_ARG:
@@ -1133,12 +1269,27 @@ read_var_value (var, frame)
break;
}
+ case LOC_THREAD_LOCAL_STATIC:
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ get_saved_register(buf, NULL, NULL, frame, SYMBOL_BASEREG (var),
+ NULL);
+ addr = extract_address (buf, REGISTER_RAW_SIZE (SYMBOL_BASEREG (var)));
+ addr += SYMBOL_VALUE (var );
+ break;
+ }
+
case LOC_TYPEDEF:
error ("Cannot look up value of a typedef");
break;
case LOC_BLOCK:
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
+ if (overlay_debugging)
+ VALUE_ADDRESS (v) = symbol_overlayed_address
+ (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var));
+ else
+ VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
return v;
case LOC_REGISTER:
@@ -1146,22 +1297,33 @@ read_var_value (var, frame)
case LOC_REGPARM_ADDR:
{
struct block *b;
+ int regno = SYMBOL_VALUE (var);
+ value_ptr regval;
if (frame == NULL)
return 0;
b = get_frame_block (frame);
-
if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
{
- addr =
- value_as_pointer (value_from_register (lookup_pointer_type (type),
- SYMBOL_VALUE (var),
- frame));
+ regval = value_from_register (lookup_pointer_type (type),
+ regno,
+ frame);
+
+ if (regval == NULL)
+ error ("Value of register variable not available.");
+
+ addr = value_as_pointer (regval);
VALUE_LVAL (v) = lval_memory;
}
else
- return value_from_register (type, SYMBOL_VALUE (var), frame);
+ {
+ regval = value_from_register (type, regno, frame);
+
+ if (regval == NULL)
+ error ("Value of register variable not available.");
+ return regval;
+ }
}
break;
@@ -1172,7 +1334,11 @@ read_var_value (var, frame)
msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
if (msym == NULL)
return 0;
- addr = SYMBOL_VALUE_ADDRESS (msym);
+ if (overlay_debugging)
+ addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym),
+ SYMBOL_BFD_SECTION (msym));
+ else
+ addr = SYMBOL_VALUE_ADDRESS (msym);
}
break;
@@ -1192,7 +1358,10 @@ read_var_value (var, frame)
}
/* Return a value of type TYPE, stored in register REGNUM, in frame
- FRAME. */
+ FRAME.
+
+ NOTE: returns NULL if register value is not available.
+ Caller will check return value or die! */
value_ptr
value_from_register (type, regnum, frame)
@@ -1271,6 +1440,9 @@ value_from_register (type, regnum, frame)
page_regnum,
&lval);
+ if (register_valid[page_regnum] == -1)
+ return NULL; /* register value not available */
+
if (lval == lval_register)
reg_stor++;
else
@@ -1285,6 +1457,9 @@ value_from_register (type, regnum, frame)
regnum,
&lval);
+ if (register_valid[regnum] == -1)
+ return NULL; /* register value not available */
+
if (lval == lval_register)
reg_stor++;
else
@@ -1308,6 +1483,9 @@ value_from_register (type, regnum, frame)
local_regnum,
&lval);
+ if (register_valid[local_regnum] == -1)
+ return NULL; /* register value not available */
+
if (regnum == local_regnum)
first_addr = addr;
if (lval == lval_register)
@@ -1369,6 +1547,10 @@ value_from_register (type, regnum, frame)
read the data in raw format. */
get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval);
+
+ if (register_valid[regnum] == -1)
+ return NULL; /* register value not available */
+
VALUE_OPTIMIZED_OUT (v) = optim;
VALUE_LVAL (v) = lval;
VALUE_ADDRESS (v) = addr;
@@ -1422,8 +1604,12 @@ locate_var_value (var, frame)
if (VALUE_LAZY (lazy_value)
|| TYPE_CODE (type) == TYPE_CODE_FUNC)
{
+ value_ptr val;
+
addr = VALUE_ADDRESS (lazy_value);
- return value_from_longest (lookup_pointer_type (type), (LONGEST) addr);
+ val = value_from_longest (lookup_pointer_type (type), (LONGEST) addr);
+ VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value);
+ return val;
}
/* Not a memory address; check what the problem was. */
diff --git a/contrib/gdb/gdb/fork-child.c b/contrib/gdb/gdb/fork-child.c
index df289d4..f3504bc 100644
--- a/contrib/gdb/gdb/fork-child.c
+++ b/contrib/gdb/gdb/fork-child.c
@@ -1,5 +1,5 @@
/* Fork a Unix child process, and set up to debug it, for GDB.
- Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB.
@@ -20,25 +20,83 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdb_string.h"
-#include "frame.h" /* required by inferior.h */
+#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "target.h"
#include "wait.h"
#include "gdbcore.h"
#include "terminal.h"
-#include "thread.h"
+#include "gdbthread.h"
#include <signal.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-extern char **environ;
+#define DEBUGGING 0
+/* This just gets used as a default if we can't find SHELL */
#ifndef SHELL_FILE
#define SHELL_FILE "/bin/sh"
#endif
+extern char **environ;
+
+/* This function breaks up an argument string into an argument
+ * vector suitable for passing to execvp().
+ * E.g., on "run a b c d" this routine would get as input
+ * the string "a b c d", and as output it would fill in argv with
+ * the four arguments "a", "b", "c", "d".
+ */
+static void
+breakup_args (
+ scratch,
+ argv)
+ char *scratch;
+ char **argv;
+{
+ char *cp = scratch;
+
+#if DEBUGGING
+ printf ("breakup_args: input = %s\n", scratch);
+#endif
+ for (;;)
+ {
+
+ /* Scan past leading separators */
+ while (*cp == ' ' || *cp == '\t' || *cp == '\n')
+ {
+ cp++;
+ }
+
+ /* Break if at end of string */
+ if (*cp == '\0')
+ break;
+
+ /* Take an arg */
+ *argv++ = cp;
+
+ /* Scan for next arg separator */
+ cp = strchr (cp, ' ');
+ if (cp == NULL)
+ cp = strchr (cp, '\t');
+ if (cp == NULL)
+ cp = strchr (cp, '\n');
+
+ /* No separators => end of string => break */
+ if (cp == NULL)
+ break;
+
+ /* Replace the separator with a terminator */
+ *cp++ = '\0';
+ }
+
+ /* execv requires a null-terminated arg vector */
+ *argv = NULL;
+
+}
+
+
/* Start an inferior Unix child process and sets inferior_pid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
@@ -47,12 +105,13 @@ extern char **environ;
void
fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
- shell_file)
+ pre_trace_fun, shell_file)
char *exec_file;
char *allargs;
char **env;
void (*traceme_fun) PARAMS ((void));
void (*init_trace_fun) PARAMS ((int));
+ void (*pre_trace_fun) PARAMS ((void));
char *shell_file;
{
int pid;
@@ -65,22 +124,32 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
to you in the parent process. It's only used by humans for debugging. */
static int debug_setpgrp = 657473;
char **save_our_env;
+ int shell = 0;
+ char **argv;
+ char *tryname;
/* If no exec file handed to us, get it from the exec-file command -- with
a good, common error message if none is specified. */
if (exec_file == 0)
- exec_file = get_exec_file(1);
-
- /* The user might want tilde-expansion, and in general probably wants
- the program to behave the same way as if run from
- his/her favorite shell. So we let the shell run it for us.
- FIXME-maybe, we might want a "set shell" command so the user can change
- the shell from within GDB (if so, change callers which pass in a non-NULL
- shell_file too). */
- if (shell_file == NULL)
- shell_file = getenv ("SHELL");
- if (shell_file == NULL)
- shell_file = default_shell_file;
+ exec_file = get_exec_file (1);
+
+ /* STARTUP_WITH_SHELL is defined in inferior.h.
+ * If 0, we'll just do a fork/exec, no shell, so don't
+ * bother figuring out what shell.
+ */
+ if (STARTUP_WITH_SHELL)
+ {
+ /* Figure out what shell to start up the user program under. */
+ if (shell_file == NULL)
+ shell_file = getenv ("SHELL");
+ if (shell_file == NULL)
+ shell_file = default_shell_file;
+ shell = 1;
+ }
+
+#if DEBUGGING
+ printf ("shell is %s\n", shell_file);
+#endif
/* Multiplying the length of exec_file by 4 is to account for the fact
that it may expand when quoted; it is a worst-case number based on
@@ -95,70 +164,94 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
shell_command = (char *) alloca (len);
shell_command[0] = '\0';
#endif
- strcat (shell_command, "exec ");
- /* Now add exec_file, quoting as necessary. */
- {
- char *p;
- int need_to_quote;
+ if (!shell)
+ {
+ /* We're going to call execvp. Create argv */
+ /* Largest case: every other character is a separate arg */
+#if DEBUGGING
+ printf ("allocating argv, length = %d\n",
+ (
+ (strlen (allargs) + 1) / (unsigned) 2
+ + 2
+ ) * sizeof (*argv)
+ );
+#endif
+ argv = (char **) xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) * sizeof (*argv));
+ argv[0] = exec_file;
+ breakup_args (allargs, &argv[1]);
- /* Quoting in this style is said to work with all shells. But csh
+ }
+ else
+ {
+
+ /* We're going to call a shell */
+
+ /* Now add exec_file, quoting as necessary. */
+
+ char *p;
+ int need_to_quote;
+
+ strcat (shell_command, "exec ");
+
+ /* Quoting in this style is said to work with all shells. But csh
on IRIX 4.0.1 can't deal with it. So we only quote it if we need
to. */
- p = exec_file;
- while (1)
- {
- switch (*p)
- {
- case '\'':
- case '"':
- case '(':
- case ')':
- case '$':
- case '&':
- case ';':
- case '<':
- case '>':
- case ' ':
- case '\n':
- case '\t':
- need_to_quote = 1;
- goto end_scan;
-
- case '\0':
- need_to_quote = 0;
- goto end_scan;
-
- default:
- break;
- }
- ++p;
- }
- end_scan:
- if (need_to_quote)
- {
- strcat (shell_command, "'");
- for (p = exec_file; *p != '\0'; ++p)
- {
- if (*p == '\'')
- strcat (shell_command, "'\\''");
- else
- strncat (shell_command, p, 1);
- }
- strcat (shell_command, "'");
- }
- else
- strcat (shell_command, exec_file);
- }
-
- strcat (shell_command, " ");
- strcat (shell_command, allargs);
+ p = exec_file;
+ while (1)
+ {
+ switch (*p)
+ {
+ case '\'':
+ case '"':
+ case '(':
+ case ')':
+ case '$':
+ case '&':
+ case ';':
+ case '<':
+ case '>':
+ case ' ':
+ case '\n':
+ case '\t':
+ need_to_quote = 1;
+ goto end_scan;
+
+ case '\0':
+ need_to_quote = 0;
+ goto end_scan;
+
+ default:
+ break;
+ }
+ ++p;
+ }
+ end_scan:
+ if (need_to_quote)
+ {
+ strcat (shell_command, "'");
+ for (p = exec_file; *p != '\0'; ++p)
+ {
+ if (*p == '\'')
+ strcat (shell_command, "'\\''");
+ else
+ strncat (shell_command, p, 1);
+ }
+ strcat (shell_command, "'");
+ }
+ else
+ strcat (shell_command, exec_file);
+
+ strcat (shell_command, " ");
+ strcat (shell_command, allargs);
+
+ }
/* exec is said to fail if the executable is open. */
close_exec_file ();
/* Retain a copy of our environment variables, since the child will
- replace the value of environ and if we're vforked, we have to
+ replace the value of environ and if we're vforked, we have to
restore it. */
save_our_env = environ;
@@ -174,6 +267,12 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
+ /* If there's any initialization of the target layers that must happen
+ to prepare to handle the child we're about fork, do it now...
+ */
+ if (pre_trace_fun != NULL)
+ (*pre_trace_fun) ();
+
#if defined(USG) && !defined(HAVE_VFORK)
pid = fork ();
#else
@@ -188,13 +287,13 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
if (pid == 0)
{
- if (debug_fork)
+ if (debug_fork)
sleep (debug_fork);
/* Run inferior in a separate process group. */
debug_setpgrp = gdb_setpgid ();
if (debug_setpgrp == -1)
- perror("setpgrp failed in child");
+ perror ("setpgrp failed in child");
/* Ask the tty subsystem to switch to the one we specified earlier
(or to share the current terminal, if none was specified). */
@@ -209,6 +308,14 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
/* "Trace me, Dr. Memory!" */
(*traceme_fun) ();
+ /* The call above set this process (the "child") as debuggable
+ * by the original gdb process (the "parent"). Since processes
+ * (unlike people) can have only one parent, if you are
+ * debugging gdb itself (and your debugger is thus _already_ the
+ * controller/parent for this child), code from here on out
+ * is undebuggable. Indeed, you probably got an error message
+ * saying "not parent". Sorry--you'll have to use print statements!
+ */
/* There is no execlpe call, so we have to set the environment
for our child in the global variable. If we've vforked, this
@@ -216,24 +323,83 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
in the parent. By the way, yes we do need to look down the
path to find $SHELL. Rich Pixley says so, and I agree. */
environ = env;
- execlp (shell_file, shell_file, "-c", shell_command, (char *)0);
- fprintf_unfiltered (gdb_stderr, "Cannot exec %s: %s.\n", shell_file,
- safe_strerror (errno));
- gdb_flush (gdb_stderr);
- _exit (0177);
+ /* If we decided above to start up with a shell,
+ * we exec the shell,
+ * "-c" says to interpret the next arg as a shell command
+ * to execute, and this command is "exec <target-program> <args>".
+ * "-f" means "fast startup" to the c-shell, which means
+ * don't do .cshrc file. Doing .cshrc may cause fork/exec
+ * events which will confuse debugger start-up code.
+ */
+ if (shell)
+ {
+#if 0
+
+ /* HP change is problematic. The -f option has different meanings
+ for different shells. It is particularly inappropriate for
+ bourne shells. */
+ execlp (shell_file, shell_file, "-f", "-c", shell_command, (char *) 0);
+#else
+ execlp (shell_file, shell_file, "-c", shell_command, (char *) 0);
+#endif
+
+
+ /* If we get here, it's an error */
+ fprintf_unfiltered (gdb_stderr, "Cannot exec %s: %s.\n", shell_file,
+ safe_strerror (errno));
+ gdb_flush (gdb_stderr);
+ _exit (0177);
+ }
+ else
+ {
+ /* Otherwise, we directly exec the target program with execvp. */
+ int i;
+ char *errstring;
+#if DEBUGGING
+ printf ("about to exec target, exec_file = %s\n", exec_file);
+ i = 0;
+ while (argv[i] != NULL)
+ {
+ printf ("strlen(argv[%d]) is %d\n", i, strlen (argv[i]));
+ printf ("argv[%d] is %s\n", i, argv[i]);
+ i++;
+ }
+#endif
+ execvp (exec_file, argv);
+
+ /* If we get here, it's an error */
+ errstring = safe_strerror (errno);
+ fprintf_unfiltered (gdb_stderr, "Cannot exec %s ", exec_file);
+
+ i = 1;
+ while (argv[i] != NULL)
+ {
+ if (i != 1)
+ fprintf_unfiltered (gdb_stderr, " ");
+ fprintf_unfiltered (gdb_stderr, "%s", argv[i]);
+ i++;
+ }
+ fprintf_unfiltered (gdb_stderr, ".\n");
+ /* This extra info seems to be useless
+ fprintf_unfiltered (gdb_stderr, "Got error %s.\n", errstring);
+ */
+ gdb_flush (gdb_stderr);
+ _exit (0177);
+ }
}
/* Restore our environment in case a vforked child clob'd it. */
environ = save_our_env;
- init_thread_list();
+ init_thread_list ();
inferior_pid = pid; /* Needed for wait_for_inferior stuff below */
/* Now that we have a child process, make it our target, and
initialize anything target-vector-specific that needs initializing. */
- (*init_trace_fun)(pid);
+
+ (*init_trace_fun) (pid);
/* We are now in the child process of interest, having exec'd the
correct program, and are poised at the first instruction of the
@@ -249,6 +415,137 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
#endif
}
+/* An inferior Unix process CHILD_PID has been created by a call to
+ fork() (or variants like vfork). It is presently stopped, and waiting
+ to be resumed. clone_and_follow_inferior will fork the debugger,
+ and that clone will "follow" (attach to) CHILD_PID. The original copy
+ of the debugger will not touch CHILD_PID again.
+
+ Also, the original debugger will set FOLLOWED_CHILD FALSE, while the
+ clone will set it TRUE.
+ */
+void
+clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ extern int auto_solib_add;
+
+ int debugger_pid;
+ int status;
+ char pid_spelling[100]; /* Arbitrary but sufficient length. */
+
+ /* This semaphore is used to coordinate the two debuggers' handoff
+ of CHILD_PID. The original debugger will detach from CHILD_PID,
+ and then the clone debugger will attach to it. (It must be done
+ this way because on some targets, only one process at a time can
+ trace another. Thus, the original debugger must relinquish its
+ tracing rights before the clone can pick them up.)
+ */
+#define SEM_TALK (1)
+#define SEM_LISTEN (0)
+ int handoff_semaphore[2]; /* Original "talks" to [1], clone "listens" to [0] */
+ int talk_value = 99;
+ int listen_value;
+
+ /* Set debug_fork then attach to the child while it sleeps, to debug. */
+ static int debug_fork = 0;
+
+ /* It is generally good practice to flush any possible pending stdio
+ output prior to doing a fork, to avoid the possibility of both the
+ parent and child flushing the same data after the fork. */
+
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ /* Open the semaphore pipes.
+ */
+ status = pipe (handoff_semaphore);
+ if (status < 0)
+ error ("error getting pipe for handoff semaphore");
+
+ /* Clone the debugger. */
+#if defined(USG) && !defined(HAVE_VFORK)
+ debugger_pid = fork ();
+#else
+ if (debug_fork)
+ debugger_pid = fork ();
+ else
+ debugger_pid = vfork ();
+#endif
+
+ if (debugger_pid < 0)
+ perror_with_name ("fork");
+
+ /* Are we the original debugger? If so, we must relinquish all claims
+ to CHILD_PID. */
+ if (debugger_pid != 0)
+ {
+ char signal_spelling[100];/* Arbitrary but sufficient length */
+
+ /* Detach from CHILD_PID. Deliver a "stop" signal when we do, though,
+ so that it remains stopped until the clone debugger can attach
+ to it.
+ */
+ detach_breakpoints (child_pid);
+
+ sprintf (signal_spelling, "%d", target_signal_to_host (TARGET_SIGNAL_STOP));
+ target_require_detach (child_pid, signal_spelling, 1);
+
+ /* Notify the clone debugger that it should attach to CHILD_PID. */
+ write (handoff_semaphore[SEM_TALK], &talk_value, sizeof (talk_value));
+
+ *followed_child = 0;
+ }
+
+ /* We're the child. */
+ else
+ {
+ if (debug_fork)
+ sleep (debug_fork);
+
+ /* The child (i.e., the cloned debugger) must now attach to
+ CHILD_PID. inferior_pid is presently set to the parent process
+ of the fork, while CHILD_PID should be the child process of the
+ fork.
+
+ Wait until the original debugger relinquishes control of CHILD_PID,
+ though.
+ */
+ read (handoff_semaphore[SEM_LISTEN], &listen_value, sizeof (listen_value));
+
+ /* Note that we DON'T want to actually detach from inferior_pid,
+ because that would allow it to run free. The original
+ debugger wants to retain control of the process. So, we
+ just reset inferior_pid to CHILD_PID, and then ensure that all
+ breakpoints are really set in CHILD_PID.
+ */
+ target_mourn_inferior ();
+
+ /* Ask the tty subsystem to switch to the one we specified earlier
+ (or to share the current terminal, if none was specified). */
+
+ new_tty ();
+
+ dont_repeat ();
+ sprintf (pid_spelling, "%d", child_pid);
+ target_require_attach (pid_spelling, 1);
+
+ /* Perform any necessary cleanup, after attachment. (This form
+ of attaching can behave differently on some targets than the
+ standard method, where a process formerly not under debugger
+ control was suddenly attached to..)
+ */
+ target_post_follow_inferior_by_clone ();
+
+ *followed_child = 1;
+ }
+
+ /* Discard the handoff sempahore. */
+ (void) close (handoff_semaphore[SEM_LISTEN]);
+ (void) close (handoff_semaphore[SEM_TALK]);
+}
+
/* Accept NTRAPS traps from the inferior. */
void
@@ -268,6 +565,13 @@ startup_inferior (ntraps)
terminal_initted = 0;
+ if (STARTUP_WITH_SHELL)
+ inferior_ignoring_startup_exec_events = ntraps;
+ else
+ inferior_ignoring_startup_exec_events = 0;
+ inferior_ignoring_leading_exec_events =
+ target_reported_exec_events_per_exec_call () - 1;
+
#ifdef STARTUP_INFERIOR
STARTUP_INFERIOR (pending_execs);
#else
@@ -299,9 +603,12 @@ startup_inferior (ntraps)
terminal_initted = 1;
}
- if (0 == --pending_execs)
+
+ pending_execs = pending_execs - 1;
+ if (0 == pending_execs)
break;
- resume (0, TARGET_SIGNAL_0); /* Just make it go on */
+
+ resume (0, TARGET_SIGNAL_0); /* Just make it go on */
}
}
#endif /* STARTUP_INFERIOR */
diff --git a/contrib/gdb/gdb/fr30-tdep.c b/contrib/gdb/gdb/fr30-tdep.c
new file mode 100644
index 0000000..0d442da
--- /dev/null
+++ b/contrib/gdb/gdb/fr30-tdep.c
@@ -0,0 +1,552 @@
+/* Target-dependent code for the Fujitsu FR30.
+ Copyright 1999, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+
+/* Function: pop_frame
+ This routine gets called when either the user uses the `return'
+ command, or the call dummy breakpoint gets hit. */
+
+void
+fr30_pop_frame ()
+{
+ struct frame_info *frame = get_current_frame();
+ int regnum;
+ CORE_ADDR sp = read_register(SP_REGNUM);
+
+ if (PC_IN_CALL_DUMMY(frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0) {
+ write_register (regnum,
+ read_memory_unsigned_integer (frame->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum)));
+ }
+ write_register (SP_REGNUM, sp + frame->framesize);
+ }
+ flush_cached_frames ();
+}
+
+/* Function: skip_prologue
+ Return the address of the first code past the prologue of the function. */
+
+CORE_ADDR
+fr30_skip_prologue(CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end < func_end) {
+ return sal.end;
+ }
+ }
+
+/* Either we didn't find the start of this function (nothing we can do),
+ or there's no line info, or the line after the prologue is after
+ the end of the function (there probably isn't a prologue). */
+
+ return pc;
+}
+
+
+/* Function: push_arguments
+ Setup arguments and RP for a call to the target. First four args
+ go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on stack...
+ Structs are passed by reference. XXX not right now Z.R.
+ 64 bit quantities (doubles and long longs) may be split between
+ the regs and the stack.
+ When calling a function that returns a struct, a pointer to the struct
+ is passed in as a secret first argument (always in FIRST_ARGREG).
+
+ Stack space for the args has NOT been allocated: that job is up to us.
+*/
+
+CORE_ADDR
+fr30_push_arguments(nargs, args, sp, struct_return, struct_addr)
+ int nargs;
+ value_ptr * args;
+ CORE_ADDR sp;
+ int struct_return;
+ CORE_ADDR struct_addr;
+{
+ int argreg;
+ int argnum;
+ int stack_offset;
+ struct stack_arg {
+ char *val;
+ int len;
+ int offset;
+ };
+ struct stack_arg *stack_args =
+ (struct stack_arg*)alloca (nargs * sizeof (struct stack_arg));
+ int nstack_args = 0;
+
+ argreg = FIRST_ARGREG;
+
+ /* the struct_return pointer occupies the first parameter-passing reg */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ stack_offset = 0;
+
+ /* Process args from left to right. Store as many as allowed in
+ registers, save the rest to be pushed on the stack */
+ for(argnum = 0; argnum < nargs; argnum++)
+ {
+ char * val;
+ value_ptr arg = args[argnum];
+ struct type * arg_type = check_typedef (VALUE_TYPE (arg));
+ struct type * target_type = TYPE_TARGET_TYPE (arg_type);
+ int len = TYPE_LENGTH (arg_type);
+ enum type_code typecode = TYPE_CODE (arg_type);
+ CORE_ADDR regval;
+ int newarg;
+
+ val = (char *) VALUE_CONTENTS (arg);
+
+ {
+ /* Copy the argument to general registers or the stack in
+ register-sized pieces. Large arguments are split between
+ registers and stack. */
+ while (len > 0)
+ {
+ if (argreg <= LAST_ARGREG)
+ {
+ int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
+ regval = extract_address (val, partial_len);
+
+ /* It's a simple argument being passed in a general
+ register. */
+ write_register (argreg, regval);
+ argreg++;
+ len -= partial_len;
+ val += partial_len;
+ }
+ else
+ {
+ /* keep for later pushing */
+ stack_args[nstack_args].val = val;
+ stack_args[nstack_args++].len = len;
+ break;
+ }
+ }
+ }
+ }
+ /* now do the real stack pushing, process args right to left */
+ while(nstack_args--)
+ {
+ sp -= stack_args[nstack_args].len;
+ write_memory(sp, stack_args[nstack_args].val,
+ stack_args[nstack_args].len);
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+_initialize_fr30_tdep()
+{
+ extern int print_insn_fr30(bfd_vma, disassemble_info *);
+
+ tm_print_insn = print_insn_fr30;
+}
+
+/* Function: check_prologue_cache
+ Check if prologue for this frame's PC has already been scanned.
+ If it has, copy the relevant information about that prologue and
+ return non-zero. Otherwise do not copy anything and return zero.
+
+ The information saved in the cache includes:
+ * the frame register number;
+ * the size of the stack frame;
+ * the offsets of saved regs (relative to the old SP); and
+ * the offset from the stack pointer to the frame pointer
+
+ The cache contains only one entry, since this is adequate
+ for the typical sequence of prologue scan requests we get.
+ When performing a backtrace, GDB will usually ask to scan
+ the same function twice in a row (once to get the frame chain,
+ and once to fill in the extra frame information).
+*/
+
+static struct frame_info prologue_cache;
+
+static int
+check_prologue_cache (fi)
+ struct frame_info * fi;
+{
+ int i;
+
+ if (fi->pc == prologue_cache.pc)
+ {
+ fi->framereg = prologue_cache.framereg;
+ fi->framesize = prologue_cache.framesize;
+ fi->frameoffset = prologue_cache.frameoffset;
+ for (i = 0; i <= NUM_REGS; i++)
+ fi->fsr.regs[i] = prologue_cache.fsr.regs[i];
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/* Function: save_prologue_cache
+ Copy the prologue information from fi to the prologue cache.
+*/
+
+static void
+save_prologue_cache (fi)
+ struct frame_info * fi;
+{
+ int i;
+
+ prologue_cache.pc = fi->pc;
+ prologue_cache.framereg = fi->framereg;
+ prologue_cache.framesize = fi->framesize;
+ prologue_cache.frameoffset = fi->frameoffset;
+
+ for (i = 0; i <= NUM_REGS; i++) {
+ prologue_cache.fsr.regs[i] = fi->fsr.regs[i];
+ }
+}
+
+
+/* Function: scan_prologue
+ Scan the prologue of the function that contains PC, and record what
+ we find in PI. PI->fsr must be zeroed by the called. Returns the
+ pc after the prologue. Note that the addresses saved in pi->fsr
+ are actually just frame relative (negative offsets from the frame
+ pointer). This is because we don't know the actual value of the
+ frame pointer yet. In some circumstances, the frame pointer can't
+ be determined till after we have scanned the prologue. */
+
+static void
+fr30_scan_prologue (fi)
+ struct frame_info * fi;
+{
+ int sp_offset, fp_offset;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+
+ /* Check if this function is already in the cache of frame information. */
+ if (check_prologue_cache (fi))
+ return;
+
+ /* Assume there is no frame until proven otherwise. */
+ fi->framereg = SP_REGNUM;
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+
+ /* Find the function prologue. If we can't find the function in
+ the symbol table, peek in the stack frame to find the PC. */
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ /* Assume the prologue is everything between the first instruction
+ in the function and the first source line. */
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+ {
+ /* XXX Z.R. What now??? The following is entirely bogus */
+ prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12;
+ prologue_end = prologue_start + 40;
+ }
+
+ /* Now search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers. */
+
+ sp_offset = fp_offset = 0;
+ for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2)
+ {
+ unsigned int insn;
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+
+ if ((insn & 0xfe00) == 0x8e00) /* stm0 or stm1 */
+ {
+ int reg, mask = insn & 0xff;
+
+ /* scan in one sweep - create virtual 16-bit mask from either insn's mask */
+ if((insn & 0x0100) == 0)
+ {
+ mask <<= 8; /* stm0 - move to upper byte in virtual mask */
+ }
+
+ /* Calculate offsets of saved registers (to be turned later into addresses). */
+ for (reg = R4_REGNUM; reg <= R11_REGNUM; reg++)
+ if (mask & (1 << (15 - reg)))
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[reg] = sp_offset;
+ }
+ }
+ else if((insn & 0xfff0) == 0x1700) /* st rx,@-r15 */
+ {
+ int reg = insn & 0xf;
+
+ sp_offset -= 4;
+ fi->fsr.regs[reg] = sp_offset;
+ }
+ else if((insn & 0xff00) == 0x0f00) /* enter */
+ {
+ fp_offset = fi->fsr.regs[FP_REGNUM] = sp_offset - 4;
+ sp_offset -= 4 * (insn & 0xff);
+ fi->framereg = FP_REGNUM;
+ }
+ else if(insn == 0x1781) /* st rp,@-sp */
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[RP_REGNUM] = sp_offset;
+ }
+ else if(insn == 0x170e) /* st fp,@-sp */
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[FP_REGNUM] = sp_offset;
+ }
+ else if(insn == 0x8bfe) /* mov sp,fp */
+ {
+ fi->framereg = FP_REGNUM;
+ }
+ else if((insn & 0xff00) == 0xa300) /* addsp xx */
+ {
+ sp_offset += 4 * (signed char)(insn & 0xff);
+ }
+ else if((insn & 0xff0f) == 0x9b00 && /* ldi:20 xx,r0 */
+ read_memory_unsigned_integer(current_pc+4, 2)
+ == 0xac0f) /* sub r0,sp */
+ {
+ /* large stack adjustment */
+ sp_offset -= (((insn & 0xf0) << 12) | read_memory_unsigned_integer(current_pc+2, 2));
+ current_pc += 4;
+ }
+ else if(insn == 0x9f80 && /* ldi:32 xx,r0 */
+ read_memory_unsigned_integer(current_pc+6, 2)
+ == 0xac0f) /* sub r0,sp */
+ {
+ /* large stack adjustment */
+ sp_offset -=
+ (read_memory_unsigned_integer(current_pc+2, 2) << 16 |
+ read_memory_unsigned_integer(current_pc+4, 2));
+ current_pc += 6;
+ }
+ }
+
+ /* The frame size is just the negative of the offset (from the original SP)
+ of the last thing thing we pushed on the stack. The frame offset is
+ [new FP] - [new SP]. */
+ fi->framesize = -sp_offset;
+ fi->frameoffset = fp_offset - sp_offset;
+
+ save_prologue_cache (fi);
+}
+
+/* Function: init_extra_frame_info
+ Setup the frame's frame pointer, pc, and frame addresses for saved
+ registers. Most of the work is done in scan_prologue().
+
+ Note that when we are called for the last frame (currently active frame),
+ that fi->pc and fi->frame will already be setup. However, fi->frame will
+ be valid only if this routine uses FP. For previous frames, fi-frame will
+ always be correct (since that is derived from fr30_frame_chain ()).
+
+ We can be called with the PC in the call dummy under two circumstances.
+ First, during normal backtracing, second, while figuring out the frame
+ pointer just prior to calling the target function (see run_stack_dummy). */
+
+void
+fr30_init_extra_frame_info (fi)
+ struct frame_info * fi;
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+ return;
+ }
+ fr30_scan_prologue (fi);
+
+ if (!fi->next) /* this is the innermost frame? */
+ fi->frame = read_register (fi->framereg);
+ else /* not the innermost frame */
+ /* If we have an FP, the callee saved it. */
+ if (fi->framereg == FP_REGNUM)
+ if (fi->next->fsr.regs[fi->framereg] != 0)
+ fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg],
+ 4);
+ /* Calculate actual addresses of saved registers using offsets determined
+ by fr30_scan_prologue. */
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->fsr.regs[reg] != 0) {
+ fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset;
+ }
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register.
+ One thing we might want to do here is to check REGNUM against the
+ clobber mask, and somehow flag it as invalid if it isn't saved on
+ the stack somewhere. This would provide a graceful failure mode
+ when trying to get the value of caller-saves registers for an inner
+ frame. */
+
+CORE_ADDR
+fr30_find_callers_reg (fi, regnum)
+ struct frame_info *fi;
+ int regnum;
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->fsr.regs[regnum] != 0)
+ return read_memory_unsigned_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum));
+
+ return read_register (regnum);
+}
+
+
+/* Function: frame_chain
+ Figure out the frame prior to FI. Unfortunately, this involves
+ scanning the prologue of the caller, which will also be done
+ shortly by fr30_init_extra_frame_info. For the dummy frame, we
+ just return the stack pointer that was in use at the time the
+ function call was made. */
+
+
+CORE_ADDR
+fr30_frame_chain (fi)
+ struct frame_info * fi;
+{
+ CORE_ADDR fn_start, callers_pc, fp;
+ struct frame_info caller_fi;
+ int framereg;
+
+ /* is this a dummy frame? */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return fi->frame; /* dummy frame same as caller's frame */
+
+ /* is caller-of-this a dummy frame? */
+ callers_pc = FRAME_SAVED_PC(fi); /* find out who called us: */
+ fp = fr30_find_callers_reg (fi, FP_REGNUM);
+ if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
+ return fp; /* dummy frame's frame may bear no relation to ours */
+
+ if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0; /* in _start fn, don't chain further */
+
+ framereg = fi->framereg;
+
+ /* If the caller is the startup code, we're at the end of the chain. */
+ if (find_pc_partial_function (callers_pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0;
+
+ memset (& caller_fi, 0, sizeof (caller_fi));
+ caller_fi.pc = callers_pc;
+ fr30_scan_prologue (& caller_fi);
+ framereg = caller_fi.framereg;
+
+ /* If the caller used a frame register, return its value.
+ Otherwise, return the caller's stack pointer. */
+ if (framereg == FP_REGNUM)
+ return fr30_find_callers_reg (fi, framereg);
+ else
+ return fi->frame + fi->framesize;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers. If the inner frame is a dummy frame, return its PC
+ instead of RP, because that's where "caller" of the dummy-frame
+ will be found. */
+
+CORE_ADDR
+fr30_frame_saved_pc (fi)
+ struct frame_info *fi;
+{
+ if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM);
+ else
+ return fr30_find_callers_reg (fi, RP_REGNUM);
+}
+
+/* Function: fix_call_dummy
+ Pokes the callee function's address into the CALL_DUMMY assembly stub.
+ Assumes that the CALL_DUMMY looks like this:
+ jarl <offset24>, r31
+ trap
+ */
+
+int
+fr30_fix_call_dummy (dummy, sp, fun, nargs, args, type, gcc_p)
+ char *dummy;
+ CORE_ADDR sp;
+ CORE_ADDR fun;
+ int nargs;
+ value_ptr *args;
+ struct type *type;
+ int gcc_p;
+{
+ long offset24;
+
+ offset24 = (long) fun - (long) entry_point_address ();
+ offset24 &= 0x3fffff;
+ offset24 |= 0xff800000; /* jarl <offset24>, r31 */
+
+ store_unsigned_integer ((unsigned int *)&dummy[2], 2, offset24 & 0xffff);
+ store_unsigned_integer ((unsigned int *)&dummy[0], 2, offset24 >> 16);
+ return 0;
+}
diff --git a/contrib/gdb/gdb/frame.h b/contrib/gdb/gdb/frame.h
index d9dc0f8..6836c6c 100644
--- a/contrib/gdb/gdb/frame.h
+++ b/contrib/gdb/gdb/frame.h
@@ -1,5 +1,5 @@
/* Definitions for dealing with stack frames, for GDB, the GNU debugger.
- Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc.
+ Copyright 1986, 1989, 1991, 1992, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -20,6 +20,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if !defined (FRAME_H)
#define FRAME_H 1
+/* Describe the saved registers of a frame. */
+
+#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)
+/* XXXX - deprecated */
+struct frame_saved_regs
+ {
+
+ /* For each register, address of where it was saved on entry to
+ the frame, or zero if it was not saved on entry to this frame.
+ This includes special registers such as pc and fp saved in
+ special ways in the stack frame. The SP_REGNUM is even more
+ special, the address here is the sp for the next frame, not the
+ address where the sp was saved. */
+
+ CORE_ADDR regs[NUM_REGS];
+ };
+#endif
+
/* We keep a cache of stack frames, each of which is a "struct
frame_info". The innermost one gets allocated (in
wait_for_inferior) each time the inferior stops; current_frame
@@ -53,34 +71,54 @@ struct frame_info
set this to prevent us from trying to print it like a normal frame. */
int signal_handler_caller;
+ /* For each register, address of where it was saved on entry to
+ the frame, or zero if it was not saved on entry to this frame.
+ This includes special registers such as pc and fp saved in
+ special ways in the stack frame. The SP_REGNUM is even more
+ special, the address here is the sp for the next frame, not the
+ address where the sp was saved. */
+ /* Allocated by frame_saved_regs_zalloc () which is called /
+ initialized by FRAME_INIT_SAVED_REGS(). */
+ CORE_ADDR *saved_regs; /*NUM_REGS*/
+
+#ifdef EXTRA_FRAME_INFO
+ /* XXXX - deprecated */
/* Anything extra for this structure that may have been defined
in the machine dependent files. */
-#ifdef EXTRA_FRAME_INFO
EXTRA_FRAME_INFO
#endif
- /* We should probably also store a "struct frame_saved_regs" here.
- This is already done by some machines (e.g. config/m88k/tm-m88k.h)
- but there is no reason it couldn't be general. */
+ /* Anything extra for this structure that may have been defined
+ in the machine dependent files. */
+ /* Allocated by frame_obstack_alloc () which is called /
+ initialized by INIT_EXTRA_FRAME_INFO */
+ struct frame_extra_info *extra_info;
/* Pointers to the next and previous frame_info's in the frame cache. */
struct frame_info *next, *prev;
};
-/* Describe the saved registers of a frame. */
+/* Allocate additional space for appendices to a struct frame_info. */
-struct frame_saved_regs
- {
+#ifndef SIZEOF_FRAME_SAVED_REGS
+#define SIZEOF_FRAME_SAVED_REGS (sizeof (CORE_ADDR) * (NUM_REGS))
+#endif
+extern void *frame_obstack_alloc PARAMS ((unsigned long size));
+extern void frame_saved_regs_zalloc PARAMS ((struct frame_info *));
- /* For each register, address of where it was saved on entry to
- the frame, or zero if it was not saved on entry to this frame.
- This includes special registers such as pc and fp saved in
- special ways in the stack frame. The SP_REGNUM is even more
- special, the address here is the sp for the next frame, not the
- address where the sp was saved. */
+/* Dummy frame. This saves the processor state just prior to setting up the
+ inferior function call. On most targets, the registers are saved on the
+ target stack, but that really slows down function calls. */
- CORE_ADDR regs[NUM_REGS];
- };
+struct dummy_frame
+{
+ struct dummy_frame *next;
+
+ CORE_ADDR pc;
+ CORE_ADDR fp;
+ CORE_ADDR sp;
+ char regs[REGISTER_BYTES];
+};
/* Return the frame address from FR. Except in the machine-dependent
*FRAME* macros, a frame address has no defined meaning other than
@@ -101,29 +139,25 @@ struct frame_saved_regs
is the outermost one and has no caller.
If a particular target needs a different definition, then it can override
- the definition here by providing one in the tm file. */
+ the definition here by providing one in the tm file.
-#if !defined (FRAME_CHAIN_VALID)
+ XXXX - both default and alternate frame_chain_valid functions are
+ deprecated. New code should use generic dummy frames. */
-#if defined (FRAME_CHAIN_VALID_ALTERNATE)
+extern int default_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
+extern int alternate_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
+extern int nonnull_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
+extern int generic_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
+#if !defined (FRAME_CHAIN_VALID)
+#if !defined (FRAME_CHAIN_VALID_ALTERNATE)
+#define FRAME_CHAIN_VALID(chain, thisframe) default_frame_chain_valid (chain, thisframe)
+#else
/* Use the alternate method of avoiding running up off the end of the frame
chain or following frames back into the startup code. See the comments
in objfiles.h. */
-
-#define FRAME_CHAIN_VALID(chain, thisframe) \
- ((chain) != 0 \
- && !inside_main_func ((thisframe) -> pc) \
- && !inside_entry_func ((thisframe) -> pc))
-
-#else
-
-#define FRAME_CHAIN_VALID(chain, thisframe) \
- ((chain) != 0 \
- && !inside_entry_file (FRAME_SAVED_PC (thisframe)))
-
+#define FRAME_CHAIN_VALID(chain, thisframe) alternate_frame_chain_valid (chain,thisframe)
#endif /* FRAME_CHAIN_VALID_ALTERNATE */
-
#endif /* FRAME_CHAIN_VALID */
/* The stack frame that the user has specified for commands to act on.
@@ -145,9 +179,14 @@ extern void flush_cached_frames PARAMS ((void));
extern void reinit_frame_cache PARAMS ((void));
+
+#ifdef FRAME_FIND_SAVED_REGS
+/* XXX - deprecated */
+#define FRAME_INIT_SAVED_REGS(FI) get_frame_saved_regs (FI, NULL)
extern void get_frame_saved_regs PARAMS ((struct frame_info *,
struct frame_saved_regs *));
-
+#endif
+
extern void set_current_frame PARAMS ((struct frame_info *));
extern struct frame_info *get_prev_frame PARAMS ((struct frame_info *));
@@ -170,6 +209,8 @@ extern CORE_ADDR get_pc_function_start PARAMS ((CORE_ADDR));
extern struct block * block_for_pc PARAMS ((CORE_ADDR));
+extern struct block * block_for_pc_sect PARAMS ((CORE_ADDR, asection *));
+
extern int frameless_look_for_prologue PARAMS ((struct frame_info *));
extern void print_frame_args PARAMS ((struct symbol *, struct frame_info *,
@@ -179,12 +220,20 @@ extern struct frame_info *find_relative_frame PARAMS ((struct frame_info *, int*
extern void print_stack_frame PARAMS ((struct frame_info *, int, int));
+extern void print_only_stack_frame PARAMS ((struct frame_info *, int, int));
+
+extern void show_stack_frame PARAMS ((struct frame_info *));
+
extern void select_frame PARAMS ((struct frame_info *, int));
extern void record_selected_frame PARAMS ((CORE_ADDR *, int *));
+extern void select_and_print_frame PARAMS ((struct frame_info *, int));
+
extern void print_frame_info PARAMS ((struct frame_info *, int, int, int));
+extern void show_frame_info PARAMS ((struct frame_info *, int, int, int));
+
extern CORE_ADDR find_saved_register PARAMS ((struct frame_info *, int));
extern struct frame_info *block_innermost_frame PARAMS ((struct block *));
@@ -193,4 +242,23 @@ extern struct frame_info *find_frame_addr_in_frame_chain PARAMS ((CORE_ADDR));
extern CORE_ADDR sigtramp_saved_pc PARAMS ((struct frame_info *));
+extern CORE_ADDR generic_read_register_dummy PARAMS ((CORE_ADDR pc,
+ CORE_ADDR fp,
+ int));
+extern void generic_push_dummy_frame PARAMS ((void));
+extern void generic_pop_current_frame PARAMS ((void (*) (struct frame_info *)));
+extern void generic_pop_dummy_frame PARAMS ((void));
+
+extern int generic_pc_in_call_dummy PARAMS ((CORE_ADDR pc,
+ CORE_ADDR fp));
+extern char * generic_find_dummy_frame PARAMS ((CORE_ADDR pc,
+ CORE_ADDR fp));
+
+#ifdef __GNUC__
+/* Some native compilers, even ones that are supposed to be ANSI and for which __STDC__
+ is true, complain about forward decls of enums. */
+enum lval_type;
+extern void generic_get_saved_register PARAMS ((char *, int *, CORE_ADDR *, struct frame_info *, int, enum lval_type *));
+#endif
+
#endif /* !defined (FRAME_H) */
diff --git a/contrib/gdb/gdb/gdb-stabs.h b/contrib/gdb/gdb/gdb-stabs.h
index cb7b621..1ad782a 100644
--- a/contrib/gdb/gdb/gdb-stabs.h
+++ b/contrib/gdb/gdb/gdb-stabs.h
@@ -64,9 +64,20 @@ struct dbx_symfile_info {
int symbol_size; /* Bytes in a single symbol */
struct stab_section_info *stab_section_info; /* section starting points
of the original .o files before linking. */
+
+ /* See stabsread.h for the use of the following. */
+ struct header_file *header_files;
+ int n_header_files;
+ int n_allocated_header_files;
+
+ /* Pointers to BFD sections. These are used to speed up the building of
+ minimal symbols. */
+ asection *text_section;
+ asection *data_section;
+ asection *bss_section;
};
-#define DBX_SYMFILE_INFO(o) ((struct dbx_symfile_info *)((o)->sym_stab_info))
+#define DBX_SYMFILE_INFO(o) ((o)->sym_stab_info)
#define DBX_TEXT_ADDR(o) (DBX_SYMFILE_INFO(o)->text_addr)
#define DBX_TEXT_SIZE(o) (DBX_SYMFILE_INFO(o)->text_size)
#define DBX_SYMCOUNT(o) (DBX_SYMFILE_INFO(o)->symcount)
@@ -74,5 +85,8 @@ struct dbx_symfile_info {
#define DBX_STRINGTAB_SIZE(o) (DBX_SYMFILE_INFO(o)->stringtab_size)
#define DBX_SYMTAB_OFFSET(o) (DBX_SYMFILE_INFO(o)->symtab_offset)
#define DBX_SYMBOL_SIZE(o) (DBX_SYMFILE_INFO(o)->symbol_size)
+#define DBX_TEXT_SECTION(o) (DBX_SYMFILE_INFO(o)->text_section)
+#define DBX_DATA_SECTION(o) (DBX_SYMFILE_INFO(o)->data_section)
+#define DBX_BSS_SECTION(o) (DBX_SYMFILE_INFO(o)->bss_section)
#endif /* GDBSTABS_H */
diff --git a/contrib/gdb/gdb/gdb.1 b/contrib/gdb/gdb/gdb.1
index cb1cba1..2e55a49 100644
--- a/contrib/gdb/gdb/gdb.1
+++ b/contrib/gdb/gdb/gdb.1
@@ -1,6 +1,6 @@
.\" Copyright (c) 1991 Free Software Foundation
.\" See section COPYING for conditions for redistribution
-.\" $Id: gdb.1,v 1.3 1991/12/13 22:22:58 pesch Exp $
+.\" $Id: gdb.1,v 1.4 1999/01/05 00:50:50 jsm Exp $
.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
.SH NAME
gdb \- The GNU Debugger
@@ -216,6 +216,10 @@ Read symbol table from file \c
\&.
.TP
+.B \-write
+Enable writing into executable and core files.
+
+.TP
.BI "\-exec=" "file"\c
.TP
.BI "\-e " "file"\c
diff --git a/contrib/gdb/gdb/gdb_string.h b/contrib/gdb/gdb/gdb_string.h
index 4fb53bb..944eec1 100644
--- a/contrib/gdb/gdb/gdb_string.h
+++ b/contrib/gdb/gdb/gdb_string.h
@@ -1,5 +1,5 @@
/* Portable <string.h>
- Copyright 1995 Free Software Foundation, Inc.
+ Copyright 1995, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -28,11 +28,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
# else
# include <strings.h>
# endif
-extern char *strchr();
-extern char *strrchr();
-extern char *strstr();
-extern char *strtok();
-extern char *strerror();
+
+#ifndef strchr
+extern char *strchr PARAMS ((const char *, int)); /* X3.159-1989 4.11.5.2 */
+#endif
+
+#ifndef strrchr
+extern char *strrchr PARAMS ((const char *, int)); /* X3.159-1989 4.11.5.5 */
+#endif
+
+#ifndef strstr
+extern char *strstr PARAMS ((const char *, const char *)); /* X3.159-1989 4.11.5.7 */
+#endif
+
+#ifndef strtok
+extern char *strtok PARAMS ((char *, const char *)); /* X3.159-1989 4.11.5.8 */
+#endif
+
# ifdef HAVE_MEMORY_H
# include <memory.h>
# else
@@ -41,8 +53,16 @@ extern void *memcpy();
extern void *memmove();
extern int memcmp();
# endif
+#endif /* STDC_HEADERS */
+
+#ifdef NEED_DECLARATION_STRERROR
+#ifndef strerror
+extern char *strerror PARAMS ((int)); /* X3.159-1989 4.11.6.2 */
+#endif
#endif
-extern char *strdup();
+#ifdef NEED_DECLARATION_STRDUP
+extern char *strdup (); /* full prototype collides w/ some OSes (AIX 3.2.5) */
+#endif
#endif /* !defined(GDB_STRING_H) */
diff --git a/contrib/gdb/gdb/gdbarch.c b/contrib/gdb/gdb/gdbarch.c
new file mode 100644
index 0000000..154fa8f
--- /dev/null
+++ b/contrib/gdb/gdb/gdbarch.c
@@ -0,0 +1,360 @@
+/* Semi-dynamic architecture support for GDB, the GNU debugger.
+ Copyright 1998, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "bfd.h"
+#include "gdbcmd.h"
+
+
+
+/* Non-zero if we want to trace architecture code. */
+
+#ifndef GDBARCH_DEBUG
+#define GDBARCH_DEBUG 0
+#endif
+int gdbarch_debug = GDBARCH_DEBUG;
+
+
+/* Functions to manipulate the endianness of the target. */
+
+#ifdef TARGET_BYTE_ORDER_SELECTABLE
+/* compat - Catch old targets that expect a selectable byte-order to
+ default to BIG_ENDIAN */
+#ifndef TARGET_BYTE_ORDER_DEFAULT
+#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN
+#endif
+#endif
+#ifndef TARGET_BYTE_ORDER_DEFAULT
+/* compat - Catch old non byte-order selectable targets that do not
+ define TARGET_BYTE_ORDER_DEFAULT and instead expect
+ TARGET_BYTE_ORDER to be used as the default. For targets that
+ defined neither TARGET_BYTE_ORDER nor TARGET_BYTE_ORDER_DEFAULT the
+ below will get a strange compiler warning. */
+#define TARGET_BYTE_ORDER_DEFAULT TARGET_BYTE_ORDER
+#endif
+int target_byte_order = TARGET_BYTE_ORDER_DEFAULT;
+int target_byte_order_auto = 1;
+
+/* Chain containing the \"set endian\" commands. */
+static struct cmd_list_element *endianlist = NULL;
+
+/* Called by ``show endian''. */
+static void show_endian PARAMS ((char *, int));
+static void
+show_endian (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char *msg =
+ (TARGET_BYTE_ORDER_AUTO
+ ? "The target endianness is set automatically (currently %s endian)\n"
+ : "The target is assumed to be %s endian\n");
+ printf_unfiltered (msg, (TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little"));
+}
+
+/* Called if the user enters ``set endian'' without an argument. */
+static void set_endian PARAMS ((char *, int));
+static void
+set_endian (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ printf_unfiltered ("\"set endian\" must be followed by \"auto\", \"big\" or \"little\".\n");
+ show_endian (args, from_tty);
+}
+
+/* Called by ``set endian big''. */
+static void set_endian_big PARAMS ((char *, int));
+static void
+set_endian_big (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (TARGET_BYTE_ORDER_SELECTABLE_P)
+ {
+ target_byte_order = BIG_ENDIAN;
+ target_byte_order_auto = 0;
+ }
+ else
+ {
+ printf_unfiltered ("Byte order is not selectable.");
+ show_endian (args, from_tty);
+ }
+}
+
+/* Called by ``set endian little''. */
+static void set_endian_little PARAMS ((char *, int));
+static void
+set_endian_little (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (TARGET_BYTE_ORDER_SELECTABLE_P)
+ {
+ target_byte_order = LITTLE_ENDIAN;
+ target_byte_order_auto = 0;
+ }
+ else
+ {
+ printf_unfiltered ("Byte order is not selectable.");
+ show_endian (args, from_tty);
+ }
+}
+
+/* Called by ``set endian auto''. */
+static void set_endian_auto PARAMS ((char *, int));
+static void
+set_endian_auto (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (TARGET_BYTE_ORDER_SELECTABLE_P)
+ {
+ target_byte_order_auto = 1;
+ }
+ else
+ {
+ printf_unfiltered ("Byte order is not selectable.");
+ show_endian (args, from_tty);
+ }
+}
+
+/* Set the endianness from a BFD. */
+static void set_endian_from_file PARAMS ((bfd *));
+static void
+set_endian_from_file (abfd)
+ bfd *abfd;
+{
+ if (TARGET_BYTE_ORDER_SELECTABLE_P)
+ {
+ int want;
+
+ if (bfd_big_endian (abfd))
+ want = BIG_ENDIAN;
+ else
+ want = LITTLE_ENDIAN;
+ if (TARGET_BYTE_ORDER_AUTO)
+ target_byte_order = want;
+ else if (TARGET_BYTE_ORDER != want)
+ warning ("%s endian file does not match %s endian target.",
+ want == BIG_ENDIAN ? "big" : "little",
+ TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
+ }
+ else
+ {
+ if (bfd_big_endian (abfd)
+ ? TARGET_BYTE_ORDER != BIG_ENDIAN
+ : TARGET_BYTE_ORDER == BIG_ENDIAN)
+ warning ("%s endian file does not match %s endian target.",
+ bfd_big_endian (abfd) ? "big" : "little",
+ TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
+ }
+}
+
+
+
+/* Functions to manipulate the architecture of the target */
+
+int target_architecture_auto = 1;
+extern const struct bfd_arch_info bfd_default_arch_struct;
+const struct bfd_arch_info *target_architecture = &bfd_default_arch_struct;
+int (*target_architecture_hook) PARAMS ((const struct bfd_arch_info *ap));
+
+/* Do the real work of changing the current architecture */
+static void
+set_arch (arch)
+ const struct bfd_arch_info *arch;
+{
+ /* FIXME: Is it compatible with gdb? */
+ /* Check with the target on the setting */
+ if (target_architecture_hook != NULL
+ && !target_architecture_hook (arch))
+ printf_unfiltered ("Target does not support `%s' architecture.\n",
+ arch->printable_name);
+ else
+ {
+ target_architecture_auto = 0;
+ target_architecture = arch;
+ }
+}
+
+/* Called if the user enters ``show architecture'' without an argument. */
+static void show_architecture PARAMS ((char *, int));
+static void
+show_architecture (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ const char *arch;
+ arch = TARGET_ARCHITECTURE->printable_name;
+ if (target_architecture_auto)
+ printf_filtered ("The target architecture is set automatically (currently %s)\n", arch);
+ else
+ printf_filtered ("The target architecture is assumed to be %s\n", arch);
+}
+
+/* Called if the user enters ``set architecture'' with or without an
+ argument. */
+static void set_architecture PARAMS ((char *, int));
+static void
+set_architecture (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (args == NULL)
+ {
+ printf_unfiltered ("\"set architecture\" must be followed by \"auto\" or an architecture name.\n");
+ }
+ else if (strcmp (args, "auto") == 0)
+ {
+ target_architecture_auto = 1;
+ }
+ else
+ {
+ const struct bfd_arch_info *arch = bfd_scan_arch (args);
+ if (arch != NULL)
+ set_arch (arch);
+ else
+ printf_unfiltered ("Architecture `%s' not reconized.\n", args);
+ }
+}
+
+/* Called if the user enters ``info architecture'' without an argument. */
+static void info_architecture PARAMS ((char *, int));
+static void
+info_architecture (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ enum bfd_architecture a;
+ printf_filtered ("Available architectures are:\n");
+ for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
+ {
+ const struct bfd_arch_info *ap = bfd_lookup_arch (a, 0);
+ if (ap != NULL)
+ {
+ do
+ {
+ printf_filtered (" %s", ap->printable_name);
+ ap = ap->next;
+ }
+ while (ap != NULL);
+ printf_filtered ("\n");
+ }
+ }
+}
+
+/* Set the architecture from arch/machine */
+void
+set_architecture_from_arch_mach (arch, mach)
+ enum bfd_architecture arch;
+ unsigned long mach;
+{
+ const struct bfd_arch_info *wanted = bfd_lookup_arch (arch, mach);
+ if (wanted != NULL)
+ set_arch (wanted);
+ else
+ fatal ("hardwired architecture/machine not reconized");
+}
+
+/* Set the architecture from a BFD */
+static void set_architecture_from_file PARAMS ((bfd *));
+static void
+set_architecture_from_file (abfd)
+ bfd *abfd;
+{
+ const struct bfd_arch_info *wanted = bfd_get_arch_info (abfd);
+ if (target_architecture_auto)
+ {
+ if (target_architecture_hook != NULL
+ && !target_architecture_hook (wanted))
+ warning ("Target may not support %s architecture",
+ wanted->printable_name);
+ target_architecture = wanted;
+ }
+ else if (wanted != target_architecture)
+ {
+ warning ("%s architecture file may be incompatible with %s target.",
+ wanted->printable_name,
+ target_architecture->printable_name);
+ }
+}
+
+
+
+/* Disassembler */
+
+/* Pointer to the target-dependent disassembly function. */
+int (*tm_print_insn) PARAMS ((bfd_vma, disassemble_info *));
+disassemble_info tm_print_insn_info;
+
+
+
+/* Set the dynamic target-system-dependant parameters (architecture,
+ byte-order) using information found in the BFD */
+
+void
+set_gdbarch_from_file (abfd)
+ bfd *abfd;
+{
+ set_architecture_from_file (abfd);
+ set_endian_from_file (abfd);
+}
+
+
+extern void _initialize_gdbarch PARAMS ((void));
+void
+_initialize_gdbarch ()
+{
+ add_prefix_cmd ("endian", class_support, set_endian,
+ "Set endianness of target.",
+ &endianlist, "set endian ", 0, &setlist);
+ add_cmd ("big", class_support, set_endian_big,
+ "Set target as being big endian.", &endianlist);
+ add_cmd ("little", class_support, set_endian_little,
+ "Set target as being little endian.", &endianlist);
+ add_cmd ("auto", class_support, set_endian_auto,
+ "Select target endianness automatically.", &endianlist);
+ add_cmd ("endian", class_support, show_endian,
+ "Show endianness of target.", &showlist);
+
+ add_cmd ("architecture", class_support, set_architecture,
+ "Set architecture of target.", &setlist);
+ add_alias_cmd ("processor", "architecture", class_support, 1, &setlist);
+ add_cmd ("architecture", class_support, show_architecture,
+ "Show architecture of target.", &showlist);
+ add_cmd ("architecture", class_support, info_architecture,
+ "List supported target architectures", &infolist);
+
+ INIT_DISASSEMBLE_INFO_NO_ARCH (tm_print_insn_info, gdb_stdout, (fprintf_ftype)fprintf_filtered);
+ tm_print_insn_info.flavour = bfd_target_unknown_flavour;
+ tm_print_insn_info.read_memory_func = dis_asm_read_memory;
+ tm_print_insn_info.memory_error_func = dis_asm_memory_error;
+ tm_print_insn_info.print_address_func = dis_asm_print_address;
+
+#ifdef MAINTENANCE_CMDS
+ add_show_from_set (add_set_cmd ("archdebug",
+ class_maintenance,
+ var_zinteger,
+ (char *)&gdbarch_debug,
+ "Set architecture debugging.\n\
+When non-zero, architecture debugging is enabled.", &setlist),
+ &showlist);
+#endif
+}
diff --git a/contrib/gdb/gdb/gdbarch.h b/contrib/gdb/gdb/gdbarch.h
new file mode 100644
index 0000000..098db4c
--- /dev/null
+++ b/contrib/gdb/gdb/gdbarch.h
@@ -0,0 +1,118 @@
+/* Architecture commands for GDB, the GNU debugger.
+ Copyright 1998, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GDBARCH_H
+#define GDBARCH_H
+
+
+/* The target-system-dependant byte order is dynamic */
+
+/* TARGET_BYTE_ORDER_SELECTABLE_P determines if the target endianness
+ is selectable at runtime. The user can use the `set endian'
+ command to change it. TARGET_BYTE_ORDER_AUTO is nonzero when
+ target_byte_order should be auto-detected (from the program image
+ say). */
+
+#ifndef TARGET_BYTE_ORDER_SELECTABLE_P
+/* compat - Catch old targets that define TARGET_BYTE_ORDER_SLECTABLE
+ when they should have defined TARGET_BYTE_ORDER_SELECTABLE_P 1 */
+#ifdef TARGET_BYTE_ORDER_SELECTABLE
+#define TARGET_BYTE_ORDER_SELECTABLE_P 1
+#else
+#define TARGET_BYTE_ORDER_SELECTABLE_P 0
+#endif
+#endif
+
+extern int target_byte_order;
+#ifdef TARGET_BYTE_ORDER_SELECTABLE
+/* compat - Catch old targets that define TARGET_BYTE_ORDER_SELECTABLE
+ and expect defs.h to re-define TARGET_BYTE_ORDER. */
+#undef TARGET_BYTE_ORDER
+#endif
+#ifndef TARGET_BYTE_ORDER
+#define TARGET_BYTE_ORDER (target_byte_order + 0)
+#endif
+
+extern int target_byte_order_auto;
+#ifndef TARGET_BYTE_ORDER_AUTO
+#define TARGET_BYTE_ORDER_AUTO (target_byte_order_auto + 0)
+#endif
+
+
+
+/* The target-system-dependant BFD architecture is dynamic */
+
+extern int target_architecture_auto;
+#ifndef TARGET_ARCHITECTURE_AUTO
+#define TARGET_ARCHITECTURE_AUTO (target_architecture_auto + 0)
+#endif
+
+extern const struct bfd_arch_info *target_architecture;
+#ifndef TARGET_ARCHITECTURE
+#define TARGET_ARCHITECTURE (target_architecture + 0)
+#endif
+
+/* Notify the target dependant backend of a change to the selected
+ architecture. A zero return status indicates that the target did
+ not like the change. */
+
+extern int (*target_architecture_hook) PARAMS ((const struct bfd_arch_info *));
+
+
+
+/* The target-system-dependant disassembler is semi-dynamic */
+
+#include "dis-asm.h" /* Get defs for disassemble_info */
+
+extern int dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr,
+ int len, disassemble_info *info));
+
+extern void dis_asm_memory_error PARAMS ((int status, bfd_vma memaddr,
+ disassemble_info *info));
+
+extern void dis_asm_print_address PARAMS ((bfd_vma addr,
+ disassemble_info *info));
+
+extern int (*tm_print_insn) PARAMS ((bfd_vma, disassemble_info*));
+extern disassemble_info tm_print_insn_info;
+#ifndef TARGET_PRINT_INSN
+#define TARGET_PRINT_INSN(vma, info) (*tm_print_insn) (vma, info)
+#endif
+#ifndef TARGET_PRINT_INSN_INFO
+#define TARGET_PRINT_INSN_INFO (&tm_print_insn_info)
+#endif
+
+
+
+/* Set the dynamic target-system-dependant parameters (architecture,
+ byte-order, ...) using information found in the BFD */
+
+extern void set_gdbarch_from_file PARAMS ((bfd *));
+
+
+/* Explicitly set the dynamic target-system-dependant parameters based
+ on bfd_architecture and machine. */
+
+extern void set_architecture_from_arch_mach PARAMS ((enum bfd_architecture, unsigned long));
+
+
+/* gdbarch trace variable */
+extern int gdbarch_debug;
+
+#endif
diff --git a/contrib/gdb/gdb/gdbcmd.h b/contrib/gdb/gdb/gdbcmd.h
index 2459f81..65b3b7a 100644
--- a/contrib/gdb/gdb/gdbcmd.h
+++ b/contrib/gdb/gdb/gdbcmd.h
@@ -40,6 +40,14 @@ extern struct cmd_list_element *disablelist;
extern struct cmd_list_element *deletelist;
+/* Chain containing all defined toggle subcommands. */
+
+extern struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+extern struct cmd_list_element *stoplist;
+
/* Chain containing all defined "enable breakpoint" subcommands. */
extern struct cmd_list_element *enablebreaklist;
diff --git a/contrib/gdb/gdb/gdbcore.h b/contrib/gdb/gdb/gdbcore.h
index bf7cb32..6501e30 100644
--- a/contrib/gdb/gdb/gdbcore.h
+++ b/contrib/gdb/gdb/gdbcore.h
@@ -50,6 +50,9 @@ extern void memory_error PARAMS ((int status, CORE_ADDR memaddr));
extern void read_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+extern void read_memory_section PARAMS ((CORE_ADDR memaddr, char *myaddr,
+ int len, asection *bfd_section));
+
/* Read an integer from debugged memory, given address and number of
bytes. */
@@ -58,7 +61,11 @@ extern LONGEST read_memory_integer PARAMS ((CORE_ADDR memaddr, int len));
/* Read an unsigned integer from debugged memory, given address and
number of bytes. */
-extern unsigned LONGEST read_memory_unsigned_integer PARAMS ((CORE_ADDR memaddr, int len));
+extern ULONGEST read_memory_unsigned_integer PARAMS ((CORE_ADDR memaddr, int len));
+
+/* Read a null-terminated string from the debuggee's memory, given address,
+ * a buffer into which to place the string, and the maximum available space */
+extern void read_memory_string PARAMS ((CORE_ADDR, char *, int));
/* This takes a char *, not void *. This is probably right, because
passing in an int * or whatever is wrong with respect to
@@ -75,7 +82,12 @@ extern void generic_search PARAMS ((int len, char *data, char *mask,
/* Hook for `exec_file_command' command to call. */
extern void (*exec_file_display_hook) PARAMS ((char *filename));
-
+
+/* Hook for "file_command", which is more useful than above
+ (because it is invoked AFTER symbols are read, not before) */
+
+extern void (*file_changed_hook) PARAMS ((char *filename));
+
extern void specify_exec_file_hook PARAMS ((void (*hook) (char *filename)));
/* Binary File Diddlers for the exec and core files */
@@ -89,11 +101,13 @@ extern int write_files;
extern void core_file_command PARAMS ((char *filename, int from_tty));
+extern void exec_file_attach PARAMS ((char *filename, int from_tty));
+
extern void exec_file_command PARAMS ((char *filename, int from_tty));
extern void validate_files PARAMS ((void));
-extern unsigned int register_addr PARAMS ((int regno, int blockend));
+extern CORE_ADDR register_addr PARAMS ((int regno, CORE_ADDR blockend));
extern void registers_fetched PARAMS ((void));
@@ -140,7 +154,7 @@ struct core_fns {
address X is at location core_reg_sect+x+reg_addr. */
void (*core_read_registers) PARAMS ((char *core_reg_sect, unsigned core_reg_size,
- int which, unsigned reg_addr));
+ int which, CORE_ADDR reg_addr));
/* Finds the next struct core_fns. They are allocated and initialized
in whatever module implements the functions pointed to; an
diff --git a/contrib/gdb/gdb/gdbinit.in b/contrib/gdb/gdb/gdbinit.in
new file mode 100644
index 0000000..af97d2c
--- /dev/null
+++ b/contrib/gdb/gdb/gdbinit.in
@@ -0,0 +1,18 @@
+echo Setting up the environment for debugging gdb.\n
+
+set complaints 1
+
+b fatal
+
+b info_command
+commands
+ silent
+ return
+end
+
+dir @srcdir@
+dir .
+dir @srcdir@/../mmalloc
+dir @srcdir@/../libiberty
+dir @srcdir@/../bfd
+set prompt (top-gdb)
diff --git a/contrib/gdb/gdb/gdbserver/Makefile.in b/contrib/gdb/gdb/gdbserver/Makefile.in
index 2ce6fac..b016e13 100644
--- a/contrib/gdb/gdb/gdbserver/Makefile.in
+++ b/contrib/gdb/gdb/gdbserver/Makefile.in
@@ -1,4 +1,5 @@
-#Copyright 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+#Copyright 1989, 90, 91, 92, 93, 94, 95, 96, 1997
+#Free Software Foundation, Inc.
# This file is part of GDB.
@@ -24,7 +25,7 @@ bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
tooldir = $(libdir)/$(target_alias)
-datadir = $(prefix)/lib
+datadir = $(prefix)/share
mandir = $(prefix)/man
man1dir = $(mandir)/man1
man2dir = $(mandir)/man2
@@ -37,15 +38,12 @@ man8dir = $(mandir)/man8
man9dir = $(mandir)/man9
infodir = $(prefix)/info
includedir = $(prefix)/include
-docdir = $(datadir)/doc
SHELL = /bin/sh
-INSTALL = `cd $(srcdir)/../..;pwd`/install.sh -c
+INSTALL = `cd $(srcdir)/../..;pwd`/install-sh -c
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA = $(INSTALL)
-INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)'
-INSTALL_XFORM1 = $(INSTALL_XFORM) -b=.1
AR = ar
AR_FLAGS = qv
@@ -77,19 +75,6 @@ CC-LD=${CC}
INCLUDE_DIR = ${srcdir}/../../include
INCLUDE_DEP = $$(INCLUDE_DIR)
-# Where is the source dir for the MMALLOC library? Traditionally ../mmalloc
-# or ./mmalloc (When we want the binary library built from it, we use
-# ${MMALLOC_DIR}${subdir}.)
-# Note that mmalloc can still be used on systems without mmap().
-# To use your system malloc, comment out the following defines.
-MMALLOC_DIR = ${srcdir}/../../mmalloc
-MMALLOC_DEP = $$(MMALLOC_DIR)
-# To use your system malloc, uncomment MMALLOC_DISABLE.
-#MMALLOC_DISABLE = -DNO_MMALLOC
-# To use mmalloc but disable corruption checking, uncomment MMALLOC_CHECK
-#MMALLOC_CHECK = -DNO_MMALLOC_CHECK
-MMALLOC_CFLAGS = ${MMALLOC_CHECK} ${MMALLOC_DISABLE} -I${MMALLOC_DIR}
-
# Where are the BFD library?
BFD_DIR = ../../bfd
BFD = $(BFD_DIR)/libbfd.a
@@ -117,7 +102,7 @@ GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS}
CFLAGS = -g
# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} \
- ${BFD_CFLAGS} ${MMALLOC_CFLAGS} ${INCLUDE_CFLAGS}
+ ${BFD_CFLAGS} ${INCLUDE_CFLAGS}
# LDFLAGS is specifically reserved for setting from the command line
# when running make.
@@ -160,11 +145,15 @@ all: gdbserver gdbreplay
# install-only is intended to address that need.
install: all install-only
install-only:
- $(INSTALL_XFORM) gdbserver $(bindir)/gdbserver
- $(INSTALL_XFORM1) $(srcdir)/gdbserver.1 $(man1dir)/gdbserver.1
+ n=`echo gdbserver | sed '$(program_transform_name)'`; \
+ if [ x$$n = x ]; then n=gdbserver; else true; fi; \
+ $(INSTALL_PROGRAM) gdbserver $(bindir)/$$n; \
+ $(INSTALL_DATA) $(srcdir)/gdbserver.1 $(man1dir)/$$n.1
uninstall: force
- rm -f $(bindir)/gdbserver $(man1dir)/gdbserver.1
+ n=`echo gdbserver | sed '$(program_transform_name)'`; \
+ if [ x$$n = x ]; then n=gdbserver; else true; fi; \
+ rm -f $(bindir)/$$n $(man1dir)/$$n.1
installcheck:
check:
@@ -175,7 +164,12 @@ clean-info:
gdbserver: $(OBS) ${ADD_DEPS} ${CDEPS}
rm -f gdbserver
${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbserver $(OBS) \
- $(GDBSERVER_LIBS)
+ $(GDBSERVER_LIBS) $(XM_CLIBS)
+
+gdbreplay: gdbreplay.o
+ rm -f gdbreplay
+ ${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbreplay gdbreplay.o \
+ $(XM_CLIBS)
config.status:
@echo "You must configure gdbserver. Look at the README file for details."
@@ -236,7 +230,9 @@ unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
server.o : ${srcdir}/server.c ${srcdir}/server.h
remote-utils.o : ${srcdir}/remote-utils.c ${srcdir}/server.h
+low-linux.o : ${srcdir}/low-linux.c ${srcdir}/server.h
low-lynx.o : ${srcdir}/low-lynx.c ${srcdir}/server.h
+low-sim.o : ${srcdir}/low-sim.c ${srcdir}/server.h
low-sparc.o : $(srcdir)/low-sparc.c $(srcdir)/server.h
low-sun3.o : $(srcdir)/low-sun3.c $(srcdir)/server.h
low-hppabsd.o : $(srcdir)/low-hppabsd.c $(srcdir)/server.h
diff --git a/contrib/gdb/gdb/gdbserver/configure.in b/contrib/gdb/gdb/gdbserver/configure.in
index 67215bd..1bbb73c 100644
--- a/contrib/gdb/gdb/gdbserver/configure.in
+++ b/contrib/gdb/gdb/gdbserver/configure.in
@@ -4,115 +4,9 @@ gdb_serial_driver=../ser-unix.c
# per-host:
-# per-target:
-
-# Hack alert! We want this directory to be configured only for the target,
-# which is where it will be running, so we just eliminate the per-host section,
-# and make the per-target stuff setup host & host_cpu according to the target.
-
-host_cpu=$target_cpu
-host=$target
-
-# Map host cpu into the config cpu subdirectory name.
-# The default is $host_cpu.
-
-case "${host_cpu}" in
-
-c[12]) gdb_host_cpu=convex ;;
-hppa*) gdb_host_cpu=pa ;;
-i[345]86) gdb_host_cpu=i386 ;;
-m68*) gdb_host_cpu=m68k ;;
-np1) gdb_host_cpu=gould ;;
-pyramid) gdb_host_cpu=pyr ;;
-*) gdb_host_cpu=$target_cpu ;;
-
-esac
-
-# map host info into gdb names.
-
-case "${host}" in
-
-a29k-*-*) gdb_host=ultra3 ;;
-
-arm-*-*) gdb_host=arm ;;
-
-c[12]-*-*) gdb_host=convex ;;
-
-hppa*-hp-bsd*) gdb_host=hppabsd ;;
-hppa*-hp-hpux*) gdb_host=hppahpux ;;
-
-i[345]86-ncr-*) gdb_host=ncr3000 ;;
-i[345]86-sequent-*) gdb_host=symmetry ;;
-
-i[345]86-*-bsd*) gdb_host=i386bsd ;;
-i[345]86-*-lynxos*) gdb_host=i386lynx ;;
-i[345]86-*-go32) gdb_host=go32
- gdb_serial_driver=ser-go32.c
- ;;
-i[345]86-*-linux*) gdb_host=linux ;;
-i[345]86-*-mach) gdb_host=i386mach ;;
-i[345]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
-i[345]86-*-sco*) gdb_host=i386sco ;;
-i[345]86-*-solaris*) gdb_host=i386sol2 ;;
-i[345]86-*-sunos*) gdb_host=sun386 ;;
-i[345]86-*-sysv3.2) gdb_host=i386v32 ;;
-i[345]86-*-sysv4*) gdb_host=i386v4 ;;
-i[345]86-*-sysv*) gdb_host=i386v ;;
+. ${srcdir}/../configure.host
-m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
-m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
-m68030-sony-*) gdb_host=news1000 ;;
-
-m68*-altos-*) gdb_host=altos ;;
-m68*-apollo*-sysv*) gdb_host=apollo68v ;;
-m68*-apollo*-bsd*) gdb_host=apollo68b ;;
-m68*-att-*) gdb_host=3b1 ;;
-m68*-cbm-sysv4*) gdb_host=amix ;;
-m68*-hp-bsd*) gdb_host=hp300bsd ;;
-m68*-hp-hpux*) gdb_host=hp300hpux ;;
-m68*-isi-*) gdb_host=isi ;;
-m68*-*-lynxos*) gdb_host=m68klynx ;;
-m68*-sony-*) gdb_host=news ;;
-m68*-sun-sunos3*) gdb_host=sun3os3 ;;
-m68*-sun-sunos4*) gdb_host=sun3os4 ;;
-m68*-sun-*) gdb_host=sun3os4 ;;
-
-m88k-motorola-*) gdb_host=delta88 ;;
-m88k-*-*) gdb_host=m88k ;;
-
-mips-dec-*) gdb_host=decstation ;;
-mips-little-*) gdb_host=littlemips ;;
-mips-sgi-irix3) gdb_host=irix3 ;;
-mips-sgi-irix4*) gdb_host=irix4 ;;
-mips-sony-*) gdb_host=bigmips ;;
-
-none-*-*) gdb_host=none ;;
-
-np1-*-*) gdb_host=np1 ;;
-
-ns32k-umax-*) gdb_host=umax ;;
-ns32k-utek-sysv) gdb_host=merlin ;;
-
-pn-*-*) gdb_host=pn ;;
-
-pyramid-*-*) gdb_host=pyramid ;;
-
-romp-*-*) gdb_host=rtbsd ;;
-
-rs6000-*-*) gdb_host=rs6000 ;;
-
-sparc-*-lynxos*) gdb_host=sparclynx ;;
-sparc-*-solaris2*) gdb_host=sun4sol2 ;;
-sparc-*-sunos4*) gdb_host=sun4os4 ;;
-sparc-*-*) gdb_host=sun4os4 ;;
-
-tahoe-*-*) gdb_host=tahoe ;;
-
-vax-*-bsd*) gdb_host=vaxbsd ;;
-vax-*-ultrix2*) gdb_host=vaxult2 ;;
-vax-*-ultrix*) gdb_host=vaxult ;;
-
-esac
+echo "gdbserver/configure.in: host is $host, target is $target"
if [ ! -f ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ]; then
echo '***' "GDB remote does not support host ${host}" 1>&2
@@ -124,138 +18,9 @@ hostfile=`awk '$1 == "XM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cp
# per-target:
-# Map target cpu into the config cpu subdirectory name.
-# The default is $target_cpu.
-
-case "${target_cpu}" in
-
-c[12]) gdb_target_cpu=convex ;;
-hppa*) gdb_target_cpu=pa ;;
-i[345]86) gdb_target_cpu=i386 ;;
-m68*) gdb_target_cpu=m68k ;;
-np1) gdb_target_cpu=gould ;;
-pn) gdb_target_cpu=gould ;;
-pyramid) gdb_target_cpu=pyr ;;
-sparc*) gdb_target_cpu=sparc ;;
-*) gdb_target_cpu=$target_cpu ;;
-
-esac
-
-# map target info into gdb names.
-
-case "${target}" in
-
-a29k-*-aout) gdb_target=a29k ;;
-a29k-*-coff) gdb_target=a29k ;;
-a29k-*-elf) gdb_target=a29k ;;
-a29k-*-ebmon) gdb_target=a29k ;;
-a29k-*-kern) gdb_target=a29k-kern ;;
-a29k-*-none) gdb_target=a29k ;;
-a29k-*-sym1) gdb_target=ultra3 ;;
-a29k-*-udi) gdb_target=a29k-udi ;;
-
-arm-*-*) gdb_target=arm ;;
-
-c1-*-*) gdb_target=convex ;;
-c2-*-*) gdb_target=convex ;;
-
-h8300-*-*) gdb_target=h8300hms ;;
-h8500-*-*) gdb_target=h8500hms ;;
-
-sh-*-*) gdb_target=sh ;;
-
-hppa*-*-bsd*) gdb_target=hppabsd ;;
-hppa*-*-hpux*) gdb_target=hppahpux ;;
-
-i[345]86-sequent-*) gdb_target=symmetry ;;
-i[345]86-ncr-*) gdb_target=ncr3000 ;;
-
-i[345]86-*-aout) gdb_target=i386aout ;;
-i[345]86-*-coff) gdb_target=i386v ;;
-i[345]86-*-elf) gdb_target=i386v ;;
-
-i[345]86-*-bsd*) gdb_target=i386bsd ;;
-i[345]86-*-lynxos*) gdb_target=i386lynx ;;
-i[345]86-*-go32) gdb_target=i386aout ;;
-i[345]86-*-solaris*) gdb_target=i386sol2 ;;
-i[345]86-*-sunos*) gdb_target=sun386 ;;
-i[345]86-*-sysv4*) gdb_target=i386v4 ;;
-i[345]86-*-sco*) gdb_target=i386v ;;
-i[345]86-*-sysv*) gdb_target=i386v ;;
-i[345]86-*-linux*) gdb_target=linux ;;
-
-i960-*-bout) gdb_target=vxworks960 ;;
-i960-*-coff) gdb_target=nindy960 ;;
-i960-*-elf) gdb_target=nindy960 ;;
-
-i960-*-nindy) gdb_target=nindy960 ;;
-i960-*-vxworks) gdb_target=vxworks960 ;;
-
-m68000-*-aout) gdb_target=m68k-nofp ;;
-m68000-*-coff) gdb_target=m68k-nofp ;;
-m68000-*-elf) gdb_target=m68k-nofp ;;
-m68000-*-sunos3*) gdb_target=sun2os3 ;;
-m68000-*-sunos4*) gdb_target=sun2os4 ;;
-
-m68*-cbm-sysv4*) gdb_target=amix ;;
-m68*-hp-bsd*) gdb_target=hp300bsd ;;
-m68*-hp-hpux*) gdb_target=hp300hpux ;;
-
-m68*-altos-*) gdb_target=altos ;;
-m68*-att-*) gdb_target=3b1 ;;
-m68*-ericsson-*) gdb_target=es1800 ;;
-m68*-isi-*) gdb_target=isi ;;
-m68*-netx-*) gdb_target=vxworks68 ;;
-m68*-sony-*) gdb_target=news ;;
-m68*-tandem-*) gdb_target=st2000 ;;
-
-m68*-*-aout) gdb_target=m68k-fp ;;
-m68*-*-coff) gdb_target=m68k-fp ;;
-m68*-*-elf) gdb_target=m68k-fp ;;
-m68*-*-lynxos*) gdb_target=m68klynx ;;
-m68*-*-os68k) gdb_target=os68k ;;
-m68*-*-sunos3*) gdb_target=sun3os3 ;;
-m68*-*-sunos4*) gdb_target=sun3os4 ;;
-m68*-*-vxworks*) gdb_target=vxworks68 ;;
-
-m88k-motorola-*) gdb_target=delta88 ;;
-m88k-*-*) gdb_target=m88k ;;
-
-mips-big-*) gdb_target=bigmips ;;
-mips-dec-*) gdb_target=decstation ;;
-mips-idt-ecoff) gdb_target=idt ;;
-mips-little-*) gdb_target=littlemips ;;
-mips-sgi-*) gdb_target=irix3 ;;
-mips-sony-*) gdb_target=bigmips ;;
-
-none-*-*) gdb_target=none ;;
-
-np1-*-*) gdb_target=np1 ;;
-
-ns32k-utek-sysv) gdb_target=merlin ;;
-ns32k-utek-*) gdb_target=umax ;;
-
-pn-*-*) gdb_target=pn ;;
-
-pyramid-*-*) gdb_target=pyramid ;;
-
-rs6000-*-*) gdb_target=rs6000 ;;
-
-sparc-*-aout) gdb_target=sparc-em ;;
-sparc-*-coff) gdb_target=sparc-em ;;
-sparc-*-elf) gdb_target=sparc-em ;;
-sparc-*-lynxos*) gdb_target=sparclynx ;;
-sparc-*-solaris2*) gdb_target=sun4sol2 ;;
-sparc-*-sunos4*) gdb_target=sun4os4 ;;
-sparc-*-vxworks*) gdb_target=sparc-em ;;
-sparc-*-*) gdb_target=sun4os4 ;;
-sparclite*-*-*) gdb_target=sparclite ;;
-
-tahoe-*-*) gdb_target=tahoe ;;
-vax-*-*) gdb_target=vax ;;
+. ${srcdir}/../configure.tgt
-z8k-*-sim) gdb_target=z8ksim ;;
-esac
+echo "gdbserver/configure.in: host_cpu is $host_cpu, target_cpu is $target_cpu"
if [ ! -f ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt ]; then
echo '***' "GDB remote does not support target ${target}" 1>&2
@@ -318,7 +83,7 @@ if [ "${nativefile}" != "" ]; then
# temporary scaffolding until all hosts have the host/target/native
# split in place.
else
- files="${files} ../config/nm-trash.h"
+ files="${files} ../config/nm-empty.h"
links="${links} nm.h"
fi
diff --git a/contrib/gdb/gdb/gdbserver/gdbreplay.c b/contrib/gdb/gdb/gdbserver/gdbreplay.c
index 4d5795a..ebe06ba 100644
--- a/contrib/gdb/gdb/gdbserver/gdbreplay.c
+++ b/contrib/gdb/gdb/gdbserver/gdbreplay.c
@@ -19,7 +19,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <stdio.h>
-#include <sgtty.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <sys/socket.h>
@@ -27,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <netinet/tcp.h>
#include <signal.h>
#include <ctype.h>
+#include <fcntl.h>
/* Sort of a hack... */
#define EOL (EOF - 1)
@@ -84,7 +84,6 @@ void
remote_open (name)
char *name;
{
- struct sgttyb sg;
extern char *strchr ();
if (!strchr (name, ':'))
diff --git a/contrib/gdb/gdb/gdbserver/low-hppabsd.c b/contrib/gdb/gdb/gdbserver/low-hppabsd.c
index 337e6ed..c784d0c 100644
--- a/contrib/gdb/gdb/gdbserver/low-hppabsd.c
+++ b/contrib/gdb/gdb/gdbserver/low-hppabsd.c
@@ -161,12 +161,12 @@ myresume (step, signal)
- KERNEL_U_ADDR
#endif
-unsigned int
+CORE_ADDR
register_addr (regno, blockend)
int regno;
- int blockend;
+ CORE_ADDR blockend;
{
- int addr;
+ CORE_ADDR addr;
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
diff --git a/contrib/gdb/gdb/gdbserver/low-linux.c b/contrib/gdb/gdb/gdbserver/low-linux.c
index 34dc643..1060210 100644
--- a/contrib/gdb/gdb/gdbserver/low-linux.c
+++ b/contrib/gdb/gdb/gdbserver/low-linux.c
@@ -45,8 +45,9 @@ char buf2[MAX_REGISTER_RAW_SIZE];
/***************End MY defs*********************/
#include <sys/ptrace.h>
-#if 0
-#include <machine/reg.h>
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#include <sys/reg.h>
#endif
extern char **environ;
@@ -165,6 +166,7 @@ myresume (step, signal)
- KERNEL_U_ADDR
#endif
+#ifndef TARGET_M68K
/* this table must line up with REGISTER_NAMES in tm-i386v.h */
/* symbols like 'EAX' come from <sys/reg.h> */
static int regmap[] =
@@ -198,13 +200,44 @@ i386_register_u_addr (blockend, regnum)
return (blockend + 4 * regmap[regnum]);
}
+#else /* TARGET_M68K */
+/* This table must line up with REGISTER_NAMES in tm-m68k.h */
+static int regmap[] =
+{
+#ifdef PT_D0
+ PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+ PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+ PT_SR, PT_PC,
+#else
+ 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15,
+ 17, 18,
+#endif
+#ifdef PT_FP0
+ PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
+ PT_FPCR, PT_FPSR, PT_FPIAR
+#else
+ 21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47
+#endif
+};
+
+/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
+ is stored. */
+
+int
+m68k_linux_register_u_addr (blockend, regnum)
+ int blockend;
+ int regnum;
+{
+ return (blockend + 4 * regmap[regnum]);
+}
+#endif
-unsigned int
+CORE_ADDR
register_addr (regno, blockend)
int regno;
- int blockend;
+ CORE_ADDR blockend;
{
- int addr;
+ CORE_ADDR addr;
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
@@ -221,7 +254,6 @@ fetch_register (regno)
int regno;
{
register unsigned int regaddr;
- char buf[MAX_REGISTER_RAW_SIZE];
register int i;
/* Offset of registers within the u area. */
@@ -272,10 +304,8 @@ store_inferior_registers (regno)
int regno;
{
register unsigned int regaddr;
- char buf[80];
register int i;
unsigned int offset = U_REGS_OFFSET;
- int scratch;
if (regno >= 0)
{
@@ -334,6 +364,7 @@ store_inferior_registers (regno)
/* Copy LEN bytes from inferior's memory starting at MEMADDR
to debugger memory starting at MYADDR. */
+void
read_inferior_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
diff --git a/contrib/gdb/gdb/gdbserver/low-sim.c b/contrib/gdb/gdb/gdbserver/low-sim.c
new file mode 100644
index 0000000..8ad6e91
--- /dev/null
+++ b/contrib/gdb/gdb/gdbserver/low-sim.c
@@ -0,0 +1,289 @@
+/* Low level interface to simulators, for the remote server for GDB.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "bfd.h"
+#include "server.h"
+#include "callback.h" /* GDB simulator callback interface */
+#include "remote-sim.h" /* GDB simulator interface */
+
+extern int remote_debug;
+
+extern host_callback default_callback; /* in sim/common/callback.c */
+
+char registers[REGISTER_BYTES] __attribute__ ((aligned));
+
+int target_byte_order; /* used by simulator */
+
+/* We record the result of sim_open so we can pass it
+ back to the other sim_foo routines. */
+static SIM_DESC gdbsim_desc = 0;
+
+/* This version of "load" should be usable for any simulator that
+ does not support loading itself. */
+
+static void
+generic_load (loadfile_bfd)
+ bfd *loadfile_bfd;
+{
+ asection *s;
+
+ for (s = loadfile_bfd->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size > 0)
+ {
+ char *buffer;
+ bfd_vma lma; /* use load address, not virtual address */
+
+ buffer = xmalloc (size);
+ lma = s->lma;
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
+ bfd_get_section_name (loadfile_bfd, s),
+ (unsigned long) size,
+ (unsigned long) lma); /* chops high 32 bits. FIXME!! */
+
+ bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
+
+ write_inferior_memory (lma, buffer, size);
+ free (buffer);
+ }
+ }
+ }
+
+ printf ("Start address 0x%lx\n",
+ (unsigned long)loadfile_bfd->start_address);
+
+ /* We were doing this in remote-mips.c, I suspect it is right
+ for other targets too. */
+ /* write_pc (loadfile_bfd->start_address); */ /* FIXME!! */
+}
+
+int
+create_inferior (program, argv)
+ char *program;
+ char **argv;
+{
+ bfd *abfd;
+ int pid = 0;
+#ifdef TARGET_BYTE_ORDER_SELECTABLE
+ char **new_argv;
+ int nargs;
+#endif
+
+ abfd = bfd_openr (program, 0);
+ if (!abfd)
+ {
+ fprintf (stderr, "gdbserver: can't open %s: %s\n",
+ program, bfd_errmsg (bfd_get_error ()));
+ exit (1);
+ }
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ fprintf (stderr, "gdbserver: unknown load format for %s: %s\n",
+ program, bfd_errmsg (bfd_get_error ()));
+ exit (1);
+ }
+
+#ifdef TARGET_BYTE_ORDER_SELECTABLE
+ /* Add "-E big" or "-E little" to the argument list depending on the
+ endianness of the program to be loaded. */
+ for (nargs = 0; argv[nargs] != NULL; nargs++) /* count the args */
+ ;
+ new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */
+ for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */
+ new_argv[nargs] = argv[nargs];
+ new_argv[nargs] = "-E";
+ new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
+ new_argv[nargs + 2] = NULL;
+ argv = new_argv;
+#endif
+
+ /* Create an instance of the simulator. */
+ default_callback.init (&default_callback);
+ gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
+ if (gdbsim_desc == 0)
+ exit (1);
+
+ /* Load the program into the simulator. */
+ if (abfd)
+ if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
+ generic_load (abfd);
+
+ /* Create an inferior process in the simulator. This initializes SP. */
+ sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
+ sim_resume (gdbsim_desc, 1, 0); /* execute one instr */
+ return pid;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior ()
+{
+ sim_close (gdbsim_desc, 0);
+ default_callback.shutdown (&default_callback);
+}
+
+/* Fetch one register. */
+
+static void
+fetch_register (regno)
+ int regno;
+{
+ sim_fetch_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+}
+
+/* Fetch all registers, or just one, from the child process. */
+
+void
+fetch_inferior_registers (regno)
+ int regno;
+{
+ if (regno == -1 || regno == 0)
+ for (regno = 0; regno < NUM_REGS/*-NUM_FREGS*/; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* 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). */
+
+void
+store_inferior_registers (regno)
+ int regno;
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_inferior_registers (regno);
+ }
+ else
+ sim_store_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (pid)
+ int pid;
+{
+ return 1;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (status)
+ char *status;
+{
+ int sigrc;
+ enum sim_stop reason;
+
+ sim_stop_reason (gdbsim_desc, &reason, &sigrc);
+ switch (reason)
+ {
+ case sim_exited:
+ if (remote_debug)
+ printf ("\nChild exited with retcode = %x \n", sigrc);
+ *status = 'W';
+ return sigrc;
+
+#if 0
+ case sim_stopped:
+ if (remote_debug)
+ printf ("\nChild terminated with signal = %x \n", sigrc);
+ *status = 'X';
+ return sigrc;
+#endif
+
+ default: /* should this be sim_signalled or sim_stopped? FIXME!! */
+ if (remote_debug)
+ printf ("\nChild received signal = %x \n", sigrc);
+ fetch_inferior_registers (0);
+ *status = 'T';
+ return (unsigned char) sigrc;
+ }
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (step, signo)
+ int step;
+ int signo;
+{
+ /* Should be using target_signal_to_host() or signal numbers in target.h
+ to convert GDB signal number to target signal number. */
+ sim_resume (gdbsim_desc, step, signo);
+}
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ sim_read (gdbsim_desc, memaddr, myaddr, len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ sim_write (gdbsim_desc, memaddr, myaddr, len); /* should check for error. FIXME!! */
+ return 0;
+}
+
+#if 0
+void
+initialize ()
+{
+ inferior_pid = 0;
+}
+
+int
+have_inferior_p ()
+{
+ return inferior_pid != 0;
+}
+#endif
diff --git a/contrib/gdb/gdb/gdbserver/low-sparc.c b/contrib/gdb/gdb/gdbserver/low-sparc.c
index 6f9810e..ddffaec 100644
--- a/contrib/gdb/gdb/gdbserver/low-sparc.c
+++ b/contrib/gdb/gdb/gdbserver/low-sparc.c
@@ -46,7 +46,7 @@ char buf2[MAX_REGISTER_RAW_SIZE];
/***************End MY defs*********************/
#include <sys/ptrace.h>
-#include <machine/reg.h>
+#include <sys/reg.h>
extern int sys_nerr;
extern char **sys_errlist;
diff --git a/contrib/gdb/gdb/gdbserver/remote-utils.c b/contrib/gdb/gdb/gdbserver/remote-utils.c
index ff2183e..0a7e0fb 100644
--- a/contrib/gdb/gdb/gdbserver/remote-utils.c
+++ b/contrib/gdb/gdb/gdbserver/remote-utils.c
@@ -18,8 +18,10 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "server.h"
+#include "terminal.h"
#include <stdio.h>
-#include <sgtty.h>
+#include <string.h>
+#include <sys/ioctl.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <sys/socket.h>
@@ -27,8 +29,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <signal.h>
+#include <fcntl.h>
+
+int remote_debug = 0;
-static int kiodebug = 0;
static int remote_desc;
/* Open a connection to a remote debugger.
@@ -38,7 +42,7 @@ void
remote_open (name)
char *name;
{
- struct sgttyb sg;
+ int save_fcntl_flags;
if (!strchr (name, ':'))
{
@@ -46,9 +50,51 @@ remote_open (name)
if (remote_desc < 0)
perror_with_name ("Could not open remote device");
- ioctl (remote_desc, TIOCGETP, &sg);
- sg.sg_flags = RAW;
- ioctl (remote_desc, TIOCSETP, &sg);
+#ifdef HAVE_TERMIOS
+ {
+ struct termios termios;
+ tcgetattr(remote_desc, &termios);
+
+ termios.c_iflag = 0;
+ termios.c_oflag = 0;
+ termios.c_lflag = 0;
+ termios.c_cflag &= ~(CSIZE|PARENB);
+ termios.c_cflag |= CLOCAL | CS8;
+ termios.c_cc[VMIN] = 0;
+ termios.c_cc[VTIME] = 0;
+
+ tcsetattr(remote_desc, TCSANOW, &termios);
+ }
+#endif
+
+#ifdef HAVE_TERMIO
+ {
+ struct termio termio;
+ ioctl (remote_desc, TCGETA, &termio);
+
+ termio.c_iflag = 0;
+ termio.c_oflag = 0;
+ termio.c_lflag = 0;
+ termio.c_cflag &= ~(CSIZE|PARENB);
+ termio.c_cflag |= CLOCAL | CS8;
+ termio.c_cc[VMIN] = 0;
+ termio.c_cc[VTIME] = 0;
+
+ ioctl (remote_desc, TCSETA, &termio);
+ }
+#endif
+
+#ifdef HAVE_SGTTY
+ {
+ struct sgttyb sg;
+
+ ioctl (remote_desc, TIOCGETP, &sg);
+ sg.sg_flags = RAW;
+ ioctl (remote_desc, TIOCSETP, &sg);
+ }
+#endif
+
+
}
else
{
@@ -105,8 +151,11 @@ remote_open (name)
exits when the remote side dies. */
}
- fcntl (remote_desc, F_SETFL, FASYNC);
-
+#if defined(F_SETFL) && defined (FASYNC)
+ save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
+ fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
+ disable_async_io ();
+#endif /* FASYNC */
fprintf (stderr, "Remote debugging using %s\n", name);
}
@@ -171,6 +220,8 @@ putpkt (buf)
*p++ = tohex ((csum >> 4) & 0xf);
*p++ = tohex (csum & 0xf);
+ *p = '\0';
+
/* Send it over and over until we get a positive ack. */
do
@@ -183,7 +234,11 @@ putpkt (buf)
return -1;
}
+ if (remote_debug)
+ printf ("putpkt (\"%s\"); [looking for ack]\n", buf2);
cc = read (remote_desc, buf3, 1);
+ if (remote_debug)
+ printf ("[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
if (cc <= 0)
{
if (cc == 0)
@@ -282,6 +337,8 @@ getpkt (buf)
c = readchar ();
if (c == '$')
break;
+ if (remote_debug)
+ printf ("[getpkt: discarding char '%c']\n", c);
if (c < 0)
return -1;
}
@@ -301,6 +358,7 @@ getpkt (buf)
c1 = fromhex (readchar ());
c2 = fromhex (readchar ());
+
if (csum == (c1 << 4) + c2)
break;
@@ -309,7 +367,13 @@ getpkt (buf)
write (remote_desc, "-", 1);
}
+ if (remote_debug)
+ printf ("getpkt (\"%s\"); [sending ack] \n", buf);
+
write (remote_desc, "+", 1);
+
+ if (remote_debug)
+ printf ("[sent ack]\n");
return bp - buf;
}
@@ -371,25 +435,25 @@ outreg(regno, buf)
char *buf;
{
extern char registers[];
+ int regsize = REGISTER_RAW_SIZE (regno);
*buf++ = tohex (regno >> 4);
*buf++ = tohex (regno & 0xf);
*buf++ = ':';
- convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, 4);
- buf += 8;
+ convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, regsize);
+ buf += 2 * regsize;
*buf++ = ';';
return buf;
}
void
-prepare_resume_reply (buf, status, signal)
+prepare_resume_reply (buf, status, signo)
char *buf;
char status;
- unsigned char signal;
+ unsigned char signo;
{
int nib;
- char ch;
*buf++ = status;
@@ -397,9 +461,9 @@ prepare_resume_reply (buf, status, signal)
according to the signal numbering of the system we are running on)
to the signal numbers used by the gdb protocol (see enum target_signal
in gdb/target.h). */
- nib = ((signal & 0xf0) >> 4);
+ nib = ((signo & 0xf0) >> 4);
*buf++ = tohex (nib);
- nib = signal & 0x0f;
+ nib = signo & 0x0f;
*buf++ = tohex (nib);
if (status == 'T')
@@ -433,7 +497,8 @@ prepare_resume_reply (buf, status, signal)
void
decode_m_packet (from, mem_addr_ptr, len_ptr)
char *from;
- unsigned int *mem_addr_ptr, *len_ptr;
+ CORE_ADDR *mem_addr_ptr;
+ unsigned int *len_ptr;
{
int i = 0, j = 0;
char ch;
@@ -457,9 +522,10 @@ decode_m_packet (from, mem_addr_ptr, len_ptr)
void
decode_M_packet (from, mem_addr_ptr, len_ptr, to)
char *from, *to;
- unsigned int *mem_addr_ptr, *len_ptr;
+ CORE_ADDR *mem_addr_ptr;
+ unsigned int *len_ptr;
{
- int i = 0, j = 0;
+ int i = 0;
char ch;
*mem_addr_ptr = *len_ptr = 0;
diff --git a/contrib/gdb/gdb/gdbserver/server.c b/contrib/gdb/gdb/gdbserver/server.c
index a583c54..cdec0f8 100644
--- a/contrib/gdb/gdb/gdbserver/server.c
+++ b/contrib/gdb/gdb/gdbserver/server.c
@@ -24,6 +24,22 @@ int general_thread;
int thread_from_wait;
int old_thread_from_wait;
int extended_protocol;
+jmp_buf toplevel;
+int inferior_pid;
+
+static unsigned char
+start_inferior (argv, statusptr)
+ char *argv[];
+ char *statusptr;
+{
+ inferior_pid = create_inferior (argv[0], argv);
+ fprintf (stderr, "Process %s created; pid = %d\n", argv[0], inferior_pid);
+
+ /* Wait till we are at 1st instruction in program, return signal number. */
+ return mywait (statusptr);
+}
+
+extern int remote_debug;
int
main (argc, argv)
@@ -33,7 +49,8 @@ main (argc, argv)
char ch, status, own_buf[2000], mem_buf[2000];
int i = 0;
unsigned char signal;
- unsigned int mem_addr, len;
+ unsigned int len;
+ CORE_ADDR mem_addr;
if (setjmp(toplevel))
{
@@ -44,10 +61,8 @@ main (argc, argv)
if (argc < 3)
error("Usage: gdbserver tty prog [args ...]");
- inferior_pid = create_inferior (argv[2], &argv[2]);
- fprintf (stderr, "Process %s created; pid = %d\n", argv[2], inferior_pid);
-
- signal = mywait (&status); /* Wait till we are at 1st instr in prog */
+ /* Wait till we are at first instruction in program. */
+ signal = start_inferior (&argv[2], &status);
/* We are now stopped at the first instruction of the target process */
@@ -64,6 +79,9 @@ restart:
ch = own_buf[i++];
switch (ch)
{
+ case 'd':
+ remote_debug = !remote_debug;
+ break;
case '!':
extended_protocol = 1;
prepare_resume_reply (own_buf, status, signal);
@@ -142,12 +160,9 @@ restart:
{
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
- inferior_pid = create_inferior (argv[2], &argv[2]);
- fprintf (stderr, "Process %s created; pid = %d\n",
- argv[2], inferior_pid);
/* Wait till we are at 1st instruction in prog. */
- signal = mywait (&status);
+ signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
@@ -170,12 +185,9 @@ restart:
kill_inferior ();
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
- inferior_pid = create_inferior (argv[2], &argv[2]);
- fprintf (stderr, "Process %s created; pid = %d\n",
- argv[2], inferior_pid);
/* Wait till we are at 1st instruction in prog. */
- signal = mywait (&status);
+ signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
@@ -210,12 +222,9 @@ restart:
kill_inferior ();
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
- inferior_pid = create_inferior (argv[2], &argv[2]);
- fprintf (stderr, "Process %s created; pid = %d\n",
- argv[2], inferior_pid);
/* Wait till we are at 1st instruction in prog. */
- signal = mywait (&status);
+ signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
diff --git a/contrib/gdb/gdb/gdbserver/server.h b/contrib/gdb/gdb/gdbserver/server.h
index 6aeaa09..e23c773 100644
--- a/contrib/gdb/gdb/gdbserver/server.h
+++ b/contrib/gdb/gdb/gdbserver/server.h
@@ -20,31 +20,53 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <setjmp.h>
-void read_inferior_memory ();
-unsigned char mywait ();
-void myresume();
-int mythread_alive ();
+/* Target-specific functions */
+
+int create_inferior PARAMS ((char *program, char **allargs));
+void kill_inferior PARAMS ((void));
+void fetch_inferior_registers PARAMS ((int regno));
+void store_inferior_registers PARAMS ((int regno));
+int mythread_alive PARAMS ((int pid));
+void myresume PARAMS ((int step, int signo));
+unsigned char mywait PARAMS ((char *status));
+void read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+int write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
int create_inferior ();
+/* Target-specific variables */
+
extern char registers[];
-int inferior_pid;
+
+/* Public variables in server.c */
+
extern int cont_thread;
extern int general_thread;
extern int thread_from_wait;
extern int old_thread_from_wait;
-int remote_send ();
-int putpkt ();
-int getpkt ();
-void remote_open ();
-void write_ok ();
-void write_enn ();
-void convert_ascii_to_int ();
-void convert_int_to_ascii ();
-void prepare_resume_reply ();
-void decode_m_packet ();
-void decode_M_packet ();
-
-jmp_buf toplevel;
-
-void perror_with_name ();
+extern jmp_buf toplevel;
+extern int inferior_pid;
+
+/* Functions from remote-utils.c */
+
+int putpkt PARAMS ((char *buf));
+int getpkt PARAMS ((char *buf));
+void remote_open PARAMS ((char *name));
+void remote_close PARAMS ((void));
+void write_ok PARAMS ((char *buf));
+void write_enn PARAMS ((char *buf));
+void enable_async_io PARAMS ((void));
+void disable_async_io PARAMS ((void));
+void convert_ascii_to_int PARAMS ((char *from, char *to, int n));
+void convert_int_to_ascii PARAMS ((char *from, char *to, int n));
+void prepare_resume_reply PARAMS ((char *buf, char status, unsigned char sig));
+
+void decode_m_packet PARAMS ((char *from, CORE_ADDR *mem_addr_ptr,
+ unsigned int *len_ptr));
+void decode_M_packet PARAMS ((char *from, CORE_ADDR *mem_addr_ptr,
+ unsigned int *len_ptr, char *to));
+
+
+/* Functions from utils.c */
+
+void perror_with_name PARAMS ((char *string));
diff --git a/contrib/gdb/gdb/gdbserver/utils.c b/contrib/gdb/gdb/gdbserver/utils.c
index 032dbbf2..63d522c 100644
--- a/contrib/gdb/gdb/gdbserver/utils.c
+++ b/contrib/gdb/gdb/gdbserver/utils.c
@@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "server.h"
#include <stdio.h>
+#include <string.h>
/* Generally useful subroutines used throughout the program. */
@@ -55,7 +56,7 @@ perror_with_name (string)
#ifdef ANSI_PROTOTYPES
NORETURN void
-error (char *string, ...)
+error (const char *string, ...)
#else
void
error (va_alist)
diff --git a/contrib/gdb/gdb/gdbthread.h b/contrib/gdb/gdb/gdbthread.h
new file mode 100644
index 0000000..653dd65
--- /dev/null
+++ b/contrib/gdb/gdb/gdbthread.h
@@ -0,0 +1,121 @@
+/* Multi-process/thread control defs for GDB, the GNU debugger.
+ Copyright 1987, 88, 89, 90, 91, 92, 1993, 1998
+
+ Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
+ Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GDBTHREAD_H
+#define GDBTHREAD_H
+
+/* For bpstat */
+#include "breakpoint.h"
+
+extern void init_thread_list PARAMS ((void));
+
+extern void add_thread PARAMS ((int pid));
+
+extern void delete_thread PARAMS ((int));
+
+extern int thread_id_to_pid PARAMS ((int));
+
+extern int in_thread_list PARAMS ((int pid));
+
+extern int pid_to_thread_id PARAMS ((int pid));
+
+extern int valid_thread_id PARAMS ((int thread));
+
+extern void load_infrun_state PARAMS ((int, CORE_ADDR *, CORE_ADDR *, char **,
+ int *, struct breakpoint **,
+ struct breakpoint **, CORE_ADDR *,
+ CORE_ADDR *, CORE_ADDR *, int *, int *,
+ int *, bpstat *, int *));
+
+extern void save_infrun_state PARAMS ((int, CORE_ADDR, CORE_ADDR, char *,
+ int, struct breakpoint *,
+ struct breakpoint *, CORE_ADDR,
+ CORE_ADDR, CORE_ADDR, int, int,
+ int, bpstat, int));
+
+/* Commands with a prefix of `thread'. */
+extern struct cmd_list_element *thread_cmd_list;
+
+/* Support for external (remote) systems with threads (processes) */
+/* For example real time operating systems */
+
+#define OPAQUETHREADBYTES 8
+/* a 64 bit opaque identifier */
+typedef unsigned char threadref[OPAQUETHREADBYTES] ;
+/* WARNING: This threadref data structure comes from the remote O.S., libstub
+ protocol encoding, and remote.c. it is not particularly changable */
+
+/* Right now, the internal structure is int. We want it to be bigger.
+ Plan to fix this.
+ */
+typedef int gdb_threadref ; /* internal GDB thread reference */
+
+/* gdb_ext_thread_info is an internal GDB data structure which is
+ equivalint to the reply of the remote threadinfo packet */
+
+struct gdb_ext_thread_info
+{
+ threadref threadid ; /* External form of thread reference */
+ int active ; /* Has state interesting to GDB? , regs, stack */
+ char display[256] ; /* Brief state display, name, blocked/syspended */
+ char shortname[32] ; /* To be used to name threads */
+ char more_display[256] ; /* Long info, statistics, queue depth, whatever */
+} ;
+
+/* The volume of remote transfers can be limited by submitting
+ a mask containing bits specifying the desired information.
+ Use a union of these values as the 'selection' parameter to
+ get_thread_info. FIXME: Make these TAG names more thread specific.
+ */
+#define TAG_THREADID 1
+#define TAG_EXISTS 2
+#define TAG_DISPLAY 4
+#define TAG_THREADNAME 8
+#define TAG_MOREDISPLAY 16
+
+/* Always initialize an instance of this structure using run time assignments */
+/* Because we are likely to add entrtries to it. */
+/* Alternatly, WE COULD ADD THESE TO THE TARGET VECTOR */
+
+struct target_thread_vector
+{
+ int (*find_new_threads)PARAMS((void)) ;
+ int (*get_thread_info) PARAMS((
+ gdb_threadref * ref,
+ int selection,
+ struct gdb_ext_thread_info * info
+ )) ;
+ /* to_thread_alive - Already in the target vector */
+ /* to_switch_thread - Done via select frame */
+} ;
+
+extern void bind_target_thread_vector PARAMS((struct target_thread_vector * vec)) ;
+
+extern struct target_thread_vector * unbind_target_thread_vector PARAMS ((void)) ;
+
+extern int target_get_thread_info PARAMS((
+ gdb_threadref * ref,
+ int selection,
+ struct gdb_ext_thread_info * info)) ;
+
+
+#endif /* GDBTHREAD_H */
diff --git a/contrib/gdb/gdb/gdbtypes.c b/contrib/gdb/gdb/gdbtypes.c
index 13a111f..0393462 100644
--- a/contrib/gdb/gdb/gdbtypes.c
+++ b/contrib/gdb/gdb/gdbtypes.c
@@ -1,5 +1,5 @@
/* Support routines for manipulating internal types for GDB.
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
@@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "value.h"
#include "demangle.h"
#include "complaints.h"
+#include "gdbcmd.h"
/* These variables point to the objects
representing the predefined C data types. */
@@ -53,6 +54,30 @@ struct type *builtin_type_long_double;
struct type *builtin_type_complex;
struct type *builtin_type_double_complex;
struct type *builtin_type_string;
+struct type *builtin_type_int8;
+struct type *builtin_type_uint8;
+struct type *builtin_type_int16;
+struct type *builtin_type_uint16;
+struct type *builtin_type_int32;
+struct type *builtin_type_uint32;
+struct type *builtin_type_int64;
+struct type *builtin_type_uint64;
+struct type *builtin_type_bool;
+
+int opaque_type_resolution = 1;
+
+
+struct extra { char str[128]; int len; }; /* maximum extention is 128! FIXME */
+
+static void add_name PARAMS ((struct extra *, char *));
+static void add_mangled_type PARAMS ((struct extra *, struct type *));
+#if 0
+static void cfront_mangle_name PARAMS ((struct type *, int, int));
+#endif
+static void print_bit_vector PARAMS ((B_TYPE *, int));
+static void print_arg_types PARAMS ((struct type **, int));
+static void dump_fn_fieldlists PARAMS ((struct type *, int));
+static void print_cplus_stuff PARAMS ((struct type *, int));
/* Alloc a new type structure and fill it with some defaults. If
OBJFILE is non-NULL, then allocate the space for the type structure
@@ -83,6 +108,7 @@ alloc_type (objfile)
TYPE_CODE (type) = TYPE_CODE_UNDEF;
TYPE_OBJFILE (type) = objfile;
TYPE_VPTR_FIELDNO (type) = -1;
+ TYPE_CV_TYPE (type) = type; /* chain back to itself */
return (type);
}
@@ -103,13 +129,15 @@ make_pointer_type (type, typeptr)
ntype = TYPE_POINTER_TYPE (type);
if (ntype)
- if (typeptr == 0)
- return ntype; /* Don't care about alloc, and have new type. */
- else if (*typeptr == 0)
- {
- *typeptr = ntype; /* Tracking alloc, and we have new type. */
- return ntype;
- }
+ {
+ if (typeptr == 0)
+ return ntype; /* Don't care about alloc, and have new type. */
+ else if (*typeptr == 0)
+ {
+ *typeptr = ntype; /* Tracking alloc, and we have new type. */
+ return ntype;
+ }
+ }
if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
{
@@ -168,13 +196,15 @@ make_reference_type (type, typeptr)
ntype = TYPE_REFERENCE_TYPE (type);
if (ntype)
- if (typeptr == 0)
- return ntype; /* Don't care about alloc, and have new type. */
- else if (*typeptr == 0)
- {
- *typeptr = ntype; /* Tracking alloc, and we have new type. */
- return ntype;
- }
+ {
+ if (typeptr == 0)
+ return ntype; /* Don't care about alloc, and have new type. */
+ else if (*typeptr == 0)
+ {
+ *typeptr = ntype; /* Tracking alloc, and we have new type. */
+ return ntype;
+ }
+ }
if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
{
@@ -260,6 +290,89 @@ lookup_function_type (type)
return make_function_type (type, (struct type **)0);
}
+
+/* Make a "c-v" variant of a type -- a type that is identical to the
+ one supplied except that it may have const or volatile attributes
+ CNST is a flag for setting the const attribute
+ VOLTL is a flag for setting the volatile attribute
+ TYPE is the base type whose variant we are creating.
+ TYPEPTR, if nonzero, points
+ to a pointer to memory where the reference type should be stored.
+ If *TYPEPTR is zero, update it to point to the reference type we return.
+ We allocate new memory if needed. */
+
+struct type *
+make_cv_type (cnst, voltl, type, typeptr)
+ int cnst;
+ int voltl;
+ struct type *type;
+ struct type **typeptr;
+{
+ register struct type *ntype; /* New type */
+ register struct type *tmp_type = type; /* tmp type */
+ struct objfile *objfile;
+
+ ntype = TYPE_CV_TYPE (type);
+
+ while (ntype != type)
+ {
+ if ((TYPE_CONST (ntype) == cnst) &&
+ (TYPE_VOLATILE (ntype) == voltl))
+ {
+ if (typeptr == 0)
+ return ntype;
+ else if (*typeptr == 0)
+ {
+ *typeptr = ntype; /* Tracking alloc, and we have new type. */
+ return ntype;
+ }
+ }
+ tmp_type = ntype;
+ ntype = TYPE_CV_TYPE (ntype);
+ }
+
+ if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
+ {
+ ntype = alloc_type (TYPE_OBJFILE (type));
+ if (typeptr)
+ *typeptr = ntype;
+ }
+ else /* We have storage, but need to reset it. */
+ {
+ ntype = *typeptr;
+ objfile = TYPE_OBJFILE (ntype);
+ /* memset ((char *) ntype, 0, sizeof (struct type)); */
+ TYPE_OBJFILE (ntype) = objfile;
+ }
+
+ /* Copy original type */
+ memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+ /* But zero out fields that shouldn't be copied */
+ TYPE_POINTER_TYPE (ntype) = (struct type *) 0; /* Need new pointer kind */
+ TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; /* Need new referene kind */
+ /* Note: TYPE_TARGET_TYPE can be left as is */
+
+ /* Set flags appropriately */
+ if (cnst)
+ TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST;
+ else
+ TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST;
+
+ if (voltl)
+ TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE;
+ else
+ TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE;
+
+ /* Fix the chain of cv variants */
+ TYPE_CV_TYPE (ntype) = type;
+ TYPE_CV_TYPE (tmp_type) = ntype;
+
+ return ntype;
+}
+
+
+
+
/* Implement direct support for MEMBER_TYPE in GNU C++.
May need to construct such a type if this is the first use.
The TYPE is the type of the member. The DOMAIN is the type
@@ -334,6 +447,9 @@ create_range_type (result_type, index_type, low_bound, high_bound)
TYPE_FIELD_TYPE (result_type, 0) = builtin_type_int; /* FIXME */
TYPE_FIELD_TYPE (result_type, 1) = builtin_type_int; /* FIXME */
+ if(low_bound >= 0)
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+
return (result_type);
}
@@ -368,6 +484,12 @@ get_discrete_bounds (type, lowp, highp)
if (TYPE_FIELD_BITPOS (type, i) > *highp)
*highp = TYPE_FIELD_BITPOS (type, i);
}
+
+ /* Set unsigned indicator if warranted. */
+ if(*lowp >= 0)
+ {
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ }
}
else
{
@@ -437,6 +559,10 @@ create_array_type (result_type, element_type, range_type)
TYPE_FIELD_TYPE (result_type, 0) = range_type;
TYPE_VPTR_FIELDNO (result_type) = -1;
+ /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */
+ if (TYPE_LENGTH (result_type) == 0)
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
+
return (result_type);
}
@@ -488,6 +614,10 @@ create_set_type (result_type, domain_type)
= (bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
}
TYPE_FIELD_TYPE (result_type, 0) = domain_type;
+
+ if(low_bound >= 0)
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+
return (result_type);
}
@@ -674,21 +804,31 @@ lookup_union (name, block)
struct block *block;
{
register struct symbol *sym;
+ struct type * t;
sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
(struct symtab **) NULL);
if (sym == NULL)
- {
- error ("No union type named %s.", name);
- }
- if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
- {
- error ("This context has class, struct or enum %s, not a union.", name);
- }
- return (SYMBOL_TYPE (sym));
+ error ("No union type named %s.", name);
+
+ t = SYMBOL_TYPE(sym);
+
+ if (TYPE_CODE (t) == TYPE_CODE_UNION)
+ return (t);
+
+ /* C++ unions may come out with TYPE_CODE_CLASS, but we look at
+ * a further "declared_type" field to discover it is really a union.
+ */
+ if (HAVE_CPLUS_STRUCT (t))
+ if (TYPE_DECLARED_TYPE(t) == DECLARED_TYPE_UNION)
+ return (t);
+
+ /* If we get here, it's not a union */
+ error ("This context has class, struct or enum %s, not a union.", name);
}
+
/* Lookup an enum type named "enum NAME",
visible in lexical block BLOCK. */
@@ -863,6 +1003,35 @@ fill_in_vptr_fieldno (type)
}
}
+/* Find the method and field indices for the destructor in class type T.
+ Return 1 if the destructor was found, otherwise, return 0. */
+
+int
+get_destructor_fn_field (t, method_indexp, field_indexp)
+ struct type *t;
+ int *method_indexp;
+ int *field_indexp;
+{
+ int i;
+
+ for (i = 0; i < TYPE_NFN_FIELDS (t); i++)
+ {
+ int j;
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
+
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
+ {
+ if (DESTRUCTOR_PREFIX_P (TYPE_FN_FIELD_PHYSNAME (f, j)))
+ {
+ *method_indexp = i;
+ *field_indexp = j;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
/* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
If this is a stubbed struct (i.e. declared as struct foo *), see if
@@ -916,7 +1085,28 @@ check_typedef (type)
type = TYPE_TARGET_TYPE (type);
}
- if ((TYPE_FLAGS(type) & TYPE_FLAG_STUB) && ! currently_reading_symtab)
+ /* If this is a struct/class/union with no fields, then check whether a
+ full definition exists somewhere else. This is for systems where a
+ type definition with no fields is issued for such types, instead of
+ identifying them as stub types in the first place */
+
+ if (TYPE_IS_OPAQUE (type) && opaque_type_resolution && !currently_reading_symtab)
+ {
+ char * name = type_name_no_tag (type);
+ struct type * newtype;
+ if (name == NULL)
+ {
+ complain (&stub_noname_complaint);
+ return type;
+ }
+ newtype = lookup_transparent_type (name);
+ if (newtype)
+ {
+ memcpy ((char *) type, (char *) newtype, sizeof (struct type));
+ }
+ }
+ /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
+ else if ((TYPE_FLAGS(type) & TYPE_FLAG_STUB) && ! currently_reading_symtab)
{
char* name = type_name_no_tag (type);
/* FIXME: shouldn't we separately check the TYPE_NAME and the
@@ -929,13 +1119,10 @@ check_typedef (type)
complain (&stub_noname_complaint);
return type;
}
- sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
- (struct symtab **) NULL);
+ sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **) NULL);
if (sym)
{
- memcpy ((char *)type,
- (char *)SYMBOL_TYPE(sym),
- sizeof (struct type));
+ memcpy ((char *)type, (char *)SYMBOL_TYPE(sym), sizeof (struct type));
}
}
@@ -944,7 +1131,7 @@ check_typedef (type)
struct type *range_type;
struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
- if (TYPE_FLAGS (target_type) & TYPE_FLAG_STUB)
+ if (TYPE_FLAGS (target_type) & (TYPE_FLAG_STUB | TYPE_FLAG_TARGET_STUB))
{ }
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_NFIELDS (type) == 1
@@ -971,6 +1158,202 @@ check_typedef (type)
return type;
}
+/* New code added to support parsing of Cfront stabs strings */
+#include <ctype.h>
+#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; }
+#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; }
+
+static void
+add_name(pextras,n)
+ struct extra * pextras;
+ char * n;
+{
+ int nlen;
+
+ if ((nlen = (n ? strlen(n) : 0))==0)
+ return;
+ sprintf(pextras->str+pextras->len,"%d%s",nlen,n);
+ pextras->len=strlen(pextras->str);
+}
+
+static void
+add_mangled_type(pextras,t)
+ struct extra * pextras;
+ struct type * t;
+{
+ enum type_code tcode;
+ int tlen, tflags;
+ char * tname;
+
+ tcode = TYPE_CODE(t);
+ tlen = TYPE_LENGTH(t);
+ tflags = TYPE_FLAGS(t);
+ tname = TYPE_NAME(t);
+ /* args of "..." seem to get mangled as "e" */
+
+ switch (tcode)
+ {
+ case TYPE_CODE_INT:
+ if (tflags==1)
+ ADD_EXTRA('U');
+ switch (tlen)
+ {
+ case 1:
+ ADD_EXTRA('c');
+ break;
+ case 2:
+ ADD_EXTRA('s');
+ break;
+ case 4:
+ {
+ char* pname;
+ if ((pname=strrchr(tname,'l'),pname) && !strcmp(pname,"long"))
+ ADD_EXTRA('l')
+ else
+ ADD_EXTRA('i')
+ }
+ break;
+ default:
+ {
+
+ static struct complaint msg = {"Bad int type code length x%x\n",0,0};
+
+ complain (&msg, tlen);
+
+ }
+ }
+ break;
+ case TYPE_CODE_FLT:
+ switch (tlen)
+ {
+ case 4:
+ ADD_EXTRA('f');
+ break;
+ case 8:
+ ADD_EXTRA('d');
+ break;
+ case 16:
+ ADD_EXTRA('r');
+ break;
+ default:
+ {
+ static struct complaint msg = {"Bad float type code length x%x\n",0,0};
+ complain (&msg, tlen);
+ }
+ }
+ break;
+ case TYPE_CODE_REF:
+ ADD_EXTRA('R');
+ /* followed by what it's a ref to */
+ break;
+ case TYPE_CODE_PTR:
+ ADD_EXTRA('P');
+ /* followed by what it's a ptr to */
+ break;
+ case TYPE_CODE_TYPEDEF:
+ {
+ static struct complaint msg = {"Typedefs in overloaded functions not yet supported\n",0,0};
+ complain (&msg);
+ }
+ /* followed by type bytes & name */
+ break;
+ case TYPE_CODE_FUNC:
+ ADD_EXTRA('F');
+ /* followed by func's arg '_' & ret types */
+ break;
+ case TYPE_CODE_VOID:
+ ADD_EXTRA('v');
+ break;
+ case TYPE_CODE_METHOD:
+ ADD_EXTRA('M');
+ /* followed by name of class and func's arg '_' & ret types */
+ add_name(pextras,tname);
+ ADD_EXTRA('F'); /* then mangle function */
+ break;
+ case TYPE_CODE_STRUCT: /* C struct */
+ case TYPE_CODE_UNION: /* C union */
+ case TYPE_CODE_ENUM: /* Enumeration type */
+ /* followed by name of type */
+ add_name(pextras,tname);
+ break;
+
+ /* errors possible types/not supported */
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ARRAY: /* Array type */
+ case TYPE_CODE_MEMBER: /* Member type */
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_COMPLEX: /* Complex float */
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_SET: /* Pascal sets */
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_ERROR:
+ default:
+ {
+ static struct complaint msg = {"Unknown type code x%x\n",0,0};
+ complain (&msg, tcode);
+ }
+ }
+ if (t->target_type)
+ add_mangled_type(pextras,t->target_type);
+}
+
+#if 0
+void
+cfront_mangle_name(type, i, j)
+ struct type *type;
+ int i;
+ int j;
+{
+ struct fn_field *f;
+ char *mangled_name = gdb_mangle_name (type, i, j);
+
+ f = TYPE_FN_FIELDLIST1 (type, i); /* moved from below */
+
+ /* kludge to support cfront methods - gdb expects to find "F" for
+ ARM_mangled names, so when we mangle, we have to add it here */
+ if (ARM_DEMANGLING)
+ {
+ int k;
+ char * arm_mangled_name;
+ struct fn_field *method = &f[j];
+ char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+ char *newname = type_name_no_tag (type);
+
+ struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+ int nargs = TYPE_NFIELDS(ftype); /* number of args */
+ struct extra extras, * pextras = &extras;
+ INIT_EXTRA
+
+ if (TYPE_FN_FIELD_STATIC_P (f, j)) /* j for sublist within this list */
+ ADD_EXTRA('S')
+ ADD_EXTRA('F')
+ /* add args here! */
+ if (nargs <= 1) /* no args besides this */
+ ADD_EXTRA('v')
+ else {
+ for (k=1; k<nargs; k++)
+ {
+ struct type * t;
+ t = TYPE_FIELD_TYPE(ftype,k);
+ add_mangled_type(pextras,t);
+ }
+ }
+ ADD_EXTRA('\0')
+ printf("add_mangled_type: %s\n",extras.str); /* FIXME */
+ arm_mangled_name = malloc(strlen(mangled_name)+extras.len);
+ sprintf(arm_mangled_name,"%s%s",mangled_name,extras.str);
+ free(mangled_name);
+ mangled_name = arm_mangled_name;
+ }
+}
+#endif /* 0 */
+
+#undef ADD_EXTRA
+/* End of new code added to support parsing of Cfront stabs strings */
+
/* Ugly hack to convert method stubs into method types.
He ain't kiddin'. This demangles the name of the method into a string
@@ -982,13 +1365,13 @@ check_typedef (type)
the space required for them. */
void
-check_stub_method (type, i, j)
+check_stub_method (type, method_id, signature_id)
struct type *type;
- int i;
- int j;
+ int method_id;
+ int signature_id;
{
struct fn_field *f;
- char *mangled_name = gdb_mangle_name (type, i, j);
+ char *mangled_name = gdb_mangle_name (type, method_id, signature_id);
char *demangled_name = cplus_demangle (mangled_name,
DMGL_PARAMS | DMGL_ANSI);
char *argtypetext, *p;
@@ -1075,15 +1458,16 @@ check_stub_method (type, i, j)
free (demangled_name);
- f = TYPE_FN_FIELDLIST1 (type, i);
- TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
+ f = TYPE_FN_FIELDLIST1 (type, method_id);
+
+ TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name;
/* Now update the old "stub" type into a real type. */
- mtype = TYPE_FN_FIELD_TYPE (f, j);
+ mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
TYPE_DOMAIN_TYPE (mtype) = type;
TYPE_ARG_TYPES (mtype) = argtypes;
TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
- TYPE_FN_FIELD_STUB (f, j) = 0;
+ TYPE_FN_FIELD_STUB (f, signature_id) = 0;
}
const struct cplus_struct_type cplus_struct_default;
@@ -1227,6 +1611,787 @@ chill_varying_type (type)
return 1;
}
+/* Check whether BASE is an ancestor or base class or DCLASS
+ Return 1 if so, and 0 if not.
+ Note: callers may want to check for identity of the types before
+ calling this function -- identical types are considered to satisfy
+ the ancestor relationship even if they're identical */
+
+int
+is_ancestor (base, dclass)
+ struct type * base;
+ struct type * dclass;
+{
+ int i;
+
+ CHECK_TYPEDEF (base);
+ CHECK_TYPEDEF (dclass);
+
+ if (base == dclass)
+ return 1;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ if (is_ancestor (base, TYPE_BASECLASS (dclass, i)))
+ return 1;
+
+ return 0;
+}
+
+
+
+/* See whether DCLASS has a virtual table. This routine is aimed at
+ the HP/Taligent ANSI C++ runtime model, and may not work with other
+ runtime models. Return 1 => Yes, 0 => No. */
+
+int
+has_vtable (dclass)
+ struct type * dclass;
+{
+ /* In the HP ANSI C++ runtime model, a class has a vtable only if it
+ has virtual functions or virtual bases. */
+
+ register int i;
+
+ if (TYPE_CODE(dclass) != TYPE_CODE_CLASS)
+ return 0;
+
+ /* First check for the presence of virtual bases */
+ if (TYPE_FIELD_VIRTUAL_BITS(dclass))
+ for (i=0; i < TYPE_N_BASECLASSES(dclass); i++)
+ if (B_TST(TYPE_FIELD_VIRTUAL_BITS(dclass), i))
+ return 1;
+
+ /* Next check for virtual functions */
+ if (TYPE_FN_FIELDLISTS(dclass))
+ for (i=0; i < TYPE_NFN_FIELDS(dclass); i++)
+ if (TYPE_FN_FIELD_VIRTUAL_P(TYPE_FN_FIELDLIST1(dclass, i), 0))
+ return 1;
+
+ /* Recurse on non-virtual bases to see if any of them needs a vtable */
+ if (TYPE_FIELD_VIRTUAL_BITS(dclass))
+ for (i=0; i < TYPE_N_BASECLASSES(dclass); i++)
+ if ((!B_TST (TYPE_FIELD_VIRTUAL_BITS(dclass), i)) &&
+ (has_vtable (TYPE_FIELD_TYPE(dclass, i))))
+ return 1;
+
+ /* Well, maybe we don't need a virtual table */
+ return 0;
+}
+
+/* Return a pointer to the "primary base class" of DCLASS.
+
+ A NULL return indicates that DCLASS has no primary base, or that it
+ couldn't be found (insufficient information).
+
+ This routine is aimed at the HP/Taligent ANSI C++ runtime model,
+ and may not work with other runtime models. */
+
+struct type *
+primary_base_class (dclass)
+ struct type * dclass;
+{
+ /* In HP ANSI C++'s runtime model, a "primary base class" of a class
+ is the first directly inherited, non-virtual base class that
+ requires a virtual table */
+
+ register int i;
+
+ if (TYPE_CODE(dclass) != TYPE_CODE_CLASS)
+ return NULL;
+
+ for (i=0; i < TYPE_N_BASECLASSES(dclass); i++)
+ if (!TYPE_FIELD_VIRTUAL(dclass, i) &&
+ has_vtable(TYPE_FIELD_TYPE(dclass, i)))
+ return TYPE_FIELD_TYPE(dclass, i);
+
+ return NULL;
+}
+
+/* Global manipulated by virtual_base_list[_aux]() */
+
+static struct vbase * current_vbase_list = NULL;
+
+/* Return a pointer to a null-terminated list of struct vbase
+ items. The vbasetype pointer of each item in the list points to the
+ type information for a virtual base of the argument DCLASS.
+
+ Helper function for virtual_base_list().
+ Note: the list goes backward, right-to-left. virtual_base_list()
+ copies the items out in reverse order. */
+
+struct vbase *
+virtual_base_list_aux (dclass)
+ struct type * dclass;
+{
+ struct vbase * tmp_vbase;
+ register int i;
+
+ if (TYPE_CODE(dclass) != TYPE_CODE_CLASS)
+ return NULL;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ {
+ /* Recurse on this ancestor, first */
+ virtual_base_list_aux(TYPE_FIELD_TYPE(dclass, i));
+
+ /* If this current base is itself virtual, add it to the list */
+ if (BASETYPE_VIA_VIRTUAL(dclass, i))
+ {
+ struct type * basetype = TYPE_FIELD_TYPE (dclass, i);
+
+ /* Check if base already recorded */
+ tmp_vbase = current_vbase_list;
+ while (tmp_vbase)
+ {
+ if (tmp_vbase->vbasetype == basetype)
+ break; /* found it */
+ tmp_vbase = tmp_vbase->next;
+ }
+
+ if (!tmp_vbase) /* normal exit from loop */
+ {
+ /* Allocate new item for this virtual base */
+ tmp_vbase = (struct vbase *) xmalloc (sizeof (struct vbase));
+
+ /* Stick it on at the end of the list */
+ tmp_vbase->vbasetype = basetype;
+ tmp_vbase->next = current_vbase_list;
+ current_vbase_list = tmp_vbase;
+ }
+ } /* if virtual */
+ } /* for loop over bases */
+}
+
+
+/* Compute the list of virtual bases in the right order. Virtual
+ bases are laid out in the object's memory area in order of their
+ occurrence in a depth-first, left-to-right search through the
+ ancestors.
+
+ Argument DCLASS is the type whose virtual bases are required.
+ Return value is the address of a null-terminated array of pointers
+ to struct type items.
+
+ This routine is aimed at the HP/Taligent ANSI C++ runtime model,
+ and may not work with other runtime models.
+
+ This routine merely hands off the argument to virtual_base_list_aux()
+ and then copies the result into an array to save space. */
+
+struct type **
+virtual_base_list (dclass)
+ struct type * dclass;
+{
+ register struct vbase * tmp_vbase;
+ register struct vbase * tmp_vbase_2;
+ register int i;
+ int count;
+ struct type ** vbase_array;
+
+ current_vbase_list = NULL;
+ virtual_base_list_aux(dclass);
+
+ for (i=0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; i++, tmp_vbase = tmp_vbase->next)
+ /* no body */ ;
+
+ count = i;
+
+ vbase_array = (struct type **) xmalloc((count + 1) * sizeof (struct type *));
+
+ for (i=count -1, tmp_vbase = current_vbase_list; i >= 0; i--, tmp_vbase = tmp_vbase->next)
+ vbase_array[i] = tmp_vbase->vbasetype;
+
+ /* Get rid of constructed chain */
+ tmp_vbase_2 = tmp_vbase = current_vbase_list;
+ while (tmp_vbase)
+ {
+ tmp_vbase = tmp_vbase->next;
+ free(tmp_vbase_2);
+ tmp_vbase_2 = tmp_vbase;
+ }
+
+ vbase_array[count] = NULL;
+ return vbase_array;
+}
+
+/* Return the length of the virtual base list of the type DCLASS. */
+
+int
+virtual_base_list_length (dclass)
+ struct type * dclass;
+{
+ register int i;
+ register struct vbase * tmp_vbase;
+
+ current_vbase_list = NULL;
+ virtual_base_list_aux(dclass);
+
+ for (i=0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; i++, tmp_vbase = tmp_vbase->next)
+ /* no body */ ;
+ return i;
+}
+
+/* Return the number of elements of the virtual base list of the type
+ DCLASS, ignoring those appearing in the primary base (and its
+ primary base, recursively). */
+
+int
+virtual_base_list_length_skip_primaries (dclass)
+ struct type * dclass;
+{
+ register int i;
+ register struct vbase * tmp_vbase;
+ struct type * primary;
+
+ primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
+
+ if (!primary)
+ return virtual_base_list_length (dclass);
+
+ current_vbase_list = NULL;
+ virtual_base_list_aux(dclass);
+
+ for (i=0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; tmp_vbase = tmp_vbase->next)
+ {
+ if (virtual_base_index (tmp_vbase->vbasetype, primary) >= 0)
+ continue;
+ i++;
+ }
+ return i;
+}
+
+
+/* Return the index (position) of type BASE, which is a virtual base
+ class of DCLASS, in the latter's virtual base list. A return of -1
+ indicates "not found" or a problem. */
+
+int
+virtual_base_index(base, dclass)
+ struct type * base;
+ struct type * dclass;
+{
+ register struct type * vbase;
+ register int i;
+
+ if ((TYPE_CODE(dclass) != TYPE_CODE_CLASS) ||
+ (TYPE_CODE(base) != TYPE_CODE_CLASS))
+ return -1;
+
+ i = 0;
+ vbase = TYPE_VIRTUAL_BASE_LIST(dclass)[0];
+ while (vbase)
+ {
+ if (vbase == base)
+ break;
+ vbase = TYPE_VIRTUAL_BASE_LIST(dclass)[++i];
+ }
+
+ return vbase ? i : -1;
+}
+
+
+
+/* Return the index (position) of type BASE, which is a virtual base
+ class of DCLASS, in the latter's virtual base list. Skip over all
+ bases that may appear in the virtual base list of the primary base
+ class of DCLASS (recursively). A return of -1 indicates "not
+ found" or a problem. */
+
+int
+virtual_base_index_skip_primaries(base, dclass)
+ struct type * base;
+ struct type * dclass;
+{
+ register struct type * vbase;
+ register int i, j;
+ struct type * primary;
+
+ if ((TYPE_CODE(dclass) != TYPE_CODE_CLASS) ||
+ (TYPE_CODE(base) != TYPE_CODE_CLASS))
+ return -1;
+
+ primary = TYPE_RUNTIME_PTR(dclass) ? TYPE_PRIMARY_BASE(dclass) : NULL;
+
+ j = -1;
+ i = 0;
+ vbase = TYPE_VIRTUAL_BASE_LIST(dclass)[0];
+ while (vbase)
+ {
+ if (!primary || (virtual_base_index_skip_primaries(vbase, primary) < 0))
+ j++;
+ if (vbase == base)
+ break;
+ vbase = TYPE_VIRTUAL_BASE_LIST(dclass)[++i];
+ }
+
+ return vbase ? j : -1;
+}
+
+/* Return position of a derived class DCLASS in the list of
+ * primary bases starting with the remotest ancestor.
+ * Position returned is 0-based. */
+
+int
+class_index_in_primary_list (dclass)
+ struct type * dclass;
+{
+ struct type * pbc; /* primary base class */
+
+ /* Simply recurse on primary base */
+ pbc = TYPE_PRIMARY_BASE (dclass);
+ if (pbc)
+ return 1 + class_index_in_primary_list (pbc);
+ else
+ return 0;
+}
+
+/* Return a count of the number of virtual functions a type has.
+ * This includes all the virtual functions it inherits from its
+ * base classes too.
+ */
+
+/* pai: FIXME This doesn't do the right thing: count redefined virtual
+ * functions only once (latest redefinition)
+ */
+
+int
+count_virtual_fns (dclass)
+ struct type * dclass;
+{
+ int base; /* index for base classes */
+ int fn, oi; /* function and overloaded instance indices */
+
+ int vfuncs; /* count to return */
+
+ /* recurse on bases that can share virtual table */
+ struct type * pbc = primary_base_class (dclass);
+ if (pbc)
+ vfuncs = count_virtual_fns (pbc);
+
+ for (fn = 0; fn < TYPE_NFN_FIELDS (dclass); fn++)
+ for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (dclass, fn); oi++)
+ if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, fn), oi))
+ vfuncs++;
+
+ return vfuncs;
+}
+
+
+
+/* Functions for overload resolution begin here */
+
+/* Compare two badness vectors A and B and return the result.
+ * 0 => A and B are identical
+ * 1 => A and B are incomparable
+ * 2 => A is better than B
+ * 3 => A is worse than B */
+
+int
+compare_badness (a, b)
+ struct badness_vector * a;
+ struct badness_vector * b;
+{
+ int i;
+ int tmp;
+ short found_pos = 0; /* any positives in c? */
+ short found_neg = 0; /* any negatives in c? */
+
+ /* differing lengths => incomparable */
+ if (a->length != b->length)
+ return 1;
+
+ /* Subtract b from a */
+ for (i=0; i < a->length; i++)
+ {
+ tmp = a->rank[i] - b->rank[i];
+ if (tmp > 0)
+ found_pos = 1;
+ else if (tmp < 0)
+ found_neg = 1;
+ }
+
+ if (found_pos)
+ {
+ if (found_neg)
+ return 1; /* incomparable */
+ else
+ return 3; /* A > B */
+ }
+ else /* no positives */
+ {
+ if (found_neg)
+ return 2; /* A < B */
+ else
+ return 0; /* A == B */
+ }
+}
+
+/* Rank a function by comparing its parameter types (PARMS, length NPARMS),
+ * to the types of an argument list (ARGS, length NARGS).
+ * Return a pointer to a badness vector. This has NARGS + 1 entries. */
+
+struct badness_vector *
+rank_function (parms, nparms, args, nargs)
+ struct type ** parms;
+ int nparms;
+ struct type ** args;
+ int nargs;
+{
+ int i;
+ struct badness_vector * bv;
+ int min_len = nparms < nargs ? nparms : nargs;
+
+ bv = xmalloc (sizeof (struct badness_vector));
+ bv->length = nargs + 1; /* add 1 for the length-match rank */
+ bv->rank = xmalloc ((nargs + 1) * sizeof (int));
+
+ /* First compare the lengths of the supplied lists.
+ * If there is a mismatch, set it to a high value. */
+
+ /* pai/1997-06-03 FIXME: when we have debug info about default
+ * arguments and ellipsis parameter lists, we should consider those
+ * and rank the length-match more finely. */
+
+ LENGTH_MATCH (bv) = (nargs != nparms) ? LENGTH_MISMATCH_BADNESS : 0;
+
+ /* Now rank all the parameters of the candidate function */
+ for (i=1; i <= min_len; i++)
+ bv->rank[i] = rank_one_type (parms[i-1], args[i-1]);
+
+ /* If more arguments than parameters, add dummy entries */
+ for (i = min_len +1; i <= nargs; i++)
+ bv->rank[i] = TOO_FEW_PARAMS_BADNESS;
+
+ return bv;
+}
+
+/* Compare one type (PARM) for compatibility with another (ARG).
+ * PARM is intended to be the parameter type of a function; and
+ * ARG is the supplied argument's type. This function tests if
+ * the latter can be converted to the former.
+ *
+ * Return 0 if they are identical types;
+ * Otherwise, return an integer which corresponds to how compatible
+ * PARM is to ARG. The higher the return value, the worse the match.
+ * Generally the "bad" conversions are all uniformly assigned a 100 */
+
+int
+rank_one_type (parm, arg)
+ struct type * parm;
+ struct type * arg;
+{
+ /* Identical type pointers */
+ /* However, this still doesn't catch all cases of same type for arg
+ * and param. The reason is that builtin types are different from
+ * the same ones constructed from the object. */
+ if (parm == arg)
+ return 0;
+
+ /* Resolve typedefs */
+ if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
+ parm = check_typedef (parm);
+ if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
+ arg = check_typedef (arg);
+
+ /* Check if identical after resolving typedefs */
+ if (parm == arg)
+ return 0;
+
+#if 0
+ /* Debugging only */
+ printf("------ Arg is %s [%d], parm is %s [%d]\n",
+ TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm));
+#endif
+
+ /* x -> y means arg of type x being supplied for parameter of type y */
+
+ switch (TYPE_CODE (parm))
+ {
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_PTR:
+ if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID)
+ return VOID_PTR_CONVERSION_BADNESS;
+ else
+ return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+ case TYPE_CODE_ARRAY:
+ return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+ case TYPE_CODE_FUNC:
+ return rank_one_type (TYPE_TARGET_TYPE (parm), arg);
+ case TYPE_CODE_INT:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ return POINTER_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ case TYPE_CODE_ARRAY:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ARRAY:
+ return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ case TYPE_CODE_FUNC:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_PTR: /* funcptr -> func */
+ return rank_one_type (parm, TYPE_TARGET_TYPE (arg));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ case TYPE_CODE_INT:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+ {
+ /* Deal with signed, unsigned, and plain chars and
+ signed and unsigned ints */
+ if (TYPE_NOSIGN (parm))
+ {
+ /* This case only for character types */
+ if (TYPE_NOSIGN (arg)) /* plain char -> plain char */
+ return 0;
+ else
+ return INTEGER_COERCION_BADNESS; /* signed/unsigned char -> plain char */
+ }
+ else if (TYPE_UNSIGNED (parm))
+ {
+ if (TYPE_UNSIGNED (arg))
+ {
+ if (!strcmp (TYPE_NAME (parm), TYPE_NAME (arg)))
+ return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */
+ else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long"))
+ return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */
+ else
+ return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */
+ }
+ else
+ {
+ if (!strcmp (TYPE_NAME (arg), "long") && !strcmp (TYPE_NAME (parm), "int"))
+ return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */
+ else
+ return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */
+ }
+ }
+ else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+ {
+ if (!strcmp (TYPE_NAME (parm), TYPE_NAME (arg)))
+ return 0;
+ else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long"))
+ return INTEGER_PROMOTION_BADNESS;
+ else
+ return INTEGER_COERCION_BADNESS;
+ }
+ else
+ return INTEGER_COERCION_BADNESS;
+ }
+ else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return INTEGER_PROMOTION_BADNESS;
+ else
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ return INTEGER_PROMOTION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_PTR:
+ return NS_POINTER_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_ENUM:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_CHAR:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
+ return INTEGER_COERCION_BADNESS;
+ else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return INTEGER_PROMOTION_BADNESS;
+ /* >>> !! else fall through !! <<< */
+ case TYPE_CODE_CHAR:
+ /* Deal with signed, unsigned, and plain chars for C++
+ and with int cases falling through from previous case */
+ if (TYPE_NOSIGN (parm))
+ {
+ if (TYPE_NOSIGN (arg))
+ return 0;
+ else
+ return INTEGER_COERCION_BADNESS;
+ }
+ else if (TYPE_UNSIGNED (parm))
+ {
+ if (TYPE_UNSIGNED (arg))
+ return 0;
+ else
+ return INTEGER_PROMOTION_BADNESS;
+ }
+ else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+ return 0;
+ else
+ return INTEGER_COERCION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_RANGE:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_BOOL:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_PTR:
+ return BOOLEAN_CONVERSION_BADNESS;
+ case TYPE_CODE_BOOL:
+ return 0;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_FLT:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_FLT:
+ if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return FLOAT_PROMOTION_BADNESS;
+ else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+ return 0;
+ else
+ return FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_CHAR:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_COMPLEX:
+ switch (TYPE_CODE (arg))
+ { /* Strictly not needed for C++, but... */
+ case TYPE_CODE_FLT:
+ return FLOAT_PROMOTION_BADNESS;
+ case TYPE_CODE_COMPLEX:
+ return 0;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_STRUCT:
+ /* currently same as TYPE_CODE_CLASS */
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_STRUCT:
+ /* Check for derivation */
+ if (is_ancestor (parm, arg))
+ return BASE_CONVERSION_BADNESS;
+ /* else fall through */
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_UNION:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_UNION:
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_MEMBER:
+ switch (TYPE_CODE (arg))
+ {
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_METHOD:
+ switch (TYPE_CODE (arg))
+ {
+
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_REF:
+ switch (TYPE_CODE (arg))
+ {
+
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+
+ break;
+ case TYPE_CODE_SET:
+ switch (TYPE_CODE (arg))
+ {
+ /* Not in C++ */
+ case TYPE_CODE_SET:
+ return rank_one_type (TYPE_FIELD_TYPE (parm, 0), TYPE_FIELD_TYPE (arg, 0));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_VOID:
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ } /* switch (TYPE_CODE (arg)) */
+}
+
+
+/* End of functions for overload resolution */
+
+
+
#if MAINTENANCE_CMDS
static void
@@ -1603,8 +2768,10 @@ recursive_dump_type (type, spaces)
#endif /* MAINTENANCE_CMDS */
-void
-_initialize_gdbtypes ()
+
+static void build_gdbtypes PARAMS ((void));
+static void
+build_gdbtypes ()
{
builtin_type_void =
init_type (TYPE_CODE_VOID, 1,
@@ -1614,6 +2781,8 @@ _initialize_gdbtypes ()
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
"char", (struct objfile *) NULL);
+ TYPE_FLAGS (builtin_type_char) |= TYPE_FLAG_NOSIGN;
+
builtin_type_signed_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
@@ -1680,4 +2849,57 @@ _initialize_gdbtypes ()
init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
0,
"string", (struct objfile *) NULL);
+ builtin_type_int8 =
+ init_type (TYPE_CODE_INT, 8 / 8,
+ 0,
+ "int8_t", (struct objfile *) NULL);
+ builtin_type_uint8 =
+ init_type (TYPE_CODE_INT, 8 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint8_t", (struct objfile *) NULL);
+ builtin_type_int16 =
+ init_type (TYPE_CODE_INT, 16 / 8,
+ 0,
+ "int16_t", (struct objfile *) NULL);
+ builtin_type_uint16 =
+ init_type (TYPE_CODE_INT, 16 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint16_t", (struct objfile *) NULL);
+ builtin_type_int32 =
+ init_type (TYPE_CODE_INT, 32 / 8,
+ 0,
+ "int32_t", (struct objfile *) NULL);
+ builtin_type_uint32 =
+ init_type (TYPE_CODE_INT, 32 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint32_t", (struct objfile *) NULL);
+ builtin_type_int64 =
+ init_type (TYPE_CODE_INT, 64 / 8,
+ 0,
+ "int64_t", (struct objfile *) NULL);
+ builtin_type_uint64 =
+ init_type (TYPE_CODE_INT, 64 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint64_t", (struct objfile *) NULL);
+ builtin_type_bool =
+ init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "bool", (struct objfile *) NULL);
+
+ /* Add user knob for controlling resolution of opaque types */
+ add_show_from_set
+ (add_set_cmd ("opaque-type-resolution", class_support, var_boolean, (char *)&opaque_type_resolution,
+ "Set resolution of opaque struct/class/union types (if set before loading symbols).",
+ &setlist),
+ &showlist);
+ opaque_type_resolution = 1;
+
+}
+
+
+extern void _initialize_gdbtypes PARAMS ((void));
+void
+_initialize_gdbtypes ()
+{
+ build_gdbtypes ();
}
diff --git a/contrib/gdb/gdb/gdbtypes.h b/contrib/gdb/gdb/gdbtypes.h
index 59313d7..107eb46 100644
--- a/contrib/gdb/gdb/gdbtypes.h
+++ b/contrib/gdb/gdb/gdbtypes.h
@@ -1,5 +1,6 @@
/* Internal type definitions for GDB.
- Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1996, 1998, 1999
+ Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
@@ -29,9 +30,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define FT_VOID 0
#define FT_BOOLEAN 1
-#define FT_CHAR 2
-#define FT_SIGNED_CHAR 3
-#define FT_UNSIGNED_CHAR 4
+#define FT_CHAR 2 /* we use this for not-unsigned C/C++ chars */
+#define FT_SIGNED_CHAR 3 /* we use this for C++ signed chars */
+#define FT_UNSIGNED_CHAR 4 /* we use this for C/C++ unsigned chars */
#define FT_SHORT 5
#define FT_SIGNED_SHORT 6
#define FT_UNSIGNED_SHORT 7
@@ -55,8 +56,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define FT_FLOAT_DECIMAL 25
#define FT_BYTE 26
#define FT_UNSIGNED_BYTE 27
+#define FT_TEMPLATE_ARG 28
-#define FT_NUM_MEMBERS 28 /* Highest FT_* above, plus one. */
+#define FT_NUM_MEMBERS 29 /* Highest FT_* above, plus one. */
/* Some macros for char-based bitfields. */
@@ -122,7 +124,10 @@ enum type_code
/* Fortran */
TYPE_CODE_COMPLEX, /* Complex float */
- TYPE_CODE_TYPEDEF
+ TYPE_CODE_TYPEDEF,
+ TYPE_CODE_TEMPLATE, /* C++ template */
+ TYPE_CODE_TEMPLATE_ARG /* C++ template arg */
+
};
/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
@@ -136,10 +141,16 @@ enum type_code
/* Some bits for the type's flags word. */
/* Unsigned integer type. If this is not set for a TYPE_CODE_INT, the
- type is signed. */
+ type is signed (unless TYPE_FLAG_NOSIGN (below) is set). */
#define TYPE_FLAG_UNSIGNED (1 << 0)
+/* No sign for this type. In C++, "char", "signed char", and "unsigned
+ char" are distinct types; so we need an extra flag to indicate the
+ absence ofa sign! */
+
+#define TYPE_FLAG_NOSIGN (1 << 1)
+
/* This appears in a type's flags word if it is a stub type (e.g., if
someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */
@@ -154,6 +165,44 @@ enum type_code
#define TYPE_FLAG_TARGET_STUB (1 << 3)
+/* Static type. If this is set, the corresponding type had
+ * a static modifier.
+ * Note: This may be unnecessary, since static data members
+ * are indicated by other means (bitpos == -1)
+ */
+
+#define TYPE_FLAG_STATIC (1 << 4)
+
+/* Constant type. If this is set, the corresponding type has a
+ * const modifier.
+ */
+
+#define TYPE_FLAG_CONST (1 << 5)
+
+/* Volatile type. If this is set, the corresponding type has a
+ * volatile modifier.
+ */
+
+#define TYPE_FLAG_VOLATILE (1 << 6)
+
+
+/* This is a function type which appears to have a prototype. We need this
+ for function calls in order to tell us if it's necessary to coerce the args,
+ or to just do the standard conversions. This is used with a short field. */
+
+#define TYPE_FLAG_PROTOTYPED (1 << 7)
+
+/* This flag is used to indicate that processing for this type
+ is incomplete.
+
+ (Mostly intended for HP platforms, where class methods, for
+ instance, can be encountered before their classes in the debug
+ info; the incomplete type has to be marked so that the class and
+ the method can be assigned correct types.) */
+
+#define TYPE_FLAG_INCOMPLETE (1 << 8)
+
+
struct type
{
@@ -239,9 +288,15 @@ struct type
struct type *reference_type;
+ /* C-v variant chain. This points to a type that
+ differs from this one only in a const or volatile
+ attribute (or both). The various c-v variants
+ are chained together in a ring. */
+ struct type *cv_type;
+
/* Flags about this type. */
- short flags;
+ int flags;
/* Number of fields described for this type */
@@ -266,25 +321,38 @@ struct type
struct field
{
- /* Position of this field, counting in bits from start of
- containing structure. For a function type, this is the
- position in the argument list of this argument.
- For a range bound or enum value, this is the value itself.
- (FIXME: What about ranges larger than host int size?)
- For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
- For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB. */
- int bitpos;
+
+ union field_location
+ {
+ /* Position of this field, counting in bits from start of
+ containing structure.
+ For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
+ For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
+ For a function type, this is the position in the argument list
+ of this argument.
+ For a range bound or enum value, this is the value itself. */
+
+ int bitpos;
+
+ /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr
+ is the location (in the target) of the static field.
+ Otherwise, physname is the mangled label of the static field. */
+
+ CORE_ADDR physaddr;
+ char* physname;
+ } loc;
/* Size of this field, in bits, or zero if not packed.
For an unpacked field, the field's type's length
- says how many bytes the field occupies. */
- /* FIXME: This is abused by TYPE_FIELD_STATIC_PHYSNAME to contain
- a pointer, so it has to be long. */
+ says how many bytes the field occupies.
+ A value of -1 or -2 indicates a static field; -1 means the location
+ is specified by the label loc.physname; -2 means that loc.physaddr
+ specifies the actual address. */
- long bitsize;
+ int bitsize;
- /* In a struct or enum type, type of this field.
+ /* In a struct or union type, type of this field.
In a function type, type of this argument.
In an array type, the domain-type of the array. */
@@ -297,11 +365,14 @@ struct type
} *fields;
- /* For types with virtual functions, VPTR_BASETYPE is the base class which
- defined the virtual function table pointer.
+ /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
+ is the base class which defined the virtual function table pointer.
- For types that are pointer to member types, VPTR_BASETYPE
- is the type that this pointer is a member of.
+ For types that are pointer to member types (TYPE_CODE_MEMBER),
+ VPTR_BASETYPE is the type that this pointer is a member of.
+
+ For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate
+ type that contains the method.
Unused otherwise. */
@@ -321,7 +392,11 @@ struct type
union type_specific
{
- /* ARG_TYPES is for TYPE_CODE_METHOD and TYPE_CODE_FUNC. */
+ /* ARG_TYPES is for TYPE_CODE_METHOD.
+ Contains the type of each argument, ending with a void type
+ after the last argument for normal member functions or a NULL
+ pointer after the last argument for functions with variable
+ arguments. */
struct type **arg_types;
@@ -356,8 +431,22 @@ struct cplus_struct_type
/* Number of methods described for this type, not including the
methods that it derives from. */
- int nfn_fields_total;
-
+ short nfn_fields_total;
+
+ /* The "declared_type" field contains a code saying how the
+ user really declared this type, e.g., "class s", "union s",
+ "struct s".
+ The 3 above things come out from the C++ compiler looking like classes,
+ but we keep track of the real declaration so we can give
+ the correct information on "ptype". (Note: TEMPLATE may not
+ belong in this list...) */
+
+#define DECLARED_TYPE_CLASS 0
+#define DECLARED_TYPE_UNION 1
+#define DECLARED_TYPE_STRUCT 2
+#define DECLARED_TYPE_TEMPLATE 3
+ short declared_type; /* One of the above codes */
+
/* For derived classes, the number of base classes is given by n_baseclasses
and virtual_field_bits is a bit vector containing one bit per base class.
If the base class is virtual, the corresponding bit will be set.
@@ -427,7 +516,11 @@ struct cplus_struct_type
char *physname;
- /* The return value of the method */
+ /* The function type for the method.
+ (This comment used to say "The return value of the method",
+ but that's wrong. The function type
+ is expected here, i.e. something with TYPE_CODE_FUNC,
+ and *not* the return-value type). */
struct type *type;
@@ -449,18 +542,27 @@ struct cplus_struct_type
unsigned int is_volatile : 1;
unsigned int is_private : 1;
unsigned int is_protected : 1;
+ unsigned int is_public : 1;
+ unsigned int is_abstract : 1;
+ unsigned int is_static : 1;
+ unsigned int is_final : 1;
+ unsigned int is_synchronized : 1;
+ unsigned int is_native : 1;
/* A stub method only has some fields valid (but they are enough
to reconstruct the rest of the fields). */
unsigned int is_stub : 1;
+ /* C++ method that is inlined */
+ unsigned int is_inlined : 1;
+
/* Unused. */
- unsigned int dummy : 3;
+ unsigned int dummy : 4;
/* Index into that baseclass's virtual function table,
minus 2; else if static: VOFFSET_STATIC; else: 0. */
- unsigned int voffset : 24;
+ unsigned int voffset : 16;
# define VOFFSET_STATIC 1
@@ -468,6 +570,72 @@ struct cplus_struct_type
} *fn_fieldlists;
+ /* If this "struct type" describes a template, then it
+ * has arguments. "template_args" points to an array of
+ * template arg descriptors, of length "ntemplate_args".
+ * The only real information in each of these template arg descriptors
+ * is a name. "type" will typically just point to a "struct type" with
+ * the placeholder TYPE_CODE_TEMPLATE_ARG type.
+ */
+ short ntemplate_args;
+ struct template_arg
+ {
+ char *name;
+ struct type *type;
+ } *template_args;
+
+ /* If this "struct type" describes a template, it has a list
+ * of instantiations. "instantiations" is a pointer to an array
+ * of type's, one representing each instantiation. There
+ * are "ninstantiations" elements in this array.
+ */
+ short ninstantiations;
+ struct type **instantiations;
+
+ /* The following points to information relevant to the runtime model
+ * of the compiler.
+ * Currently being used only for HP's ANSI C++ compiler.
+ * (This type may have to be changed/enhanced for other compilers.)
+ *
+ * RUNTIME_PTR is NULL if there is no runtime information (currently
+ * this means the type was not compiled by HP aCC).
+ *
+ * Fields in structure pointed to:
+ * ->HAS_VTABLE : 0 => no virtual table, 1 => vtable present
+ *
+ * ->PRIMARY_BASE points to the first non-virtual base class that has
+ * a virtual table.
+ *
+ * ->VIRTUAL_BASE_LIST points to a list of struct type * pointers that
+ * point to the type information for all virtual bases among this type's
+ * ancestors.
+ */
+ struct runtime_info {
+ short has_vtable;
+ struct type * primary_base;
+ struct type ** virtual_base_list;
+ } * runtime_ptr;
+
+ /* Pointer to information about enclosing scope, if this is a
+ * local type. If it is not a local type, this is NULL
+ */
+ struct local_type_info {
+ char * file;
+ int line;
+ } * localtype_ptr;
+};
+
+/* Struct used in computing virtual base list */
+struct vbase
+{
+ struct type * vbasetype; /* pointer to virtual base */
+ struct vbase * next; /* next in chain */
+};
+
+/* Struct used for ranking a function for overload resolution */
+struct badness_vector {
+ int length;
+ int * rank;
};
/* The default value of TYPE_CPLUS_SPECIFIC(T) points to the
@@ -489,6 +657,7 @@ allocate_cplus_struct_type PARAMS ((struct type *));
#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type
#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
+#define TYPE_CV_TYPE(thistype) (thistype)->cv_type
/* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
so you only have to call check_typedef once. Since allocate_value
@@ -497,11 +666,17 @@ allocate_cplus_struct_type PARAMS ((struct type *));
#define TYPE_OBJFILE(thistype) (thistype)->objfile
#define TYPE_FLAGS(thistype) (thistype)->flags
#define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED)
+#define TYPE_NOSIGN(thistype) ((thistype)->flags & TYPE_FLAG_NOSIGN)
+#define TYPE_CONST(thistype) ((thistype)->flags & TYPE_FLAG_CONST)
+#define TYPE_VOLATILE(thistype) ((thistype)->flags & TYPE_FLAG_VOLATILE)
+#define TYPE_INCOMPLETE(thistype) ((thistype)->flags & TYPE_FLAG_INCOMPLETE)
/* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you wan the real
type, you need to do TYPE_CODE (check_type (this_type)). */
#define TYPE_CODE(thistype) (thistype)->code
#define TYPE_NFIELDS(thistype) (thistype)->nfields
#define TYPE_FIELDS(thistype) (thistype)->fields
+#define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args
+#define TYPE_INSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->instantiations
#define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
#define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0)
@@ -526,24 +701,41 @@ allocate_cplus_struct_type PARAMS ((struct type *));
#define TYPE_FN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fields
#define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields
#define TYPE_NFN_FIELDS_TOTAL(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields_total
+#define TYPE_NTEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ntemplate_args
+#define TYPE_NINSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ninstantiations
+#define TYPE_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type
#define TYPE_TYPE_SPECIFIC(thistype) (thistype)->type_specific
#define TYPE_ARG_TYPES(thistype) (thistype)->type_specific.arg_types
#define TYPE_CPLUS_SPECIFIC(thistype) (thistype)->type_specific.cplus_stuff
#define TYPE_BASECLASS(thistype,index) (thistype)->fields[index].type
#define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
#define TYPE_BASECLASS_NAME(thistype,index) (thistype)->fields[index].name
-#define TYPE_BASECLASS_BITPOS(thistype,index) (thistype)->fields[index].bitpos
-#define BASETYPE_VIA_PUBLIC(thistype, index) (!TYPE_FIELD_PRIVATE(thistype, index))
-#define BASETYPE_VIA_VIRTUAL(thistype, index) \
- B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (index))
+#define TYPE_BASECLASS_BITPOS(thistype,index) TYPE_FIELD_BITPOS(thistype,index)
+#define BASETYPE_VIA_PUBLIC(thistype, index) \
+ ((!TYPE_FIELD_PRIVATE(thistype, index)) && (!TYPE_FIELD_PROTECTED(thistype, index)))
+#define BASETYPE_VIA_VIRTUAL(thistype, index) \
+ (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (index)))
+
+#define FIELD_TYPE(thisfld) ((thisfld).type)
+#define FIELD_NAME(thisfld) ((thisfld).name)
+#define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos)
+#define FIELD_BITSIZE(thisfld) ((thisfld).bitsize)
+#define FIELD_PHYSNAME(thisfld) ((thisfld).loc.physname)
+#define FIELD_PHYSADDR(thisfld) ((thisfld).loc.physaddr)
+#define SET_FIELD_PHYSNAME(thisfld, name) \
+ ((thisfld).bitsize = -1, FIELD_PHYSNAME(thisfld) = (name))
+#define SET_FIELD_PHYSADDR(thisfld, name) \
+ ((thisfld).bitsize = -2, FIELD_PHYSADDR(thisfld) = (name))
#define TYPE_FIELD(thistype, n) (thistype)->fields[n]
-#define TYPE_FIELD_TYPE(thistype, n) (thistype)->fields[n].type
-#define TYPE_FIELD_NAME(thistype, n) (thistype)->fields[n].name
-#define TYPE_FIELD_VALUE(thistype, n) (* (int*) &(thistype)->fields[n].type)
-#define TYPE_FIELD_BITPOS(thistype, n) (thistype)->fields[n].bitpos
-#define TYPE_FIELD_BITSIZE(thistype, n) (thistype)->fields[n].bitsize
-#define TYPE_FIELD_PACKED(thistype, n) (thistype)->fields[n].bitsize
+#define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS(TYPE_FIELD(thistype,n))
+#define TYPE_FIELD_BITSIZE(thistype, n) FIELD_BITSIZE(TYPE_FIELD(thistype,n))
+#define TYPE_FIELD_PACKED(thistype, n) (FIELD_BITSIZE(TYPE_FIELD(thistype,n))!=0)
+#define TYPE_TEMPLATE_ARG(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->template_args[n]
+#define TYPE_INSTANTIATION(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->instantiations[n]
#define TYPE_FIELD_PRIVATE_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits
@@ -571,10 +763,13 @@ allocate_cplus_struct_type PARAMS ((struct type *));
(TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits == NULL ? 0 \
: B_TST(TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits, (n)))
#define TYPE_FIELD_VIRTUAL(thistype, n) \
- B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
+ (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)))
-#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1)
-#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize)
+#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitsize < 0)
+#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) ((thistype)->fields[n].bitsize == -2)
+#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_PHYSADDR(TYPE_FIELD(thistype, n))
#define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists
#define TYPE_FN_FIELDLIST(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n]
@@ -590,12 +785,37 @@ allocate_cplus_struct_type PARAMS ((struct type *));
#define TYPE_FN_FIELD_VOLATILE(thisfn, n) ((thisfn)[n].is_volatile)
#define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private)
#define TYPE_FN_FIELD_PROTECTED(thisfn, n) ((thisfn)[n].is_protected)
+#define TYPE_FN_FIELD_PUBLIC(thisfn, n) ((thisfn)[n].is_public)
+#define TYPE_FN_FIELD_STATIC(thisfn, n) ((thisfn)[n].is_static)
+#define TYPE_FN_FIELD_FINAL(thisfn, n) ((thisfn)[n].is_final)
+#define TYPE_FN_FIELD_SYNCHRONIZED(thisfn, n) ((thisfn)[n].is_synchronized)
+#define TYPE_FN_FIELD_NATIVE(thisfn, n) ((thisfn)[n].is_native)
+#define TYPE_FN_FIELD_ABSTRACT(thisfn, n) ((thisfn)[n].is_abstract)
#define TYPE_FN_FIELD_STUB(thisfn, n) ((thisfn)[n].is_stub)
+#define TYPE_FN_FIELD_INLINED(thisfn, n) ((thisfn)[n].is_inlined)
#define TYPE_FN_FIELD_FCONTEXT(thisfn, n) ((thisfn)[n].fcontext)
#define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2)
#define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
#define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
+#define TYPE_RUNTIME_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->runtime_ptr)
+#define TYPE_VTABLE(thistype) (TYPE_RUNTIME_PTR(thistype)->has_vtable)
+#define TYPE_HAS_VTABLE(thistype) (TYPE_RUNTIME_PTR(thistype) && TYPE_VTABLE(thistype))
+#define TYPE_PRIMARY_BASE(thistype) (TYPE_RUNTIME_PTR(thistype)->primary_base)
+#define TYPE_VIRTUAL_BASE_LIST(thistype) (TYPE_RUNTIME_PTR(thistype)->virtual_base_list)
+
+#define TYPE_LOCALTYPE_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr)
+#define TYPE_LOCALTYPE_FILE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->file)
+#define TYPE_LOCALTYPE_LINE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->line)
+
+#define TYPE_IS_OPAQUE(thistype) (((TYPE_CODE (thistype) == TYPE_CODE_STRUCT) || \
+ (TYPE_CODE (thistype) == TYPE_CODE_UNION)) && \
+ (TYPE_NFIELDS (thistype) == 0) && \
+ (TYPE_CPLUS_SPECIFIC (thistype) && (TYPE_NFN_FIELDS (thistype) == 0)))
+
+
+
+/* Implicit sizes */
extern struct type *builtin_type_void;
extern struct type *builtin_type_char;
extern struct type *builtin_type_short;
@@ -612,6 +832,17 @@ extern struct type *builtin_type_long_double;
extern struct type *builtin_type_complex;
extern struct type *builtin_type_double_complex;
extern struct type *builtin_type_string;
+extern struct type *builtin_type_bool;
+
+/* Explicit sizes - see <intypes.h> for naming schema */
+extern struct type *builtin_type_int8;
+extern struct type *builtin_type_uint8;
+extern struct type *builtin_type_int16;
+extern struct type *builtin_type_uint16;
+extern struct type *builtin_type_int32;
+extern struct type *builtin_type_uint32;
+extern struct type *builtin_type_int64;
+extern struct type *builtin_type_uint64;
/* This type represents a type that was unrecognized in symbol
read-in. */
@@ -654,6 +885,9 @@ extern struct type *builtin_type_f_complex_s16;
extern struct type *builtin_type_f_complex_s32;
extern struct type *builtin_type_f_void;
+/* RTTI for C++ */
+/* extern struct type *builtin_type_cxx_typeinfo; */
+
/* Maximum and minimum values of built-in types */
#define MAX_OF_TYPE(t) \
@@ -691,6 +925,9 @@ extern struct type *
make_reference_type PARAMS ((struct type *, struct type **));
extern struct type *
+make_cv_type PARAMS ((int, int, struct type *, struct type **));
+
+extern struct type *
lookup_member_type PARAMS ((struct type *, struct type *));
extern void
@@ -769,8 +1006,113 @@ lookup_fundamental_type PARAMS ((struct objfile *, int));
extern void
fill_in_vptr_fieldno PARAMS ((struct type *));
+extern int get_destructor_fn_field PARAMS ((struct type *, int *, int *));
+
extern int get_discrete_bounds PARAMS ((struct type*, LONGEST*, LONGEST*));
+extern int
+is_ancestor PARAMS ((struct type *, struct type *));
+
+extern int
+has_vtable PARAMS ((struct type *));
+
+extern struct type *
+primary_base_class PARAMS ((struct type *));
+
+extern struct type **
+virtual_base_list PARAMS ((struct type *));
+
+extern int
+virtual_base_list_length PARAMS ((struct type *));
+extern int
+virtual_base_list_length_skip_primaries PARAMS ((struct type *));
+
+extern int
+virtual_base_index PARAMS ((struct type *, struct type *));
+extern int
+virtual_base_index_skip_primaries PARAMS ((struct type *, struct type *));
+
+
+extern int
+class_index_in_primary_list PARAMS ((struct type *));
+
+extern int
+count_virtual_fns PARAMS ((struct type*));
+
+/* Constants for HP/Taligent ANSI C++ runtime model */
+
+/* Where virtual function entries begin in the
+ * virtual table, in the non-RRBC vtable format.
+ * First 4 are the metavtable pointer, top offset,
+ * typeinfo pointer, and dup base info pointer */
+#define HP_ACC_VFUNC_START 4
+
+/* (Negative) Offset where virtual base offset entries begin
+ * in the virtual table. Skips over metavtable pointer and
+ * the self-offset entry.
+ * NOTE: NEGATE THIS BEFORE USING! The virtual base offsets
+ * appear before the address point of the vtable (the slot
+ * pointed to by the object's vtable pointer), i.e. at lower
+ * addresses than the vtable pointer. */
+#define HP_ACC_VBASE_START 2
+
+/* (Positive) Offset where the pointer to the typeinfo
+ * object is present in the virtual table */
+#define HP_ACC_TYPEINFO_OFFSET 2
+
+/* (Positive) Offset where the ``top offset'' entry of
+ * the virtual table is */
+#define HP_ACC_TOP_OFFSET_OFFSET 1
+
+/* Overload resolution */
+
+#define LENGTH_MATCH(bv) ((bv)->rank[0])
+
+/* Badness if parameter list length doesn't match arg list length */
+#define LENGTH_MISMATCH_BADNESS 100
+/* Dummy badness value for nonexistent parameter positions */
+#define TOO_FEW_PARAMS_BADNESS 100
+/* Badness if no conversion among types */
+#define INCOMPATIBLE_TYPE_BADNESS 100
+/* Badness of coercing large integer to smaller size */
+#define INTEGER_COERCION_BADNESS 100
+/* Badness of coercing large floating type to smaller size */
+#define FLOAT_COERCION_BADNESS 100
+
+/* Badness of integral promotion */
+#define INTEGER_PROMOTION_BADNESS 1
+/* Badness of floating promotion */
+#define FLOAT_PROMOTION_BADNESS 1
+/* Badness of integral conversion */
+#define INTEGER_CONVERSION_BADNESS 2
+/* Badness of floating conversion */
+#define FLOAT_CONVERSION_BADNESS 2
+/* Badness of integer<->floating conversions */
+#define INT_FLOAT_CONVERSION_BADNESS 2
+/* Badness of converting to a boolean */
+#define BOOLEAN_CONVERSION_BADNESS 2
+/* Badness of pointer conversion */
+#define POINTER_CONVERSION_BADNESS 2
+/* Badness of conversion of pointer to void pointer */
+#define VOID_PTR_CONVERSION_BADNESS 2
+/* Badness of convering derived to base class */
+#define BASE_CONVERSION_BADNESS 2
+
+/* Non-standard conversions allowed by the debugger */
+/* Converting a pointer to an int is usually OK */
+#define NS_POINTER_CONVERSION_BADNESS 10
+
+
+extern int
+compare_badness PARAMS ((struct badness_vector *, struct badness_vector *));
+
+extern struct badness_vector *
+rank_function PARAMS ((struct type **, int, struct type **, int));
+
+extern int
+rank_one_type PARAMS ((struct type *, struct type *));
+
+
#if MAINTENANCE_CMDS
extern void recursive_dump_type PARAMS ((struct type *, int));
#endif
@@ -786,4 +1128,8 @@ extern int can_dereference PARAMS ((struct type *));
extern void maintenance_print_type PARAMS ((char *, int));
#endif
+/* typeprint.c */
+
+extern void print_type_scalar PARAMS ((struct type *, LONGEST, GDB_FILE *));
+
#endif /* GDBTYPES_H */
diff --git a/contrib/gdb/gdb/gnu-nat.c b/contrib/gdb/gdb/gnu-nat.c
index 2d9cbed..156d981 100644
--- a/contrib/gdb/gdb/gnu-nat.c
+++ b/contrib/gdb/gdb/gnu-nat.c
@@ -1,5 +1,5 @@
/* Interface GDB to the GNU Hurd
- Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of GDB.
@@ -49,6 +49,8 @@
#include <hurd/interrupt.h>
#include <hurd/sigpreempt.h>
+#include <portinfo.h>
+
#include "defs.h"
#include "inferior.h"
#include "symtab.h"
@@ -65,7 +67,6 @@
#include "notify_S.h"
#include "process_reply_S.h"
#include "msg_reply_S.h"
-
#include "exc_request_U.h"
#include "msg_U.h"
@@ -83,20 +84,22 @@ int gnu_debug_flag = 0;
/* Forward decls */
extern struct target_ops gnu_ops;
+extern char *strerror();
+int inf_update_procs (struct inf *inf);
struct inf *make_inf ();
void inf_clear_wait (struct inf *inf);
void inf_cleanup (struct inf *inf);
-void inf_startup (struct inf *inf, int pid, task_t task);
+void inf_startup (struct inf *inf, int pid);
int inf_update_suspends (struct inf *inf);
-void inf_set_task (struct inf *inf, task_t port);
+void inf_set_pid (struct inf *inf, pid_t pid);
void inf_validate_procs (struct inf *inf);
void inf_steal_exc_ports (struct inf *inf);
void inf_restore_exc_ports (struct inf *inf);
-int inf_update_procs (struct inf *inf);
struct proc *inf_tid_to_proc (struct inf *inf, int tid);
-inline void inf_set_threads_resume_sc (struct inf *inf, struct proc
- *run_thread, int run_others);
+inline void inf_set_threads_resume_sc (struct inf *inf,
+ struct proc *run_thread,
+ int run_others);
inline int inf_set_threads_resume_sc_for_signal_thread (struct inf *inf);
inline void inf_suspend (struct inf *inf);
inline void inf_resume (struct inf *inf);
@@ -109,11 +112,11 @@ void inf_signal (struct inf *inf, enum target_signal sig);
do { struct inf *__inf = (_inf); \
debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0)
+void proc_abort (struct proc *proc, int force);
+thread_state_t proc_get_state (struct proc *proc, int force);
struct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
struct proc *_proc_free (struct proc *proc);
int proc_update_sc (struct proc *proc);
-void proc_abort (struct proc *proc, int force);
-thread_state_t proc_get_state (struct proc *proc, int force);
error_t proc_get_exception_port (struct proc *proc, mach_port_t *port);
error_t proc_set_exception_port (struct proc *proc, mach_port_t port);
static mach_port_t _proc_get_exc_port (struct proc *proc);
@@ -217,10 +220,14 @@ struct inf
(pausing individual threads as necessary). */
int pause_sc;
+ /* The task suspend count left when detaching from a task. */
+ int detach_sc;
+
/* The initial values used for the run_sc and pause_sc of newly discovered
threads -- see the definition of those fields in struct proc. */
int default_thread_run_sc;
int default_thread_pause_sc;
+ int default_thread_detach_sc;
/* True if the process should be traced when started/attached. Newly
started processes *must* be traced at first to exec them properly, but
@@ -232,6 +239,7 @@ struct inf
int want_exceptions;
};
+
int __proc_pid (struct proc *proc)
{
return proc->inf->pid;
@@ -255,7 +263,7 @@ proc_update_sc (struct proc *proc)
assert (proc_is_thread (proc));
proc_debug (proc, "storing back changed thread state");
err = thread_set_state (proc->port, THREAD_STATE_FLAVOR,
- &proc->state, THREAD_STATE_SIZE);
+ (thread_state_t)&proc->state, THREAD_STATE_SIZE);
if (! err)
proc->state_changed = 0;
}
@@ -353,7 +361,7 @@ proc_get_state (struct proc *proc, int will_modify)
mach_msg_type_number_t state_size = THREAD_STATE_SIZE;
error_t err =
thread_get_state (proc->port, THREAD_STATE_FLAVOR,
- &proc->state, &state_size);
+ (thread_state_t)&proc->state, &state_size);
proc_debug (proc, "getting thread state");
proc->state_valid = !err;
}
@@ -362,12 +370,13 @@ proc_get_state (struct proc *proc, int will_modify)
{
if (will_modify)
proc->state_changed = 1;
- return &proc->state;
+ return (thread_state_t)&proc->state;
}
else
return 0;
}
+/* Set PORT to PROC's exception port. */
error_t
proc_get_exception_port (struct proc *proc, mach_port_t *port)
{
@@ -377,6 +386,7 @@ proc_get_exception_port (struct proc *proc, mach_port_t *port)
return thread_get_exception_port (proc->port, port);
}
+/* Set PROC's exception port to PORT. */
error_t
proc_set_exception_port (struct proc *proc, mach_port_t port)
{
@@ -450,9 +460,9 @@ proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
}
}
-/* If we previously replaced PROC's exception port, put back what we found
- there at the time, unless *our* exception port has since be overwritten,
- in which case who knows what's going on. */
+/* If we previously replaced PROC's exception port, put back what we
+ found there at the time, unless *our* exception port has since been
+ overwritten, in which case who knows what's going on. */
void
proc_restore_exc_port (struct proc *proc)
{
@@ -480,7 +490,7 @@ proc_restore_exc_port (struct proc *proc)
}
}
-/* Turns hardware tracing in PROC on or off when SET is true or fals,
+/* Turns hardware tracing in PROC on or off when SET is true or false,
respectively. Returns true on success. */
int
proc_trace (struct proc *proc, int set)
@@ -524,12 +534,19 @@ make_proc (struct inf *inf, mach_port_t port, int tid)
proc->next = 0;
proc->saved_exc_port = MACH_PORT_NULL;
proc->exc_port = MACH_PORT_NULL;
+
proc->sc = 0;
proc->cur_sc = 0;
+
+ /* Note that these are all the values for threads; the task simply uses the
+ corresponding field in INF directly. */
proc->run_sc = inf->default_thread_run_sc;
proc->pause_sc = inf->default_thread_pause_sc;
+ proc->detach_sc = inf->default_thread_detach_sc;
proc->resume_sc = proc->run_sc;
+
proc->aborted = 0;
+ proc->dead = 0;
proc->state_valid = 0;
proc->state_changed = 0;
@@ -563,8 +580,8 @@ make_proc (struct inf *inf, mach_port_t port, int tid)
return proc;
}
-/* Frees PROC and any resources it uses, and returns the value of PROC's next
- field. */
+/* Frees PROC and any resources it uses, and returns the value of PROC's
+ next field. */
struct proc *
_proc_free (struct proc *proc)
{
@@ -623,14 +640,17 @@ struct inf *make_inf ()
inf->no_wait = 0;
inf->pending_execs = 0;
inf->pause_sc = 1;
+ inf->detach_sc = 0;
inf->default_thread_run_sc = 0;
inf->default_thread_pause_sc = 0;
+ inf->default_thread_detach_sc = 0;
inf->want_signals = 1; /* By default */
inf->want_exceptions = 1; /* By default */
return inf;
}
+/* clear INF's target wait status. */
void
inf_clear_wait (struct inf *inf)
{
@@ -657,7 +677,7 @@ inf_cleanup (struct inf *inf)
inf_clear_wait (inf);
- inf_set_task (inf, MACH_PORT_NULL);
+ inf_set_pid (inf, -1);
inf->pid = 0;
inf->traced = 0;
inf->no_wait = 0;
@@ -673,11 +693,11 @@ inf_cleanup (struct inf *inf)
}
void
-inf_startup (struct inf *inf, int pid, task_t task)
+inf_startup (struct inf *inf, int pid)
{
error_t err;
- inf_debug (inf, "startup: pid = %d, task = %d", pid, task);
+ inf_debug (inf, "startup: pid = %d", pid);
inf_cleanup (inf);
@@ -690,39 +710,53 @@ inf_startup (struct inf *inf, int pid, task_t task)
/* Make a send right for it, so we can easily copy it for other people. */
mach_port_insert_right (mach_task_self (), inf->event_port,
inf->event_port, MACH_MSG_TYPE_MAKE_SEND);
-
- if (inf->pause_sc)
- task_suspend (task);
-
- inf_set_task (inf, task);
-
- if (inf->task)
- {
- inf->pid = pid;
- if (inf->pause_sc)
- inf->task->sc = inf->task->cur_sc = 1; /* Reflect task_suspend above */
- }
+ inf_set_pid (inf, pid);
}
+/* close current process, if any, and attach INF to process PORT */
void
-inf_set_task (struct inf *inf, mach_port_t port)
+inf_set_pid (struct inf *inf, pid_t pid)
{
+ task_t task_port;
struct proc *task = inf->task;
- inf_debug (inf, "setting task: %d", port);
+ inf_debug (inf, "setting pid: %d", pid);
+
+ if (pid < 0)
+ task_port = MACH_PORT_NULL;
+ else
+ {
+ error_t err = proc_pid2task (proc_server, pid, &task_port);
+ if (err)
+ error ("Error getting task for pid %d: %s", pid, strerror (err));
+ }
+
+ inf_debug (inf, "setting task: %d", task_port);
- if (task && task->port != port)
+ if (inf->pause_sc)
+ task_suspend (task_port);
+
+ if (task && task->port != task_port)
{
inf->task = 0;
inf_validate_procs (inf); /* Trash all the threads. */
_proc_free (task); /* And the task. */
}
- if (port != MACH_PORT_NULL)
+ if (task_port != MACH_PORT_NULL)
{
- inf->task = make_proc (inf, port, PROC_TID_TASK);
+ inf->task = make_proc (inf, task_port, PROC_TID_TASK);
inf->threads_up_to_date = 0;
}
+
+ if (inf->task)
+ {
+ inf->pid = pid;
+ if (inf->pause_sc)
+ inf->task->sc = inf->task->cur_sc = 1; /* Reflect task_suspend above */
+ }
+ else
+ inf->pid = -1;
}
/* Validates INF's stopped field from the actual proc server state. */
@@ -733,8 +767,9 @@ inf_validate_stopped (struct inf *inf)
mach_msg_type_number_t noise_len = 0;
struct procinfo *pi;
mach_msg_type_number_t pi_len = 0;
+ int info_flags = 0;
error_t err =
- proc_getprocinfo (proc_server, inf->pid, 0,
+ proc_getprocinfo (proc_server, inf->pid, &info_flags,
(procinfo_t *)&pi, &pi_len, &noise, &noise_len);
if (! err)
@@ -746,17 +781,31 @@ inf_validate_stopped (struct inf *inf)
}
}
-/* Validates INF's task suspend count. */
+/* Validates INF's task suspend count. If it's higher than we expect, verify
+ with the user before `stealing' the extra count. */
static void
inf_validate_task_sc (struct inf *inf)
{
struct task_basic_info info;
mach_msg_type_number_t info_len = TASK_BASIC_INFO_COUNT;
- error_t err = task_info (inf->task->port, TASK_BASIC_INFO, &info, &info_len);
- if (! err)
+ error_t err =
+ task_info (inf->task->port, TASK_BASIC_INFO, (task_info_t)&info, &info_len);
+
+ if (err)
+ inf->task->dead = 1; /* oh well */
+ else if (inf->task->cur_sc < info.suspend_count)
{
- if (inf->task->cur_sc < info.suspend_count)
- warning ("Pid %d is suspended; continuing will clear existing suspend count.", inf->pid);
+ int abort;
+
+ target_terminal_ours (); /* Allow I/O. */
+ abort =
+ !query ("Pid %d has an additional task suspend count of %d; clear it? ",
+ inf->pid, info.suspend_count - inf->task->cur_sc);
+ target_terminal_inferior (); /* Give it back to the child. */
+
+ if (abort)
+ error ("Additional task suspend count left untouched.");
+
inf->task->cur_sc = info.suspend_count;
}
}
@@ -768,16 +817,20 @@ void
inf_set_traced (struct inf *inf, int on)
{
if (on != inf->traced)
- if (inf->task)
+ if (inf->task && !inf->task->dead)
/* Make it take effect immediately. */
{
- error_t (*f)(mach_port_t, mach_port_t, int) =
- on ? msg_set_some_exec_flags : msg_clear_some_exec_flags;
+ sigset_t mask = on ? ~(sigset_t)0 : 0;
error_t err =
- INF_RESUME_MSGPORT_RPC (inf, (*f)(msgport, refport, EXEC_TRACED));
+ INF_RESUME_MSGPORT_RPC (inf, msg_set_init_int (msgport, refport,
+ INIT_TRACEMASK, mask));
if (err == EIEIO)
- warning ("Can't modify tracing state for pid %d: No signal thread",
- inf->pid);
+ {
+ if (on)
+ warning ("Can't modify tracing state for pid %d: No signal thread",
+ inf->pid);
+ inf->traced = on;
+ }
else if (err)
warning ("Can't modify tracing state for pid %d: %s",
inf->pid, strerror (err));
@@ -845,6 +898,7 @@ struct proc *
inf_tid_to_thread (struct inf *inf, int tid)
{
struct proc *thread = inf->threads;
+
while (thread)
if (thread->tid == tid)
return thread;
@@ -875,7 +929,11 @@ inf_validate_procs (struct inf *inf)
unsigned num_threads;
struct proc *task = inf->task;
- inf->threads_up_to_date = !inf->running;
+ /* If no threads are currently running, this function will guarantee that
+ things are up to date. The exception is if there are zero threads --
+ then it is almost certainly in an odd state, and probably some outside
+ agent will create threads. */
+ inf->threads_up_to_date = inf->threads ? !inf->running : 0;
if (task)
{
@@ -884,9 +942,8 @@ inf_validate_procs (struct inf *inf)
if (err)
/* TASK must be dead. */
{
- task->port = MACH_PORT_NULL;
- _proc_free (task);
- task = inf->task = 0;
+ task->dead = 1;
+ task = 0;
}
}
@@ -996,7 +1053,14 @@ inf_resume (struct inf *inf)
thread->sc = thread->resume_sc;
if (inf->task)
- inf->task->sc = 0;
+ {
+ if (! inf->pending_execs)
+ /* Try to make sure our task count is correct -- in the case where
+ we're waiting for an exec though, things are too volatile, so just
+ assume things will be reasonable (which they usually will be). */
+ inf_validate_task_sc (inf);
+ inf->task->sc = 0;
+ }
inf_update_suspends (inf);
}
@@ -1019,9 +1083,9 @@ inf_suspend (struct inf *inf)
inf_update_suspends (inf);
}
-/* INF has one thread PROC that is in single-stepping mode. This functions
+/* INF has one thread PROC that is in single-stepping mode. This function
changes it to be PROC, changing any old step_thread to be a normal one. A
- PROC of 0 clears an any existing value. */
+ PROC of 0 clears any existing value. */
void
inf_set_step_thread (struct inf *inf, struct proc *thread)
{
@@ -1087,12 +1151,12 @@ inf_detach (struct inf *inf)
inf_signal (inf, TARGET_SIGNAL_0);
proc_restore_exc_port (task);
- task->sc = 0;
+ task->sc = inf->detach_sc;
for (thread = inf->threads; thread; thread = thread->next)
{
proc_restore_exc_port (thread);
- thread->sc = 0;
+ thread->sc = thread->detach_sc;
}
inf_update_suspends (inf);
@@ -1106,19 +1170,12 @@ inf_detach (struct inf *inf)
void
inf_attach (struct inf *inf, int pid)
{
- error_t err;
- task_t task;
-
inf_debug (inf, "attaching: %d", pid);
- err = proc_pid2task (proc_server, pid, &task);
- if (err)
- error ("Error getting task for pid %d: %s", pid, strerror (err));
-
if (inf->pid)
inf_detach (inf);
- inf_startup (inf, pid, task);
+ inf_startup (inf, pid);
}
/* Makes sure that we've got our exception ports entrenched in the process. */
@@ -1188,12 +1245,12 @@ inf_signal (struct inf *inf, enum target_signal sig)
e->exception, e->code, e->subcode);
}
else
- warning ("Can't forward spontaneous exception (%s).", NAME);
+ error ("Can't forward spontaneous exception (%s).", NAME);
}
else
/* A Unix signal. */
if (inf->stopped)
- /* The process is stopped an expecting a signal. Just send off a
+ /* The process is stopped and expecting a signal. Just send off a
request and let it get handled when we resume everything. */
{
inf_debug (inf, "sending %s to stopped process", NAME);
@@ -1202,7 +1259,7 @@ inf_signal (struct inf *inf, enum target_signal sig)
msg_sig_post_untraced_request (msgport,
inf->event_port,
MACH_MSG_TYPE_MAKE_SEND_ONCE,
- host_sig,
+ host_sig, 0,
refport));
if (! err)
/* Posting an untraced signal automatically continues it.
@@ -1220,9 +1277,8 @@ inf_signal (struct inf *inf, enum target_signal sig)
{
inf_debug (inf, "sending %s to unstopped process (so resuming signal thread)", NAME);
err =
- INF_RESUME_MSGPORT_RPC (inf,
- msg_sig_post_untraced (msgport,
- host_sig, refport));
+ INF_RESUME_MSGPORT_RPC (inf, msg_sig_post_untraced (msgport,
+ host_sig, 0, refport));
}
if (err == EIEIO)
@@ -1254,6 +1310,18 @@ gnu_wait (int tid, struct target_waitstatus *status)
struct proc *thread;
struct inf *inf = current_inferior;
+ assert (inf->task);
+
+ if (!inf->threads && !inf->pending_execs)
+ /* No threads! Assume that maybe some outside agency is frobbing our
+ task, and really look for new threads. If we can't find any, just tell
+ the user to try again later. */
+ {
+ inf_validate_procs (inf);
+ if (!inf->threads && !inf->task->dead)
+ error ("There are no threads; try again later.");
+ }
+
waiting_inf = inf;
inf_debug (inf, "waiting for: %d", tid);
@@ -1269,7 +1337,7 @@ gnu_wait (int tid, struct target_waitstatus *status)
outstanding wait request, so we have to cancel the previous one. */
{
inf_debug (inf, "cancelling previous wait on pid %d", proc_wait_pid);
- interrupt_operation (proc_server);
+ interrupt_operation (proc_server, 0);
}
err =
@@ -1294,14 +1362,20 @@ gnu_wait (int tid, struct target_waitstatus *status)
(3) wait reply from the proc server. */
inf_debug (inf, "waiting for an event...");
- err = _hurd_intr_rpc_mach_msg (&msg.hdr, MACH_RCV_MSG, 0,
- sizeof (struct msg),
- inf->event_port, MACH_PORT_NULL);
+ err = mach_msg (&msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT,
+ 0, sizeof (struct msg), inf->event_port,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
/* Re-suspend the task. */
inf_suspend (inf);
- if (err == EINTR)
+ if (!inf->task && inf->pending_execs)
+ /* When doing an exec, it's possible that the old task wasn't reused
+ (e.g., setuid execs). So if the task seems to have disappeared,
+ attempt to refetch it, as the pid should still be the same. */
+ inf_set_pid (inf, inf->pid);
+
+ if (err == EMACH_RCV_INTERRUPTED)
inf_debug (inf, "interrupted");
else if (err)
error ("Couldn't wait for an event: %s", strerror (err));
@@ -1339,17 +1413,34 @@ gnu_wait (int tid, struct target_waitstatus *status)
/* Since gdb is actually counting the number of times the inferior
stops, expecting one stop per exec, we only return major events
while execing. */
- w->suppress = 1;
+ {
+ w->suppress = 1;
+ inf_debug (inf, "pending_execs = %d, ignoring minor event",
+ inf->pending_execs);
+ }
else if (kind == TARGET_WAITKIND_STOPPED
&& w->status.value.sig == TARGET_SIGNAL_TRAP)
/* Ah hah! A SIGTRAP from the inferior while starting up probably
means we've succesfully completed an exec! */
- if (--inf->pending_execs == 0)
- /* We're done! */
- {
- prune_threads (1); /* Get rid of the old shell threads */
- renumber_threads (0); /* Give our threads reasonable names. */
- }
+ {
+ if (--inf->pending_execs == 0)
+ /* We're done! */
+ {
+#if 0 /* do we need this? */
+ prune_threads (1); /* Get rid of the old shell threads */
+ renumber_threads (0); /* Give our threads reasonable names. */
+#endif
+ }
+ inf_debug (inf, "pending exec completed, pending_execs => %d",
+ inf->pending_execs);
+ }
+ else if (kind == TARGET_WAITKIND_STOPPED)
+ /* It's possible that this signal is because of a crashed process
+ being handled by the hurd crash server; in this case, the process
+ will have an extra task suspend, which we need to know about.
+ Since the code in inf_resume that normally checks for this is
+ disabled while INF->pending_execs, we do the check here instead. */
+ inf_validate_task_sc (inf);
}
if (inf->wait.suppress)
@@ -1375,7 +1466,7 @@ gnu_wait (int tid, struct target_waitstatus *status)
if (inf_update_procs (inf) && inf->threads)
tid = inf->threads->tid; /* The first available thread. */
else
- tid = -1;
+ tid = inferior_pid; /* let wait_for_inferior handle exit case */
if (thread && tid >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS
&& inf->pause_sc == 0 && thread->pause_sc == 0)
@@ -1442,9 +1533,15 @@ S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
/* Record the exception so that we can forward it later. */
{
if (thread->exc_port == port)
- inf->wait.exc.handler = thread->saved_exc_port;
+ {
+ inf_debug (waiting_inf, "Handler is thread exeption port <%d>",
+ thread->saved_exc_port);
+ inf->wait.exc.handler = thread->saved_exc_port;
+ }
else
{
+ inf_debug (waiting_inf, "Handler is task exeption port <%d>",
+ inf->task->saved_exc_port);
inf->wait.exc.handler = inf->task->saved_exc_port;
assert (inf->task->exc_port == port);
}
@@ -1484,9 +1581,8 @@ inf_task_died_status (struct inf *inf)
inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED;
inf->wait.status.value.sig = TARGET_SIGNAL_KILL;
}
-
-/* Notify server routines. The only real one is dead name notification. */
+/* Notify server routines. The only real one is dead name notification. */
error_t
do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
{
@@ -1522,7 +1618,7 @@ do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
return 0;
}
-
+
static error_t
ill_rpc (char *fun)
{
@@ -1564,12 +1660,12 @@ do_mach_notify_send_once (mach_port_t notify)
error_t
S_proc_wait_reply (mach_port_t reply, error_t err,
- int status, rusage_t rusage, pid_t pid)
+ int status, int sigcode, rusage_t rusage, pid_t pid)
{
struct inf *inf = waiting_inf;
- inf_debug (inf, "err = %s, pid = %d, status = 0x%x",
- err ? strerror (err) : "0", pid, status);
+ inf_debug (inf, "err = %s, pid = %d, status = 0x%x, sigcode = %d",
+ err ? strerror (err) : "0", pid, status, sigcode);
if (err && proc_wait_pid && (!inf->task || !inf->task->port))
/* Ack. The task has died, but the task-died notification code didn't
@@ -1606,10 +1702,6 @@ S_proc_wait_reply (mach_port_t reply, error_t err,
{
inf_debug (inf, "process has stopped itself");
inf->stopped = 1;
-
- /* We recheck the task suspend count here because the crash server
- messes with it in an unfriendly way, right before `stopping'. */
- inf_validate_task_sc (inf);
}
}
else
@@ -1724,6 +1816,8 @@ gnu_resume (int tid, int step, enum target_signal sig)
the process, as we're just going to stop it right away anyway. */
return;
+ inf_update_procs (inf);
+
if (tid < 0)
/* Allow all threads to run, except perhaps single-stepping one. */
{
@@ -1735,8 +1829,8 @@ gnu_resume (int tid, int step, enum target_signal sig)
/* Just allow a single thread to run. */
{
struct proc *thread = inf_tid_to_thread (inf, tid);
- assert (thread);
-
+ if (! thread)
+ error ("Can't run single thread id %d: no such thread!");
inf_debug (inf, "running one thread: %d/%d", inf->pid, thread->tid);
inf_set_threads_resume_sc (inf, thread, 0);
}
@@ -1744,8 +1838,10 @@ gnu_resume (int tid, int step, enum target_signal sig)
if (step)
{
step_thread = inf_tid_to_thread (inf, tid);
- assert (step_thread);
- inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid);
+ if (! step_thread)
+ warning ("Can't step thread id %d: no such thread.", tid);
+ else
+ inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid);
}
if (step_thread != inf->step_thread)
inf_set_step_thread (inf, step_thread);
@@ -1762,8 +1858,7 @@ gnu_kill_inferior ()
{
proc_debug (task, "terminating...");
task_terminate (task->port);
- task->port = MACH_PORT_NULL;
- inf_validate_procs (current_inferior); /* Clear out the thread list &c */
+ inf_set_pid (current_inferior, -1);
}
target_mourn_inferior ();
}
@@ -1782,15 +1877,15 @@ gnu_mourn_inferior ()
/* Fork an inferior process, and start debugging it. */
/* Set INFERIOR_PID to the first thread available in the child, if any. */
-static void
-pick_first_thread ()
+static int
+inf_pick_first_thread ()
{
if (current_inferior->task && current_inferior->threads)
/* The first thread. */
- inferior_pid = current_inferior->threads->tid;
+ return current_inferior->threads->tid;
else
/* What may be the next thread. */
- inferior_pid = next_thread_id;
+ return next_thread_id;
}
static struct inf *
@@ -1813,15 +1908,15 @@ gnu_create_inferior (exec_file, allargs, env)
{
/* We're in the child; make this process stop as soon as it execs. */
inf_debug (inf, "tracing self");
- ptrace (PTRACE_TRACEME, 0, 0, 0);
+ if (ptrace (PTRACE_TRACEME) != 0)
+ error ("ptrace (PTRACE_TRACEME) failed!");
}
- void attach_to_child (int pid)
+ int attach_to_child (int pid)
{
/* Attach to the now stopped child, which is actually a shell... */
inf_debug (inf, "attaching to child: %d", pid);
inf_attach (inf, pid);
- pick_first_thread ();
attach_flag = 0;
push_target (&gnu_ops);
@@ -1832,13 +1927,16 @@ gnu_create_inferior (exec_file, allargs, env)
/* Now let the child run again, knowing that it will stop immediately
because of the ptrace. */
inf_resume (inf);
+ inferior_pid = inf_pick_first_thread ();
- startup_inferior (pid, inf->pending_execs);
+ startup_inferior (inf->pending_execs);
+
+ return inferior_pid;
}
inf_debug (inf, "creating inferior");
- fork_inferior (exec_file, allargs, env, trace_me, attach_to_child, NULL);
+ fork_inferior (exec_file, allargs, env, trace_me, attach_to_child, NULL, NULL);
inf_update_signal_thread (inf);
inf_set_traced (inf, inf->want_signals);
@@ -1901,7 +1999,7 @@ gnu_attach (args, from_tty)
inf_attach (inf, pid);
inf_update_procs (inf);
- pick_first_thread ();
+ inferior_pid = inf_pick_first_thread ();
attach_flag = 1;
push_target (&gnu_ops);
@@ -1912,7 +2010,10 @@ gnu_attach (args, from_tty)
/* If the process was stopped before we attached, make it continue the next
time the user does a continue. */
inf_validate_stopped (inf);
- inf_validate_task_sc (inf);
+
+#if 0 /* Do we need this? */
+ renumber_threads (0); /* Give our threads reasonable names. */
+#endif
}
/* Take a program previously attached to and detaches it.
@@ -1981,6 +2082,13 @@ gnu_stop ()
error ("to_stop target function not implemented");
}
+static void
+gnu_pid_to_exec_file ()
+{
+ error ("to_pid_to_exec_file target function not implemented");
+}
+
+
static int
gnu_thread_alive (int tid)
{
@@ -2040,8 +2148,8 @@ struct vm_region_list {
struct obstack region_obstack;
/*
- * Write inferior task's LEN bytes from ADDR and copy it to MYADDR
- * in gdb's address space.
+ * Write gdb's LEN bytes from MYADDR and copy it to ADDR
+ * in inferior task's address space.
*/
int
gnu_write_inferior (task, addr, myaddr, length)
@@ -2239,50 +2347,77 @@ gnu_xfer_memory (memaddr, myaddr, len, write, target)
extern void gnu_store_registers (int regno);
extern void gnu_fetch_registers (int regno);
-struct target_ops gnu_ops = {
- "GNU", /* to_shortname */
- "GNU Hurd process", /* to_longname */
- "GNU Hurd process", /* to_doc */
- gnu_open, /* to_open */
- 0, /* to_close */
- gnu_attach, /* to_attach */
- gnu_detach, /* to_detach */
- gnu_resume, /* to_resume */
- gnu_wait, /* to_wait */
- gnu_fetch_registers, /* to_fetch_registers */
- gnu_store_registers, /* to_store_registers */
- gnu_prepare_to_store, /* to_prepare_to_store */
- gnu_xfer_memory, /* to_xfer_memory */
- 0, /* to_files_info */
- memory_insert_breakpoint, /* to_insert_breakpoint */
- memory_remove_breakpoint, /* to_remove_breakpoint */
- gnu_terminal_init_inferior, /* to_terminal_init */
- terminal_inferior, /* to_terminal_inferior */
- terminal_ours_for_output, /* to_terminal_ours_for_output */
- terminal_ours, /* to_terminal_ours */
- child_terminal_info, /* to_terminal_info */
- gnu_kill_inferior, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
-
- gnu_create_inferior, /* to_create_inferior */
- gnu_mourn_inferior, /* to_mourn_inferior */
- gnu_can_run, /* to_can_run */
- 0, /* to_notice_signals */
- gnu_thread_alive, /* to_thread_alive */
- gnu_stop, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+struct target_ops gnu_ops ;
+
+static void
+init_gnu_ops(void)
+{
+ gnu_ops.to_shortname = "GNU"; /* to_shortname */
+ gnu_ops.to_longname = "GNU Hurd process"; /* to_longname */
+ gnu_ops.to_doc = "GNU Hurd process"; /* to_doc */
+ gnu_ops.to_open = gnu_open; /* to_open */
+ gnu_ops.to_close = 0; /* to_close */
+ gnu_ops.to_attach = gnu_attach; /* to_attach */
+ gnu_ops.to_post_attach = NULL;
+ gnu_ops.to_require_attach = NULL; /* to_require_attach */
+ gnu_ops.to_detach = gnu_detach; /* to_detach */
+ gnu_ops.to_require_detach = NULL; /* to_require_detach */
+ gnu_ops.to_resume = gnu_resume; /* to_resume */
+ gnu_ops.to_wait = gnu_wait; /* to_wait */
+ gnu_ops.to_post_wait = NULL; /* to_post_wait */
+ gnu_ops.to_fetch_registers = gnu_fetch_registers; /* to_fetch_registers */
+ gnu_ops.to_store_registers = gnu_store_registers; /* to_store_registers */
+ gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */
+ gnu_ops.to_xfer_memory = gnu_xfer_memory; /* to_xfer_memory */
+ gnu_ops.to_files_info = 0; /* to_files_info */
+ gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ gnu_ops.to_terminal_init = gnu_terminal_init_inferior;
+ gnu_ops.to_terminal_inferior = terminal_inferior;
+ gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ gnu_ops.to_terminal_ours = terminal_ours;
+ gnu_ops.to_terminal_info = child_terminal_info;
+ gnu_ops.to_kill = gnu_kill_inferior; /* to_kill */
+ gnu_ops.to_load = 0; /* to_load */
+ gnu_ops.to_lookup_symbol = 0; /* to_lookup_symbol */
+ gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */
+ gnu_ops.to_post_startup_inferior = NULL; /* to_post_startup_inferior */
+ gnu_ops.to_acknowledge_created_inferior = NULL; /* to_acknowledge_created_inferior */
+ gnu_ops.to_clone_and_follow_inferior = NULL; /* to_clone_and_follow_inferior */
+ gnu_ops.to_post_follow_inferior_by_clone = NULL; /* to_post_follow_inferior_by_clone */
+ gnu_ops.to_insert_fork_catchpoint = NULL;
+ gnu_ops.to_remove_fork_catchpoint = NULL;
+ gnu_ops.to_insert_vfork_catchpoint = NULL;
+ gnu_ops.to_remove_vfork_catchpoint = NULL;
+ gnu_ops.to_has_forked = NULL; /* to_has_forked */
+ gnu_ops.to_has_vforked = NULL; /* to_has_vforked */
+ gnu_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ gnu_ops.to_post_follow_vfork = NULL; /* to_post_follow_vfork */
+ gnu_ops.to_insert_exec_catchpoint = NULL;
+ gnu_ops.to_remove_exec_catchpoint = NULL;
+ gnu_ops.to_has_execd = NULL;
+ gnu_ops.to_reported_exec_events_per_exec_call = NULL;
+ gnu_ops.to_has_exited = NULL;
+ gnu_ops.to_mourn_inferior = gnu_mourn_inferior; /* to_mourn_inferior */
+ gnu_ops.to_can_run = gnu_can_run; /* to_can_run */
+ gnu_ops.to_notice_signals = 0; /* to_notice_signals */
+ gnu_ops.to_thread_alive = gnu_thread_alive;/* to_thread_alive */
+ gnu_ops.to_stop = gnu_stop; /* to_stop */
+ gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file; /* to_pid_to_exec_file */
+ gnu_ops.to_core_file_to_sym_file = NULL;
+ gnu_ops.to_stratum = process_stratum; /* to_stratum */
+ gnu_ops.DONT_USE = 0; /* to_next */
+ gnu_ops.to_has_all_memory = 1; /* to_has_all_memory */
+ gnu_ops.to_has_memory = 1; /* to_has_memory */
+ gnu_ops.to_has_stack = 1; /* to_has_stack */
+ gnu_ops.to_has_registers = 1; /* to_has_registers */
+ gnu_ops.to_has_execution = 1; /* to_has_execution */
+ gnu_ops.to_sections = 0; /* sections */
+ gnu_ops.to_sections_end = 0; /* sections_end */
+ gnu_ops.to_magic = OPS_MAGIC ; /* to_magic */
+} /* init_gnu_ops */
+/* Return printable description of proc. */
char *proc_string (struct proc *proc)
{
static char tid_str[80];
@@ -2290,8 +2425,7 @@ char *proc_string (struct proc *proc)
sprintf (tid_str, "process %d", proc->inf->pid);
else
sprintf (tid_str, "thread %d.%d",
- proc->inf->pid,
- pid_to_thread_id (proc->tid));
+ proc->inf->pid, pid_to_thread_id (proc->tid));
return tid_str;
}
@@ -2315,9 +2449,54 @@ gnu_target_pid_to_str (int tid)
struct cmd_list_element *set_task_cmd_list = 0;
struct cmd_list_element *show_task_cmd_list = 0;
+/* User thread commands. */
+
+/* Commands with a prefix of `set/show thread'. */
+extern struct cmd_list_element *thread_cmd_list;
+struct cmd_list_element *set_thread_cmd_list = NULL;
+struct cmd_list_element *show_thread_cmd_list = NULL;
+
+/* Commands with a prefix of `set/show thread default'. */
+struct cmd_list_element *set_thread_default_cmd_list = NULL;
+struct cmd_list_element *show_thread_default_cmd_list = NULL;
+
+static void
+set_thread_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set thread\" must be followed by the name of a thread
+property, or \"default\".\n");
+}
-extern struct cmd_list_element *set_thread_default_cmd_list;
-extern struct cmd_list_element *show_thread_default_cmd_list;
+static void
+show_thread_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n");
+}
+
+static void
+set_thread_default_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n");
+}
+
+static void
+show_thread_default_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n");
+}
+
+static int
+parse_int_arg (char *args, char *cmd_prefix)
+{
+ if (args)
+ {
+ char *arg_end;
+ int val = strtoul (args, &arg_end, 10);
+ if (*args && *arg_end == '\0')
+ return val;
+ }
+ error ("Illegal argument for \"%s\" command, should be an integer.", cmd_prefix);
+}
static int
_parse_bool_arg (char *args, char *t_val, char *f_val, char *cmd_prefix)
@@ -2352,6 +2531,16 @@ cur_thread ()
return thread;
}
+/* Returns the current inferior, but signals an error if it has no task. */
+static struct inf *
+active_inf ()
+{
+ struct inf *inf = cur_inf ();
+ if (! inf->task)
+ error ("No current process.");
+ return inf;
+}
+
static void
set_task_pause_cmd (char *args, int from_tty)
{
@@ -2378,6 +2567,20 @@ show_task_pause_cmd (char *args, int from_tty)
}
static void
+set_task_detach_sc_cmd (char *args, int from_tty)
+{
+ cur_inf ()->detach_sc = parse_int_arg (args, "set task detach-suspend-count");
+}
+
+static void
+show_task_detach_sc_cmd (char *args, int from_tty)
+{
+ check_empty (args, "show task detach-suspend-count");
+ printf_unfiltered ("The inferior task will be left with a suspend count of %d when detaching.\n",
+ cur_inf ()->detach_sc);
+}
+
+static void
set_thread_default_pause_cmd (char *args, int from_tty)
{
struct inf *inf = cur_inf ();
@@ -2393,7 +2596,7 @@ show_thread_default_pause_cmd (char *args, int from_tty)
check_empty (args, "show thread default pause");
printf_unfiltered ("New threads %s suspended while gdb has control%s.\n",
sc ? "are" : "aren't",
- !sc && inf->pause_sc ? "(but the task is)" : "");
+ !sc && inf->pause_sc ? " (but the task is)" : "");
}
static void
@@ -2413,6 +2616,21 @@ show_thread_default_run_cmd (char *args, int from_tty)
inf->default_thread_run_sc == 0 ? "are" : "aren't");
}
+static void
+set_thread_default_detach_sc_cmd (char *args, int from_tty)
+{
+ cur_inf ()->default_thread_detach_sc =
+ parse_int_arg (args, "set thread default detach-suspend-count");
+}
+
+static void
+show_thread_default_detach_sc_cmd (char *args, int from_tty)
+{
+ check_empty (args, "show thread default detach-suspend-count");
+ printf_unfiltered ("New threads will get a detach-suspend-count of %d.\n",
+ cur_inf ()->default_thread_detach_sc);
+}
+
/* Steal a send right called NAME in the inferior task, and make it PROC's
saved exception port. */
static void
@@ -2448,7 +2666,7 @@ steal_exc_port (struct proc *proc, mach_port_t name)
proc_string (proc), strerror (err));
}
}
-
+
static void
set_task_exc_port_cmd (char *args, int from_tty)
{
@@ -2459,30 +2677,6 @@ set_task_exc_port_cmd (char *args, int from_tty)
}
static void
-set_signals_cmd (char *args, int from_tty)
-{
- int trace;
- struct inf *inf = cur_inf ();
-
- inf->want_signals = parse_bool_arg (args, "set signals");
-
- if (inf->task && inf->want_signals != inf->traced)
- /* Make this take effect immediately in a running process. */
- inf_set_traced (inf, inf->want_signals);
-}
-
-static void
-show_signals_cmd (char *args, int from_tty)
-{
- struct inf *inf = cur_inf ();
- check_empty (args, "show signals");
- printf_unfiltered ("The inferior process's signals %s intercepted.\n",
- inf->task
- ? (inf->traced ? "are" : "aren't")
- : (inf->want_signals ? "will be" : "won't be"));
-}
-
-static void
set_stopped_cmd (char *args, int from_tty)
{
cur_inf ()->stopped = _parse_bool_arg (args, "yes", "no", "set stopped");
@@ -2491,10 +2685,8 @@ set_stopped_cmd (char *args, int from_tty)
static void
show_stopped_cmd (char *args, int from_tty)
{
- struct inf *inf = cur_inf ();
+ struct inf *inf = active_inf ();
check_empty (args, "show stopped");
- if (! inf->task)
- error ("No current process.");
printf_unfiltered ("The inferior process %s stopped.\n",
inf->stopped ? "is" : "isn't");
}
@@ -2524,16 +2716,38 @@ set_sig_thread_cmd (char *args, int from_tty)
static void
show_sig_thread_cmd (char *args, int from_tty)
{
- struct inf *inf = cur_inf ();
+ struct inf *inf = active_inf ();
check_empty (args, "show signal-thread");
- if (! inf->task)
- error ("No current process.");
if (inf->signal_thread)
printf_unfiltered ("The signal thread is %s.\n",
proc_string (inf->signal_thread));
else
printf_unfiltered ("There is no signal thread.\n");
}
+
+static void
+set_signals_cmd (char *args, int from_tty)
+{
+ int trace;
+ struct inf *inf = cur_inf ();
+
+ inf->want_signals = parse_bool_arg (args, "set signals");
+
+ if (inf->task && inf->want_signals != inf->traced)
+ /* Make this take effect immediately in a running process. */
+ inf_set_traced (inf, inf->want_signals);
+}
+
+static void
+show_signals_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ check_empty (args, "show signals");
+ printf_unfiltered ("The inferior process's signals %s intercepted.\n",
+ inf->task
+ ? (inf->traced ? "are" : "aren't")
+ : (inf->want_signals ? "will be" : "won't be"));
+}
static void
set_exceptions_cmd (char *args, int from_tty)
@@ -2558,7 +2772,7 @@ show_exceptions_cmd (char *args, int from_tty)
? (inf->want_exceptions ? "are" : "aren't")
: (inf->want_exceptions ? "will be" : "won't be"));
}
-
+
static void
set_task_cmd (char *args, int from_tty)
{
@@ -2585,8 +2799,83 @@ show_task_cmd (char *args, int from_tty)
show_stopped_cmd (0, from_tty);
show_sig_thread_cmd (0, from_tty);
}
+
+ if (inf->detach_sc != 0)
+ show_task_detach_sc_cmd (0, from_tty);
+ if (inf->default_thread_detach_sc != 0)
+ show_thread_default_detach_sc_cmd (0, from_tty);
+}
+
+static void
+set_noninvasive_cmd (char *args, int from_tty)
+{
+ /* Invert the sense of the arg for each component. */
+ char *inv_args = parse_bool_arg (args, "set noninvasive") ? "off" : "on";
+
+ set_task_pause_cmd (inv_args, from_tty);
+ set_signals_cmd (inv_args, from_tty);
+ set_exceptions_cmd (inv_args, from_tty);
+}
+
+static void
+info_port_rights (char *args, mach_port_type_t only)
+{
+ struct inf *inf = active_inf ();
+ value_ptr vmark = value_mark ();
+
+ if (args)
+ /* Explicit list of port rights. */
+ {
+ while (*args)
+ {
+ value_ptr val = parse_to_comma_and_eval (&args);
+ long right = value_as_long (val);
+ error_t err =
+ print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS,
+ stdout);
+ if (err)
+ error ("%ld: %s.", right, strerror (err));
+ }
+ }
+ else
+ /* Print all of them. */
+ {
+ error_t err =
+ print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS,
+ stdout);
+ if (err)
+ error ("%s.", strerror (err));
+ }
+
+ value_free_to_mark (vmark);
}
+static void
+info_send_rights_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_SEND);
+}
+static void
+info_recv_rights_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_RECEIVE);
+}
+static void
+info_port_sets_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_PORT_SET);
+}
+static void
+info_dead_names_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_DEAD_NAME);
+}
+static void
+info_port_rights_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, ~0);
+}
+
static void add_task_commands ()
{
add_cmd ("pause", class_run, set_thread_default_pause_cmd,
@@ -2605,6 +2894,12 @@ static void add_task_commands ()
"Show whether new threads are allowed to run (once gdb has noticed
them).",
&show_thread_default_cmd_list);
+ add_cmd ("detach-suspend-count", class_run, set_thread_default_detach_sc_cmd,
+ "Set the default detach-suspend-count value for new threads.",
+ &set_thread_default_cmd_list);
+ add_cmd ("detach-suspend-count", no_class, show_thread_default_detach_sc_cmd,
+ "Show the default detach-suspend-count value for new threads.",
+ &show_thread_default_cmd_list);
add_cmd ("signals", class_run, set_signals_cmd,
"Set whether the inferior process's signals will be intercepted.\n"
@@ -2645,8 +2940,6 @@ them).",
"Show whether exceptions in the inferior process will be trapped.",
&showlist);
-
-
add_prefix_cmd ("task", no_class, set_task_cmd,
"Command prefix for setting task attributes.",
&set_task_cmd_list, "set task ", 0, &setlist);
@@ -2664,6 +2957,12 @@ them).",
add_cmd ("pause", no_class, show_task_pause_cmd,
"Show whether the task is suspended while gdb has control.",
&show_task_cmd_list);
+ add_cmd ("detach-suspend-count", class_run, set_task_detach_sc_cmd,
+ "Set the suspend count will leave on the thread when detaching.",
+ &set_task_cmd_list);
+ add_cmd ("detach-suspend-count", no_class, show_task_detach_sc_cmd,
+ "Show the suspend count will leave on the thread when detaching.",
+ &show_task_cmd_list);
add_cmd ("exception-port", no_class, set_task_exc_port_cmd,
"Set the task exception port to which we forward exceptions.\n"
@@ -2671,12 +2970,36 @@ them).",
&set_task_cmd_list);
add_alias_cmd ("excp", "exception-port", no_class, 1, &set_task_cmd_list);
add_alias_cmd ("exc-port", "exception-port", no_class, 1, &set_task_cmd_list);
+
+ /* A convenient way of turning on all options require to noninvasively
+ debug running tasks. */
+ add_cmd ("noninvasive", no_class, set_noninvasive_cmd,
+ "Set task options so that we interfere as little as possible.\n"
+ "This is the same as setting `task pause', `exceptions', and"
+ "`signals' to the opposite value.",
+ &setlist);
+
+ /* Commands to show information about the task's ports. */
+ add_cmd ("send-rights", class_info, info_send_rights_cmd,
+ "Show information about the task's send rights",
+ &infolist);
+ add_cmd ("receive-rights", class_info, info_recv_rights_cmd,
+ "Show information about the task's receive rights",
+ &infolist);
+ add_cmd ("port-rights", class_info, info_send_rights_cmd,
+ "Show information about the task's port rights",
+ &infolist);
+ add_cmd ("port-sets", class_info, info_port_sets_cmd,
+ "Show information about the task's port sets",
+ &infolist);
+ add_cmd ("dead-names", class_info, info_dead_names_cmd,
+ "Show information about the task's dead names",
+ &infolist);
+ add_info_alias ("ports", "port-rights", 1);
+ add_info_alias ("port", "port-rights", 1);
+ add_info_alias ("psets", "port-sets", 1);
}
-/* User thread commands. */
-
-extern struct cmd_list_element *set_thread_cmd_list;
-extern struct cmd_list_element *show_thread_cmd_list;
static void
set_thread_pause_cmd (char *args, int from_tty)
@@ -2699,7 +3022,7 @@ show_thread_pause_cmd (char *args, int from_tty)
printf_unfiltered ("Thread %s %s suspended while gdb has control%s.\n",
proc_string (thread),
sc ? "is" : "isn't",
- !sc && thread->inf->pause_sc ? "(but the task is)" : "");
+ !sc && thread->inf->pause_sc ? " (but the task is)" : "");
}
static void
@@ -2714,12 +3037,28 @@ show_thread_run_cmd (char *args, int from_tty)
{
struct proc *thread = cur_thread ();
check_empty (args, "show thread run");
- printf_unfiltered ("Thread %s allowed to run.",
+ printf_unfiltered ("Thread %s %s allowed to run.",
proc_string (thread),
thread->run_sc == 0 ? "is" : "isn't");
}
static void
+set_thread_detach_sc_cmd (char *args, int from_tty)
+{
+ cur_thread ()->detach_sc = parse_int_arg (args, "set thread detach-suspend-count");
+}
+
+static void
+show_thread_detach_sc_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ check_empty (args, "show thread detach-suspend-count");
+ printf_unfiltered ("Thread %s will be left with a suspend count of %d when detaching.\n",
+ proc_string (thread),
+ thread->detach_sc);
+}
+
+static void
set_thread_exc_port_cmd (char *args, int from_tty)
{
struct proc *thread = cur_thread ();
@@ -2728,22 +3067,54 @@ set_thread_exc_port_cmd (char *args, int from_tty)
steal_exc_port (thread, parse_and_eval_address (args));
}
-static void
-set_thread_cmd (char *args, int from_tty)
-{
- printf_unfiltered ("\"set thread\" must be followed by the name of a thread property.\n");
-}
-
+#if 0
static void
show_thread_cmd (char *args, int from_tty)
{
+ struct proc *thread = cur_thread ();
check_empty (args, "show thread");
show_thread_run_cmd (0, from_tty);
show_thread_pause_cmd (0, from_tty);
+ if (thread->detach_sc != 0)
+ show_thread_detach_sc_cmd (0, from_tty);
+}
+#endif
+
+static void
+thread_takeover_sc_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ thread_basic_info_data_t _info;
+ thread_basic_info_t info = &_info;
+ mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT;
+ error_t err =
+ thread_info (thread->port, THREAD_BASIC_INFO, (int *)&info, &info_len);
+ if (err)
+ error ("%s.", strerror (err));
+ thread->sc = info->suspend_count;
+ if (from_tty)
+ printf_unfiltered ("Suspend count was %d.\n", thread->sc);
+ if (info != &_info)
+ vm_deallocate (mach_task_self (), (vm_address_t)info, info_len * sizeof (int));
}
add_thread_commands ()
{
+ add_prefix_cmd ("thread", no_class, set_thread_cmd,
+ "Command prefix for setting thread properties.",
+ &set_thread_cmd_list, "set thread ", 0, &setlist);
+ add_prefix_cmd ("default", no_class, show_thread_cmd,
+ "Command prefix for setting default thread properties.",
+ &set_thread_default_cmd_list, "set thread default ", 0,
+ &set_thread_cmd_list);
+ add_prefix_cmd ("thread", no_class, set_thread_default_cmd,
+ "Command prefix for showing thread properties.",
+ &show_thread_cmd_list, "show thread ", 0, &showlist);
+ add_prefix_cmd ("default", no_class, show_thread_default_cmd,
+ "Command prefix for showing default thread properties.",
+ &show_thread_default_cmd_list, "show thread default ", 0,
+ &show_thread_cmd_list);
+
add_cmd ("pause", class_run, set_thread_pause_cmd,
"Set whether the current thread is suspended while gdb has control.\n"
"A value of \"on\" takes effect immediately, otherwise nothing\n"
@@ -2763,6 +3134,17 @@ add_thread_commands ()
"Show whether the current thread is allowed to run.",
&show_thread_cmd_list);
+ add_cmd ("detach-suspend-count", class_run, set_thread_detach_sc_cmd,
+ "Set the suspend count will leave on the thread when detaching.\n"
+ "Note that this is relative to suspend count when gdb noticed the thread;\n"
+ "use the `thread takeover-suspend-count' to force it to an absolute value.",
+ &set_thread_cmd_list);
+ add_cmd ("detach-suspend-count", no_class, show_thread_detach_sc_cmd,
+ "Show the suspend count will leave on the thread when detaching."
+ "Note that this is relative to suspend count when gdb noticed the thread;\n"
+ "use the `thread takeover-suspend-count' to force it to an absolute value.",
+ &show_thread_cmd_list);
+
add_cmd ("exception-port", no_class, set_thread_exc_port_cmd,
"Set the exception port to which we forward exceptions for the\n"
"current thread, overriding the task exception port.\n"
@@ -2770,15 +3152,20 @@ add_thread_commands ()
&set_thread_cmd_list);
add_alias_cmd ("excp", "exception-port", no_class, 1, &set_thread_cmd_list);
add_alias_cmd ("exc-port", "exception-port", no_class, 1, &set_thread_cmd_list);
+
+ add_cmd ("takeover-suspend-count", no_class, thread_takeover_sc_cmd,
+ "Force the threads absolute suspend-count to be gdb's.\n"
+ "Prior to giving this command, gdb's thread suspend-counts are relative to\n"
+ "the thread's initial suspend-count when gdb notices the threads.",
+ &thread_cmd_list);
}
void
_initialize_gnu_nat ()
{
proc_server = getproc ();
-
+ init_gnu_ops() ;
add_target (&gnu_ops);
-
add_task_commands ();
add_thread_commands ();
diff --git a/contrib/gdb/gdb/gnu-nat.h b/contrib/gdb/gdb/gnu-nat.h
index 6f29b73..d238dc0 100644
--- a/contrib/gdb/gdb/gnu-nat.h
+++ b/contrib/gdb/gdb/gnu-nat.h
@@ -1,22 +1,21 @@
/* Common things used by the various *gnu-nat.c files
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Copyright (C) 1995 Free Software Foundation, Inc.
+Written by Miles Bader <miles@gnu.ai.mit.edu>
- Written by Miles Bader <miles@gnu.ai.mit.edu>
+The GNU Hurd is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2, or (at
+your option) any later version.
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
+The GNU Hurd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef __GNU_NAT_H__
#define __GNU_NAT_H__
@@ -46,13 +45,16 @@ struct proc
int cur_sc; /* Implemented suspend count. */
int run_sc; /* Default sc when the program is running. */
int pause_sc; /* Default sc when gdb has control. */
- int resume_sc; /* Sc resulting form the last resume. */
+ int resume_sc; /* Sc resulting from the last resume. */
+ int detach_sc; /* SC to leave around when detaching
+ from program. */
thread_state_data_t state; /* Registers, &c. */
int state_valid : 1; /* True if STATE is up to date. */
int state_changed : 1;
int aborted : 1; /* True if thread_abort has been called. */
+ int dead : 1; /* We happen to know it's actually dead. */
/* Bit mask of registers fetched by gdb. This is used when we re-fetch
STATE after aborting the thread, to detect that gdb may have out-of-date
diff --git a/contrib/gdb/gdb/gnu-regex.c b/contrib/gdb/gdb/gnu-regex.c
index dec0cf1..84db70f 100644
--- a/contrib/gdb/gdb/gnu-regex.c
+++ b/contrib/gdb/gdb/gnu-regex.c
@@ -1,59 +1,160 @@
-/* Extended regular expression matching and search library.
- Copyright (C) 1985, 1989 Free Software Foundation, Inc.
+/* Extended regular expression matching and search library,
+ version 0.12.
+ (Implements POSIX draft P1003.2/D11.2, except for some of the
+ internationalization features.)
+ Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
+
+ NOTE: The canonical source of this file is maintained with the
+ GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined _AIX && !defined REGEX_MALLOC
+ #pragma alloca
+#endif
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#ifndef PARAMS
+# if defined __GNUC__ || (defined __STDC__ && __STDC__)
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif /* GCC. */
+#endif /* Not PARAMS. */
-/* To test, compile with -Dtest.
- This Dtestable feature turns this into a self-contained program
- which reads a pattern, describes how it compiles,
- then reads a string and searches for it. */
+#if defined STDC_HEADERS && !defined emacs
+# include <stddef.h>
+#else
+/* We need this for `gnu-regex.h', and perhaps for the Emacs include files. */
+# include <sys/types.h>
+#endif
-#ifdef emacs
+/* For platform which support the ISO C amendement 1 functionality we
+ support user defined character classes. */
+#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
+# include <wchar.h>
+# include <wctype.h>
+#endif
-/* The `emacs' switch turns on certain special matching commands
- that make sense only in emacs. */
+/* This is for other GNU distributions with internationalized messages. */
+/* CYGNUS LOCAL: ../intl will handle this for us */
+#ifdef ENABLE_NLS
+# include <libintl.h>
+#else
+# define gettext(msgid) (msgid)
+#endif
-#include "config.h"
-#include "lisp.h"
-#include "buffer.h"
-#include "syntax.h"
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+ strings. */
+# define gettext_noop(String) String
+#endif
-#else /* not emacs */
+/* The `emacs' switch turns on certain matching commands
+ that make sense only in Emacs. */
+#ifdef emacs
-#include "defs.h"
-#include "gdb_string.h"
-#undef malloc
-#define malloc xmalloc
+# include "lisp.h"
+# include "buffer.h"
+# include "syntax.h"
-/*
- * Define the syntax stuff, so we can do the \<...\> things.
- */
+#else /* not emacs */
-#ifndef Sword /* must be non-zero in some of the tests below... */
-#define Sword 1
+/* If we are not linking with Emacs proper,
+ we can't use the relocating allocator
+ even if config.h says that we can. */
+# undef REL_ALLOC
+
+# if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+# else
+char *malloc ();
+char *realloc ();
+# endif
+
+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
+ If nothing else has been done, use the method below. */
+# ifdef INHIBIT_STRING_HEADER
+# if !(defined HAVE_BZERO && defined HAVE_BCOPY)
+# if !defined bzero && !defined bcopy
+# undef INHIBIT_STRING_HEADER
+# endif
+# endif
+# endif
+
+/* This is the normal way of making sure we have a bcopy and a bzero.
+ This is used in most programs--a few other programs avoid this
+ by defining INHIBIT_STRING_HEADER. */
+# ifndef INHIBIT_STRING_HEADER
+# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
+# include <string.h>
+# ifndef bzero
+# ifndef _LIBC
+# define bzero(s, n) (memset (s, '\0', n), (s))
+# else
+# define bzero(s, n) __bzero (s, n)
+# endif
+# endif
+# else
+# include <strings.h>
+# ifndef memcmp
+# define memcmp(s1, s2, n) bcmp (s1, s2, n)
+# endif
+# ifndef memcpy
+# define memcpy(d, s, n) (bcopy (s, d, n), (d))
+# endif
+# endif
+# endif
+
+/* Define the syntax stuff for \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+# ifndef Sword
+# define Sword 1
+# endif
+
+# ifdef SWITCH_ENUM_BUG
+# define SWITCH_ENUM_CAST(x) ((int)(x))
+# else
+# define SWITCH_ENUM_CAST(x) (x)
+# endif
+
+/* How many characters in the character set. */
+# define CHAR_SET_SIZE 256
+
+/* GDB LOCAL: define _REGEX_RE_COMP to get BSD style re_comp and re_exec */
+#ifndef _REGEX_RE_COMP
+#define _REGEX_RE_COMP
#endif
-#define SYNTAX(c) re_syntax_table[c]
+# ifdef SYNTAX_TABLE
-#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
-char *re_syntax_table;
-
-#else
+# else /* not SYNTAX_TABLE */
-static char re_syntax_table[256];
+static char re_syntax_table[CHAR_SET_SIZE];
static void
init_syntax_once ()
@@ -64,7 +165,7 @@ init_syntax_once ()
if (done)
return;
- memset (re_syntax_table, '\0', sizeof re_syntax_table);
+ bzero (re_syntax_table, sizeof re_syntax_table);
for (c = 'a'; c <= 'z'; c++)
re_syntax_table[c] = Sword;
@@ -75,25 +176,69 @@ init_syntax_once ()
for (c = '0'; c <= '9'; c++)
re_syntax_table[c] = Sword;
+ re_syntax_table['_'] = Sword;
+
done = 1;
}
-#endif /* SYNTAX_TABLE */
-#endif /* not emacs */
+# endif /* not SYNTAX_TABLE */
+# define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+
+/* Get the interface, including the syntax bits. */
+/* CYGNUS LOCAL: call it gnu-regex.h, not regex.h, to avoid name conflicts */
#include "gnu-regex.h"
-/* Number of failure points to allocate space for initially,
- when matching. If this number is exceeded, more space is allocated,
- so it is not a hard limit. */
+/* isalpha etc. are used for the character classes. */
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding."
+ Solaris defines some of these symbols so we must undefine them first. */
-#ifndef NFAILURES
-#define NFAILURES 80
-#endif /* NFAILURES */
+#undef ISASCII
+#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
+# define ISASCII(c) 1
+#else
+# define ISASCII(c) isascii(c)
+#endif
-/* width of a byte in bits */
+#ifdef isblank
+# define ISBLANK(c) (ISASCII (c) && isblank (c))
+#else
+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+#else
+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+#endif
-#define BYTEWIDTH 8
+#undef ISPRINT
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+#ifndef NULL
+# define NULL (void *)0
+#endif
/* We remove any previous definition of `SIGN_EXTEND_CHAR',
since ours (we hope) works properly with all combinations of
@@ -101,726 +246,2970 @@ init_syntax_once ()
(Per Bothner suggested the basic approach.) */
#undef SIGN_EXTEND_CHAR
#if __STDC__
-#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+# define SIGN_EXTEND_CHAR(c) ((signed char) (c))
#else /* not __STDC__ */
/* As in Harbison and Steele. */
-#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
#endif
-static int obscure_syntax = 0;
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ use `alloca' instead of `malloc'. This is because using malloc in
+ re_search* or re_match* could cause memory leaks when C-g is used in
+ Emacs; also, malloc is slower and causes storage fragmentation. On
+ the other hand, malloc is more portable, and easier to debug.
-/* Specify the precise syntax of regexp for compilation.
- This provides for compatibility for various utilities
- which historically have different, incompatible syntaxes.
+ Because we sometimes use alloca, some routines have to be macros,
+ not functions -- `alloca'-allocated space disappears at the end of the
+ function it is called in. */
- The argument SYNTAX is a bit-mask containing the two bits
- RE_NO_BK_PARENS and RE_NO_BK_VBAR. */
+#ifdef REGEX_MALLOC
-int
-re_set_syntax (syntax)
- int syntax;
+# define REGEX_ALLOCATE malloc
+# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+# define REGEX_FREE free
+
+#else /* not REGEX_MALLOC */
+
+/* Emacs already defines alloca, sometimes. */
+# ifndef alloca
+
+/* Make alloca work the best possible way. */
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# else /* not __GNUC__ */
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# endif /* HAVE_ALLOCA_H */
+# endif /* not __GNUC__ */
+
+# endif /* not alloca */
+
+# define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable. */
+# define REGEX_REALLOCATE(source, osize, nsize) \
+ (destination = (char *) alloca (nsize), \
+ memcpy (destination, source, osize))
+
+/* No need to do anything to free, after alloca. */
+# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
+
+#endif /* not REGEX_MALLOC */
+
+/* Define how to allocate the failure stack. */
+
+#if defined REL_ALLOC && defined REGEX_MALLOC
+
+# define REGEX_ALLOCATE_STACK(size) \
+ r_alloc (&failure_stack_ptr, (size))
+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
+ r_re_alloc (&failure_stack_ptr, (nsize))
+# define REGEX_FREE_STACK(ptr) \
+ r_alloc_free (&failure_stack_ptr)
+
+#else /* not using relocating allocator */
+
+# ifdef REGEX_MALLOC
+
+# define REGEX_ALLOCATE_STACK malloc
+# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
+# define REGEX_FREE_STACK free
+
+# else /* not REGEX_MALLOC */
+
+# define REGEX_ALLOCATE_STACK alloca
+
+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
+ REGEX_REALLOCATE (source, osize, nsize)
+/* No need to explicitly free anything. */
+# define REGEX_FREE_STACK(arg)
+
+# endif /* not REGEX_MALLOC */
+#endif /* not using relocating allocator */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+ `string1' or just past its end. This works if PTR is NULL, which is
+ a good thing. */
+#define FIRST_STRING_P(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail. */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define RETALLOC_IF(addr, n, t) \
+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits. */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp,
+ const char *string1, int size1,
+ const char *string2, int size2,
+ int pos,
+ struct re_registers *regs,
+ int stop));
+
+/* These are the command codes that appear in compiled regular
+ expressions. Some opcodes are followed by argument bytes. A
+ command code can specify any interpretation whatsoever for its
+ arguments. Zero bytes may appear in the compiled regular expression. */
+
+typedef enum
{
- int ret;
+ no_op = 0,
+
+ /* Succeed right away--no more backtracking. */
+ succeed,
+
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn,
+
+ /* Matches any (more or less) character. */
+ anychar,
+
+ /* Matches any one char belonging to specified set. First
+ following byte is number of bitmap bytes. Then come bytes
+ for a bitmap saying which chars are in. Bits in each byte
+ are ordered low-bit-first. A character is in the set if its
+ bit is 1. A character too large to have a bit in the map is
+ automatically not in the set. */
+ charset,
+
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
+ charset_not,
+
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
+ start_memory,
+
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
+ stop_memory,
+
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
+ duplicate,
+
+ /* Fail unless at beginning of line. */
+ begline,
+
+ /* Fail unless at end of line. */
+ endline,
+
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
+ begbuf,
+
+ /* Analogously, for end of buffer/string. */
+ endbuf,
+
+ /* Followed by two byte relative address to which to jump. */
+ jump,
+
+ /* Same as jump, but marks the end of an alternative. */
+ jump_past_alt,
+
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
+ on_failure_jump,
+
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
+ on_failure_keep_string_jump,
+
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
+ pop_failure_jump,
+
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
+ maybe_pop_jump,
+
+ /* Jump to following two-byte address, and push a dummy failure
+ point. This failure point will be thrown away if an attempt
+ is made to use it for a failure. A `+' construct makes this
+ before the first repeat. Also used as an intermediary kind
+ of jump when compiling an alternative. */
+ dummy_failure_jump,
+
+ /* Push a dummy failure point and continue. Used at the end of
+ alternatives. */
+ push_dummy_failure,
+
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
+ succeed_n,
+
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
+ jump_n,
+
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
+ set_number_at,
+
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+
+#ifdef emacs
+ ,before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+
+ /* Matches any character whose syntax is specified. Followed by
+ a byte which contains a syntax code, e.g., Sword. */
+ syntaxspec,
+
+ /* Matches any character whose syntax is not that specified. */
+ notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+
+/* Common operations on the compiled pattern. */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+
+#define STORE_NUMBER(destination, number) \
+ do { \
+ (destination)[0] = (number) & 0377; \
+ (destination)[1] = (number) >> 8; \
+ } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+ the byte after where the number is stored. Therefore, DESTINATION
+ must be an lvalue. */
+
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ do { \
+ STORE_NUMBER (destination, number); \
+ (destination) += 2; \
+ } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+ at SOURCE. */
+
+#define EXTRACT_NUMBER(destination, source) \
+ do { \
+ (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
+ } while (0)
+
+#ifdef DEBUG
+static void extract_number _RE_ARGS ((int *dest, unsigned char *source));
+static void
+extract_number (dest, source)
+ int *dest;
+ unsigned char *source;
+{
+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
+ *dest = *source & 0377;
+ *dest += temp << 8;
+}
+
+# ifndef EXTRACT_MACROS /* To debug the macros. */
+# undef EXTRACT_NUMBER
+# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+# endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+ SOURCE must be an lvalue. */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ do { \
+ EXTRACT_NUMBER (destination, source); \
+ (source) += 2; \
+ } while (0)
+
+#ifdef DEBUG
+static void extract_number_and_incr _RE_ARGS ((int *destination,
+ unsigned char **source));
+static void
+extract_number_and_incr (destination, source)
+ int *destination;
+ unsigned char **source;
+{
+ extract_number (destination, *source);
+ *source += 2;
+}
+
+# ifndef EXTRACT_MACROS
+# undef EXTRACT_NUMBER_AND_INCR
+# define EXTRACT_NUMBER_AND_INCR(dest, src) \
+ extract_number_and_incr (&dest, &src)
+# endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+ it is doing (if the variable `debug' is nonzero). If linked with the
+ main program in `iregex.c', you can enter patterns and strings
+ interactively. And if linked with the main program in `main.c' and
+ the other test files, you can run the already-written tests. */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging. */
+# include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging. */
+# include <assert.h>
+
+static int debug = 0;
+
+# define DEBUG_STATEMENT(e) e
+# define DEBUG_PRINT1(x) if (debug) printf (x)
+# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+ if (debug) print_partial_compiled_pattern (s, e)
+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
+ if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+/* Print the fastmap in human-readable form. */
+
+void
+print_fastmap (fastmap)
+ char *fastmap;
+{
+ unsigned was_a_range = 0;
+ unsigned i = 0;
+
+ while (i < (1 << BYTEWIDTH))
+ {
+ if (fastmap[i++])
+ {
+ was_a_range = 0;
+ putchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
+ if (was_a_range)
+ {
+ printf ("-");
+ putchar (i - 1);
+ }
+ }
+ }
+ putchar ('\n');
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+ the START pointer into it and ending just before the pointer END. */
+
+void
+print_partial_compiled_pattern (start, end)
+ unsigned char *start;
+ unsigned char *end;
+{
+ int mcnt, mcnt2;
+ unsigned char *p1;
+ unsigned char *p = start;
+ unsigned char *pend = end;
+
+ if (start == NULL)
+ {
+ printf ("(null)\n");
+ return;
+ }
+
+ /* Loop over pattern commands. */
+ while (p < pend)
+ {
+ printf ("%d:\t", p - start);
+
+ switch ((re_opcode_t) *p++)
+ {
+ case no_op:
+ printf ("/no_op");
+ break;
+
+ case exactn:
+ mcnt = *p++;
+ printf ("/exactn/%d", mcnt);
+ do
+ {
+ putchar ('/');
+ putchar (*p++);
+ }
+ while (--mcnt);
+ break;
+
+ case start_memory:
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case stop_memory:
+ mcnt = *p++;
+ printf ("/stop_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case duplicate:
+ printf ("/duplicate/%d", *p++);
+ break;
+
+ case anychar:
+ printf ("/anychar");
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ register int c, last = -100;
+ register int in_range = 0;
+
+ printf ("/charset [%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < 256; c++)
+ if (c / 8 < *p
+ && (p[1 + (c/8)] & (1 << (c % 8))))
+ {
+ /* Are we starting a range? */
+ if (last + 1 == c && ! in_range)
+ {
+ putchar ('-');
+ in_range = 1;
+ }
+ /* Have we broken a range? */
+ else if (last + 1 != c && in_range)
+ {
+ putchar (last);
+ in_range = 0;
+ }
+
+ if (! in_range)
+ putchar (c);
+
+ last = c;
+ }
- ret = obscure_syntax;
- obscure_syntax = syntax;
+ if (in_range)
+ putchar (last);
+
+ putchar (']');
+
+ p += 1 + *p;
+ }
+ break;
+
+ case begline:
+ printf ("/begline");
+ break;
+
+ case endline:
+ printf ("/endline");
+ break;
+
+ case on_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case on_failure_keep_string_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+ break;
+
+ case dummy_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case push_dummy_failure:
+ printf ("/push_dummy_failure");
+ break;
+
+ case maybe_pop_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/maybe_pop_jump to %d", p + mcnt - start);
+ break;
+
+ case pop_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/pop_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case jump_past_alt:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump_past_alt to %d", p + mcnt - start);
+ break;
+
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump to %d", p + mcnt - start);
+ break;
+
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ p1 = p + mcnt;
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n to %d, %d times", p1 - start, mcnt2);
+ break;
+
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ p1 = p + mcnt;
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
+ break;
+
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ p1 = p + mcnt;
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at location %d to %d", p1 - start, mcnt2);
+ break;
+
+ case wordbound:
+ printf ("/wordbound");
+ break;
+
+ case notwordbound:
+ printf ("/notwordbound");
+ break;
+
+ case wordbeg:
+ printf ("/wordbeg");
+ break;
+
+ case wordend:
+ printf ("/wordend");
+
+# ifdef emacs
+ case before_dot:
+ printf ("/before_dot");
+ break;
+
+ case at_dot:
+ printf ("/at_dot");
+ break;
+
+ case after_dot:
+ printf ("/after_dot");
+ break;
+
+ case syntaxspec:
+ printf ("/syntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+
+ case notsyntaxspec:
+ printf ("/notsyntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+# endif /* emacs */
+
+ case wordchar:
+ printf ("/wordchar");
+ break;
+
+ case notwordchar:
+ printf ("/notwordchar");
+ break;
+
+ case begbuf:
+ printf ("/begbuf");
+ break;
+
+ case endbuf:
+ printf ("/endbuf");
+ break;
+
+ default:
+ printf ("?%d", *(p-1));
+ }
+
+ putchar ('\n');
+ }
+
+ printf ("%d:\tend of pattern.\n", p - start);
+}
+
+
+void
+print_compiled_pattern (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ unsigned char *buffer = bufp->buffer;
+
+ print_partial_compiled_pattern (buffer, buffer + bufp->used);
+ printf ("%ld bytes used/%ld bytes allocated.\n",
+ bufp->used, bufp->allocated);
+
+ if (bufp->fastmap_accurate && bufp->fastmap)
+ {
+ printf ("fastmap: ");
+ print_fastmap (bufp->fastmap);
+ }
+
+ printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
+ printf ("can_be_null: %d\t", bufp->can_be_null);
+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
+ printf ("no_sub: %d\t", bufp->no_sub);
+ printf ("not_bol: %d\t", bufp->not_bol);
+ printf ("not_eol: %d\t", bufp->not_eol);
+ printf ("syntax: %lx\n", bufp->syntax);
+ /* Perhaps we should print the translate table? */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+ const char *where;
+ const char *string1;
+ const char *string2;
+ int size1;
+ int size2;
+{
+ int this_char;
+
+ if (where == NULL)
+ printf ("(null)");
+ else
+ {
+ if (FIRST_STRING_P (where))
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ putchar (string1[this_char]);
+
+ where = string2;
+ }
+
+ for (this_char = where - string2; this_char < size2; this_char++)
+ putchar (string2[this_char]);
+ }
+}
+
+void
+printchar (c)
+ int c;
+{
+ putc (c, stderr);
+}
+
+#else /* not DEBUG */
+
+# undef assert
+# define assert(e)
+
+# define DEBUG_STATEMENT(e)
+# define DEBUG_PRINT1(x)
+# define DEBUG_PRINT2(x1, x2)
+# define DEBUG_PRINT3(x1, x2, x3)
+# define DEBUG_PRINT4(x1, x2, x3, x4)
+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+/* This has no initializer because initialized variables in Emacs
+ become read-only after dumping. */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in gnu-regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+#ifdef DEBUG
+ if (syntax & RE_DEBUG)
+ debug = 1;
+ else if (debug) /* was on but now is not */
+ debug = 0;
+#endif /* DEBUG */
return ret;
}
+#ifdef _LIBC
+weak_alias (__re_set_syntax, re_set_syntax)
+#endif
+
+/* This table gives an error message for each of the error codes listed
+ in gnu-regex.h. Obviously the order here has to be same as there.
+ POSIX doesn't require that we do anything for REG_NOERROR,
+ but why not be nice? */
+
+static const char *re_error_msgid[] =
+ {
+ gettext_noop ("Success"), /* REG_NOERROR */
+ gettext_noop ("No match"), /* REG_NOMATCH */
+ gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
+ gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
+ gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
+ gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
+ gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
+ gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */
+ gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
+ gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
+ gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
+ gettext_noop ("Invalid range end"), /* REG_ERANGE */
+ gettext_noop ("Memory exhausted"), /* REG_ESPACE */
+ gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
+ gettext_noop ("Premature end of regular expression"), /* REG_EEND */
+ gettext_noop ("Regular expression too big"), /* REG_ESIZE */
+ gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */
+ };
+
+/* Avoiding alloca during matching, to placate r_alloc. */
+
+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
+ searching and matching functions should not call alloca. On some
+ systems, alloca is implemented in terms of malloc, and if we're
+ using the relocating allocator routines, then malloc could cause a
+ relocation, which might (if the strings being searched are in the
+ ralloc heap) shift the data out from underneath the regexp
+ routines.
+
+ Here's another reason to avoid allocation: Emacs
+ processes input from X in a signal handler; processing X input may
+ call malloc; if input arrives while a matching routine is calling
+ malloc, then we're scrod. But Emacs can't just block input while
+ calling matching routines; then we don't notice interrupts when
+ they come in. So, Emacs blocks input around all regexp calls
+ except the matching calls, which it leaves unprotected, in the
+ faith that they will not malloc. */
+
+/* Normally, this is fine. */
+#define MATCH_MAY_ALLOCATE
+
+/* When using GNU C, we are not REALLY using the C alloca, no matter
+ what config.h may say. So don't take precautions for it. */
+#ifdef __GNUC__
+# undef C_ALLOCA
+#endif
+
+/* The match routines may not allocate if (1) they would do it with malloc
+ and (2) it's not safe for them to use malloc.
+ Note that if REL_ALLOC is defined, matching would not use malloc for the
+ failure stack, but we would still use it for the register vectors;
+ so REL_ALLOC should not affect this. */
+#if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
+# undef MATCH_MAY_ALLOCATE
+#endif
+
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE_STACK. */
+
+
+/* Number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+# define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+
+#ifdef INT_IS_16BIT
+
+# if defined MATCH_MAY_ALLOCATE
+/* 4400 was enough to cause a crash on Alpha OSF/1,
+ whose default stack limit is 2mb. */
+long int re_max_failures = 4000;
+# else
+long int re_max_failures = 2000;
+# endif
+
+union fail_stack_elt
+{
+ unsigned char *pointer;
+ long int integer;
+};
+
+typedef union fail_stack_elt fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned long int size;
+ unsigned long int avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#else /* not INT_IS_16BIT */
+
+# if defined MATCH_MAY_ALLOCATE
+/* 4400 was enough to cause a crash on Alpha OSF/1,
+ whose default stack limit is 2mb. */
+int re_max_failures = 20000;
+# else
+int re_max_failures = 2000;
+# endif
+
+union fail_stack_elt
+{
+ unsigned char *pointer;
+ int integer;
+};
+
+typedef union fail_stack_elt fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#endif /* INT_IS_16BIT */
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+
+
+/* Define macros to initialize and free the failure stack.
+ Do `return -2' if the alloc fails. */
+
+#ifdef MATCH_MAY_ALLOCATE
+# define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+
+# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
+#else
+# define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.avail = 0; \
+ } while (0)
+
+# define RESET_FAIL_STACK()
+#endif
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE_STACK requires `destination' be declared. */
+
+#define DOUBLE_FAIL_STACK(fail_stack) \
+ ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \
+ ? 0 \
+ : ((fail_stack).stack = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE_STACK ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size <<= 1, \
+ 1)))
+
+
+/* Push pointer POINTER on FAIL_STACK.
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
+ ((FAIL_STACK_FULL () \
+ && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
+ ? 0 \
+ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
+ 1))
+
+/* Push a pointer value onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_POINTER(item) \
+ fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item)
+
+/* This pushes an integer-valued item onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_INT(item) \
+ fail_stack.stack[fail_stack.avail++].integer = (item)
+
+/* Push a fail_stack_elt_t value onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ELT(item) \
+ fail_stack.stack[fail_stack.avail++] = (item)
+
+/* These three POP... operations complement the three PUSH... operations.
+ All assume that `fail_stack' is nonempty. */
+#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
+#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
+#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+# define DEBUG_PUSH PUSH_FAILURE_INT
+# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
+#else
+# define DEBUG_PUSH(item)
+# define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination'
+ be declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ /* Can't be int, since there is not a shred of a guarantee that int \
+ is wide enough to hold a value of something to which pointer can \
+ be assigned */ \
+ active_reg_t this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ } \
+ \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ if (1) \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
+ PUSH_FAILURE_POINTER (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
+ PUSH_FAILURE_POINTER (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: %p\n ", \
+ reg_info[this_reg].word.pointer); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ELT (reg_info[this_reg].word); \
+ } \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\
+ PUSH_FAILURE_INT (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\
+ PUSH_FAILURE_INT (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_POINTER (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string %p: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_POINTER (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+# define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack. */
+/* We used to use (num_regs - 1), which is the number of registers
+ this regexp will save; but that was changed to 5
+ to avoid stack overflow for a regexp with lots of parens. */
+#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items. */
+#define NUM_FAILURE_ITEMS \
+ (((0 \
+ ? 0 : highest_active_reg - lowest_active_reg + 1) \
+ * NUM_REG_ITEMS) \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (unsigned failure_id;) \
+ active_reg_t this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_POINTER (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string %p: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ /* Restore register info. */ \
+ high_reg = (active_reg_t) POP_FAILURE_INT (); \
+ DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \
+ \
+ low_reg = (active_reg_t) POP_FAILURE_INT (); \
+ DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \
+ \
+ if (1) \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ELT (); \
+ DEBUG_PRINT2 (" info: %p\n", \
+ reg_info[this_reg].word.pointer); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
+ } \
+ else \
+ { \
+ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
+ { \
+ reg_info[this_reg].word.integer = 0; \
+ regend[this_reg] = 0; \
+ regstart[this_reg] = 0; \
+ } \
+ highest_active_reg = high_reg; \
+ } \
+ \
+ set_regs_matched_done = 0; \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+
-/* re_compile_pattern takes a regular-expression string
- and converts it into a buffer full of byte commands for matching.
+/* Structure for per-register (a.k.a. per-group) information.
+ Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
- PATTERN is the address of the pattern string
- SIZE is the length of it.
- BUFP is a struct re_pattern_buffer * which points to the info
- on where to store the byte commands.
- This structure contains a char * which points to the
- actual space, which should have been obtained with malloc.
- re_compile_pattern may use realloc to grow the buffer space.
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
- The number of bytes of commands can be found out by looking in
- the struct re_pattern_buffer that bufp pointed to,
- after re_compile_pattern returns.
-*/
-#define PATPUSH(ch) (*b++ = (char) (ch))
+/* Declarations and macros for re_match_2. */
-#define PATFETCH(c) \
- {if (p == pend) goto end_of_pattern; \
- c = * (unsigned char *) p++; \
- if (translate) c = translate[c]; }
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ if (!set_regs_matched_done) \
+ { \
+ active_reg_t r; \
+ set_regs_matched_done = 1; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ } \
+ while (0)
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+static char reg_unset_dummy;
+#define REG_UNSET_VALUE (&reg_unset_dummy)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+/* Subroutine declarations and macros for regex_compile. */
+
+static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size,
+ reg_syntax_t syntax,
+ struct re_pattern_buffer *bufp));
+static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg));
+static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
+ int arg1, int arg2));
+static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
+ int arg, unsigned char *end));
+static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
+ int arg1, int arg2, unsigned char *end));
+static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p,
+ reg_syntax_t syntax));
+static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend,
+ reg_syntax_t syntax));
+static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr,
+ const char *pend,
+ char *translate,
+ reg_syntax_t syntax,
+ unsigned char *b));
+
+/* Fetch the next character in the uncompiled pattern---translating it
+ if necessary. Also cast from a signed character in the constant
+ string passed to us by the user to an unsigned char that we can use
+ as an array index (in, e.g., `translate'). */
+#ifndef PATFETCH
+# define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ if (translate) c = (unsigned char) translate[c]; \
+ } while (0)
+#endif
-#define PATFETCH_RAW(c) \
- {if (p == pend) goto end_of_pattern; \
- c = * (unsigned char *) p++; }
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+/* Go backwards one character in the pattern. */
#define PATUNFETCH p--
+
+/* If `translate' is non-null, return translate[D], else just D. We
+ cast the subscript to translate because some data is declared as
+ `char *', to avoid warnings when a string constant is passed. But
+ when we use a character as a subscript we must make it unsigned. */
+#ifndef TRANSLATE
+# define TRANSLATE(d) \
+ (translate ? (char) translate[(unsigned char) (d)] : (d))
+#endif
+
+
+/* Macros for outputting the compiled pattern into `buffer'. */
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 32
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \
+ EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it. */
+#define BUF_PUSH(c) \
+ do { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (unsigned char) (c); \
+ } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
+#define BUF_PUSH_2(c1, c2) \
+ do { \
+ GET_BUFFER_SPACE (2); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes. */
+#define BUF_PUSH_3(c1, c2, c3) \
+ do { \
+ GET_BUFFER_SPACE (3); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ *b++ = (unsigned char) (c3); \
+ } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO. We store a
+ relative address offset by the three bytes the jump itself occupies. */
+#define STORE_JUMP(op, loc, to) \
+ store_op1 (op, loc, (int) ((to) - (loc) - 3))
+
+/* Likewise, for a two-argument jump. */
+#define STORE_JUMP2(op, loc, to, arg) \
+ store_op2 (op, loc, (int) ((to) - (loc) - 3), arg)
+
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP(op, loc, to) \
+ insert_op1 (op, loc, (int) ((to) - (loc) - 3), b)
+
+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP2(op, loc, to, arg) \
+ insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b)
+
+
/* This is not an arbitrary limit: the arguments which represent offsets
into the pattern are two bytes long. So if 2^16 bytes turns out to
be too small, many things would have to change. */
-#define MAX_BUF_SIZE (1 << 16)
-
+/* Any other compiler which, like MSC, has allocation limit below 2^16
+ bytes will have to use approach similar to what was done below for
+ MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
+ reallocating to 0 bytes. Such thing is not going to work too well.
+ You have been warned!! */
+#if defined _MSC_VER && !defined WIN32
+/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
+ The REALLOC define eliminates a flurry of conversion warnings,
+ but is not required. */
+# define MAX_BUF_SIZE 65500L
+# define REALLOC(p,s) realloc ((p), (size_t) (s))
+#else
+# define MAX_BUF_SIZE (1L << 16)
+# define REALLOC(p,s) realloc ((p), (s))
+#endif
/* Extend the buffer by twice its current size via realloc and
reset the pointers that pointed into the old block to point to the
correct places in the new one. If extending the buffer results in it
being larger than MAX_BUF_SIZE, then flag memory exhausted. */
-#define EXTEND_BUFFER \
- do { \
- char *old_buffer = bufp->buffer; \
- if (bufp->allocated == MAX_BUF_SIZE) \
- goto too_big; \
- bufp->allocated <<= 1; \
- if (bufp->allocated > MAX_BUF_SIZE) \
- bufp->allocated = MAX_BUF_SIZE; \
- bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated);\
- if (bufp->buffer == NULL) \
- goto memory_exhausted; \
- /* If the buffer moved, move all the pointers into it. */ \
- if (old_buffer != bufp->buffer) \
- { \
- b = (b - old_buffer) + bufp->buffer; \
- begalt = (begalt - old_buffer) + bufp->buffer; \
- if (fixup_jump) \
- fixup_jump = (fixup_jump - old_buffer) + bufp->buffer;\
- if (laststart) \
- laststart = (laststart - old_buffer) + bufp->buffer; \
- if (pending_exact) \
- pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
- } \
+#define EXTEND_BUFFER() \
+ do { \
+ unsigned char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == MAX_BUF_SIZE) \
+ return REG_ESIZE; \
+ bufp->allocated <<= 1; \
+ if (bufp->allocated > MAX_BUF_SIZE) \
+ bufp->allocated = MAX_BUF_SIZE; \
+ bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\
+ if (bufp->buffer == NULL) \
+ return REG_ESPACE; \
+ /* If the buffer moved, move all the pointers into it. */ \
+ if (old_buffer != bufp->buffer) \
+ { \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ } \
} while (0)
-static void store_jump (), insert_jump ();
-char *
-re_compile_pattern (pattern, size, bufp)
- char *pattern;
- int size;
- struct re_pattern_buffer *bufp;
-{
- register char *b = bufp->buffer;
- register char *p = pattern;
- char *pend = pattern + size;
- register unsigned c, c1;
- char *p1;
- unsigned char *translate = (unsigned char *) bufp->translate;
+/* Since we have one byte reserved for the register number argument to
+ {start,stop}_memory, the maximum number of groups we can report
+ things about is what fits in that byte. */
+#define MAX_REGNUM 255
- /* address of the count-byte of the most recently inserted "exactn" command.
- This makes it possible to tell whether a new exact-match character
- can be added to that command or requires a new "exactn" command. */
-
- char *pending_exact = 0;
+/* But patterns can have more than `MAX_REGNUM' registers. We just
+ ignore the excess. */
+typedef unsigned regnum_t;
- /* address of the place where a forward-jump should go
- to the end of the containing expression.
- Each alternative of an "or", except the last, ends with a forward-jump
- of this sort. */
- char *fixup_jump = 0;
+/* Macros for the compile stack. */
- /* address of start of the most recently finished expression.
- This tells postfix * where to find the start of its operand. */
+/* Since offsets can go either forwards or backwards, this type needs to
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
+/* int may be not enough when sizeof(int) == 2. */
+typedef long pattern_offset_t;
- char *laststart = 0;
-
- /* In processing a repeat, 1 means zero matches is allowed */
+typedef struct
+{
+ pattern_offset_t begalt_offset;
+ pattern_offset_t fixup_alt_jump;
+ pattern_offset_t inner_group_offset;
+ pattern_offset_t laststart_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
- char zero_times_ok;
- /* In processing a repeat, 1 means many matches is allowed */
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (ISDIGIT (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
- char many_times_ok;
+#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+/* The GNU C library provides support for user-defined character classes
+ and the functions from ISO C amendement 1. */
+# ifdef CHARCLASS_NAME_MAX
+# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
+# else
+/* This shouldn't happen but some implementation might still have this
+ problem. Use a reasonable default value. */
+# define CHAR_CLASS_MAX_LENGTH 256
+# endif
+
+# ifdef _LIBC
+# define IS_CHAR_CLASS(string) __wctype (string)
+# else
+# define IS_CHAR_CLASS(string) wctype (string)
+# endif
+#else
+# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+# define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+#endif
+
+#ifndef MATCH_MAY_ALLOCATE
+
+/* If we cannot allocate large objects within re_match_2_internal,
+ we make the fail stack and register vectors global.
+ The fail stack, we grow to the maximum size when a regexp
+ is compiled.
+ The register vectors, we adjust in size each time we
+ compile a regexp, according to the number of registers it needs. */
+
+static fail_stack_type fail_stack;
+
+/* Size with which the following vectors are currently allocated.
+ That is so we can make them bigger as needed,
+ but never make them smaller. */
+static int regs_allocated_size;
+
+static const char ** regstart, ** regend;
+static const char ** old_regstart, ** old_regend;
+static const char **best_regstart, **best_regend;
+static register_info_type *reg_info;
+static const char **reg_dummy;
+static register_info_type *reg_info_dummy;
+
+/* Make the register vectors big enough for NUM_REGS registers,
+ but don't make them smaller. */
+
+static
+regex_grow_registers (num_regs)
+ int num_regs;
+{
+ if (num_regs > regs_allocated_size)
+ {
+ RETALLOC_IF (regstart, num_regs, const char *);
+ RETALLOC_IF (regend, num_regs, const char *);
+ RETALLOC_IF (old_regstart, num_regs, const char *);
+ RETALLOC_IF (old_regend, num_regs, const char *);
+ RETALLOC_IF (best_regstart, num_regs, const char *);
+ RETALLOC_IF (best_regend, num_regs, const char *);
+ RETALLOC_IF (reg_info, num_regs, register_info_type);
+ RETALLOC_IF (reg_dummy, num_regs, const char *);
+ RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
+
+ regs_allocated_size = num_regs;
+ }
+}
- /* address of beginning of regexp, or inside of last \( */
+#endif /* not MATCH_MAY_ALLOCATE */
+
+static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type
+ compile_stack,
+ regnum_t regnum));
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `gnu-regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is zero;
+ `re_nsub' is the number of subexpressions in PATTERN;
+ `not_bol' and `not_eol' are zero;
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+/* Return, freeing storage we allocated. */
+#define FREE_STACK_RETURN(value) \
+ return (free (compile_stack.stack), value)
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+ const char *pattern;
+ size_t size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer *bufp;
+{
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random temporary spot in PATTERN. */
+ const char *p1;
+
+ /* Points to the end of the buffer, where we should append. */
+ register unsigned char *b;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ const char *p = pattern;
+ const char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ RE_TRANSLATE_TYPE translate = bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell if a new exact-match
+ character can be added to that command or if the character requires
+ a new `exactn' command. */
+ unsigned char *pending_exact = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells, e.g., postfix * where to find the start of its
+ operand. Reset at the beginning of groups and alternatives. */
+ unsigned char *laststart = 0;
+
+ /* Address of beginning of regexp, or inside of last group. */
+ unsigned char *begalt;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ which to go back if the interval is invalid. */
+ const char *beg_interval;
+
+ /* Address of the place where a forward jump should go to the end of
+ the containing expression. Each alternative of an `or' -- except the
+ last -- ends with a forward jump of this sort. */
+ unsigned char *fixup_alt_jump = 0;
+
+ /* Counts open-groups as they are encountered. Remembered for the
+ matching close-group on the compile stack, so the same register
+ number is put in the stop_memory as the start_memory. */
+ regnum_t regnum = 0;
+
+#ifdef DEBUG
+ DEBUG_PRINT1 ("\nCompiling pattern: ");
+ if (debug)
+ {
+ unsigned debug_count;
- char *begalt = b;
+ for (debug_count = 0; debug_count < size; debug_count++)
+ putchar (pattern[debug_count]);
+ putchar ('\n');
+ }
+#endif /* DEBUG */
- /* Stack of information saved by \( and restored by \).
- Four stack elements are pushed by each \(:
- First, the value of b.
- Second, the value of fixup_jump.
- Third, the value of regnum.
- Fourth, the value of begalt. */
+ /* Initialize the compile stack. */
+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+ if (compile_stack.stack == NULL)
+ return REG_ESPACE;
- int stackb[40];
- int *stackp = stackb;
- int *stacke = stackb + 40;
- int *stackt;
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
- /* Counts \('s as they are encountered. Remembered for the matching \),
- where it becomes the "register number" to put in the stop_memory command */
+ /* Initialize the pattern buffer. */
+ bufp->syntax = syntax;
+ bufp->fastmap_accurate = 0;
+ bufp->not_bol = bufp->not_eol = 0;
- int regnum = 1;
+ /* Set `used' to zero, so that if we return an error, the pattern
+ printer (for debugging) will think there's no pattern. We reset it
+ at the end. */
+ bufp->used = 0;
- bufp->fastmap_accurate = 0;
+ /* Always count groups, whether or not bufp->no_sub is set. */
+ bufp->re_nsub = 0;
-#ifndef emacs
-#ifndef SYNTAX_TABLE
- /*
- * Initialize the syntax table.
- */
- init_syntax_once();
-#endif
+#if !defined emacs && !defined SYNTAX_TABLE
+ /* Initialize the syntax table. */
+ init_syntax_once ();
#endif
if (bufp->allocated == 0)
{
- bufp->allocated = 28;
if (bufp->buffer)
- /* EXTEND_BUFFER loses when bufp->allocated is 0 */
- bufp->buffer = (char *) realloc (bufp->buffer, 28);
+ { /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
else
- /* Caller did not allocate a buffer. Do it for him */
- bufp->buffer = (char *) malloc (28);
- if (!bufp->buffer) goto memory_exhausted;
- begalt = b = bufp->buffer;
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE);
+
+ bufp->allocated = INIT_BUF_SIZE;
}
+ begalt = b = bufp->buffer;
+
+ /* Loop through the uncompiled pattern until we're at the end. */
while (p != pend)
{
- if (b - bufp->buffer > bufp->allocated - 10)
- /* Note that EXTEND_BUFFER clobbers c */
- EXTEND_BUFFER;
-
PATFETCH (c);
switch (c)
- {
- case '$':
- if (obscure_syntax & RE_TIGHT_VBAR)
- {
- if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
- goto normal_char;
- /* Make operand of last vbar end before this `$'. */
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
- fixup_jump = 0;
- PATPUSH (endline);
- break;
- }
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ BUF_PUSH (begline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ BUF_PUSH (endline);
+ else
+ goto normal_char;
+ }
+ break;
- /* $ means succeed if at end of line, but only in special contexts.
- If randomly in the middle of a pattern, it is a normal character. */
- if (p == pend || *p == '\n'
- || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
- || (obscure_syntax & RE_NO_BK_PARENS
- ? *p == ')'
- : *p == '\\' && p[1] == ')')
- || (obscure_syntax & RE_NO_BK_VBAR
- ? *p == '|'
- : *p == '\\' && p[1] == '|'))
- {
- PATPUSH (endline);
- break;
- }
- goto normal_char;
-
- case '^':
- /* ^ means succeed if at beg of line, but only if no preceding pattern. */
-
- if (laststart && p[-2] != '\n'
- && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- if (obscure_syntax & RE_TIGHT_VBAR)
- {
- if (p != pattern + 1
- && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- PATPUSH (begline);
- begalt = b;
- }
- else
- PATPUSH (begline);
- break;
case '+':
- case '?':
- if (obscure_syntax & RE_BK_PLUS_QM)
- goto normal_char;
- handle_plus:
- case '*':
- /* If there is no previous pattern, char not special. */
- if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- /* If there is a sequence of repetition chars,
- collapse it down to equivalent to just one. */
- zero_times_ok = 0;
- many_times_ok = 0;
- while (1)
- {
- zero_times_ok |= c != '+';
- many_times_ok |= c != '?';
- if (p == pend)
- break;
- PATFETCH (c);
- if (c == '*')
- ;
- else if (!(obscure_syntax & RE_BK_PLUS_QM)
- && (c == '+' || c == '?'))
- ;
- else if ((obscure_syntax & RE_BK_PLUS_QM)
- && c == '\\')
- {
- int c1;
- PATFETCH (c1);
- if (!(c1 == '+' || c1 == '?'))
- {
- PATUNFETCH;
- PATUNFETCH;
- break;
- }
- c = c1;
- }
- else
- {
- PATUNFETCH;
- break;
- }
- }
-
- /* Star, etc. applied to an empty pattern is equivalent
- to an empty pattern. */
- if (!laststart)
- break;
-
- /* Now we know whether 0 matches is allowed,
- and whether 2 or more matches is allowed. */
- if (many_times_ok)
- {
- /* If more than one repetition is allowed,
- put in a backward jump at the end. */
- store_jump (b, maybe_finalize_jump, laststart - 3);
- b += 3;
- }
- insert_jump (on_failure_jump, laststart, b + 3, b);
- pending_exact = 0;
- b += 3;
- if (!zero_times_ok)
- {
- /* At least one repetition required: insert before the loop
- a skip over the initial on-failure-jump instruction */
- insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
- b += 3;
- }
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ { /* More than one repetition is allowed, so put in at the
+ end a backward relative jump from `b' to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ && zero_times_ok
+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' before the initial
+ `on_failure_jump' instruction of the loop. This
+ effects a skip over that instruction the first time
+ we hit that loop. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
break;
+
case '.':
- laststart = b;
- PATPUSH (anychar);
- break;
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
+
+
+ case '[':
+ {
+ boolean had_char_class = false;
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
+ GET_BUFFER_SPACE (34);
+
+ laststart = b;
+
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ FREE_STACK_RETURN (REG_ERANGE);
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character: if this is a hyphen not at the
+ beginning or the end of a list, then it's the range
+ operator. */
+ if (c == '-'
+ && !(p - 2 >= pattern && p[-2] == '[')
+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+ && *p != ']')
+ {
+ reg_errcode_t ret
+ = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ else if (p[0] == '-' && p[1] != ']')
+ { /* This handles ranges made up of characters only. */
+ reg_errcode_t ret;
+
+ /* Move past the `-'. */
+ PATFETCH (c1);
+
+ ret = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ { /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if ((c == ':' && *p == ']') || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and `:]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']')
+ {
+/* CYGNUS LOCAL: Skip this code if we don't have btowc(). btowc() is */
+/* defined in the 1994 Amendment 1 to ISO C and may not be present on */
+/* systems where we have wchar.h and wctype.h. */
+#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_BTOWC)
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_upper = STREQ (str, "upper");
+ wctype_t wt;
+ int ch;
+
+ wt = IS_CHAR_CLASS (str);
+ if (wt == 0)
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
+ {
+# ifdef _LIBC
+ if (__iswctype (__btowc (ch), wt))
+ SET_LIST_BIT (ch);
+#else
+ if (iswctype (btowc (ch), wt))
+ SET_LIST_BIT (ch);
+#endif
- case '[':
- while (b - bufp->buffer
- > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
- /* Note that EXTEND_BUFFER clobbers c */
- EXTEND_BUFFER;
+ if (translate && (is_upper || is_lower)
+ && (ISUPPER (ch) || ISLOWER (ch)))
+ SET_LIST_BIT (ch);
+ }
+
+ had_char_class = true;
+#else
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str))
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ /* This was split into 3 if's to
+ avoid an arbitrary limit in some compiler. */
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (ch);
+ if ( translate && (is_upper || is_lower)
+ && (ISUPPER (ch) || ISLOWER (ch)))
+ SET_LIST_BIT (ch);
+ }
+ had_char_class = true;
+#endif /* libc || wctype.h */
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ had_char_class = false;
+ }
+ }
+ else
+ {
+ had_char_class = false;
+ SET_LIST_BIT (c);
+ }
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ }
+ break;
- laststart = b;
- if (*p == '^')
- PATPUSH (charset_not), p++;
- else
- PATPUSH (charset);
- p1 = p;
-
- PATPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
- /* Clear the whole map */
- memset (b, '\0', (1 << BYTEWIDTH) / BYTEWIDTH);
- /* Read in characters and ranges, setting map bits */
- while (1)
- {
- PATFETCH (c);
- if (c == ']' && p != p1 + 1) break;
- if (*p == '-' && p[1] != ']')
- {
- PATFETCH (c1);
- PATFETCH (c1);
- while (c <= c1)
- b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH), c++;
- }
- else
- {
- b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH);
- }
- }
- /* Discard any bitmap bytes that are all 0 at the end of the map.
- Decrement the map-length byte too. */
- while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
- b[-1]--;
- b += b[-1];
- break;
case '(':
- if (! (obscure_syntax & RE_NO_BK_PARENS))
- goto normal_char;
- else
- goto handle_open;
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
- case ')':
- if (! (obscure_syntax & RE_NO_BK_PARENS))
- goto normal_char;
- else
- goto handle_close;
- case '\n':
- if (! (obscure_syntax & RE_NEWLINE_OR))
- goto normal_char;
- else
- goto handle_bar;
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
+
+
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
+
case '|':
- if (! (obscure_syntax & RE_NO_BK_VBAR))
- goto normal_char;
- else
- goto handle_bar;
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
+
case '\\':
- if (p == pend) goto invalid_pattern;
- PATFETCH_RAW (c);
- switch (c)
- {
- case '(':
- if (obscure_syntax & RE_NO_BK_PARENS)
- goto normal_backsl;
- handle_open:
- if (stackp == stacke) goto nesting_too_deep;
- if (regnum < RE_NREGS)
- {
- PATPUSH (start_memory);
- PATPUSH (regnum);
- }
- *stackp++ = b - bufp->buffer;
- *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
- *stackp++ = regnum++;
- *stackp++ = begalt - bufp->buffer;
- fixup_jump = 0;
- laststart = 0;
- begalt = b;
- break;
-
- case ')':
- if (obscure_syntax & RE_NO_BK_PARENS)
- goto normal_backsl;
- handle_close:
- if (stackp == stackb) goto unmatched_close;
- begalt = *--stackp + bufp->buffer;
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
- if (stackp[-1] < RE_NREGS)
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
+
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
+
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
+
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
+
+ compile_stack.size <<= 1;
+ }
+
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
+
+ compile_stack.avail++;
+
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+ break;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+ if (COMPILE_STACK_EMPTY)
+ {
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+ }
+
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
{
- PATPUSH (stop_memory);
- PATPUSH (stackp[-1]);
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
}
- stackp -= 2;
- fixup_jump = 0;
- if (*stackp)
- fixup_jump = *stackp + bufp->buffer - 1;
- laststart = *--stackp + bufp->buffer;
- break;
-
- case '|':
- if (obscure_syntax & RE_NO_BK_VBAR)
- goto normal_backsl;
- handle_bar:
- insert_jump (on_failure_jump, begalt, b + 6, b);
- pending_exact = 0;
- b += 3;
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
- fixup_jump = b;
- b += 3;
- laststart = 0;
- begalt = b;
- break;
+
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (syntax & RE_LIMITED_OPS)
+ goto normal_char;
+
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this alternative's analogous
+ jump (put in below, which in turn will jump to the next
+ (if any) alternative's such jump, etc.). The last such
+ jump jumps to the correct final destination. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_EBRACE);
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the upper bound is zero, don't want to succeed at
+ all; jump from `laststart' to `b + 3', which will be
+ the end of the buffer after we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succeed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
#ifdef emacs
- case '=':
- PATPUSH (at_dot);
- break;
-
- case 's':
- laststart = b;
- PATPUSH (syntaxspec);
- PATFETCH (c);
- PATPUSH (syntax_spec_code[c]);
- break;
-
- case 'S':
- laststart = b;
- PATPUSH (notsyntaxspec);
- PATFETCH (c);
- PATPUSH (syntax_spec_code[c]);
- break;
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
#endif /* emacs */
- case 'w':
- laststart = b;
- PATPUSH (wordchar);
- break;
-
- case 'W':
- laststart = b;
- PATPUSH (notwordchar);
- break;
-
- case '<':
- PATPUSH (wordbeg);
- break;
-
- case '>':
- PATPUSH (wordend);
- break;
-
- case 'b':
- PATPUSH (wordbound);
- break;
-
- case 'B':
- PATPUSH (notwordbound);
- break;
-
- case '`':
- PATPUSH (begbuf);
- break;
-
- case '\'':
- PATPUSH (endbuf);
- break;
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- c1 = c - '0';
- if (c1 >= regnum)
+
+ case 'w':
+ if (syntax & RE_NO_GNU_OPS)
goto normal_char;
- for (stackt = stackp - 2; stackt > stackb; stackt -= 4)
- if (*stackt == c1)
- goto normal_char;
- laststart = b;
- PATPUSH (duplicate);
- PATPUSH (c1);
- break;
-
- case '+':
- case '?':
- if (obscure_syntax & RE_BK_PLUS_QM)
- goto handle_plus;
-
- default:
- normal_backsl:
- /* You might think it would be useful for \ to mean
- not to translate; but if we don't translate it
- it will never match anything. */
- if (translate) c = translate[c];
- goto normal_char;
- }
- break;
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
+
+
+ case 'W':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
+
+
+ case '<':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordbeg);
+ break;
+
+ case '>':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordend);
+ break;
+
+ case 'b':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordbound);
+ break;
+
+ case 'B':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (notwordbound);
+ break;
+
+ case '`':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (begbuf);
+ break;
+
+ case '\'':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (endbuf);
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
+
+ c1 = c - '0';
+
+ if (c1 > regnum)
+ FREE_STACK_RETURN (REG_ESUBREG);
+
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, (regnum_t) c1))
+ goto normal_char;
+
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
+
+
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
+
default:
+ /* Expects the character in `c'. */
normal_char:
- if (!pending_exact || pending_exact + *pending_exact + 1 != b
- || *pending_exact == 0177 || *p == '*' || *p == '^'
- || ((obscure_syntax & RE_BK_PLUS_QM)
+ /* If no exactn currently being built. */
+ if (!pending_exact
+
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
+
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact == (1 << BYTEWIDTH) - 1
+
+ /* If followed by a repetition operator. */
+ || *p == '*' || *p == '^'
+ || ((syntax & RE_BK_PLUS_QM)
? *p == '\\' && (p[1] == '+' || p[1] == '?')
- : (*p == '+' || *p == '?')))
+ : (*p == '+' || *p == '?'))
+ || ((syntax & RE_INTERVALS)
+ && ((syntax & RE_NO_BK_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
{
- laststart = b;
- PATPUSH (exactn);
- pending_exact = b;
- PATPUSH (0);
- }
- PATPUSH (c);
- (*pending_exact)++;
- }
- }
+ /* Start building a new exactn. */
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
+ laststart = b;
- if (stackp != stackb) goto unmatched_open;
+ BUF_PUSH_2 (exactn, 0);
+ pending_exact = b - 1;
+ }
+
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ break;
+ } /* switch (c) */
+ } /* while p != pend */
- bufp->used = b - bufp->buffer;
- return 0;
- invalid_pattern:
- return "Invalid regular expression";
+ /* Through the pattern now. */
- unmatched_open:
- return "Unmatched \\(";
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
- unmatched_close:
- return "Unmatched \\)";
+ if (!COMPILE_STACK_EMPTY)
+ FREE_STACK_RETURN (REG_EPAREN);
- end_of_pattern:
- return "Premature end of regular expression";
+ /* If we don't want backtracking, force success
+ the first time we reach the end of the compiled pattern. */
+ if (syntax & RE_NO_POSIX_BACKTRACKING)
+ BUF_PUSH (succeed);
- nesting_too_deep:
- return "Nesting too deep";
+ free (compile_stack.stack);
- too_big:
- return "Regular expression too big";
+ /* We have succeeded; set the length of the buffer. */
+ bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+ if (debug)
+ {
+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
+ print_compiled_pattern (bufp);
+ }
+#endif /* DEBUG */
+
+#ifndef MATCH_MAY_ALLOCATE
+ /* Initialize the failure stack to the largest possible stack. This
+ isn't necessary unless we're trying to avoid calling alloca in
+ the search and match routines. */
+ {
+ int num_regs = bufp->re_nsub + 1;
+
+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
+ is strictly greater than re_max_failures, the largest possible stack
+ is 2 * re_max_failures failure points. */
+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
+ {
+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
+
+# ifdef emacs
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) xmalloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+# else /* not emacs */
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) malloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) realloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+# endif /* not emacs */
+ }
+
+ regex_grow_registers (num_regs);
+ }
+#endif /* not MATCH_MAY_ALLOCATE */
+
+ return REG_NOERROR;
+} /* regex_compile */
+
+/* Subroutines for `regex_compile'. */
- memory_exhausted:
- return "Memory exhausted";
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
+
+static void
+store_op1 (op, loc, arg)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg);
}
-/* Store where `from' points a jump operation to jump to where `to' points.
- `opcode' is the opcode to store. */
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
static void
-store_jump (from, opcode, to)
- char *from, *to;
- char opcode;
+store_op2 (op, loc, arg1, arg2)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
{
- from[0] = opcode;
- from[1] = (to - (from + 3)) & 0377;
- from[2] = (to - (from + 3)) >> 8;
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg1);
+ STORE_NUMBER (loc + 3, arg2);
}
-/* Open up space at char FROM, and insert there a jump to TO.
- CURRENT_END gives te end of the storage no in use,
- so we know how much data to copy up.
- OP is the opcode of the jump to insert.
- If you call this function, you must zero out pending_exact. */
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+ for OP followed by two-byte integer parameter ARG. */
static void
-insert_jump (op, from, to, current_end)
- char op;
- char *from, *to, *current_end;
+insert_op1 (op, loc, arg, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+ unsigned char *end;
{
- register char *pto = current_end + 3;
- register char *pfrom = current_end;
- while (pfrom != from)
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 3;
+
+ while (pfrom != loc)
*--pto = *--pfrom;
- store_jump (from, op, to);
+
+ store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 5;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ after an alternative or a begin-subexpression. We assume there is at
+ least one character before the ^. */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ const char *pattern, *p;
+ reg_syntax_t syntax;
+{
+ const char *prev = p - 2;
+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+
+ return
+ /* After a subexpression? */
+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+ /* After an alternative? */
+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ at least one character after the $, i.e., `P < PEND'. */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ const char *p, *pend;
+ reg_syntax_t syntax;
+{
+ const char *next = p;
+ boolean next_backslash = *next == '\\';
+ const char *next_next = p + 1 < pend ? p + 1 : 0;
+
+ return
+ /* Before a subexpression? */
+ (syntax & RE_NO_BK_PARENS ? *next == ')'
+ : next_backslash && next_next && *next_next == ')')
+ /* Before an alternative? */
+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
+ : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ Then we set the translation of all bits between the starting and
+ ending characters (inclusive) in the compiled pattern B.
+
+ Return an error code.
+
+ We use these short variable names so we can use the same macros as
+ `regex_compile' itself. */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+ const char **p_ptr, *pend;
+ RE_TRANSLATE_TYPE translate;
+ reg_syntax_t syntax;
+ unsigned char *b;
+{
+ unsigned this_char;
+
+ const char *p = *p_ptr;
+ unsigned int range_start, range_end;
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ /* Even though the pattern is a signed `char *', we need to fetch
+ with unsigned char *'s; if the high bit of the pattern character
+ is set, the range endpoints will be negative if we fetch using a
+ signed char *.
+
+ We also want to fetch the endpoints without translating them; the
+ appropriate translation is done in the bit-setting loop below. */
+ /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */
+ range_start = ((const unsigned char *) p)[-2];
+ range_end = ((const unsigned char *) p)[0];
+
+ /* Have to increment the pointer into the pattern string, so the
+ caller isn't still at the ending character. */
+ (*p_ptr)++;
+
+ /* If the start is after the end, the range is empty. */
+ if (range_start > range_end)
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+ /* Here we see why `this_char' has to be larger than an `unsigned
+ char' -- the range is inclusive, so if `range_end' == 0xff
+ (assuming 8-bit characters), we would otherwise go into an infinite
+ loop, since all characters <= 0xff. */
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+
+ return REG_NOERROR;
}
-/* Given a pattern, compute a fastmap from it.
- The fastmap records which of the (1 << BYTEWIDTH) possible characters
- can start a string that matches the pattern.
- This fastmap is used by re_search to skip quickly over totally implausible text.
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
+ characters can start a string that matches the pattern. This fastmap
+ is used by re_search to skip quickly over impossible starting points.
- The caller must supply the address of a (1 << BYTEWIDTH)-byte data area
- as bufp->fastmap.
- The other components of bufp describe the pattern to be used. */
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as BUFP->fastmap.
-void
+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+ the pattern buffer.
+
+ Returns 0 if we succeed, -2 if an internal error. */
+
+int
re_compile_fastmap (bufp)
struct re_pattern_buffer *bufp;
{
- unsigned char *pattern = (unsigned char *) bufp->buffer;
- int size = bufp->used;
+ int j, k;
+#ifdef MATCH_MAY_ALLOCATE
+ fail_stack_type fail_stack;
+#endif
+#ifndef REGEX_MALLOC
+ char *destination;
+#endif
+
register char *fastmap = bufp->fastmap;
- register unsigned char *p = pattern;
- register unsigned char *pend = pattern + size;
- register int j;
- unsigned char *translate = (unsigned char *) bufp->translate;
+ unsigned char *pattern = bufp->buffer;
+ unsigned char *p = pattern;
+ register unsigned char *pend = pattern + bufp->used;
+
+#ifdef REL_ALLOC
+ /* This holds the pointer to the failure stack, when
+ it is allocated relocatably. */
+ fail_stack_elt_t *failure_stack_ptr;
+#endif
+
+ /* Assume that each path through the pattern can be null until
+ proven otherwise. We set this false at the bottom of switch
+ statement, to which we get only if a particular path doesn't
+ match the empty string. */
+ boolean path_can_be_null = true;
- unsigned char *stackb[NFAILURES];
- unsigned char **stackp = stackb;
+ /* We aren't doing a `succeed_n' to begin with. */
+ boolean succeed_n_p = false;
- memset (fastmap, '\0', (1 << BYTEWIDTH));
- bufp->fastmap_accurate = 1;
+ assert (fastmap != NULL && p != NULL);
+
+ INIT_FAIL_STACK ();
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
bufp->can_be_null = 0;
-
- while (p)
+
+ while (1)
{
- if (p == pend)
+ if (p == pend || *p == succeed)
{
- bufp->can_be_null = 1;
- break;
+ /* We have reached the (effective) end of pattern. */
+ if (!FAIL_STACK_EMPTY ())
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail].pointer;
+
+ continue;
+ }
+ else
+ break;
}
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((enum regexpcode) *p++))
-#else
- switch ((enum regexpcode) *p++)
-#endif
+
+ /* We should never be about to go beyond the end of the pattern. */
+ assert (p < pend);
+
+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
{
+
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
+ case duplicate:
+ bufp->can_be_null = 1;
+ goto done;
+
+
+ /* Following are the cases which match a character. These end
+ with `break'. */
+
case exactn:
- if (translate)
- fastmap[translate[p[1]]] = 1;
- else
- fastmap[p[1]] = 1;
+ fastmap[p[1]] = 1;
break;
- case begline:
- case before_dot:
- case at_dot:
- case after_dot:
- case begbuf:
- case endbuf:
- case wordbound:
- case notwordbound:
- case wordbeg:
- case wordend:
- continue;
- case endline:
- if (translate)
- fastmap[translate['\n']] = 1;
- else
- fastmap['\n'] = 1;
- if (bufp->can_be_null != 1)
- bufp->can_be_null = 2;
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
break;
- case finalize_jump:
- case maybe_finalize_jump:
- case jump:
- case dummy_failure_jump:
- bufp->can_be_null = 1;
- j = *p++ & 0377;
- j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
- p += j + 1; /* The 1 compensates for missing ++ above */
- if (j > 0)
- continue;
- /* Jump backward reached implies we just went through
- the body of a loop and matched nothing.
- Opcode jumped to should be an on_failure_jump.
- Just treat it like an ordinary jump.
- For a * loop, it has pushed its failure point already;
- if so, discard that as redundant. */
- if ((enum regexpcode) *p != on_failure_jump)
- continue;
- p++;
- j = *p++ & 0377;
- j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
- p += j + 1; /* The 1 compensates for missing ++ above */
- if (stackp != stackb && *stackp == p)
- stackp--;
- continue;
-
- case on_failure_jump:
- j = *p++ & 0377;
- j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
- p++;
- *++stackp = p + j;
- continue;
- case start_memory:
- case stop_memory:
- p++;
- continue;
+ case charset_not:
+ /* Chars beyond end of map must be allowed. */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
+ break;
- case duplicate:
- bufp->can_be_null = 1;
- fastmap['\n'] = 1;
- case anychar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (j != '\n')
- fastmap[j] = 1;
- if (bufp->can_be_null)
- return;
- /* Don't return; check the alternative paths
- so we can set can_be_null if appropriate. */
- break;
case wordchar:
for (j = 0; j < (1 << BYTEWIDTH); j++)
@@ -828,120 +3217,302 @@ re_compile_fastmap (bufp)
fastmap[j] = 1;
break;
+
case notwordchar:
for (j = 0; j < (1 << BYTEWIDTH); j++)
if (SYNTAX (j) != Sword)
fastmap[j] = 1;
break;
+
+ case anychar:
+ {
+ int fastmap_newline = fastmap['\n'];
+
+ /* `.' matches anything ... */
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = fastmap_newline;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ goto done;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+ }
+
#ifdef emacs
- case syntaxspec:
+ case syntaxspec:
k = *p++;
for (j = 0; j < (1 << BYTEWIDTH); j++)
if (SYNTAX (j) == (enum syntaxcode) k)
fastmap[j] = 1;
break;
+
case notsyntaxspec:
k = *p++;
for (j = 0; j < (1 << BYTEWIDTH); j++)
if (SYNTAX (j) != (enum syntaxcode) k)
fastmap[j] = 1;
break;
+
+
+ /* All cases after this match the empty string. These end with
+ `continue'. */
+
+
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ continue;
#endif /* emacs */
- case charset:
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
- {
- if (translate)
- fastmap[translate[j]] = 1;
- else
- fastmap[j] = 1;
- }
- break;
- case charset_not:
- /* Chars beyond end of map must be allowed */
- for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
- if (translate)
- fastmap[translate[j]] = 1;
- else
- fastmap[j] = 1;
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case push_dummy_failure:
+ continue;
+
+
+ case jump_n:
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
+ && (re_opcode_t) *p != succeed_n)
+ continue;
+
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
+ && fail_stack.stack[fail_stack.avail - 1].pointer == p)
+ fail_stack.avail--;
+
+ continue;
+
+
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ {
+ RESET_FAIL_STACK ();
+ return -2;
+ }
+ }
+ else
+ bufp->can_be_null = 1;
+
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
+ }
+
+ continue;
+
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p += 2;
+
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
+
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- {
- if (translate)
- fastmap[translate[j]] = 1;
- else
- fastmap[j] = 1;
- }
- break;
- case unused:
- case syntaxspec:
- case notsyntaxspec:
default:
- break;
- }
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
+
+ /* Getting here means we have found the possible starting
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
+ path_can_be_null = false;
+ p = pend;
+ } /* while p */
+
+ /* Set `can_be_null' for the last path (also the first path, if the
+ pattern is empty). */
+ bufp->can_be_null |= path_can_be_null;
+
+ done:
+ RESET_FAIL_STACK ();
+ return 0;
+} /* re_compile_fastmap */
+#ifdef _LIBC
+weak_alias (__re_compile_fastmap, re_compile_fastmap)
+#endif
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
- /* Get here means we have successfully found the possible starting characters
- of one path of the pattern. We need not follow this path any farther.
- Instead, look at the next alternative remembered in the stack. */
- if (stackp != stackb)
- p = *stackp--;
- else
- break;
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = (regoff_t *) 0;
}
}
+#ifdef _LIBC
+weak_alias (__re_set_registers, re_set_registers)
+#endif
-/* Like re_search_2, below, but only one string is specified. */
+/* Searching routines. */
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
int
-re_search (pbufp, string, size, startpos, range, regs)
- struct re_pattern_buffer *pbufp;
- char *string;
+re_search (bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
int size, startpos, range;
struct re_registers *regs;
{
- return re_search_2 (pbufp, 0, 0, string, size, startpos, range, regs, size);
+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
+ regs, size);
}
+#ifdef _LIBC
+weak_alias (__re_search, re_search)
+#endif
+
-/* Like re_match_2 but tries first a match starting at index STARTPOS,
- then at STARTPOS + 1, and so on.
- RANGE is the number of places to try before giving up.
- If RANGE is negative, the starting positions tried are
- STARTPOS, STARTPOS - 1, etc.
- It is up to the caller to make sure that range is not so large
- as to take the starting position outside of the input strings.
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on.
-The value returned is the position at which the match was found,
- or -1 if no match was found,
- or -2 if error (such as failure stack overflow). */
+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+
+ RANGE is how far to scan while trying to match. RANGE = 0 means try
+ only at STARTPOS; in general, the last start tried is STARTPOS +
+ RANGE.
+
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire BUFP->buffer and its contained
+ subexpressions.
+
+ Do not consider matching one past the index STOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ We return either the position in the strings at which the match was
+ found, -1 if no match, or -2 if error (such as failure
+ stack overflow). */
int
-re_search_2 (pbufp, string1, size1, string2, size2, startpos, range, regs, mstop)
- struct re_pattern_buffer *pbufp;
- char *string1, *string2;
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
int size1, size2;
int startpos;
- register int range;
+ int range;
struct re_registers *regs;
- int mstop;
+ int stop;
{
- register char *fastmap = pbufp->fastmap;
- register unsigned char *translate = (unsigned char *) pbufp->translate;
- int total = size1 + size2;
int val;
-
- /* Update the fastmap now if not correct already */
- if (fastmap && !pbufp->fastmap_accurate)
- re_compile_fastmap (pbufp);
-
- /* Don't waste time in a long search for a pattern
- that says it is anchored. */
- if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
- && range > 0)
+ register char *fastmap = bufp->fastmap;
+ register RE_TRANSLATE_TYPE translate = bufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+
+ /* Check for out-of-range STARTPOS. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up RANGE if it might eventually take us outside
+ the virtual concatenation of STRING1 and STRING2.
+ Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
+ if (endpos < 0)
+ range = 0 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ search for a pattern that must be anchored. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
{
if (startpos > 0)
return -1;
@@ -949,159 +3520,451 @@ re_search_2 (pbufp, string1, size1, string2, size2, startpos, range, regs, mstop
range = 1;
}
- while (1)
+#ifdef emacs
+ /* In a forward search for something that starts with \=.
+ don't keep searching past point. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
{
- /* If a fastmap is supplied, skip quickly over characters
- that cannot possibly be the start of a match.
- Note, however, that if the pattern can possibly match
- the null string, we must test it at each starting point
- so that we take the first null string we get. */
+ range = PT - startpos;
+ if (range <= 0)
+ return -1;
+ }
+#endif /* emacs */
- if (fastmap && startpos < total && pbufp->can_be_null != 1)
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !bufp->fastmap_accurate)
+ if (re_compile_fastmap (bufp) == -2)
+ return -2;
+
+ /* Loop through the string, looking for a place to start matching. */
+ for (;;)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
+ if (fastmap && startpos < total_size && !bufp->can_be_null)
{
- if (range > 0)
+ if (range > 0) /* Searching forwards. */
{
+ register const char *d;
register int lim = 0;
- register unsigned char *p;
int irange = range;
- if (startpos < size1 && startpos + range >= size1)
- lim = range - (size1 - startpos);
- p = ((unsigned char *)
- &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
if (translate)
- {
- while (range > lim && !fastmap[translate[*p++]])
- range--;
- }
+ while (range > lim
+ && !fastmap[(unsigned char)
+ translate[(unsigned char) *d++]])
+ range--;
else
- {
- while (range > lim && !fastmap[*p++])
- range--;
- }
+ while (range > lim && !fastmap[(unsigned char) *d++])
+ range--;
+
startpos += irange - range;
}
- else
+ else /* Searching backwards. */
{
- register unsigned char c;
- if (startpos >= size1)
- c = string2[startpos - size1];
- else
- c = string1[startpos];
- c &= 0xff;
- if (translate ? !fastmap[translate[c]] : !fastmap[c])
+ register char c = (size1 == 0 || startpos >= size1
+ ? string2[startpos - size1]
+ : string1[startpos]);
+
+ if (!fastmap[(unsigned char) TRANSLATE (c)])
goto advance;
}
}
- if (range >= 0 && startpos == total
- && fastmap && pbufp->can_be_null == 0)
+ /* If can't match the null string, and that's all we have left, fail. */
+ if (range >= 0 && startpos == total_size && fastmap
+ && !bufp->can_be_null)
return -1;
- val = re_match_2 (pbufp, string1, size1, string2, size2, startpos, regs, mstop);
- if (0 <= val)
- {
- if (val == -2)
- return -2;
- return startpos;
- }
-
-#ifdef C_ALLOCA
+ val = re_match_2_internal (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+#ifndef REGEX_MALLOC
+# ifdef C_ALLOCA
alloca (0);
-#endif /* C_ALLOCA */
+# endif
+#endif
+
+ if (val >= 0)
+ return startpos;
+
+ if (val == -2)
+ return -2;
advance:
- if (!range) break;
- if (range > 0) range--, startpos++; else range++, startpos--;
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
}
return -1;
-}
+} /* re_search_2 */
+#ifdef _LIBC
+weak_alias (__re_search_2, re_search_2)
+#endif
-#ifndef emacs /* emacs never uses this */
-int
-re_match (pbufp, string, size, pos, regs)
- struct re_pattern_buffer *pbufp;
- char *string;
- int size, pos;
- struct re_registers *regs;
-{
- return re_match_2 (pbufp, 0, 0, string, size, pos, regs, size);
-}
-#endif /* emacs */
+/* This converts PTR, a pointer into one of the search strings `string1'
+ and `string2' into an offset from the beginning of that string. */
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) \
+ ? ((regoff_t) ((ptr) - string1)) \
+ : ((regoff_t) ((ptr) - string2 + size1)))
+
+/* Macros for dealing with the split strings in re_match_2. */
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+#define PREFETCH() \
+ while (d == dend) \
+ { \
+ /* End of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
-/* Maximum size of failure stack. Beyond this, overflow is an error. */
-int re_max_failures = 2000;
+/* Test if at very beginning or at very end of the virtual concatenation
+ of `string1' and `string2'. If only one string, it's `string2'. */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)
+
+
+/* Test if D points to a character which is word-constituent. We have
+ two special cases to check for: if past the end of string1, look at
+ the first character in string2; and if before the beginning of
+ string2, look at the last character in string1. */
+#define WORDCHAR_P(d) \
+ (SYNTAX ((d) == end1 ? *string2 \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ == Sword)
+
+/* Disabled due to a compiler bug -- see comment at case wordbound */
+#if 0
+/* Test if the character before D and the one at D differ with respect
+ to being word-constituent. */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+#endif
-static int memcmp_translate();
-/* Match the pattern described by PBUFP
- against data which is the virtual concatenation of STRING1 and STRING2.
- SIZE1 and SIZE2 are the sizes of the two data strings.
- Start the match at position POS.
- Do not consider matching past the position MSTOP.
+/* Free everything we malloc. */
+#ifdef MATCH_MAY_ALLOCATE
+# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
+# define FREE_VARIABLES() \
+ do { \
+ REGEX_FREE_STACK (fail_stack.stack); \
+ FREE_VAR (regstart); \
+ FREE_VAR (regend); \
+ FREE_VAR (old_regstart); \
+ FREE_VAR (old_regend); \
+ FREE_VAR (best_regstart); \
+ FREE_VAR (best_regend); \
+ FREE_VAR (reg_info); \
+ FREE_VAR (reg_dummy); \
+ FREE_VAR (reg_info_dummy); \
+ } while (0)
+#else
+# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
+#endif /* not MATCH_MAY_ALLOCATE */
+
+/* These values must meet several constraints. They must not be valid
+ register values; since we have a limit of 255 registers (because
+ we use only one byte in the pattern for the register number), we can
+ use numbers larger than 255. They must differ by 1, because of
+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
+ be larger than the value for the highest register, so we do not try
+ to actually save any registers when none are active. */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+
+/* Matching routines. */
- If pbufp->fastmap is nonzero, then it had better be up to date.
+#ifndef emacs /* Emacs never uses this. */
+/* re_match is like re_match_2 except it takes only a single string. */
- The reason that the data to match are specified as two components
- which are to be regarded as concatenated
- is so this function can be used directly on the contents of an Emacs buffer.
+int
+re_match (bufp, string, size, pos, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, pos;
+ struct re_registers *regs;
+{
+ int result = re_match_2_internal (bufp, NULL, 0, string, size,
+ pos, regs, size);
+# ifndef REGEX_MALLOC
+# ifdef C_ALLOCA
+ alloca (0);
+# endif
+# endif
+ return result;
+}
+# ifdef _LIBC
+weak_alias (__re_match, re_match)
+# endif
+#endif /* not emacs */
- -1 is returned if there is no match. -2 is returned if there is
- an error (such as match stack overflow). Otherwise the value is the length
- of the substring which was matched. */
+static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2,
+ int len, char *translate));
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ and SIZE2, respectively). We start matching at POS, and stop
+ matching at STOP.
+
+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+ store offsets for the substring each group matched in REGS. See the
+ documentation for exactly how many groups we fill.
+
+ We return -1 if no match, -2 if an internal error (such as the
+ failure stack overflowing). Otherwise, we return the length of the
+ matched substring. */
int
-re_match_2 (pbufp, string1, size1, string2, size2, pos, regs, mstop)
- struct re_pattern_buffer *pbufp;
- unsigned char *string1, *string2;
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ int result = re_match_2_internal (bufp, string1, size1, string2, size2,
+ pos, regs, stop);
+#ifndef REGEX_MALLOC
+# ifdef C_ALLOCA
+ alloca (0);
+# endif
+#endif
+ return result;
+}
+#ifdef _LIBC
+weak_alias (__re_match_2, re_match_2)
+#endif
+
+/* This is a separate function so that we can force an alloca cleanup
+ afterwards. */
+static int
+re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
int size1, size2;
int pos;
struct re_registers *regs;
- int mstop;
+ int stop;
{
- register unsigned char *p = (unsigned char *) pbufp->buffer;
- register unsigned char *pend = p + pbufp->used;
- /* End of first string */
- unsigned char *end1;
- /* End of second string */
- unsigned char *end2;
- /* Pointer just past last char to consider matching */
- unsigned char *end_match_1, *end_match_2;
- register unsigned char *d, *dend;
- register int mcnt;
- unsigned char *translate = (unsigned char *) pbufp->translate;
-
- /* Failure point stack. Each place that can handle a failure further down the line
- pushes a failure point on this stack. It consists of two char *'s.
- The first one pushed is where to resume scanning the pattern;
- the second pushed is where to resume scanning the strings.
- If the latter is zero, the failure point is a "dummy".
- If a failure happens and the innermost failure point is dormant,
- it discards that failure point and tries the next one. */
-
- unsigned char *initial_stack[2 * NFAILURES];
- unsigned char **stackb = initial_stack;
- unsigned char **stackp = stackb, **stacke = &stackb[2 * NFAILURES];
-
- /* Information on the "contents" of registers.
- These are pointers into the input strings; they record
- just what was matched (on this attempt) by some part of the pattern.
- The start_memory command stores the start of a register's contents
- and the stop_memory command stores the end.
-
- At that point, regstart[regnum] points to the first character in the register,
- regend[regnum] points to the first character beyond the end of the register,
- regstart_seg1[regnum] is true iff regstart[regnum] points into string1,
- and regend_seg1[regnum] is true iff regend[regnum] points into string1. */
-
- unsigned char *regstart[RE_NREGS];
- unsigned char *regend[RE_NREGS];
- unsigned char regstart_seg1[RE_NREGS], regend_seg1[RE_NREGS];
-
- /* Set up pointers to ends of strings.
- Don't allow the second string to be empty unless both are empty. */
- if (!size2)
+ /* General temporaries. */
+ int mcnt;
+ unsigned char *p1;
+
+ /* Just past the end of the corresponding string. */
+ const char *end1, *end2;
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ const char *end_match_1, *end_match_2;
+
+ /* Where we are in the data, and the end of the current string. */
+ const char *d, *dend;
+
+ /* Where we are in the pattern, and the end of the pattern. */
+ unsigned char *p = bufp->buffer;
+ register unsigned char *pend = p + bufp->used;
+
+ /* Mark the opcode just after a start_memory, so we can test for an
+ empty subpattern when we get to the stop_memory. */
+ unsigned char *just_past_start_mem = 0;
+
+ /* We use this to map every character in the string. */
+ RE_TRANSLATE_TYPE translate = bufp->translate;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to
+ the subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where
+ to resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is
+ a ``dummy''; if a failure happens and the failure point is a dummy,
+ it gets discarded and the next next one is tried. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ fail_stack_type fail_stack;
+#endif
+#ifdef DEBUG
+ static unsigned failure_id = 0;
+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+#ifdef REL_ALLOC
+ /* This holds the pointer to the failure stack, when
+ it is allocated relocatably. */
+ fail_stack_elt_t *failure_stack_ptr;
+#endif
+
+ /* We fill all the registers internally, independent of what we
+ return, for use in backreferences. The number here includes
+ an element for register zero. */
+ size_t num_regs = bufp->re_nsub + 1;
+
+ /* The currently active registers. */
+ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **regstart, **regend;
+#endif
+
+ /* If a group that's operated upon by a repetition operator fails to
+ match anything, then the register for its start will need to be
+ restored because it will have been set to wherever in the string we
+ are when we last see its open-group operator. Similarly for a
+ register's end. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **old_regstart, **old_regend;
+#endif
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ register_info_type *reg_info;
+#endif
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+ unsigned best_regs_set = false;
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **best_regstart, **best_regend;
+#endif
+
+ /* Logically, this is `best_regend[0]'. But we don't want to have to
+ allocate space for that if we're not allocating space for anything
+ else (see below). Also, we never need info about register 0 for
+ any of the other register vectors, and it seems rather a kludge to
+ treat `best_regend' differently than the rest. So we keep track of
+ the end of the best match so far in a separate variable. We
+ initialize this to NULL so that when we backtrack the first time
+ and need to test it, it's not garbage. */
+ const char *match_end = NULL;
+
+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
+ int set_regs_matched_done = 0;
+
+ /* Used when we pop values we don't care about. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **reg_dummy;
+ register_info_type *reg_info_dummy;
+#endif
+
+#ifdef DEBUG
+ /* Counts the total number of registers pushed. */
+ unsigned num_regs_pushed = 0;
+#endif
+
+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+
+ INIT_FAIL_STACK ();
+
+#ifdef MATCH_MAY_ALLOCATE
+ /* Do not bother to initialize all the register variables if there are
+ no groups in the pattern, as it takes a fair amount of time. If
+ there are groups, we include space for register 0 (the whole
+ pattern), even though we never use it, since it simplifies the
+ array indexing. We should fix this. */
+ if (bufp->re_nsub)
+ {
+ regstart = REGEX_TALLOC (num_regs, const char *);
+ regend = REGEX_TALLOC (num_regs, const char *);
+ old_regstart = REGEX_TALLOC (num_regs, const char *);
+ old_regend = REGEX_TALLOC (num_regs, const char *);
+ best_regstart = REGEX_TALLOC (num_regs, const char *);
+ best_regend = REGEX_TALLOC (num_regs, const char *);
+ reg_info = REGEX_TALLOC (num_regs, register_info_type);
+ reg_dummy = REGEX_TALLOC (num_regs, const char *);
+ reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+ if (!(regstart && regend && old_regstart && old_regend && reg_info
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+ else
+ {
+ /* We must initialize all our variables to NULL, so that
+ `FREE_VARIABLES' doesn't try to free them. */
+ regstart = regend = old_regstart = old_regend = best_regstart
+ = best_regend = reg_dummy = NULL;
+ reg_info = reg_info_dummy = (register_info_type *) NULL;
+ }
+#endif /* MATCH_MAY_ALLOCATE */
+
+ /* The starting position is bogus. */
+ if (pos < 0 || pos > size1 + size2)
+ {
+ FREE_VARIABLES ();
+ return -1;
+ }
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ start_memory/stop_memory has been seen for. Also initialize the
+ register information struct. */
+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt]
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+
+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ /* We move `string1' into `string2' if the latter's empty -- but not if
+ `string1' is null. */
+ if (size2 == 0 && string1 != NULL)
{
string2 = string1;
size2 = size1;
@@ -1111,649 +3974,1824 @@ re_match_2 (pbufp, string1, size1, string2, size2, pos, regs, mstop)
end1 = string1 + size1;
end2 = string2 + size2;
- /* Compute where to stop matching, within the two strings */
- if (mstop <= size1)
+ /* Compute where to stop matching, within the two strings. */
+ if (stop <= size1)
{
- end_match_1 = string1 + mstop;
+ end_match_1 = string1 + stop;
end_match_2 = string2;
}
else
{
end_match_1 = end1;
- end_match_2 = string2 + mstop - size1;
+ end_match_2 = string2 + stop - size1;
}
- /* Initialize \) text positions to -1
- to mark ones that no \( or \) has been seen for. */
-
- for (mcnt = 0; mcnt < (int) (sizeof (regend) / sizeof (*regend)); mcnt++)
- regend[mcnt] = (unsigned char *) -1;
-
/* `p' scans through the pattern as `d' scans through the data.
- `dend' is the end of the input string that `d' points within.
- `d' is advanced into the following input string whenever necessary,
- but this happens before fetching;
- therefore, at the beginning of the loop,
- `d' can be pointing at the end of a string,
- but it cannot equal string2. */
-
- if (pos <= size1)
- d = string1 + pos, dend = end_match_1;
+ `dend' is the end of the input string that `d' points within. `d'
+ is advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal `string2'. */
+ if (size1 > 0 && pos <= size1)
+ {
+ d = string1 + pos;
+ dend = end_match_1;
+ }
else
- d = string2 + pos - size1, dend = end_match_2;
-
-/* Write PREFETCH; just before fetching a character with *d. */
-#define PREFETCH \
- while (d == dend) \
- { if (dend == end_match_2) goto fail; /* end of string2 => failure */ \
- d = string2; /* end of string1 => advance to string2. */ \
- dend = end_match_2; }
+ {
+ d = string2 + pos - size1;
+ dend = end_match_2;
+ }
- /* This loop loops over pattern commands.
- It exits by returning from the function if match is complete,
- or it drops through if match fails at this starting point in the input data. */
+ DEBUG_PRINT1 ("The compiled pattern is:\n");
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+ DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+ DEBUG_PRINT1 ("'\n");
- while (1)
+ /* This loops over pattern commands. It exits by returning from the
+ function if the match is complete, or it drops through if the match
+ fails at this starting point in the input data. */
+ for (;;)
{
+#ifdef _LIBC
+ DEBUG_PRINT2 ("\n%p: ", p);
+#else
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+#endif
+
if (p == pend)
- /* End of pattern means we have succeeded! */
- {
- /* If caller wants register contents data back, convert it to indices */
- if (regs)
+ { /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT1 ("end of pattern ... ");
+
+ /* If we haven't matched the entire string, and we want the
+ longest match, try backtracking. */
+ if (d != end_match_2)
{
- regs->start[0] = pos;
- if (dend == end_match_1)
- regs->end[0] = d - string1;
- else
- regs->end[0] = d - string2 + size1;
- for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
- {
- if (regend[mcnt] == (unsigned char *) -1)
+ /* 1 if this match ends in the same string (string1 or string2)
+ as the best previous match. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+ /* 1 if this match is the best seen so far. */
+ boolean best_match_p;
+
+ /* AIX compiler got confused when this was combined
+ with the previous declaration. */
+ if (same_str_p)
+ best_match_p = d > match_end;
+ else
+ best_match_p = !MATCHING_IN_FIRST_STRING;
+
+ DEBUG_PRINT1 ("backtracking.\n");
+
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
+
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set || best_match_p)
+ {
+ best_regs_set = true;
+ match_end = d;
+
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+
+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. And if
+ last match is real best match, don't restore second
+ best one. */
+ else if (best_regs_set && !best_match_p)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
+
+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
{
- regs->start[mcnt] = -1;
- regs->end[mcnt] = -1;
- continue;
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
}
- if (regstart_seg1[mcnt])
- regs->start[mcnt] = regstart[mcnt] - string1;
- else
- regs->start[mcnt] = regstart[mcnt] - string2 + size1;
- if (regend_seg1[mcnt])
- regs->end[mcnt] = regend[mcnt] - string1;
- else
- regs->end[mcnt] = regend[mcnt] - string2 + size1;
+ }
+ } /* d != end_match_2 */
+
+ succeed_label:
+ DEBUG_PRINT1 ("Accepting match.\n");
+
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
+ {
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+ }
+ else
+ {
+ /* These braces fend off a "empty body in an else-statement"
+ warning under GCC when assert expands to nothing. */
+ assert (bufp->regs_allocated == REGS_FIXED);
+ }
+
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING
+ ? ((regoff_t) (d - string1))
+ : ((regoff_t) (d - string2 + size1)));
+ }
+
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
+ for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
+ mcnt++)
+ {
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
+ }
+ }
+
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ } /* regs && !bufp->no_sub */
+
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+ FREE_VARIABLES ();
+ return mcnt;
+ }
+
+ /* Otherwise match next pattern command. */
+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
+ {
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+
+ case succeed:
+ DEBUG_PRINT1 ("EXECUTING succeed.\n");
+ goto succeed_label;
+
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
+ case exactn:
+ mcnt = *p++;
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH ();
+ if ((unsigned char) translate[(unsigned char) *d++]
+ != (unsigned char) *p++)
+ goto fail;
}
+ while (--mcnt);
}
- if (dend == end_match_1)
- return (d - string1 - pos);
else
- return d - string2 + size1 - pos;
- }
+ {
+ do
+ {
+ PREFETCH ();
+ if (*d++ != (char) *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED ();
+ break;
- /* Otherwise match next pattern command */
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((enum regexpcode) *p++))
-#else
- switch ((enum regexpcode) *p++)
-#endif
- {
- /* \( is represented by a start_memory, \) by a stop_memory.
- Both of those commands contain a "register number" argument.
- The text matched within the \( and \) is recorded under that number.
- Then, \<digit> turns into a `duplicate' command which
- is followed by the numeric value of <digit> as the register number. */
+ /* Match any character except possibly a newline or a null. */
+ case anychar:
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
- case start_memory:
- regstart[*p] = d;
- regstart_seg1[*p++] = (dend == end_match_1);
+ PREFETCH ();
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d++;
break;
+
+ case charset:
+ case charset_not:
+ {
+ register unsigned char c;
+ boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = TRANSLATE (*d); /* The character to match. */
+
+ /* Cast to `unsigned' instead of `unsigned char' in case the
+ bit list is a full 32 bytes long. */
+ if (c < (unsigned) (*p * BYTEWIDTH)
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+ }
+
+
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
+ DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ DEBUG_PRINT2 (" old_regstart: %d\n",
+ POINTER_TO_OFFSET (old_regstart[*p]));
+
+ regstart[*p] = d;
+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
+
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
+
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ just_past_start_mem = p;
+
+ break;
+
+
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
case stop_memory:
- regend[*p] = d;
- regend_seg1[*p++] = (dend == end_match_1);
- break;
+ DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+ DEBUG_PRINT2 (" old_regend: %d\n",
+ POINTER_TO_OFFSET (old_regend[*p]));
+
+ regend[*p] = d;
+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
+ if (r == 0)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
+
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || just_past_start_mem == p - 1)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (is_a_jump_n)
+ p1 += 2;
+ break;
+
+ default:
+ /* do nothing */ ;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, exit from the loop
+ by forcing a failure after pushing on the stack the
+ on_failure_jump's jump in the pattern, and d. */
+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
- case duplicate:
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
+ r++)
+ {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if (old_regend[r] >= regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+
+ goto fail;
+ }
+ }
+
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
+
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
{
- int regno = *p++; /* Get which register to match against */
- register unsigned char *d2, *dend2;
+ register const char *d2, *dend2;
+ int regno = *p++; /* Get which register to match against. */
+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
- d2 = regstart[regno];
- dend2 = ((regstart_seg1[regno] == regend_seg1[regno])
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((FIRST_STRING_P (regstart[regno])
+ == FIRST_STRING_P (regend[regno]))
? regend[regno] : end_match_1);
- while (1)
+ for (;;)
{
- /* Advance to next segment in register contents, if necessary */
+ /* If necessary, advance to next segment in register
+ contents. */
while (d2 == dend2)
{
if (dend2 == end_match_2) break;
if (dend2 == regend[regno]) break;
- d2 = string2, dend2 = regend[regno]; /* end of string1 => advance to string2. */
+
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
}
/* At end of register contents => success */
if (d2 == dend2) break;
- /* Advance to next segment in data being matched, if necessary */
- PREFETCH;
+ /* If necessary, advance to next segment in data. */
+ PREFETCH ();
- /* mcnt gets # consecutive chars to compare */
+ /* How many characters left in this segment to match. */
mcnt = dend - d;
- if (mcnt > dend2 - d2)
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
mcnt = dend2 - d2;
- /* Compare that many; failure if mismatch, else skip them. */
- if (translate ? memcmp_translate (d, d2, mcnt, translate) : memcmp (d, d2, mcnt))
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : memcmp (d, d2, mcnt))
goto fail;
d += mcnt, d2 += mcnt;
+
+ /* Do this because we've match some characters. */
+ SET_REGS_MATCHED ();
}
}
break;
- case anychar:
- /* fetch a data character */
- PREFETCH;
- /* Match anything but a newline. */
- if ((translate ? translate[*d++] : *d++) == '\n')
- goto fail;
- break;
- case charset:
- case charset_not:
- {
- /* Nonzero for charset_not */
- int not = 0;
- register int c;
- if (*(p - 1) == (unsigned char) charset_not)
- not = 1;
-
- /* fetch a data character */
- PREFETCH;
-
- if (translate)
- c = translate [*d];
- else
- c = *d;
-
- if (c < *p * BYTEWIDTH
- && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
-
- p += 1 + *p;
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
+ case begline:
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
- if (!not) goto fail;
- d++;
- break;
- }
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
- case begline:
- if (d == string1 || d[-1] == '\n')
- break;
- goto fail;
+ /* endline is the dual of begline. */
case endline:
- if (d == end2
- || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
+
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
+
+
+ /* Match at the very beginning of the data. */
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
+
+
+ /* Match at the very end of the data. */
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ if (AT_STRINGS_END (d))
break;
- goto fail;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
+#else
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+#endif
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ break;
- /* "or" constructs ("|") are handled by starting each alternative
- with an on_failure_jump that points to the start of the next alternative.
- Each alternative except the last ends with a jump to the joining point.
- (Actually, each jump except for the last one really jumps
- to the following jump, because tensioning the jumps is a hassle.) */
- /* The start of a stupid repeat has an on_failure_jump that points
- past the end of the repeat text.
- This makes a failure point so that, on failure to match a repetition,
- matching restarts past as many repetitions have been found
- with no way to fail and look for another one. */
+ /* Uses of on_failure_jump:
- /* A smart repeat is similar but loops back to the on_failure_jump
- so that each repetition makes another failure point. */
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
case on_failure_jump:
- if (stackp == stacke)
- {
- unsigned char **stackx;
- if (stacke - stackb > re_max_failures * 2)
- return -2;
- stackx = (unsigned char **) alloca (2 * (stacke - stackb)
- * sizeof (char *));
- memcpy (stackx, stackb, (stacke - stackb) * sizeof (char *));
- stackp = stackx + (stackp - stackb);
- stacke = stackx + 2 * (stacke - stackb);
- stackb = stackx;
- }
- mcnt = *p++ & 0377;
- mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
- p++;
- *stackp++ = mcnt + p;
- *stackp++ = d;
- break;
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
- /* The end of a smart repeat has an maybe_finalize_jump back.
- Change it either to a finalize_jump or an ordinary jump. */
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
+#else
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+#endif
- case maybe_finalize_jump:
- mcnt = *p++ & 0377;
- mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
- p++;
- {
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(zz\(a*\)b*\)\2, we need the inner group. */
+
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
+
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
register unsigned char *p2 = p;
- /* Compare what follows with the begining of the repeat.
- If we can establish that there is nothing that they would
- both match, we can change to finalize_jump */
- while (p2 != pend
- && (*p2 == (unsigned char) stop_memory
- || *p2 == (unsigned char) start_memory))
- p2++;
- if (p2 == pend)
- p[-3] = (unsigned char) finalize_jump;
- else if (*p2 == (unsigned char) exactn
- || *p2 == (unsigned char) endline)
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands.
+ If what follows this loop is a ...+ construct,
+ look at what begins its body, since we will have to
+ match at least one of that. */
+ while (1)
{
- register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
- register unsigned char *p1 = p + mcnt;
- /* p1[0] ... p1[2] are an on_failure_jump.
- Examine what follows that */
- if (p1[3] == (unsigned char) exactn && p1[5] != c)
- p[-3] = (unsigned char) finalize_jump;
- else if (p1[3] == (unsigned char) charset
- || p1[3] == (unsigned char) charset_not)
+ if (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3;
+ else if (p2 + 6 < pend
+ && (re_opcode_t) *p2 == dummy_failure_jump)
+ p2 += 6;
+ else
+ break;
+ }
+
+ p1 = p + mcnt;
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
+ {
+ /* Consider what happens when matching ":\(.*\)"
+ against ":/". I don't really understand this code
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
+
+ else if ((re_opcode_t) *p2 == exactn
+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+ {
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+ if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset
+ || (re_opcode_t) p1[3] == charset_not)
{
- int not = p1[3] == (unsigned char) charset_not;
- if (c < p1[4] * BYTEWIDTH
+ int not = (re_opcode_t) p1[3] == charset_not;
+
+ if (c < (unsigned char) (p1[4] * BYTEWIDTH)
&& p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
not = !not;
- /* not is 1 if c would match */
- /* That means it is not safe to finalize */
+
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
if (!not)
- p[-3] = (unsigned char) finalize_jump;
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ else if ((re_opcode_t) *p2 == charset)
+ {
+#ifdef DEBUG
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+#endif
+
+#if 0
+ if ((re_opcode_t) p1[3] == exactn
+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
+ && (p2[2 + p1[5] / BYTEWIDTH]
+ & (1 << (p1[5] % BYTEWIDTH)))))
+#else
+ if ((re_opcode_t) p1[3] == exactn
+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4]
+ && (p2[2 + p1[4] / BYTEWIDTH]
+ & (1 << (p1[4] % BYTEWIDTH)))))
+#endif
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset_not)
+ {
+ int idx;
+ /* We win if the charset_not inside the loop
+ lists every character listed in the charset after. */
+ for (idx = 0; idx < (int) p2[1]; idx++)
+ if (! (p2[2 + idx] == 0
+ || (idx < (int) p1[4]
+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
+ break;
+
+ if (idx == p2[1])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ else if ((re_opcode_t) p1[3] == charset)
+ {
+ int idx;
+ /* We win if the charset inside the loop
+ has no overlap with the one after the loop. */
+ for (idx = 0;
+ idx < (int) p2[1] && idx < (int) p1[4];
+ idx++)
+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
+ break;
+
+ if (idx == p2[1] || idx == p1[4])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
}
}
}
- p -= 2;
- if (p[-1] != (unsigned char) finalize_jump)
+ p -= 2; /* Point at relative address again. */
+ if ((re_opcode_t) p[-1] != pop_failure_jump)
{
p[-1] = (unsigned char) jump;
- goto nofinalize;
+ DEBUG_PRINT1 (" Match => jump.\n");
+ goto unconditional_jump;
}
+ /* Note fall through. */
+
+
+ /* The end of a simple repeat has a pop_failure_jump back to
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ active_reg_t dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+ unconditional_jump:
+#ifdef _LIBC
+ DEBUG_PRINT2 ("\n%p: ", p);
+#else
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+#endif
+ /* Note fall through. */
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+#ifdef _LIBC
+ DEBUG_PRINT2 ("(to %p).\n", p);
+#else
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
+#endif
+ break;
- /* The end of a stupid repeat has a finalize-jump
- back to the start, where another failure point will be made
- which will point after all the repetitions found so far. */
- case finalize_jump:
- stackp -= 2;
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
+
+
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (NULL, NULL, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (NULL, NULL, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt);
+#else
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt);
+#endif
+ }
+ else if (mcnt == 0)
+ {
+#ifdef _LIBC
+ DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2);
+#else
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+#endif
+ p[2] = (unsigned char) no_op;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt);
+#else
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt);
+#endif
+ goto unconditional_jump;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
- case jump:
- nofinalize:
- mcnt = *p++ & 0377;
- mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
- p += mcnt + 1; /* The 1 compensates for missing ++ above */
- break;
+ case set_number_at:
+ {
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
- case dummy_failure_jump:
- if (stackp == stacke)
- {
- unsigned char **stackx
- = (unsigned char **) alloca (2 * (stacke - stackb)
- * sizeof (char *));
- memcpy (stackx, stackb, (stacke - stackb) * sizeof (char *));
- stackp = stackx + (stackp - stackb);
- stacke = stackx + 2 * (stacke - stackb);
- stackb = stackx;
- }
- *stackp++ = 0;
- *stackp++ = 0;
- goto nofinalize;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
+#else
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+#endif
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+#if 0
+ /* The DEC Alpha C compiler 3.x generates incorrect code for the
+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
+ macro and introducing temporary variables works around the bug. */
case wordbound:
- if (d == string1 /* Points to first char */
- || d == end2 /* Points to end */
- || (d == end1 && size2 == 0)) /* Points to end */
- break;
- if ((SYNTAX (d[-1]) == Sword)
- != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
break;
goto fail;
case notwordbound:
- if (d == string1 /* Points to first char */
- || d == end2 /* Points to end */
- || (d == end1 && size2 == 0)) /* Points to end */
- goto fail;
- if ((SYNTAX (d[-1]) == Sword)
- != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
goto fail;
break;
+#else
+ case wordbound:
+ {
+ boolean prevchar, thischar;
- case wordbeg:
- if (d == end2 /* Points to end */
- || (d == end1 && size2 == 0) /* Points to end */
- || SYNTAX (* (d == end1 ? string2 : d)) != Sword) /* Next char not a letter */
- goto fail;
- if (d == string1 /* Points to first char */
- || SYNTAX (d[-1]) != Sword) /* prev char not letter */
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
break;
- goto fail;
- case wordend:
- if (d == string1 /* Points to first char */
- || SYNTAX (d[-1]) != Sword) /* prev char not letter */
- goto fail;
- if (d == end2 /* Points to end */
- || (d == end1 && size2 == 0) /* Points to end */
- || SYNTAX (d == end1 ? *string2 : *d) != Sword) /* Next char not a letter */
+ prevchar = WORDCHAR_P (d - 1);
+ thischar = WORDCHAR_P (d);
+ if (prevchar != thischar)
break;
goto fail;
+ }
-#ifdef emacs
- case before_dot:
- if (((d - string2 <= (unsigned) size2)
- ? d - bf_p2 : d - bf_p1)
- <= point)
- goto fail;
- break;
+ case notwordbound:
+ {
+ boolean prevchar, thischar;
- case at_dot:
- if (((d - string2 <= (unsigned) size2)
- ? d - bf_p2 : d - bf_p1)
- == point)
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
goto fail;
- break;
- case after_dot:
- if (((d - string2 <= (unsigned) size2)
- ? d - bf_p2 : d - bf_p1)
- >= point)
+ prevchar = WORDCHAR_P (d - 1);
+ thischar = WORDCHAR_P (d);
+ if (prevchar != thischar)
goto fail;
break;
+ }
+#endif
- case wordchar:
- mcnt = (int) Sword;
- goto matchsyntax;
+ case wordbeg:
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+ && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+ break;
+ goto fail;
+
+#ifdef emacs
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+ goto fail;
+ break;
case syntaxspec:
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
mcnt = *p++;
- matchsyntax:
- PREFETCH;
- if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
- break;
-
- case notwordchar:
+ goto matchsyntax;
+
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
mcnt = (int) Sword;
- goto matchnotsyntax;
+ matchsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
case notsyntaxspec:
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
mcnt = *p++;
- matchnotsyntax:
- PREFETCH;
- if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
- break;
-#else
+ goto matchnotsyntax;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ mcnt = (int) Sword;
+ matchnotsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+#else /* not emacs */
case wordchar:
- PREFETCH;
- if (SYNTAX (*d++) == 0) goto fail;
+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+ PREFETCH ();
+ if (!WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
break;
-
+
case notwordchar:
- PREFETCH;
- if (SYNTAX (*d++) != 0) goto fail;
+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+ PREFETCH ();
+ if (WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
break;
#endif /* not emacs */
- case begbuf:
- if (d == string1) /* Note, d cannot equal string2 */
- break; /* unless string1 == string2. */
- goto fail;
+ default:
+ abort ();
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
- case endbuf:
- if (d == end2 || (d == end1 && size2 == 0))
- break;
- goto fail;
- case exactn:
- /* Match the next few pattern characters exactly.
- mcnt is how many characters to match. */
- mcnt = *p++;
- if (translate)
- {
- do
- {
- PREFETCH;
- if (translate[*d++] != *p++) goto fail;
- }
- while (--mcnt);
- }
- else
+ /* We goto here if a matching operation fails. */
+ fail:
+ if (!FAIL_STACK_EMPTY ())
+ { /* A restart point is known. Restore to that state. */
+ DEBUG_PRINT1 ("\nFAIL:\n");
+ POP_FAILURE_POINT (d, p,
+ lowest_active_reg, highest_active_reg,
+ regstart, regend, reg_info);
+
+ /* If this failure point is a dummy, try the next one. */
+ if (!p)
+ goto fail;
+
+ /* If we failed to the end of the pattern, don't examine *p. */
+ assert (p <= pend);
+ if (p < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ switch ((re_opcode_t) *p)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case maybe_pop_jump:
+ case pop_failure_jump:
+ case jump:
+ p1 = p + 1;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+ || (!is_a_jump_n
+ && (re_opcode_t) *p1 == on_failure_jump))
+ goto fail;
+ break;
+ default:
+ /* do nothing */ ;
+ }
+ }
+
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ } /* for (;;) */
+
+ if (best_regs_set)
+ goto restore_best_regs;
+
+ FREE_VARIABLES ();
+
+ return -1; /* Failure to match. */
+} /* re_match_2 */
+
+/* Subroutine definitions for re_match_2. */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+
+ Return true if the pattern up to the corresponding stop_memory can
+ match the empty string, and false otherwise.
+
+ If we find the matching stop_memory, sets P to point to one past its number.
+ Otherwise, sets P to an undefined byte less than or equal to END.
+
+ We don't handle duplicates properly (yet). */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ /* Point to after the args to the start_memory. */
+ unsigned char *p1 = *p + 2;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and return true or
+ false, as appropriate, when we get to one that can't, or to the
+ matching stop_memory. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* Could be either a loop or a series of alternatives. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ /* If the next operation is not a jump backwards in the
+ pattern. */
+
+ if (mcnt >= 0)
{
- do
- {
- PREFETCH;
- if (*d++ != *p++) goto fail;
- }
- while (--mcnt);
- }
- break;
- case unused:
- case before_dot:
- case at_dot:
- case after_dot:
- case syntaxspec:
- case notsyntaxspec:
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
+
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
+
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
+
+
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
+
+ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+ {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return false;
+
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
+
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((re_opcode_t) *p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+ {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
+ }
+ }
+
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return false;
+
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
+ break;
+
+
+ case stop_memory:
+ assert (p1[1] == **p);
+ *p = p1 + 2;
+ return true;
+
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+ It expects P to be the first byte of a single alternative and END one
+ byte past the last. The alternative can contain groups. */
+
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+ unsigned char *p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ unsigned char *p1 = p;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and break when we get
+ to one that can't. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* It's a loop. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ break;
+
default:
- break;
- }
- continue; /* Successfully matched one pattern command; keep matching */
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
- /* Jump here if any matching operation fails. */
- fail:
- if (stackp != stackb)
- /* A restart point is known. Restart there and pop it. */
- {
- if (!stackp[-2])
- { /* If innermost failure point is dormant, flush it and keep looking */
- stackp -= 2;
- goto fail;
- }
- d = *--stackp;
- p = *--stackp;
- if (d >= string1 && d <= end1)
- dend = end_match_1;
- }
- else break; /* Matching at this starting point really fails! */
- }
- return -1; /* Failure to match */
-}
+ return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+ alt_match_null_string_p.
+
+ Sets P to one after the op and its arguments, if any. */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ boolean ret;
+ int reg_no;
+ unsigned char *p1 = *p;
+
+ switch ((re_opcode_t) *p1++)
+ {
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbeg:
+ case wordend:
+ case wordbound:
+ case notwordbound:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ break;
+
+ case start_memory:
+ reg_no = *p1;
+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+ ret = group_match_null_string_p (&p1, end, reg_info);
+
+ /* Have to set this here in case we're checking a group which
+ contains a group and a back reference to it. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+ if (!ret)
+ return false;
+ break;
+
+ /* If this is an optimized succeed_n for zero times, make the jump. */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (mcnt >= 0)
+ p1 += mcnt;
+ else
+ return false;
+ break;
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p1 += 2;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ if (mcnt == 0)
+ {
+ p1 -= 4;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ }
+ else
+ return false;
+ break;
+
+ case duplicate:
+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+ return false;
+ break;
+
+ case set_number_at:
+ p1 += 4;
+
+ default:
+ /* All other opcodes mean we cannot match the empty string. */
+ return false;
+ }
+
+ *p = p1;
+ return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+ bytes; nonzero otherwise. */
static int
-memcmp_translate (s1, s2, len, translate)
- unsigned char *s1, *s2;
+bcmp_translate (s1, s2, len, translate)
+ const char *s1, *s2;
register int len;
- unsigned char *translate;
+ RE_TRANSLATE_TYPE translate;
{
- register unsigned char *p1 = s1, *p2 = s2;
+ register const unsigned char *p1 = (const unsigned char *) s1;
+ register const unsigned char *p2 = (const unsigned char *) s2;
while (len)
{
- if (translate [*p1++] != translate [*p2++]) return 1;
+ if (translate[*p1++] != translate[*p2++]) return 1;
len--;
}
return 0;
}
-/* Entry points compatible with bsd4.2 regex library */
+/* Entry points for GNU code. */
-#ifndef emacs
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry.
+
+ We call regex_compile to do the actual compilation. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ size_t length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* GNU code is written to assume at least RE_NREGS registers will be set
+ (and at least one extra will be -1). */
+ bufp->regs_allocated = REGS_UNALLOCATED;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub. */
+ bufp->no_sub = 0;
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+ if (!ret)
+ return NULL;
+ return gettext (re_error_msgid[(int) ret]);
+}
+#ifdef _LIBC
+weak_alias (__re_compile_pattern, re_compile_pattern)
+#endif
+
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them unless specifically requested. */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+
+/* BSD has one and only one pattern buffer. */
static struct re_pattern_buffer re_comp_buf;
char *
+#ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+ these names if they don't use our functions, and still use
+ regcomp/regexec below without link errors. */
+weak_function
+#endif
re_comp (s)
- const char *s;
+ const char *s;
{
+ reg_errcode_t ret;
+
if (!s)
{
if (!re_comp_buf.buffer)
- return "No previous regular expression";
+ return gettext ("No previous regular expression");
return 0;
}
if (!re_comp_buf.buffer)
{
- if (!(re_comp_buf.buffer = (char *) malloc (200)))
- return "Memory exhausted";
+ re_comp_buf.buffer = (unsigned char *) malloc (200);
+ if (re_comp_buf.buffer == NULL)
+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
re_comp_buf.allocated = 200;
- if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
- return "Memory exhausted";
+
+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+ if (re_comp_buf.fastmap == NULL)
+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
}
- return re_compile_pattern (s, strlen (s), &re_comp_buf);
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+
+ if (!ret)
+ return NULL;
+
+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ return (char *) gettext (re_error_msgid[(int) ret]);
}
+
int
+#ifdef _LIBC
+weak_function
+#endif
re_exec (s)
- char *s;
+ const char *s;
{
- int len = strlen (s);
- return 0 <= re_search (&re_comp_buf, s, len, 0, len, 0);
+ const int len = strlen (s);
+ return
+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
}
-#endif /* emacs */
+#endif /* _REGEX_RE_COMP */
-#ifdef test
-
-#include <stdio.h>
-
-/* Indexed by a character, gives the upper case equivalent of the character */
-
-static char upcase[0400] =
- { 000, 001, 002, 003, 004, 005, 006, 007,
- 010, 011, 012, 013, 014, 015, 016, 017,
- 020, 021, 022, 023, 024, 025, 026, 027,
- 030, 031, 032, 033, 034, 035, 036, 037,
- 040, 041, 042, 043, 044, 045, 046, 047,
- 050, 051, 052, 053, 054, 055, 056, 057,
- 060, 061, 062, 063, 064, 065, 066, 067,
- 070, 071, 072, 073, 074, 075, 076, 077,
- 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
- 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
- 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
- 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
- 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
- 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
- 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
- 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
- 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
- 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
- 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
- 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
- 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
- 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
- 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
- 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
- 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
- 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
- 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
- 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
- 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
- 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
- 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
- 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
- };
+/* POSIX.2 functions. Don't define these for Emacs. */
-main (argc, argv)
- int argc;
- char **argv;
-{
- char pat[80];
- struct re_pattern_buffer buf;
- int i;
- char c;
- char fastmap[(1 << BYTEWIDTH)];
+#ifndef emacs
- /* Allow a command argument to specify the style of syntax. */
- if (argc > 1)
- obscure_syntax = atoi (argv[1]);
+/* regcomp takes a regular expression as a string and compiles it.
- buf.allocated = 40;
- buf.buffer = (char *) malloc (buf.allocated);
- buf.fastmap = fastmap;
- buf.translate = upcase;
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
- while (1)
- {
- gets (pat);
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' and `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
- if (*pat)
- {
- re_compile_pattern (pat, strlen(pat), &buf);
+ PATTERN is the address of the pattern string.
- for (i = 0; i < buf.used; i++)
- printchar (buf.buffer[i]);
+ CFLAGS is a series of bits which affect compilation.
- putchar_unfiltered ('\n');
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
- printf_unfiltered ("%d allocated, %d used.\n", buf.allocated, buf.used);
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
- re_compile_fastmap (&buf);
- printf_unfiltered ("Allowed by fastmap: ");
- for (i = 0; i < (1 << BYTEWIDTH); i++)
- if (fastmap[i]) printchar (i);
- putchar_unfiltered ('\n');
- }
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
- gets (pat); /* Now read the string to match against */
+ It returns 0 if it succeeds, nonzero if it doesn't. (See gnu-regex.h for
+ the return codes and their meanings.) */
- i = re_match (&buf, pat, strlen (pat), 0, 0);
- printf_unfiltered ("Match value %d.\n", i);
+int
+regcomp (preg, pattern, cflags)
+ regex_t *preg;
+ const char *pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ reg_syntax_t syntax
+ = (cflags & REG_EXTENDED) ?
+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+ /* regex_compile will allocate the space for the compiled pattern. */
+ preg->buffer = 0;
+ preg->allocated = 0;
+ preg->used = 0;
+
+ /* Don't bother to use a fastmap when searching. This simplifies the
+ REG_NEWLINE case: if we used a fastmap, we'd have to put all the
+ characters after newlines into the fastmap. This way, we just try
+ every character. */
+ preg->fastmap = 0;
+
+ if (cflags & REG_ICASE)
+ {
+ unsigned i;
+
+ preg->translate
+ = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
+ * sizeof (*(RE_TRANSLATE_TYPE)0));
+ if (preg->translate == NULL)
+ return (int) REG_ESPACE;
+
+ /* Map uppercase characters to corresponding lowercase ones. */
+ for (i = 0; i < CHAR_SET_SIZE; i++)
+ preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
}
+ else
+ preg->translate = NULL;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+
+ preg->no_sub = !!(cflags & REG_NOSUB);
+
+ /* POSIX says a null character in the pattern terminates it, so we
+ can use strlen here in compiling the pattern. */
+ ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
+
+ return (int) ret;
}
+#ifdef _LIBC
+weak_alias (__regcomp, regcomp)
+#endif
-#ifdef NOTDEF
-print_buf (bufp)
- struct re_pattern_buffer *bufp;
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *preg;
+ const char *string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
{
- int i;
-
- printf_unfiltered ("buf is :\n----------------\n");
- for (i = 0; i < bufp->used; i++)
- printchar (bufp->buffer[i]);
-
- printf_unfiltered ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
-
- printf_unfiltered ("Allowed by fastmap: ");
- for (i = 0; i < (1 << BYTEWIDTH); i++)
- if (bufp->fastmap[i])
- printchar (i);
- printf_unfiltered ("\nAllowed by translate: ");
- if (bufp->translate)
- for (i = 0; i < (1 << BYTEWIDTH); i++)
- if (bufp->translate[i])
- printchar (i);
- printf_unfiltered ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
- printf_unfiltered ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
+ int ret;
+ struct re_registers regs;
+ regex_t private_preg;
+ int len = strlen (string);
+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+ private_preg = *preg;
+
+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
+
+ /* The user has told us exactly how many registers to return
+ information about, via `nmatch'. We have to pass that on to the
+ matching routines. */
+ private_preg.regs_allocated = REGS_FIXED;
+
+ if (want_reg_info)
+ {
+ regs.num_regs = nmatch;
+ regs.start = TALLOC (nmatch, regoff_t);
+ regs.end = TALLOC (nmatch, regoff_t);
+ if (regs.start == NULL || regs.end == NULL)
+ return (int) REG_NOMATCH;
+ }
+
+ /* Perform the searching operation. */
+ ret = re_search (&private_preg, string, len,
+ /* start: */ 0, /* range: */ len,
+ want_reg_info ? &regs : (struct re_registers *) 0);
+
+ /* Copy the register information to the POSIX structure. */
+ if (want_reg_info)
+ {
+ if (ret >= 0)
+ {
+ unsigned r;
+
+ for (r = 0; r < nmatch; r++)
+ {
+ pmatch[r].rm_so = regs.start[r];
+ pmatch[r].rm_eo = regs.end[r];
+ }
+ }
+
+ /* If we needed the temporary register info, free the space now. */
+ free (regs.start);
+ free (regs.end);
+ }
+
+ /* We want zero return to mean success, unlike `re_search'. */
+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
}
+#ifdef _LIBC
+weak_alias (__regexec, regexec)
#endif
-printchar (c)
- char c;
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+__regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
{
- if (c < 041 || c >= 0177)
+ const char *msg;
+ size_t msg_size;
+
+ if (errcode < 0
+ || errcode >= (int) (sizeof (re_error_msgid)
+ / sizeof (re_error_msgid[0])))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = gettext (re_error_msgid[errcode]);
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (errbuf_size != 0)
{
- putchar_unfiltered ('\\');
- putchar_unfiltered (((c >> 6) & 3) + '0');
- putchar_unfiltered (((c >> 3) & 7) + '0');
- putchar_unfiltered ((c & 7) + '0');
+ if (msg_size > errbuf_size)
+ {
+#if defined HAVE_MEMPCPY || defined _LIBC
+ *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
+#else
+ memcpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+#endif
+ }
+ else
+ memcpy (errbuf, msg, msg_size);
}
- else
- putchar_unfiltered (c);
+
+ return msg_size;
}
+#ifdef _LIBC
+weak_alias (__regerror, regerror)
+#endif
+
-error (string)
- char *string;
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
{
- puts_unfiltered (string);
- exit (1);
+ if (preg->buffer != NULL)
+ free (preg->buffer);
+ preg->buffer = NULL;
+
+ preg->allocated = 0;
+ preg->used = 0;
+
+ if (preg->fastmap != NULL)
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ preg->fastmap_accurate = 0;
+
+ if (preg->translate != NULL)
+ free (preg->translate);
+ preg->translate = NULL;
}
+#ifdef _LIBC
+weak_alias (__regfree, regfree)
+#endif
-#endif /* test */
+#endif /* not emacs */
diff --git a/contrib/gdb/gdb/gnu-regex.h b/contrib/gdb/gdb/gnu-regex.h
index 7b1a4af..9153ea1 100644
--- a/contrib/gdb/gdb/gnu-regex.h
+++ b/contrib/gdb/gdb/gnu-regex.h
@@ -1,181 +1,576 @@
-/* Definitions for data structures callers pass the regex library.
- Copyright (C) 1985, 1989 Free Software Foundation, Inc.
+/* Definitions for data structures and routines for the regular
+ expression library, version 0.12.
+ Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ NOTE: The canonical source of this file is maintained with the
+ GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-/* Define number of parens for which we record the beginnings and ends.
- This affects how much space the `struct re_registers' type takes up. */
-#ifndef RE_NREGS
-#define RE_NREGS 10
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+/* Allow the use in C++ code. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+# include <stddef.h>
+#endif
+
+/* GDB LOCAL: define _REGEX_RE_COMP to get BSD style re_comp and re_exec */
+#ifndef _REGEX_RE_COMP
+#define _REGEX_RE_COMP
#endif
-/* These bits are used in the obscure_syntax variable to choose among
- alternative regexp syntaxes. */
-
-/* 1 means plain parentheses serve as grouping, and backslash
- parentheses are needed for literal searching.
- 0 means backslash-parentheses are grouping, and plain parentheses
- are for literal searching. */
-#define RE_NO_BK_PARENS 1
-
-/* 1 means plain | serves as the "or"-operator, and \| is a literal.
- 0 means \| serves as the "or"-operator, and | is a literal. */
-#define RE_NO_BK_VBAR 2
-
-/* 0 means plain + or ? serves as an operator, and \+, \? are literals.
- 1 means \+, \? are operators and plain +, ? are literals. */
-#define RE_BK_PLUS_QM 4
-
-/* 1 means | binds tighter than ^ or $.
- 0 means the contrary. */
-#define RE_TIGHT_VBAR 8
-
-/* 1 means treat \n as an _OR operator
- 0 means treat it as a normal character */
-#define RE_NEWLINE_OR 16
-
-/* 0 means that a special characters (such as *, ^, and $) always have
- their special meaning regardless of the surrounding context.
- 1 means that special characters may act as normal characters in some
- contexts. Specifically, this applies to:
- ^ - only special at the beginning, or after ( or |
- $ - only special at the end, or before ) or |
- *, +, ? - only special when not after the beginning, (, or | */
-#define RE_CONTEXT_INDEP_OPS 32
-
-/* Now define combinations of bits for the standard possibilities. */
-#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS)
-#define RE_SYNTAX_EGREP (RE_SYNTAX_AWK | RE_NEWLINE_OR)
-#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
+/* The following two types have to be signed and unsigned integer type
+ wide enough to hold a value of a pointer. For most ANSI compilers
+ ptrdiff_t and size_t should be likely OK. Still size of these two
+ types is 2 for Microsoft C. Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned long int reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+ without further backtracking. */
+#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+ If not set, then the GNU regex operators are recognized. */
+#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+ If not set, and debugging was on, turn it off.
+ This only works if regex.c is compiled -DDEBUG.
+ We define this bit always, so that all that's needed to turn on
+ debugging is to recompile regex.c; the calling code can always have
+ this bit set, and it won't affect anything in the normal case. */
+#define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
#define RE_SYNTAX_EMACS 0
-/* This data structure is used to represent a compiled pattern. */
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GNU_AWK \
+ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
+ & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS))
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
+ | RE_INTERVALS | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+# undef RE_DUP_MAX
+#endif
+/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
+#define RE_DUP_MAX (0x7fff)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+#if (_XOPEN_SOURCE - 0) == 500
+ REG_NOSYS = -1, /* This will never happen for this implementation. */
+#endif
+
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+#ifndef RE_TRANSLATE_TYPE
+# define RE_TRANSLATE_TYPE char *
+#endif
struct re_pattern_buffer
- {
- char *buffer; /* Space holding the compiled pattern commands. */
- int allocated; /* Size of space that buffer points to */
- int used; /* Length of portion of buffer actually occupied */
- char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
- /* re_search uses the fastmap, if there is one,
- to skip quickly over totally implausible characters */
- char *translate; /* Translate table to apply to all characters before comparing.
- Or zero for no translation.
- The translation is applied to a pattern when it is compiled
- and to data when it is matched. */
- char fastmap_accurate;
- /* Set to zero when a new pattern is stored,
- set to one when the fastmap is updated from it. */
- char can_be_null; /* Set to one by compiling fastmap
- if this pattern might match the null string.
- It does not necessarily match the null string
- in that case, but if this is zero, it cannot.
- 2 as value means can match null string
- but at end of range or before a character
- listed in the fastmap. */
- };
-
-/* Structure to store "register" contents data in.
-
- Pass the address of such a structure as an argument to re_match, etc.,
- if you want this information back.
-
- start[i] and end[i] record the string matched by \( ... \) grouping i,
- for i from 1 to RE_NREGS - 1.
- start[0] and end[0] record the entire string matched. */
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long int allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long int used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ RE_TRANSLATE_TYPE translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
struct re_registers
- {
- int start[RE_NREGS];
- int end[RE_NREGS];
- };
-
-/* These are the command codes that appear in compiled regular expressions, one per byte.
- Some command codes are followed by argument bytes.
- A command code can specify any interpretation whatever for its arguments.
- Zero-bytes may appear in the compiled regular expression. */
-
-enum regexpcode
- {
- unused,
- exactn, /* followed by one byte giving n, and then by n literal bytes */
- begline, /* fails unless at beginning of line */
- endline, /* fails unless at end of line */
- jump, /* followed by two bytes giving relative address to jump to */
- on_failure_jump, /* followed by two bytes giving relative address of place
- to resume at in case of failure. */
- finalize_jump, /* Throw away latest failure point and then jump to address. */
- maybe_finalize_jump, /* Like jump but finalize if safe to do so.
- This is used to jump back to the beginning
- of a repeat. If the command that follows
- this jump is clearly incompatible with the
- one at the beginning of the repeat, such that
- we can be sure that there is no use backtracking
- out of repetitions already completed,
- then we finalize. */
- dummy_failure_jump, /* jump, and push a dummy failure point.
- This failure point will be thrown away
- if an attempt is made to use it for a failure.
- A + construct makes this before the first repeat. */
- anychar, /* matches any one character */
- charset, /* matches any one char belonging to specified set.
- First following byte is # bitmap bytes.
- Then come bytes for a bit-map saying which chars are in.
- Bits in each byte are ordered low-bit-first.
- A character is in the set if its bit is 1.
- A character too large to have a bit in the map
- is automatically not in the set */
- charset_not, /* similar but match any character that is NOT one of those specified */
- start_memory, /* starts remembering the text that is matched
- and stores it in a memory register.
- followed by one byte containing the register number.
- Register numbers must be in the range 0 through NREGS. */
- stop_memory, /* stops remembering the text that is matched
- and stores it in a memory register.
- followed by one byte containing the register number.
- Register numbers must be in the range 0 through NREGS. */
- duplicate, /* match a duplicate of something remembered.
- Followed by one byte containing the index of the memory register. */
- before_dot, /* Succeeds if before dot */
- at_dot, /* Succeeds if at dot */
- after_dot, /* Succeeds if after dot */
- begbuf, /* Succeeds if at beginning of buffer */
- endbuf, /* Succeeds if at end of buffer */
- wordchar, /* Matches any word-constituent character */
- notwordchar, /* Matches any char that is not a word-constituent */
- wordbeg, /* Succeeds if at word beginning */
- wordend, /* Succeeds if at word end */
- wordbound, /* Succeeds if at a word boundary */
- notwordbound, /* Succeeds if not at a word boundary */
- syntaxspec, /* Matches any character whose syntax is specified.
- followed by a byte which contains a syntax code, Sword or such like */
- notsyntaxspec /* Matches any character whose syntax differs from the specified. */
- };
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+# define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
-extern char *re_compile_pattern ();
-/* Is this really advertised? */
-extern void re_compile_fastmap ();
-extern int re_search (), re_search_2 ();
-extern int re_match (), re_match_2 ();
-
-/* 4.2 bsd compatibility (yuck) */
-extern char *re_comp ();
-extern int re_exec ();
-
-#ifdef SYNTAX_TABLE
-extern char *re_syntax_table;
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#if __STDC__
+
+# define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+# define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t __re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *__re_compile_pattern
+ _RE_ARGS ((const char *pattern, size_t length,
+ struct re_pattern_buffer *buffer));
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, size_t length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int __re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int __re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int __re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int __re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int __re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void __re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+#ifdef _REGEX_RE_COMP
+# ifndef _CRAY
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+# endif
#endif
-extern int re_set_syntax ();
+/* POSIX compatibility. */
+extern int __regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern,
+ int __cflags));
+extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern,
+ int __cflags));
+
+extern int __regexec _RE_ARGS ((const regex_t *__preg,
+ const char *__string, size_t __nmatch,
+ regmatch_t __pmatch[], int __eflags));
+extern int regexec _RE_ARGS ((const regex_t *__preg,
+ const char *__string, size_t __nmatch,
+ regmatch_t __pmatch[], int __eflags));
+
+extern size_t __regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
+ char *__errbuf, size_t __errbuf_size));
+extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
+ char *__errbuf, size_t __errbuf_size));
+
+extern void __regfree _RE_ARGS ((regex_t *__preg));
+extern void regfree _RE_ARGS ((regex_t *__preg));
+
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
+
+#endif /* regex.h */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/contrib/gdb/gdb/hp-psymtab-read.c b/contrib/gdb/gdb/hp-psymtab-read.c
new file mode 100644
index 0000000..5926ada
--- /dev/null
+++ b/contrib/gdb/gdb/hp-psymtab-read.c
@@ -0,0 +1,2381 @@
+/* Read hp debug symbols and convert to internal format, for GDB.
+ Copyright 1993, 1996, 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support. */
+
+/* Common include file for hp_symtab_read.c and hp_psymtab_read.c.
+ This has nested includes of a bunch of stuff. */
+#include "hpread.h"
+#include "demangle.h"
+
+/* To generate dumping code, uncomment this define. The dumping
+ itself is controlled by routine-local statics called "dumping". */
+/* #define DUMPING 1 */
+
+/* To use the quick look-up tables, uncomment this define. */
+#define QUICK_LOOK_UP 1
+
+/* To call PXDB to process un-processed files, uncomment this define. */
+#define USE_PXDB 1
+
+/* Forward procedure declarations */
+
+void hpread_symfile_init
+ PARAMS ((struct objfile *));
+
+void
+do_pxdb PARAMS ((bfd *));
+
+void hpread_build_psymtabs
+ PARAMS ((struct objfile *, struct section_offsets *, int));
+
+void hpread_symfile_finish
+ PARAMS ((struct objfile *));
+
+static union dnttentry *hpread_get_gntt
+ PARAMS ((int, struct objfile *));
+
+static unsigned long hpread_get_textlow
+ PARAMS ((int, int, struct objfile *, int));
+
+static struct partial_symtab *hpread_start_psymtab
+ PARAMS ((struct objfile *, struct section_offsets *, char *, CORE_ADDR, int,
+ struct partial_symbol **, struct partial_symbol **));
+
+static struct partial_symtab *hpread_end_psymtab
+ PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
+ struct partial_symtab **, int));
+
+/* End of forward routine declarations */
+
+#ifdef USE_PXDB
+
+/* NOTE use of system files! May not be portable. */
+
+#define PXDB_SVR4 "/opt/langtools/bin/pxdb"
+#define PXDB_BSD "/usr/bin/pxdb"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* check for the existance of a file, given its full pathname */
+int
+file_exists (filename)
+ char *filename;
+{
+ if (filename)
+ return (access (filename, F_OK) == 0);
+ return 0;
+}
+
+
+/* Translate from the "hp_language" enumeration in hp-symtab.h
+ used in the debug info to gdb's generic enumeration in defs.h. */
+static enum language
+trans_lang (in_lang)
+ enum hp_language in_lang;
+{
+ if (in_lang == HP_LANGUAGE_C)
+ return language_c;
+
+ else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
+ return language_cplus;
+
+ else if (in_lang == HP_LANGUAGE_F77)
+ return language_fortran;
+
+ else
+ return language_unknown;
+}
+
+static char main_string[] = "main";
+
+/* Call PXDB to process our file.
+
+ Approach copied from DDE's "dbgk_run_pxdb". Note: we
+ don't check for BSD location of pxdb, nor for existance
+ of pxdb itself, etc.
+
+ NOTE: uses system function and string functions directly.
+
+ Return value: 1 if ok, 0 if not */
+int
+hpread_call_pxdb (file_name)
+ char *file_name;
+{
+ char *p;
+ int status;
+ int retval;
+
+ if (file_exists (PXDB_SVR4))
+ {
+ p = malloc (strlen (PXDB_SVR4) + strlen (file_name) + 2);
+ strcpy (p, PXDB_SVR4);
+ strcat (p, " ");
+ strcat (p, file_name);
+
+ warning ("File not processed by pxdb--about to process now.\n");
+ status = system (p);
+
+ retval = (status == 0);
+ }
+ else
+ {
+ warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name);
+
+ retval = 0;
+ }
+ return retval;
+} /* hpread_call_pxdb */
+
+
+/* Return 1 if the file turns out to need pre-processing
+ by PXDB, and we have thus called PXDB to do this processing
+ and the file therefore needs to be re-loaded. Otherwise
+ return 0. */
+int
+hpread_pxdb_needed (sym_bfd)
+ bfd *sym_bfd;
+{
+ asection *pinfo_section, *debug_section, *header_section;
+ unsigned int do_pxdb;
+ char *buf;
+ bfd_size_type header_section_size;
+
+ unsigned long tmp;
+ unsigned int pxdbed;
+
+ header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
+ if (!header_section)
+ {
+ return 0; /* No header at all, can't recover... */
+ }
+
+ debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$");
+ pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$");
+
+ if (pinfo_section && !debug_section)
+ {
+ /* Debug info with DOC, has different header format.
+ this only happens if the file was pxdbed and compiled optimized
+ otherwise the PINFO section is not there. */
+ header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+ if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header))
+ {
+ buf = alloca (sizeof (DOC_info_PXDB_header));
+
+ if (!bfd_get_section_contents (sym_bfd,
+ header_section,
+ buf, 0,
+ header_section_size))
+ error ("bfd_get_section_contents\n");
+
+ tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4));
+ pxdbed = (tmp >> 31) & 0x1;
+
+ if (!pxdbed)
+ error ("file debug header info invalid\n");
+ do_pxdb = 0;
+ }
+
+ else
+ error ("invalid $HEADER$ size in executable \n");
+ }
+
+ else
+ {
+
+ /* this can be three different cases:
+ 1. pxdbed and not doc
+ - DEBUG and HEADER sections are there
+ - header is PXDB_header type
+ - pxdbed flag is set to 1
+
+ 2. not pxdbed and doc
+ - DEBUG and HEADER sections are there
+ - header is DOC_info_header type
+ - pxdbed flag is set to 0
+
+ 3. not pxdbed and not doc
+ - DEBUG and HEADER sections are there
+ - header is XDB_header type
+ - pxdbed flag is set to 0
+
+ NOTE: the pxdbed flag is meaningful also in the not
+ already pxdb processed version of the header,
+ because in case on non-already processed by pxdb files
+ that same bit in the header would be always zero.
+ Why? Because the bit is the leftmost bit of a word
+ which contains a 'length' which is always a positive value
+ so that bit is never set to 1 (otherwise it would be negative)
+
+ Given the above, we have two choices : either we ignore the
+ size of the header itself and just look at the pxdbed field,
+ or we check the size and then we (for safety and paranoia related
+ issues) check the bit.
+ The first solution is used by DDE, the second by PXDB itself.
+ I am using the second one here, because I already wrote it,
+ and it is the end of a long day.
+ Also, using the first approach would still involve size issues
+ because we need to read in the contents of the header section, and
+ give the correct amount of stuff we want to read to the
+ get_bfd_section_contents function. */
+
+ /* decide which case depending on the size of the header section.
+ The size is as defined in hp-symtab.h */
+
+ header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+ if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */
+ {
+
+ buf = alloca (sizeof (PXDB_header));
+ if (!bfd_get_section_contents (sym_bfd,
+ header_section,
+ buf, 0,
+ header_section_size))
+ error ("bfd_get_section_contents\n");
+
+ tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3));
+ pxdbed = (tmp >> 31) & 0x1;
+
+ if (pxdbed)
+ do_pxdb = 0;
+ else
+ error ("file debug header invalid\n");
+ }
+ else /*not pxdbed and doc OR not pxdbed and non doc */
+ do_pxdb = 1;
+ }
+
+ if (do_pxdb)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+} /* hpread_pxdb_needed */
+
+#endif
+
+/* Check whether the file needs to be preprocessed by pxdb.
+ If so, call pxdb. */
+
+void
+do_pxdb (sym_bfd)
+ bfd *sym_bfd;
+{
+ /* The following code is HP-specific. The "right" way of
+ doing this is unknown, but we bet would involve a target-
+ specific pre-file-load check using a generic mechanism. */
+
+ /* This code will not be executed if the file is not in SOM
+ format (i.e. if compiled with gcc) */
+ if (hpread_pxdb_needed (sym_bfd))
+ {
+ /*This file has not been pre-processed. Preprocess now */
+
+ if (hpread_call_pxdb (sym_bfd->filename))
+ {
+ /* The call above has changed the on-disk file,
+ we can close the file anyway, because the
+ symbols will be reread in when the target is run */
+ bfd_close (sym_bfd);
+ }
+ }
+}
+
+
+
+#ifdef QUICK_LOOK_UP
+
+/* Code to handle quick lookup-tables follows. */
+
+
+/* Some useful macros */
+#define VALID_FILE(i) ((i) < pxdb_header_p->fd_entries)
+#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries)
+#define VALID_PROC(i) ((i) < pxdb_header_p->pd_entries)
+#define VALID_CLASS(i) ((i) < pxdb_header_p->cd_entries)
+
+#define FILE_START(i) (qFD[i].adrStart)
+#define MODULE_START(i) (qMD[i].adrStart)
+#define PROC_START(i) (qPD[i].adrStart)
+
+#define FILE_END(i) (qFD[i].adrEnd)
+#define MODULE_END(i) (qMD[i].adrEnd)
+#define PROC_END(i) (qPD[i].adrEnd)
+
+#define FILE_ISYM(i) (qFD[i].isym)
+#define MODULE_ISYM(i) (qMD[i].isym)
+#define PROC_ISYM(i) (qPD[i].isym)
+
+#define VALID_CURR_FILE (curr_fd < pxdb_header_p->fd_entries)
+#define VALID_CURR_MODULE (curr_md < pxdb_header_p->md_entries)
+#define VALID_CURR_PROC (curr_pd < pxdb_header_p->pd_entries)
+#define VALID_CURR_CLASS (curr_cd < pxdb_header_p->cd_entries)
+
+#define CURR_FILE_START (qFD[curr_fd].adrStart)
+#define CURR_MODULE_START (qMD[curr_md].adrStart)
+#define CURR_PROC_START (qPD[curr_pd].adrStart)
+
+#define CURR_FILE_END (qFD[curr_fd].adrEnd)
+#define CURR_MODULE_END (qMD[curr_md].adrEnd)
+#define CURR_PROC_END (qPD[curr_pd].adrEnd)
+
+#define CURR_FILE_ISYM (qFD[curr_fd].isym)
+#define CURR_MODULE_ISYM (qMD[curr_md].isym)
+#define CURR_PROC_ISYM (qPD[curr_pd].isym)
+
+#define TELL_OBJFILE \
+ do { \
+ if( !told_objfile ) { \
+ told_objfile = 1; \
+ warning ("\nIn object file \"%s\":\n", \
+ objfile->name); \
+ } \
+ } while (0)
+
+
+
+/* Keeping track of the start/end symbol table (LNTT) indices of
+ psymtabs created so far */
+
+typedef struct
+ {
+ int start;
+ int end;
+ }
+pst_syms_struct;
+
+static pst_syms_struct *pst_syms_array = 0;
+
+static pst_syms_count = 0;
+static pst_syms_size = 0;
+
+/* used by the TELL_OBJFILE macro */
+static boolean told_objfile = 0;
+
+/* Set up psymtab symbol index stuff */
+static void
+init_pst_syms ()
+{
+ pst_syms_count = 0;
+ pst_syms_size = 20;
+ pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct));
+}
+
+/* Clean up psymtab symbol index stuff */
+static void
+clear_pst_syms ()
+{
+ pst_syms_count = 0;
+ pst_syms_size = 0;
+ free (pst_syms_array);
+ pst_syms_array = 0;
+}
+
+/* Add information about latest psymtab to symbol index table */
+static void
+record_pst_syms (start_sym, end_sym)
+ int start_sym;
+ int end_sym;
+{
+ if (++pst_syms_count > pst_syms_size)
+ {
+ pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array,
+ 2 * pst_syms_size * sizeof (pst_syms_struct));
+ pst_syms_size *= 2;
+ }
+ pst_syms_array[pst_syms_count - 1].start = start_sym;
+ pst_syms_array[pst_syms_count - 1].end = end_sym;
+}
+
+/* Find a suitable symbol table index which can serve as the upper
+ bound of a psymtab that starts at INDEX
+
+ This scans backwards in the psymtab symbol index table to find a
+ "hole" in which the given index can fit. This is a heuristic!!
+ We don't search the entire table to check for multiple holes,
+ we don't care about overlaps, etc.
+
+ Return 0 => not found */
+static int
+find_next_pst_start (index)
+ int index;
+{
+ int i;
+
+ for (i = pst_syms_count - 1; i >= 0; i--)
+ if (pst_syms_array[i].end <= index)
+ return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1;
+
+ if (pst_syms_array[0].start > index)
+ return pst_syms_array[0].start - 1;
+
+ return 0;
+}
+
+
+
+/* Utility functions to find the ending symbol index for a psymtab */
+
+/* Find the next file entry that begins beyond INDEX, and return
+ its starting symbol index - 1.
+ QFD is the file table, CURR_FD is the file entry from where to start,
+ PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+ Return 0 => not found */
+static int
+find_next_file_isym (index, qFD, curr_fd, pxdb_header_p)
+ int index;
+ quick_file_entry *qFD;
+ int curr_fd;
+ PXDB_header_ptr pxdb_header_p;
+{
+ while (VALID_CURR_FILE)
+ {
+ if (CURR_FILE_ISYM >= index)
+ return CURR_FILE_ISYM - 1;
+ curr_fd++;
+ }
+ return 0;
+}
+
+/* Find the next procedure entry that begins beyond INDEX, and return
+ its starting symbol index - 1.
+ QPD is the procedure table, CURR_PD is the proc entry from where to start,
+ PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+ Return 0 => not found */
+static int
+find_next_proc_isym (index, qPD, curr_pd, pxdb_header_p)
+ int index;
+ quick_procedure_entry *qPD;
+ int curr_pd;
+ PXDB_header_ptr pxdb_header_p;
+{
+ while (VALID_CURR_PROC)
+ {
+ if (CURR_PROC_ISYM >= index)
+ return CURR_PROC_ISYM - 1;
+ curr_pd++;
+ }
+ return 0;
+}
+
+/* Find the next module entry that begins beyond INDEX, and return
+ its starting symbol index - 1.
+ QMD is the module table, CURR_MD is the modue entry from where to start,
+ PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+ Return 0 => not found */
+static int
+find_next_module_isym (index, qMD, curr_md, pxdb_header_p)
+ int index;
+ quick_module_entry *qMD;
+ int curr_md;
+ PXDB_header_ptr pxdb_header_p;
+{
+ while (VALID_CURR_MODULE)
+ {
+ if (CURR_MODULE_ISYM >= index)
+ return CURR_MODULE_ISYM - 1;
+ curr_md++;
+ }
+ return 0;
+}
+
+/* Scan and record partial symbols for all functions starting from index
+ pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR.
+ Other parameters are explained in comments below. */
+
+/* This used to be inline in hpread_quick_traverse, but now that we do essentially the
+ same thing for two different cases (modules and module-less files), it's better
+ organized in a separate routine, although it does take lots of arguments. pai/1997-10-08 */
+
+static int
+scan_procs (curr_pd_p, qPD, max_procs, start_adr, end_adr, pst, vt_bits, objfile, section_offsets)
+ int *curr_pd_p; /* pointer to current proc index */
+ quick_procedure_entry *qPD; /* the procedure quick lookup table */
+ int max_procs; /* number of entries in proc. table */
+ CORE_ADDR start_adr; /* beginning of code range for current psymtab */
+ CORE_ADDR end_adr; /* end of code range for current psymtab */
+ struct partial_symtab *pst; /* current psymtab */
+ char *vt_bits; /* strings table of SOM debug space */
+ struct objfile *objfile; /* current object file */
+ struct section_offsets *section_offsets; /* not really used for HP-UX currently */
+{
+ union dnttentry *dn_bufp;
+ int symbol_count = 0; /* Total number of symbols in this psymtab */
+ int curr_pd = *curr_pd_p; /* Convenience variable -- avoid dereferencing pointer all the time */
+
+#ifdef DUMPING
+ /* Turn this on for lots of debugging information in this routine */
+ static int dumping = 0;
+#endif
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
+ }
+#endif
+
+ while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
+ {
+
+ char *rtn_name; /* mangled name */
+ char *rtn_dem_name; /* qualified demangled name */
+ char *class_name;
+ int class;
+
+ if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
+ vt_bits[(long) qPD[curr_pd].sbAlias]) /* not a null string */
+ {
+ /* Get mangled name for the procedure, and demangle it */
+ rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
+ rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
+ }
+ else
+ {
+ rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc];
+ rtn_dem_name = NULL;
+ }
+
+ /* Hack to get around HP C/C++ compilers' insistence on providing
+ "_MAIN_" as an alternate name for "main" */
+ if ((strcmp (rtn_name, "_MAIN_") == 0) &&
+ (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
+ rtn_dem_name = rtn_name = main_string;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd);
+ }
+#endif
+
+ /* Check for module-spanning routines. */
+ if (CURR_PROC_END > end_adr)
+ {
+ TELL_OBJFILE;
+ warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
+ }
+
+ /* Add this routine symbol to the list in the objfile.
+ Unfortunately we have to go to the LNTT to determine the
+ correct list to put it on. An alternative (which the
+ code used to do) would be to not check and always throw
+ it on the "static" list. But if we go that route, then
+ symbol_lookup() needs to be tweaked a bit to account
+ for the fact that the function might not be found on
+ the correct list in the psymtab. - RT */
+ dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
+ if (dn_bufp->dfunc.global)
+ add_psymbol_with_dem_name_to_list (rtn_name,
+ strlen (rtn_name),
+ rtn_dem_name,
+ strlen (rtn_dem_name),
+ VAR_NAMESPACE,
+ LOC_BLOCK, /* "I am a routine" */
+ &objfile->global_psymbols,
+ (qPD[curr_pd].adrStart + /* Starting address of rtn */
+ ANOFFSET (section_offsets, SECT_OFF_TEXT)),
+ 0, /* core addr?? */
+ trans_lang ((enum hp_language) qPD[curr_pd].language),
+ objfile);
+ else
+ add_psymbol_with_dem_name_to_list (rtn_name,
+ strlen (rtn_name),
+ rtn_dem_name,
+ strlen (rtn_dem_name),
+ VAR_NAMESPACE,
+ LOC_BLOCK, /* "I am a routine" */
+ &objfile->static_psymbols,
+ (qPD[curr_pd].adrStart + /* Starting address of rtn */
+ ANOFFSET (section_offsets, SECT_OFF_TEXT)),
+ 0, /* core addr?? */
+ trans_lang ((enum hp_language) qPD[curr_pd].language),
+ objfile);
+
+ symbol_count++;
+ *curr_pd_p = ++curr_pd; /* bump up count & reflect in caller */
+ } /* loop over procedures */
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ if (symbol_count == 0)
+ printf ("Scan_procs: no symbols found!\n");
+ }
+#endif
+
+ return symbol_count;
+}
+
+
+/* Traverse the quick look-up tables, building a set of psymtabs.
+
+ This constructs a psymtab for modules and files in the quick lookup
+ tables.
+
+ Mostly, modules correspond to compilation units, so we try to
+ create psymtabs that correspond to modules; however, in some cases
+ a file can result in a compiled object which does not have a module
+ entry for it, so in such cases we create a psymtab for the file. */
+
+int
+hpread_quick_traverse (objfile, section_offsets, gntt_bits, vt_bits, pxdb_header_p)
+ struct objfile *objfile; /* The object file descriptor */
+ struct section_offsets *section_offsets; /* ?? Null for HP */
+ char *gntt_bits; /* GNTT entries, loaded in from the file */
+ char *vt_bits; /* VT (string) entries ditto. */
+ PXDB_header_ptr pxdb_header_p; /* Pointer to pxdb header ditto */
+{
+ struct partial_symtab *pst;
+
+ char *addr;
+
+ quick_procedure_entry *qPD;
+ quick_file_entry *qFD;
+ quick_module_entry *qMD;
+ quick_class_entry *qCD;
+
+ int idx;
+ int i;
+ CORE_ADDR start_adr; /* current psymtab's starting code addr */
+ CORE_ADDR end_adr; /* current psymtab's ending code addr */
+ CORE_ADDR next_mod_adr; /* next module's starting code addr */
+ int curr_pd; /* current procedure */
+ int curr_fd; /* current file */
+ int curr_md; /* current module */
+ int start_sym; /* current psymtab's starting symbol index */
+ int end_sym; /* current psymtab's ending symbol index */
+ int max_LNTT_sym_index;
+ int syms_in_pst;
+ B_TYPE *class_entered;
+
+ struct partial_symbol **global_syms; /* We'll be filling in the "global" */
+ struct partial_symbol **static_syms; /* and "static" tables in the objfile
+ as we go, so we need a pair of
+ current pointers. */
+
+#ifdef DUMPING
+ /* Turn this on for lots of debugging information in this routine.
+ You get a blow-by-blow account of quick lookup table reading */
+ static int dumping = 0;
+#endif
+
+ pst = (struct partial_symtab *) 0;
+
+ /* Clear out some globals */
+ init_pst_syms ();
+ told_objfile = 0;
+
+ /* Demangling style -- if EDG style already set, don't change it,
+ as HP style causes some problems with the KAI EDG compiler */
+ if (current_demangling_style != edg_demangling)
+ {
+ /* Otherwise, ensure that we are using HP style demangling */
+ set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+ }
+
+ /* First we need to find the starting points of the quick
+ look-up tables in the GNTT. */
+
+ addr = gntt_bits;
+
+ qPD = (quick_procedure_entry_ptr) addr;
+ addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing routines as we see them\n");
+ for (i = 0; VALID_PROC (i); i++)
+ {
+ idx = (long) qPD[i].sbProc;
+ printf ("%s %x..%x\n", &vt_bits[idx],
+ (int) PROC_START (i),
+ (int) PROC_END (i));
+ }
+ }
+#endif
+
+ qFD = (quick_file_entry_ptr) addr;
+ addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing files as we see them\n");
+ for (i = 0; VALID_FILE (i); i++)
+ {
+ idx = (long) qFD[i].sbFile;
+ printf ("%s %x..%x\n", &vt_bits[idx],
+ (int) FILE_START (i),
+ (int) FILE_END (i));
+ }
+ }
+#endif
+
+ qMD = (quick_module_entry_ptr) addr;
+ addr += pxdb_header_p->md_entries * sizeof (quick_module_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing modules as we see them\n");
+ for (i = 0; i < pxdb_header_p->md_entries; i++)
+ {
+ idx = (long) qMD[i].sbMod;
+ printf ("%s\n", &vt_bits[idx]);
+ }
+ }
+#endif
+
+ qCD = (quick_class_entry_ptr) addr;
+ addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing classes as we see them\n");
+ for (i = 0; VALID_CLASS (i); i++)
+ {
+ idx = (long) qCD[i].sbClass;
+ printf ("%s\n", &vt_bits[idx]);
+ }
+
+ printf ("\n Done with dump, on to build!\n");
+ }
+#endif
+
+ /* We need this index only while hp-symtab-read.c expects
+ a byte offset to the end of the LNTT entries for a given
+ psymtab. Thus the need for it should go away someday.
+
+ When it goes away, then we won't have any need to load the
+ LNTT from the objfile at psymtab-time, and start-up will be
+ faster. To make that work, we'll need some way to create
+ a null pst for the "globals" pseudo-module. */
+ max_LNTT_sym_index = LNTT_SYMCOUNT (objfile);
+
+ /* Scan the module descriptors and make a psymtab for each.
+
+ We know the MDs, FDs and the PDs are in order by starting
+ address. We use that fact to traverse all three arrays in
+ parallel, knowing when the next PD is in a new file
+ and we need to create a new psymtab. */
+ curr_pd = 0; /* Current procedure entry */
+ curr_fd = 0; /* Current file entry */
+ curr_md = 0; /* Current module entry */
+
+ start_adr = 0; /* Current psymtab code range */
+ end_adr = 0;
+
+ start_sym = 0; /* Current psymtab symbol range */
+ end_sym = 0;
+
+ syms_in_pst = 0; /* Symbol count for psymtab */
+
+ /* Psts actually just have pointers into the objfile's
+ symbol table, not their own symbol tables. */
+ global_syms = objfile->global_psymbols.list;
+ static_syms = objfile->static_psymbols.list;
+
+
+ /* First skip over pseudo-entries with address 0. These represent inlined
+ routines and abstract (uninstantiated) template routines.
+ FIXME: These should be read in and available -- even if we can't set
+ breakpoints, etc., there's some information that can be presented
+ to the user. pai/1997-10-08 */
+
+ while (VALID_CURR_PROC && (CURR_PROC_START == 0))
+ curr_pd++;
+
+ /* Loop over files, modules, and procedures in code address order. Each
+ time we enter an iteration of this loop, curr_pd points to the first
+ unprocessed procedure, curr_fd points to the first unprocessed file, and
+ curr_md to the first unprocessed module. Each iteration of this loop
+ updates these as required -- any or all of them may be bumpd up
+ each time around. When we exit this loop, we are done with all files
+ and modules in the tables -- there may still be some procedures, however.
+
+ Note: This code used to loop only over module entries, under the assumption
+ that files can occur via inclusions and are thus unreliable, while a
+ compiled object always corresponds to a module. With CTTI in the HP aCC
+ compiler, it turns out that compiled objects may have only files and no
+ modules; so we have to loop over files and modules, creating psymtabs for
+ either as appropriate. Unfortunately there are some problems (notably:
+ 1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers
+ to the ending symbol indices of a module or a file) which make it quite hard
+ to do this correctly. Currently it uses a bunch of heuristics to start and
+ end psymtabs; they seem to work well with most objects generated by aCC, but
+ who knows when that will change... */
+
+ while (VALID_CURR_FILE || VALID_CURR_MODULE)
+ {
+
+ char *mod_name_string;
+ char *full_name_string;
+
+ /* First check for modules like "version.c", which have no code
+ in them but still have qMD entries. They also have no qFD or
+ qPD entries. Their start address is -1 and their end address
+ is 0. */
+ if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0))
+ {
+
+ mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
+
+#ifdef DUMPING
+ if (dumping)
+ printf ("Module with data only %s\n", mod_name_string);
+#endif
+
+ /* We'll skip the rest (it makes error-checking easier), and
+ just make an empty pst. Right now empty psts are not put
+ in the pst chain, so all this is for naught, but later it
+ might help. */
+
+ pst = hpread_start_psymtab (objfile,
+ section_offsets, /* ?? */
+ mod_name_string,
+ CURR_MODULE_START, /* Low text address: bogus! */
+ (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ end_sym * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ 0, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+
+ global_syms = objfile->global_psymbols.next;
+ static_syms = objfile->static_psymbols.next;
+
+ curr_md++;
+ }
+ else if (VALID_CURR_MODULE &&
+ ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) ||
+ (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
+ {
+ TELL_OBJFILE;
+ warning ("Module \"%s\" [0x%x] has non-standard addresses. It starts at 0x%x, ends at 0x%x, and will be skipped.",
+ mod_name_string, curr_md, start_adr, end_adr);
+ /* On to next module */
+ curr_md++;
+ }
+ else
+ {
+ /* First check if we are looking at a file with code in it
+ that does not overlap the current module's code range */
+
+ if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0)
+ {
+
+ /* Looking at file not corresponding to any module,
+ create a psymtab for it */
+ full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+ start_adr = CURR_FILE_START;
+ end_adr = CURR_FILE_END;
+ start_sym = CURR_FILE_ISYM;
+
+ /* Check if there are any procedures not handled until now, that
+ begin before the start address of this file, and if so, adjust
+ this module's start address to include them. This handles routines that
+ are in between file or module ranges for some reason (probably
+ indicates a compiler bug */
+
+ if (CURR_PROC_START < start_adr)
+ {
+ TELL_OBJFILE;
+ warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+ &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+ start_adr = CURR_PROC_START;
+ if (CURR_PROC_ISYM < start_sym)
+ start_sym = CURR_PROC_ISYM;
+ }
+
+ /* Sometimes (compiler bug -- COBOL) the module end address is higher
+ than the start address of the next module, so check for that and
+ adjust accordingly */
+
+ if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+ full_name_string, curr_fd);
+ end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+ if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+ full_name_string, curr_fd);
+ end_adr = CURR_MODULE_START - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Make new psymtab for file %s (%x to %x).\n",
+ full_name_string, start_adr, end_adr);
+ }
+#endif
+ /* Create the basic psymtab, connecting it in the list
+ for this objfile and pointing its symbol entries
+ to the current end of the symbol areas in the objfile.
+
+ The "ldsymoff" parameter is the byte offset in the LNTT
+ of the first symbol in this file. Some day we should
+ turn this into an index (fix in hp-symtab-read.c as well).
+ And it's not even the right byte offset, as we're using
+ the size of a union! FIXME! */
+ pst = hpread_start_psymtab (objfile,
+ section_offsets, /* ?? */
+ full_name_string,
+ start_adr, /* Low text address */
+ (start_sym * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ /* Set up to only enter each class referenced in this module once. */
+ class_entered = malloc (B_BYTES (pxdb_header_p->cd_entries));
+ B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+ /* Scan the procedure descriptors for procedures in the current
+ file, based on the starting addresses. */
+
+ syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+ start_adr, end_adr,
+ pst, vt_bits, objfile, section_offsets);
+
+ /* Get ending symbol offset */
+
+ end_sym = 0;
+ /* First check for starting index before previous psymtab */
+ if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+ {
+ end_sym = find_next_pst_start (start_sym);
+ }
+ /* Look for next start index of a file or module, or procedure */
+ if (!end_sym)
+ {
+ int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+ int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p);
+ int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+ if (next_file_isym && next_module_isym)
+ {
+ /* pick lower of next file or module start index */
+ end_sym = min (next_file_isym, next_module_isym);
+ }
+ else
+ {
+ /* one of them is zero, pick the other */
+ end_sym = max (next_file_isym, next_module_isym);
+ }
+
+ /* As a precaution, check next procedure index too */
+ if (!end_sym)
+ end_sym = next_proc_isym;
+ else
+ end_sym = min (end_sym, next_proc_isym);
+ }
+
+ /* Couldn't find procedure, file, or module, use globals as default */
+ if (!end_sym)
+ end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
+ }
+#endif
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ end_sym * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ end_adr, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+
+ record_pst_syms (start_sym, end_sym);
+
+ if (NULL == pst)
+ warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
+ full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
+ }
+#endif
+ /* Prepare for the next psymtab. */
+ global_syms = objfile->global_psymbols.next;
+ static_syms = objfile->static_psymbols.next;
+ free (class_entered);
+
+ curr_fd++;
+ } /* Psymtab for file */
+ else
+ {
+ /* We have a module for which we create a psymtab */
+
+ mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
+
+ /* We will include the code ranges of any files that happen to
+ overlap with this module */
+
+ /* So, first pick the lower of the file's and module's start addresses */
+ start_adr = CURR_MODULE_START;
+ if (VALID_CURR_FILE)
+ {
+ if (CURR_FILE_START < CURR_MODULE_START)
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".",
+ &vt_bits[(long) qFD[curr_fd].sbFile],
+ curr_fd, mod_name_string);
+
+ start_adr = CURR_FILE_START;
+ }
+ }
+
+ /* Also pick the lower of the file's and the module's start symbol indices */
+ start_sym = CURR_MODULE_ISYM;
+ if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM))
+ start_sym = CURR_FILE_ISYM;
+
+ /* For the end address, we scan through the files till we find one
+ that overlaps the current module but ends beyond it; if no such file exists we
+ simply use the module's start address.
+ (Note, if file entries themselves overlap
+ we take the longest overlapping extension beyond the end of the module...)
+ We assume that modules never overlap. */
+
+ end_adr = CURR_MODULE_END;
+
+ if (VALID_CURR_FILE)
+ {
+ while (VALID_CURR_FILE && (CURR_FILE_START < end_adr))
+ {
+
+#ifdef DUMPING
+ if (dumping)
+ printf ("Maybe skipping file %s which overlaps with module %s\n",
+ &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
+#endif
+ if (CURR_FILE_END > end_adr)
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
+ &vt_bits[(long) qFD[curr_fd].sbFile],
+ curr_fd, mod_name_string);
+ end_adr = CURR_FILE_END;
+ }
+ curr_fd++;
+ }
+ curr_fd--; /* back up after going too far */
+ }
+
+ /* Sometimes (compiler bug -- COBOL) the module end address is higher
+ than the start address of the next module, so check for that and
+ adjust accordingly */
+
+ if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+ mod_name_string, curr_md);
+ end_adr = MODULE_START (curr_md + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+ if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+ mod_name_string, curr_md);
+ end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+
+ /* Use one file to get the full name for the module. This
+ situation can arise if there is executable code in a #include
+ file. Each file with code in it gets a qFD. Files which don't
+ contribute code don't get a qFD, even if they include files
+ which do, e.g.:
+
+ body.c: rtn.h:
+ int x; int main() {
+ #include "rtn.h" return x;
+ }
+
+ There will a qFD for "rtn.h",and a qMD for "body.c",
+ but no qMD for "rtn.h" or qFD for "body.c"!
+
+ We pick the name of the last file to overlap with this
+ module. C convention is to put include files first. In a
+ perfect world, we could check names and use the file whose full
+ path name ends with the module name. */
+
+ if (VALID_CURR_FILE)
+ full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+ else
+ full_name_string = mod_name_string;
+
+ /* Check if there are any procedures not handled until now, that
+ begin before the start address we have now, and if so, adjust
+ this psymtab's start address to include them. This handles routines that
+ are in between file or module ranges for some reason (probably
+ indicates a compiler bug */
+
+ if (CURR_PROC_START < start_adr)
+ {
+ TELL_OBJFILE;
+ warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+ &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+ start_adr = CURR_PROC_START;
+ if (CURR_PROC_ISYM < start_sym)
+ start_sym = CURR_PROC_ISYM;
+ }
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
+ mod_name_string, start_adr, end_adr, full_name_string);
+ }
+#endif
+ /* Create the basic psymtab, connecting it in the list
+ for this objfile and pointing its symbol entries
+ to the current end of the symbol areas in the objfile.
+
+ The "ldsymoff" parameter is the byte offset in the LNTT
+ of the first symbol in this file. Some day we should
+ turn this into an index (fix in hp-symtab-read.c as well).
+ And it's not even the right byte offset, as we're using
+ the size of a union! FIXME! */
+ pst = hpread_start_psymtab (objfile,
+ section_offsets, /* ?? */
+ full_name_string,
+ start_adr, /* Low text address */
+ (start_sym * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ /* Set up to only enter each class referenced in this module once. */
+ class_entered = malloc (B_BYTES (pxdb_header_p->cd_entries));
+ B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+ /* Scan the procedure descriptors for procedures in the current
+ module, based on the starting addresses. */
+
+ syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+ start_adr, end_adr,
+ pst, vt_bits, objfile, section_offsets);
+
+ /* Get ending symbol offset */
+
+ end_sym = 0;
+ /* First check for starting index before previous psymtab */
+ if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+ {
+ end_sym = find_next_pst_start (start_sym);
+ }
+ /* Look for next start index of a file or module, or procedure */
+ if (!end_sym)
+ {
+ int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+ int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p);
+ int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+ if (next_file_isym && next_module_isym)
+ {
+ /* pick lower of next file or module start index */
+ end_sym = min (next_file_isym, next_module_isym);
+ }
+ else
+ {
+ /* one of them is zero, pick the other */
+ end_sym = max (next_file_isym, next_module_isym);
+ }
+
+ /* As a precaution, check next procedure index too */
+ if (!end_sym)
+ end_sym = next_proc_isym;
+ else
+ end_sym = min (end_sym, next_proc_isym);
+ }
+
+ /* Couldn't find procedure, file, or module, use globals as default */
+ if (!end_sym)
+ end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
+ }
+#endif
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ end_sym * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ end_adr, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+
+ record_pst_syms (start_sym, end_sym);
+
+ if (NULL == pst)
+ warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
+ mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
+ }
+#endif
+
+ /* Prepare for the next psymtab. */
+ global_syms = objfile->global_psymbols.next;
+ static_syms = objfile->static_psymbols.next;
+ free (class_entered);
+
+ curr_md++;
+ curr_fd++;
+ } /* psymtab for module */
+ } /* psymtab for non-bogus file or module */
+ } /* End of while loop over all files & modules */
+
+ /* There may be some routines after all files and modules -- these will get
+ inserted in a separate new module of their own */
+ if (VALID_CURR_PROC)
+ {
+ start_adr = CURR_PROC_START;
+ end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
+ TELL_OBJFILE;
+ warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
+ curr_pd, start_adr, end_adr);
+ }
+#endif
+ pst = hpread_start_psymtab (objfile,
+ section_offsets, /* ?? */
+ "orphans",
+ start_adr, /* Low text address */
+ (CURR_PROC_ISYM * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+ start_adr, end_adr,
+ pst, vt_bits, objfile, section_offsets);
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ pxdb_header_p->globals * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ end_adr, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+ }
+
+
+#ifdef NEVER_NEVER
+ /* Now build psts for non-module things (in the tail of
+ the LNTT, after the last END MODULE entry).
+
+ If null psts were kept on the chain, this would be
+ a solution. FIXME */
+ pst = hpread_start_psymtab (objfile,
+ section_offsets,
+ "globals",
+ 0,
+ (pxdb_header_p->globals
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ hpread_end_psymtab (pst,
+ NULL, 0,
+ (max_LNTT_sym_index * sizeof (struct dntt_type_block)),
+ 0,
+ NULL, 0);
+#endif
+
+ clear_pst_syms ();
+
+ return 1;
+
+} /* End of hpread_quick_traverse. */
+
+
+/* Get appropriate header, based on pxdb type.
+ Return value: 1 if ok, 0 if not */
+int
+hpread_get_header (objfile, pxdb_header_p)
+ struct objfile *objfile;
+ PXDB_header_ptr pxdb_header_p;
+{
+ asection *pinfo_section, *debug_section, *header_section;
+
+#ifdef DUMPING
+ /* Turn on for debugging information */
+ static int dumping = 0;
+#endif
+
+ header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
+ if (!header_section)
+ {
+ /* We don't have either PINFO or DEBUG sections. But
+ stuff like "libc.sl" has no debug info. There's no
+ need to warn the user of this, as it may be ok. The
+ caller will figure it out and issue any needed
+ messages. */
+#ifdef DUMPING
+ if (dumping)
+ printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+ return 0;
+ }
+
+ /* We would like either a $DEBUG$ or $PINFO$ section.
+ Once we know which, we can understand the header
+ data (which we have defined to suit the more common
+ $DEBUG$ case). */
+ debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$");
+ pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$");
+ if (debug_section)
+ {
+ /* The expected case: normal pxdb header. */
+ bfd_get_section_contents (objfile->obfd, header_section,
+ pxdb_header_p, 0, sizeof (PXDB_header));
+
+ if (!pxdb_header_p->pxdbed)
+ {
+ /* This shouldn't happen if we check in "symfile.c". */
+ return 0;
+ } /* DEBUG section */
+ }
+
+ else if (pinfo_section)
+ {
+ /* The DOC case; we need to translate this into a
+ regular header. */
+ DOC_info_PXDB_header doc_header;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name);
+ }
+#endif
+
+ bfd_get_section_contents (objfile->obfd,
+ header_section,
+ &doc_header, 0,
+ sizeof (DOC_info_PXDB_header));
+
+ if (!doc_header.pxdbed)
+ {
+ /* This shouldn't happen if we check in "symfile.c". */
+ warning ("File \"%s\" not processed by pxdb!", objfile->name);
+ return 0;
+ }
+
+ /* Copy relevent fields to standard header passed in. */
+ pxdb_header_p->pd_entries = doc_header.pd_entries;
+ pxdb_header_p->fd_entries = doc_header.fd_entries;
+ pxdb_header_p->md_entries = doc_header.md_entries;
+ pxdb_header_p->pxdbed = doc_header.pxdbed;
+ pxdb_header_p->bighdr = doc_header.bighdr;
+ pxdb_header_p->sa_header = doc_header.sa_header;
+ pxdb_header_p->inlined = doc_header.inlined;
+ pxdb_header_p->globals = doc_header.globals;
+ pxdb_header_p->time = doc_header.time;
+ pxdb_header_p->pg_entries = doc_header.pg_entries;
+ pxdb_header_p->functions = doc_header.functions;
+ pxdb_header_p->files = doc_header.files;
+ pxdb_header_p->cd_entries = doc_header.cd_entries;
+ pxdb_header_p->aa_entries = doc_header.aa_entries;
+ pxdb_header_p->oi_entries = doc_header.oi_entries;
+ pxdb_header_p->version = doc_header.version;
+ } /* PINFO section */
+
+ else
+ {
+#ifdef DUMPING
+ if (dumping)
+ printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+ return 0;
+
+ }
+
+ return 1;
+} /* End of hpread_get_header */
+#endif /* QUICK_LOOK_UP */
+
+
+/* Initialization for reading native HP C debug symbols from OBJFILE.
+
+ Its only purpose in life is to set up the symbol reader's private
+ per-objfile data structures, and read in the raw contents of the debug
+ sections (attaching pointers to the debug info into the private data
+ structures).
+
+ Since BFD doesn't know how to read debug symbols in a format-independent
+ way (and may never do so...), we have to do it ourselves. Note we may
+ be called on a file without native HP C debugging symbols.
+
+ FIXME, there should be a cleaner peephole into the BFD environment
+ here. */
+void
+hpread_symfile_init (objfile)
+ struct objfile *objfile;
+{
+ asection *vt_section, *slt_section, *lntt_section, *gntt_section;
+
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_private = (PTR)
+ xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
+ memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
+
+ /* We haven't read in any types yet. */
+ TYPE_VECTOR (objfile) = 0;
+
+ /* Read in data from the $GNTT$ subspace. */
+ gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
+ if (!gntt_section)
+ return;
+
+ GNTT (objfile)
+ = obstack_alloc (&objfile->symbol_obstack,
+ bfd_section_size (objfile->obfd, gntt_section));
+
+ bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
+ 0, bfd_section_size (objfile->obfd, gntt_section));
+
+ GNTT_SYMCOUNT (objfile)
+ = bfd_section_size (objfile->obfd, gntt_section)
+ / sizeof (struct dntt_type_block);
+
+ /* Read in data from the $LNTT$ subspace. Also keep track of the number
+ of LNTT symbols.
+
+ FIXME: this could be moved into the psymtab-to-symtab expansion
+ code, and save startup time. At the moment this data is
+ still used, though. We'd need a way to tell hp-symtab-read.c
+ whether or not to load the LNTT. */
+ lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
+ if (!lntt_section)
+ return;
+
+ LNTT (objfile)
+ = obstack_alloc (&objfile->symbol_obstack,
+ bfd_section_size (objfile->obfd, lntt_section));
+
+ bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
+ 0, bfd_section_size (objfile->obfd, lntt_section));
+
+ LNTT_SYMCOUNT (objfile)
+ = bfd_section_size (objfile->obfd, lntt_section)
+ / sizeof (struct dntt_type_block);
+
+ /* Read in data from the $SLT$ subspace. $SLT$ contains information
+ on source line numbers. */
+ slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
+ if (!slt_section)
+ return;
+
+ SLT (objfile) =
+ obstack_alloc (&objfile->symbol_obstack,
+ bfd_section_size (objfile->obfd, slt_section));
+
+ bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
+ 0, bfd_section_size (objfile->obfd, slt_section));
+
+ /* Read in data from the $VT$ subspace. $VT$ contains things like
+ names and constants. Keep track of the number of symbols in the VT. */
+ vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
+ if (!vt_section)
+ return;
+
+ VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
+
+ VT (objfile) =
+ (char *) obstack_alloc (&objfile->symbol_obstack,
+ VT_SIZE (objfile));
+
+ bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
+ 0, VT_SIZE (objfile));
+}
+
+/* Scan and build partial symbols for a symbol file.
+
+ The minimal symbol table (either SOM or HP a.out) has already been
+ read in; all we need to do is setup partial symbols based on the
+ native debugging information.
+
+ Note that the minimal table is produced by the linker, and has
+ only global routines in it; the psymtab is based on compiler-
+ generated debug information and has non-global
+ routines in it as well as files and class information.
+
+ We assume hpread_symfile_init has been called to initialize the
+ symbol reader's private data structures.
+
+ SECTION_OFFSETS contains offsets relative to which the symbols in the
+ various sections are (depending where the sections were actually loaded).
+ MAINLINE is true if we are reading the main symbol table (as
+ opposed to a shared lib or dynamically loaded file). */
+void
+hpread_build_psymtabs (objfile, section_offsets, mainline)
+ struct objfile *objfile;
+ struct section_offsets *section_offsets;
+ int mainline;
+{
+
+#ifdef DUMPING
+ /* Turn this on to get debugging output. */
+ static int dumping = 0;
+#endif
+
+ char *namestring;
+ int past_first_source_file = 0;
+ struct cleanup *old_chain;
+
+ int hp_symnum, symcount, i;
+ int scan_start = 0;
+
+ union dnttentry *dn_bufp;
+ unsigned long valu;
+ char *p;
+ int texthigh = 0;
+ int have_name = 0;
+
+ /* Current partial symtab */
+ struct partial_symtab *pst;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ /* Just in case the stabs reader left turds lying around. */
+ free_pending_blocks ();
+ make_cleanup ((make_cleanup_func) really_free_pendings, 0);
+
+ pst = (struct partial_symtab *) 0;
+
+ /* We shouldn't use alloca, instead use malloc/free. Doing so avoids
+ a number of problems with cross compilation and creating useless holes
+ in the stack when we have to allocate new entries. FIXME. */
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ old_chain = make_cleanup ((make_cleanup_func) free_objfile, objfile);
+
+ last_source_file = 0;
+
+#ifdef QUICK_LOOK_UP
+ {
+ /* Begin code for new-style loading of quick look-up tables. */
+
+ /* elz: this checks whether the file has beeen processed by pxdb.
+ If not we would like to try to read the psymbols in
+ anyway, but it turns out to be not so easy. So this could
+ actually be commented out, but I leave it in, just in case
+ we decide to add support for non-pxdb-ed stuff in the future. */
+ PXDB_header pxdb_header;
+ int found_modules_in_program;
+
+ if (hpread_get_header (objfile, &pxdb_header))
+ {
+ /* Build a minimal table. No types, no global variables,
+ no include files.... */
+#ifdef DUMPING
+ if (dumping)
+ printf ("\nNew method for %s\n", objfile->name);
+#endif
+
+ /* elz: quick_traverse returns true if it found
+ some modules in the main source file, other
+ than those in end.c
+ In C and C++, all the files have MODULES entries
+ in the LNTT, and the quick table traverse is all
+ based on finding these MODULES entries. Without
+ those it cannot work.
+ It happens that F77 programs don't have MODULES
+ so the quick traverse gets confused. F90 programs
+ have modules, and the quick method still works.
+ So, if modules (other than those in end.c) are
+ not found we give up on the quick table stuff,
+ and fall back on the slower method */
+ found_modules_in_program = hpread_quick_traverse (objfile,
+ section_offsets,
+ GNTT (objfile),
+ VT (objfile),
+ &pxdb_header);
+
+ discard_cleanups (old_chain);
+
+ /* Set up to scan the global section of the LNTT.
+
+ This field is not always correct: if there are
+ no globals, it will point to the last record in
+ the regular LNTT, which is usually an END MODULE.
+
+ Since it might happen that there could be a file
+ with just one global record, there's no way to
+ tell other than by looking at the record, so that's
+ done below. */
+ if (found_modules_in_program)
+ scan_start = pxdb_header.globals;
+ }
+#ifdef DUMPING
+ else
+ {
+ if (dumping)
+ printf ("\nGoing on to old method for %s\n", objfile->name);
+ }
+#endif
+ }
+#endif /* QUICK_LOOK_UP */
+
+ /* Make two passes, one over the GNTT symbols, the other for the
+ LNTT symbols.
+
+ JB comment: above isn't true--they only make one pass, over
+ the LNTT. */
+ for (i = 0; i < 1; i++)
+ {
+ int within_function = 0;
+
+ if (i)
+ symcount = GNTT_SYMCOUNT (objfile);
+ else
+ symcount = LNTT_SYMCOUNT (objfile);
+
+
+ for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++)
+ {
+ QUIT;
+ if (i)
+ dn_bufp = hpread_get_gntt (hp_symnum, objfile);
+ else
+ dn_bufp = hpread_get_lntt (hp_symnum, objfile);
+
+ if (dn_bufp->dblock.extension)
+ continue;
+
+ /* Only handle things which are necessary for minimal symbols.
+ everything else is ignored. */
+ switch (dn_bufp->dblock.kind)
+ {
+ case DNTT_TYPE_SRCFILE:
+ {
+#ifdef QUICK_LOOK_UP
+ if (scan_start == hp_symnum
+ && symcount == hp_symnum + 1)
+ {
+ /* If there are NO globals in an executable,
+ PXDB's index to the globals will point to
+ the last record in the file, which
+ could be this record. (this happened for F77 libraries)
+ ignore it and be done! */
+ continue;
+ }
+#endif /* QUICK_LOOK_UP */
+
+ /* A source file of some kind. Note this may simply
+ be an included file. */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+ /* Check if this is the source file we are already working
+ with. */
+ if (pst && !strcmp (namestring, pst->filename))
+ continue;
+
+ /* Check if this is an include file, if so check if we have
+ already seen it. Add it to the include list */
+ p = strrchr (namestring, '.');
+ if (!strcmp (p, ".h"))
+ {
+ int j, found;
+
+ found = 0;
+ for (j = 0; j < includes_used; j++)
+ if (!strcmp (namestring, psymtab_include_list[j]))
+ {
+ found = 1;
+ break;
+ }
+ if (found)
+ continue;
+
+ /* Add it to the list of includes seen so far and
+ allocate more include space if necessary. */
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
+
+ if (pst)
+ {
+ if (!have_name)
+ {
+ pst->filename = (char *)
+ obstack_alloc (&pst->objfile->psymbol_obstack,
+ strlen (namestring) + 1);
+ strcpy (pst->filename, namestring);
+ have_name = 1;
+ continue;
+ }
+ continue;
+ }
+
+ /* This is a bonafide new source file.
+ End the current partial symtab and start a new one. */
+
+ if (pst && past_first_source_file)
+ {
+ hpread_end_psymtab (pst, psymtab_include_list,
+ includes_used,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ texthigh,
+ dependency_list, dependencies_used);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ else
+ past_first_source_file = 1;
+
+ valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ pst = hpread_start_psymtab (objfile, section_offsets,
+ namestring, valu,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ texthigh = valu;
+ have_name = 1;
+ continue;
+ }
+
+ case DNTT_TYPE_MODULE:
+ /* A source file. It's still unclear to me what the
+ real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
+ is supposed to be. */
+
+ /* First end the previous psymtab */
+ if (pst)
+ {
+ hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+ ((hp_symnum - 1)
+ * sizeof (struct dntt_type_block)),
+ texthigh,
+ dependency_list, dependencies_used);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ have_name = 0;
+ }
+
+ /* Now begin a new module and a new psymtab for it */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ if (!pst)
+ {
+ pst = hpread_start_psymtab (objfile, section_offsets,
+ namestring, valu,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ texthigh = valu;
+ have_name = 0;
+ }
+ continue;
+
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_ENTRY:
+ /* The beginning of a function. DNTT_TYPE_ENTRY may also denote
+ a secondary entry point. */
+ valu = dn_bufp->dfunc.hiaddr + ANOFFSET (section_offsets,
+ SECT_OFF_TEXT);
+ if (valu > texthigh)
+ texthigh = valu;
+ valu = dn_bufp->dfunc.lowaddr +
+ ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (dn_bufp->dfunc.global)
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols, valu,
+ 0, language_unknown, objfile);
+ else
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols, valu,
+ 0, language_unknown, objfile);
+ within_function = 1;
+ continue;
+
+ case DNTT_TYPE_DOC_FUNCTION:
+ valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (section_offsets,
+ SECT_OFF_TEXT);
+ if (valu > texthigh)
+ texthigh = valu;
+ valu = dn_bufp->ddocfunc.lowaddr +
+ ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (dn_bufp->ddocfunc.global)
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols, valu,
+ 0, language_unknown, objfile);
+ else
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols, valu,
+ 0, language_unknown, objfile);
+ within_function = 1;
+ continue;
+
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_END:
+ /* We don't check MODULE end here, because there can be
+ symbols beyond the module end which properly belong to the
+ current psymtab -- so we wait till the next MODULE start */
+
+
+#ifdef QUICK_LOOK_UP
+ if (scan_start == hp_symnum
+ && symcount == hp_symnum + 1)
+ {
+ /* If there are NO globals in an executable,
+ PXDB's index to the globals will point to
+ the last record in the file, which is
+ probably an END MODULE, i.e. this record.
+ ignore it and be done! */
+ continue;
+ }
+#endif /* QUICK_LOOK_UP */
+
+ /* Scope block begin/end. We only care about function
+ and file blocks right now. */
+
+ if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) ||
+ (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION))
+ within_function = 0;
+ continue;
+
+ case DNTT_TYPE_SVAR:
+ case DNTT_TYPE_DVAR:
+ case DNTT_TYPE_TYPEDEF:
+ case DNTT_TYPE_TAGDEF:
+ {
+ /* Variables, typedefs an the like. */
+ enum address_class storage;
+ namespace_enum namespace;
+
+ /* Don't add locals to the partial symbol table. */
+ if (within_function
+ && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
+ || dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
+ continue;
+
+ /* TAGDEFs go into the structure namespace. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
+ namespace = STRUCT_NAMESPACE;
+ else
+ namespace = VAR_NAMESPACE;
+
+ /* What kind of "storage" does this use? */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
+ storage = LOC_STATIC;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
+ && dn_bufp->ddvar.regvar)
+ storage = LOC_REGISTER;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
+ storage = LOC_LOCAL;
+ else
+ storage = LOC_UNDEF;
+
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (!pst)
+ {
+ pst = hpread_start_psymtab (objfile, section_offsets,
+ "globals", 0,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+
+ /* Compute address of the data symbol */
+ valu = dn_bufp->dsvar.location;
+ /* Relocate in case it's in a shared library */
+ if (storage == LOC_STATIC)
+ valu += ANOFFSET (section_offsets, SECT_OFF_DATA);
+
+ /* Luckily, dvar, svar, typedef, and tagdef all
+ have their "global" bit in the same place, so it works
+ (though it's bad programming practice) to reference
+ "dsvar.global" even though we may be looking at
+ any of the above four types. */
+ if (dn_bufp->dsvar.global)
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ namespace, storage,
+ &objfile->global_psymbols,
+ valu,
+ 0, language_unknown, objfile);
+ }
+ else
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ namespace, storage,
+ &objfile->static_psymbols,
+ valu,
+ 0, language_unknown, objfile);
+ }
+
+ /* For TAGDEF's, the above code added the tagname to the
+ struct namespace. This will cause tag "t" to be found
+ on a reference of the form "(struct t) x". But for
+ C++ classes, "t" will also be a typename, which we
+ want to find on a reference of the form "ptype t".
+ Therefore, we also add "t" to the var namespace.
+ Do the same for enum's due to the way aCC generates
+ debug info for these (see more extended comment
+ in hp-symtab-read.c).
+ We do the same for templates, so that "ptype t"
+ where "t" is a template also works. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF &&
+ dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ {
+ int global = dn_bufp->dtag.global;
+ /* Look ahead to see if it's a C++ class */
+ dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+ if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+ dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+ dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ if (global)
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, storage,
+ &objfile->global_psymbols,
+ dn_bufp->dsvar.location,
+ 0, language_unknown, objfile);
+ }
+ else
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, storage,
+ &objfile->static_psymbols,
+ dn_bufp->dsvar.location,
+ 0, language_unknown, objfile);
+ }
+ }
+ }
+ }
+ continue;
+
+ case DNTT_TYPE_MEMENUM:
+ case DNTT_TYPE_CONST:
+ /* Constants and members of enumerated types. */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (!pst)
+ {
+ pst = hpread_start_psymtab (objfile, section_offsets,
+ "globals", 0,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+ if (dn_bufp->dconst.global)
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->global_psymbols, 0,
+ 0, language_unknown, objfile);
+ else
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, language_unknown, objfile);
+ continue;
+ default:
+ continue;
+ }
+ }
+ }
+
+ /* End any pending partial symbol table. */
+ if (pst)
+ {
+ hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+ hp_symnum * sizeof (struct dntt_type_block),
+ 0, dependency_list, dependencies_used);
+ }
+
+ discard_cleanups (old_chain);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+void
+hpread_symfile_finish (objfile)
+ struct objfile *objfile;
+{
+ if (objfile->sym_private != NULL)
+ {
+ mfree (objfile->md, objfile->sym_private);
+ }
+}
+
+
+/* The remaining functions are all for internal use only. */
+
+/* Various small functions to get entries in the debug symbol sections. */
+
+union dnttentry *
+hpread_get_lntt (index, objfile)
+ int index;
+ struct objfile *objfile;
+{
+ return (union dnttentry *)
+ &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+static union dnttentry *
+hpread_get_gntt (index, objfile)
+ int index;
+ struct objfile *objfile;
+{
+ return (union dnttentry *)
+ &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+union sltentry *
+hpread_get_slt (index, objfile)
+ int index;
+ struct objfile *objfile;
+{
+ return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
+}
+
+/* Get the low address associated with some symbol (typically the start
+ of a particular source file or module). Since that information is not
+ stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we must infer it from
+ the existance of DNTT_TYPE_FUNCTION symbols. */
+
+static unsigned long
+hpread_get_textlow (global, index, objfile, symcount)
+ int global;
+ int index;
+ struct objfile *objfile;
+ int symcount;
+{
+ union dnttentry *dn_bufp;
+ struct minimal_symbol *msymbol;
+
+ /* Look for a DNTT_TYPE_FUNCTION symbol. */
+ if (index < symcount) /* symcount is the number of symbols in */
+ { /* the dbinfo, LNTT table */
+ do
+ {
+ if (global)
+ dn_bufp = hpread_get_gntt (index++, objfile);
+ else
+ dn_bufp = hpread_get_lntt (index++, objfile);
+ }
+ while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
+ && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION
+ && dn_bufp->dblock.kind != DNTT_TYPE_END
+ && index < symcount);
+ }
+
+ /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION. This
+ might happen when a sourcefile has no functions. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_END)
+ return 0;
+
+ /* Avoid going past the end of the LNTT file */
+ if (index == symcount)
+ return 0;
+
+ /* The minimal symbols are typically more accurate for some reason. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION)
+ msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
+ objfile);
+ else /* must be a DNTT_TYPE_DOC_FUNCTION */
+ msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL,
+ objfile);
+
+ if (msymbol)
+ return SYMBOL_VALUE_ADDRESS (msymbol);
+ else
+ return dn_bufp->dfunc.lowaddr;
+}
+
+/* Allocate and partially fill a partial symtab. It will be
+ completely filled at the end of the symbol list.
+
+ SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+ is the address relative to which its symbols are (incremental) or 0
+ (normal). */
+
+static struct partial_symtab *
+hpread_start_psymtab (objfile, section_offsets,
+ filename, textlow, ldsymoff, global_syms, static_syms)
+ struct objfile *objfile;
+ struct section_offsets *section_offsets;
+ char *filename;
+ CORE_ADDR textlow;
+ int ldsymoff;
+ struct partial_symbol **global_syms;
+ struct partial_symbol **static_syms;
+{
+ int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ extern void hpread_psymtab_to_symtab ();
+ struct partial_symtab *result =
+ start_psymtab_common (objfile, section_offsets,
+ filename, textlow, global_syms, static_syms);
+
+ result->textlow += offset;
+ result->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+ LDSYMOFF (result) = ldsymoff;
+ result->read_symtab = hpread_psymtab_to_symtab;
+
+ return result;
+}
+
+
+/* Close off the current usage of PST.
+ Returns PST or NULL if the partial symtab was empty and thrown away.
+
+ capping_symbol_offset --Byte index in LNTT or GNTT of the
+ last symbol processed during the build
+ of the previous pst.
+
+ FIXME: List variables and peculiarities of same. */
+
+static struct partial_symtab *
+hpread_end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
+ capping_text, dependency_list, number_dependencies)
+ struct partial_symtab *pst;
+ char **include_list;
+ int num_includes;
+ int capping_symbol_offset;
+ CORE_ADDR capping_text;
+ struct partial_symtab **dependency_list;
+ int number_dependencies;
+{
+ int i;
+ struct objfile *objfile = pst->objfile;
+ int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT);
+
+#ifdef DUMPING
+ /* Turn on to see what kind of a psymtab we've built. */
+ static int dumping = 0;
+#endif
+
+ if (capping_symbol_offset != -1)
+ LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
+ else
+ LDSYMLEN (pst) = 0;
+ pst->texthigh = capping_text + offset;
+
+ pst->n_global_syms =
+ objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms =
+ objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n",
+ pst->filename,
+ LDSYMOFF (pst),
+ LDSYMOFF (pst) / sizeof (struct dntt_type_block),
+ LDSYMLEN (pst),
+ LDSYMLEN (pst) / sizeof (struct dntt_type_block),
+ pst->n_global_syms, pst->n_static_syms);
+ }
+#endif
+
+ pst->number_of_dependencies = number_dependencies;
+ if (number_dependencies)
+ {
+ pst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ number_dependencies * sizeof (struct partial_symtab *));
+ memcpy (pst->dependencies, dependency_list,
+ number_dependencies * sizeof (struct partial_symtab *));
+ }
+ else
+ pst->dependencies = 0;
+
+ for (i = 0; i < num_includes; i++)
+ {
+ struct partial_symtab *subpst =
+ allocate_psymtab (include_list[i], objfile);
+
+ subpst->section_offsets = pst->section_offsets;
+ subpst->read_symtab_private =
+ (char *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc));
+ LDSYMOFF (subpst) =
+ LDSYMLEN (subpst) =
+ subpst->textlow =
+ subpst->texthigh = 0;
+
+ /* We could save slight bits of space by only making one of these,
+ shared by the entire set of include files. FIXME-someday. */
+ subpst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct partial_symtab *));
+ subpst->dependencies[0] = pst;
+ subpst->number_of_dependencies = 1;
+
+ subpst->globals_offset =
+ subpst->n_global_syms =
+ subpst->statics_offset =
+ subpst->n_static_syms = 0;
+
+ subpst->readin = 0;
+ subpst->symtab = 0;
+ subpst->read_symtab = pst->read_symtab;
+ }
+
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this name, remove it.
+ (If there is a symtab, more drastic things also happen.)
+ This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ if (num_includes == 0
+ && number_dependencies == 0
+ && pst->n_global_syms == 0
+ && pst->n_static_syms == 0)
+ {
+ /* Throw away this psymtab, it's empty. We can't deallocate it, since
+ it is on the obstack, but we can forget to chain it on the list.
+ Empty psymtabs happen as a result of header files which don't have
+ any symbols in them. There can be a lot of them. But this check
+ is wrong, in that a psymtab with N_SLINE entries but nothing else
+ is not empty, but we don't realize that. Fixing that without slowing
+ things down might be tricky.
+ It's also wrong if we're using the quick look-up tables, as
+ we can get empty psymtabs from modules with no routines in
+ them. */
+
+ discard_psymtab (pst);
+
+ /* Indicate that psymtab was thrown away. */
+ pst = (struct partial_symtab *) NULL;
+
+ }
+ return pst;
+}
+
+
+/* End of hp-psymtab-read.c */
+
+/* Set indentation to 4 spaces for Emacs; this file is
+ mostly non-GNU-ish in its style :-( */
+#if 0
+***Local Variables:
+***c - basic - offset:4
+*** End:
+#endif
+
+
diff --git a/contrib/gdb/gdb/hp-symtab-read.c b/contrib/gdb/gdb/hp-symtab-read.c
new file mode 100644
index 0000000..90d4a10
--- /dev/null
+++ b/contrib/gdb/gdb/hp-symtab-read.c
@@ -0,0 +1,3988 @@
+/* Read hp debug symbols and convert to internal format, for GDB.
+ Copyright 1993, 1996 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support. */
+
+/* Common include for hp-symtab-read.c and hp-psymtab-read.c.
+ * Note this has nested includes for a bunch of stuff.
+ */
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "hpread.h"
+#include "demangle.h"
+#include "complaints.h"
+
+
+
+
+static struct complaint hpread_unhandled_end_common_complaint =
+{
+ "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n", 0, 0
+};
+
+static struct complaint hpread_unhandled_type_complaint =
+{
+ "hpread_type_translate: unhandled type code.", 0, 0
+};
+
+static struct complaint hpread_struct_complaint =
+{
+ "hpread_read_struct_type: expected SVAR type...", 0, 0
+};
+
+static struct complaint hpread_array_complaint =
+{
+ "error in hpread_array_type.", 0, 0
+};
+
+static struct complaint hpread_type_lookup_complaint =
+{
+ "error in hpread_type_lookup().", 0, 0
+};
+
+
+static struct complaint hpread_unexpected_end_complaint =
+{
+ "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.", 0, 0
+};
+
+static struct complaint hpread_tagdef_complaint =
+{
+ "error processing class tagdef", 0, 0
+};
+
+static struct complaint hpread_unhandled_common_complaint =
+{
+ "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.", 0, 0
+};
+
+static struct complaint hpread_unhandled_blockdata_complaint =
+{
+ "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.", 0, 0
+};
+
+
+/* Forward procedure declarations */
+
+static unsigned long hpread_get_scope_start
+ PARAMS ((sltpointer, struct objfile *));
+
+static unsigned long hpread_get_line
+ PARAMS ((sltpointer, struct objfile *));
+
+static CORE_ADDR hpread_get_location
+ PARAMS ((sltpointer, struct objfile *));
+
+static void hpread_psymtab_to_symtab_1
+ PARAMS ((struct partial_symtab *));
+
+void hpread_psymtab_to_symtab
+ PARAMS ((struct partial_symtab *));
+
+static struct symtab *hpread_expand_symtab
+ PARAMS ((struct objfile *, int, int, CORE_ADDR, int,
+ struct section_offsets *, char *));
+
+static int hpread_type_translate
+ PARAMS ((dnttpointer));
+
+static struct type **hpread_lookup_type
+ PARAMS ((dnttpointer, struct objfile *));
+
+static struct type *hpread_alloc_type
+ PARAMS ((dnttpointer, struct objfile *));
+
+static struct type *hpread_read_enum_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *));
+
+static struct type *hpread_read_function_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *, int));
+
+static struct type *hpread_read_doc_function_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *, int));
+
+static struct type *hpread_read_struct_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *));
+
+static struct type *hpread_get_nth_template_arg
+ PARAMS ((struct objfile *, int));
+
+static struct type * hpread_read_templ_arg_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *, char *));
+
+static struct type *hpread_read_set_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *));
+
+static struct type * hpread_read_array_type
+ PARAMS ((dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile));
+
+static struct type *hpread_read_subrange_type
+ PARAMS ((dnttpointer, union dnttentry *, struct objfile *));
+
+static struct type * hpread_type_lookup
+ PARAMS ((dnttpointer, struct objfile *));
+
+static sltpointer hpread_record_lines
+ PARAMS ((struct subfile *, sltpointer, sltpointer,
+ struct objfile *, CORE_ADDR));
+
+static void hpread_process_one_debug_symbol
+ PARAMS ((union dnttentry *, char *, struct section_offsets *,
+ struct objfile *, CORE_ADDR, int, char *, int, int * ));
+
+static int hpread_get_scope_depth
+ PARAMS ((union dnttentry *, struct objfile *, int));
+
+static void fix_static_member_physnames
+ PARAMS ((struct type *, char *, struct objfile *));
+
+static void fixup_class_method_type
+ PARAMS ((struct type *, struct type *, struct objfile *));
+
+static void hpread_adjust_bitoffsets PARAMS ((struct type *, int));
+
+static dnttpointer hpread_get_next_skip_over_anon_unions
+ PARAMS ((int, dnttpointer, union dnttentry **, struct objfile *));
+
+/* Global to indicate presence of HP-compiled objects,
+ in particular, SOM executable file with SOM debug info
+ Defined in symtab.c, used in hppa-tdep.c. */
+extern int hp_som_som_object_present;
+
+/* Static used to indicate a class type that requires a
+ fix-up of one of its method types */
+static struct type * fixup_class = NULL;
+
+/* Static used to indicate the method type that is to be
+ used to fix-up the type for fixup_class */
+static struct type * fixup_method = NULL;
+
+
+
+/* Get the nesting depth for the source line identified by INDEX. */
+
+static unsigned long
+hpread_get_scope_start (index, objfile)
+ sltpointer index;
+ struct objfile *objfile;
+{
+ union sltentry *sl_bufp;
+
+ sl_bufp = hpread_get_slt (index, objfile);
+ return sl_bufp->sspec.backptr.dnttp.index;
+}
+
+/* Get the source line number the the line identified by INDEX. */
+
+static unsigned long
+hpread_get_line (index, objfile)
+ sltpointer index;
+ struct objfile *objfile;
+{
+ union sltentry *sl_bufp;
+
+ sl_bufp = hpread_get_slt (index, objfile);
+ return sl_bufp->snorm.line;
+}
+
+/* Find the code address associated with a given sltpointer */
+
+static CORE_ADDR
+hpread_get_location (index, objfile)
+ sltpointer index;
+ struct objfile *objfile;
+{
+ union sltentry *sl_bufp;
+ int i;
+
+ /* code location of special sltentrys is determined from context */
+ sl_bufp = hpread_get_slt (index, objfile);
+
+ if (sl_bufp->snorm.sltdesc == SLT_END)
+ {
+ /* find previous normal sltentry and get address */
+ for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+ (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+ (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+ sl_bufp = hpread_get_slt (index - i, objfile);
+ if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+ return sl_bufp->snormoff.address;
+ else
+ return sl_bufp->snorm.address;
+ }
+
+ /* find next normal sltentry and get address */
+ for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+ (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+ (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+ sl_bufp = hpread_get_slt (index + i, objfile);
+ if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+ return sl_bufp->snormoff.address;
+ else
+ return sl_bufp->snorm.address;
+}
+
+
+/* Return 1 if an HP debug symbol of type KIND has a name associated with
+ * it, else return 0. (This function is not currently used, but I'll
+ * leave it here in case it proves useful later on. - RT).
+ */
+
+int
+hpread_has_name (kind)
+ enum dntt_entry_type kind;
+{
+ switch (kind)
+ {
+ case DNTT_TYPE_SRCFILE:
+ case DNTT_TYPE_MODULE:
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_DOC_FUNCTION:
+ case DNTT_TYPE_ENTRY:
+ case DNTT_TYPE_IMPORT:
+ case DNTT_TYPE_LABEL:
+ case DNTT_TYPE_FPARAM:
+ case DNTT_TYPE_SVAR:
+ case DNTT_TYPE_DVAR:
+ case DNTT_TYPE_CONST:
+ case DNTT_TYPE_TYPEDEF:
+ case DNTT_TYPE_TAGDEF:
+ case DNTT_TYPE_MEMENUM:
+ case DNTT_TYPE_FIELD:
+ case DNTT_TYPE_SA:
+ case DNTT_TYPE_BLOCKDATA:
+ case DNTT_TYPE_MEMFUNC:
+ case DNTT_TYPE_DOC_MEMFUNC:
+ return 1;
+
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_END:
+ case DNTT_TYPE_POINTER:
+ case DNTT_TYPE_ENUM:
+ case DNTT_TYPE_SET:
+ case DNTT_TYPE_ARRAY:
+ case DNTT_TYPE_STRUCT:
+ case DNTT_TYPE_UNION:
+ case DNTT_TYPE_VARIANT:
+ case DNTT_TYPE_FILE:
+ case DNTT_TYPE_FUNCTYPE:
+ case DNTT_TYPE_SUBRANGE:
+ case DNTT_TYPE_WITH:
+ case DNTT_TYPE_COMMON:
+ case DNTT_TYPE_COBSTRUCT:
+ case DNTT_TYPE_XREF:
+ case DNTT_TYPE_MACRO:
+ case DNTT_TYPE_CLASS_SCOPE:
+ case DNTT_TYPE_REFERENCE:
+ case DNTT_TYPE_PTRMEM:
+ case DNTT_TYPE_PTRMEMFUNC:
+ case DNTT_TYPE_CLASS:
+ case DNTT_TYPE_GENFIELD:
+ case DNTT_TYPE_VFUNC:
+ case DNTT_TYPE_MEMACCESS:
+ case DNTT_TYPE_INHERITANCE:
+ case DNTT_TYPE_FRIEND_CLASS:
+ case DNTT_TYPE_FRIEND_FUNC:
+ case DNTT_TYPE_MODIFIER:
+ case DNTT_TYPE_OBJECT_ID:
+ case DNTT_TYPE_TEMPLATE:
+ case DNTT_TYPE_TEMPLATE_ARG:
+ case DNTT_TYPE_FUNC_TEMPLATE:
+ case DNTT_TYPE_LINK:
+ /* DNTT_TYPE_DYN_ARRAY_DESC ? */
+ /* DNTT_TYPE_DESC_SUBRANGE ? */
+ /* DNTT_TYPE_BEGIN_EXT ? */
+ /* DNTT_TYPE_INLN ? */
+ /* DNTT_TYPE_INLN_LIST ? */
+ /* DNTT_TYPE_ALIAS ? */
+ default:
+ return 0;
+ }
+}
+
+/* Do the dirty work of reading in the full symbol from a partial symbol
+ table. */
+
+static void
+hpread_psymtab_to_symtab_1 (pst)
+ struct partial_symtab *pst;
+{
+ struct cleanup *old_chain;
+ int i;
+
+ /* Get out quick if passed junk. */
+ if (!pst)
+ return;
+
+ /* Complain if we've already read in this symbol table. */
+ if (pst->readin)
+ {
+ fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* Read in all partial symtabs on which this one is dependent */
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...", pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ gdb_flush (gdb_stdout);
+ }
+ hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+
+ /* If it's real... */
+ if (LDSYMLEN (pst))
+ {
+ /* Init stuff necessary for reading in symbols */
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
+
+ pst->symtab =
+ hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
+ pst->textlow, pst->texthigh - pst->textlow,
+ pst->section_offsets, pst->filename);
+ sort_symtab_syms (pst->symtab);
+
+ do_cleanups (old_chain);
+ }
+
+ pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+ Be verbose about it if the user wants that. */
+
+void
+hpread_psymtab_to_symtab (pst)
+ struct partial_symtab *pst;
+{
+ /* Get out quick if given junk. */
+ if (!pst)
+ return;
+
+ /* Sanity check. */
+ if (pst->readin)
+ {
+ fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* elz: setting the flag to indicate that the code of the target
+ was compiled using an HP compiler (aCC, cc)
+ the processing_acc_compilation variable is declared in the
+ file buildsym.h, the HP_COMPILED_TARGET is defined to be equal
+ to 3 in the file tm_hppa.h*/
+
+ processing_gcc_compilation = 0;
+
+ if (LDSYMLEN (pst) || pst->number_of_dependencies)
+ {
+ /* Print the message now, before reading the string table,
+ to avoid disconcerting pauses. */
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ hpread_psymtab_to_symtab_1 (pst);
+
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals (pst->objfile);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+}
+
+/* Read in a defined section of a specific object file's symbols.
+
+ DESC is the file descriptor for the file, positioned at the
+ beginning of the symtab
+ SYM_OFFSET is the offset within the file of
+ the beginning of the symbols we want to read
+ SYM_SIZE is the size of the symbol info to read in.
+ TEXT_OFFSET is the beginning of the text segment we are reading symbols for
+ TEXT_SIZE is the size of the text segment read in.
+ SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
+
+static struct symtab *
+hpread_expand_symtab (objfile, sym_offset, sym_size, text_offset, text_size,
+ section_offsets, filename)
+ struct objfile *objfile;
+ int sym_offset;
+ int sym_size;
+ CORE_ADDR text_offset;
+ int text_size;
+ struct section_offsets *section_offsets;
+ char *filename;
+{
+ char *namestring;
+ union dnttentry *dn_bufp;
+ unsigned max_symnum;
+ int at_module_boundary = 0;
+ /* 1 => at end, -1 => at beginning */
+
+ int sym_index = sym_offset / sizeof (struct dntt_type_block);
+
+ current_objfile = objfile;
+ subfile_stack = 0;
+
+ last_source_file = 0;
+
+ /* Demangling style -- if EDG style already set, don't change it,
+ as HP style causes some problems with the KAI EDG compiler */
+ if (current_demangling_style != edg_demangling) {
+ /* Otherwise, ensure that we are using HP style demangling */
+ set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+ }
+
+ dn_bufp = hpread_get_lntt (sym_index, objfile);
+ if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
+ (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
+ {
+ start_symtab ("globals", NULL, 0);
+ record_debugformat ("HP");
+ }
+
+ /* The psymtab builder (hp-psymtab-read.c) is the one that
+ * determined the "sym_size" argument (i.e. how many DNTT symbols
+ * are in this symtab), which we use to compute "max_symnum"
+ * (point in DNTT to which we read).
+ *
+ * Perhaps this should be changed so that
+ * process_one_debug_symbol() "knows" when
+ * to stop reading (based on reading from the MODULE to the matching
+ * END), and take out this reliance on a #-syms being passed in...
+ * (I'm worried about the reliability of this number). But I'll
+ * leave it as-is, for now. - RT
+ *
+ * The change above has been made. I've left the "for" loop control
+ * in to prepare for backing this out again. -JB
+ */
+ max_symnum = sym_size / sizeof (struct dntt_type_block);
+ /* No reason to multiply on pst side and divide on sym side... FIXME */
+
+ /* Read in and process each debug symbol within the specified range.
+ */
+ for (symnum = 0;
+ symnum < max_symnum;
+ symnum++)
+ {
+ QUIT; /* Allow this to be interruptable */
+ dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
+
+ if (dn_bufp->dblock.extension)
+ continue;
+
+ /* Yow! We call SET_NAMESTRING on things without names! */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+ hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
+ objfile, text_offset, text_size,
+ filename, symnum + sym_index,
+ &at_module_boundary
+ );
+
+ /* OLD COMMENTS: This routine is only called for psts. All psts
+ * correspond to MODULES. If we ever do lazy-reading of globals
+ * from the LNTT, then there will be a pst which ends when the
+ * LNTT ends, and not at an END MODULE entry. Then we'll have
+ * to re-visit this break.
+
+ if( at_end_of_module )
+ break;
+
+ */
+
+ /* We no longer break out of the loop when we reach the end of a
+ module. The reason is that with CTTI, the compiler can generate
+ function symbols (for template function instantiations) which are not
+ in any module; typically they show up beyond a module's end, and
+ before the next module's start. We include them in the current
+ module. However, we still don't trust the MAX_SYMNUM value from
+ the psymtab, so we break out if we enter a new module. */
+
+ if (at_module_boundary == -1)
+ break;
+ }
+
+ current_objfile = NULL;
+ hp_som_som_object_present = 1; /* Indicate we've processed an HP SOM SOM file */
+
+ return end_symtab (text_offset + text_size, objfile, 0);
+}
+
+
+
+
+/* Convert basic types from HP debug format into GDB internal format. */
+
+static int
+hpread_type_translate (typep)
+ dnttpointer typep;
+{
+ if (!typep.dntti.immediate) {
+ error ("error in hpread_type_translate\n.");
+ return;
+ }
+
+ switch (typep.dntti.type)
+ {
+ case HP_TYPE_BOOLEAN:
+ case HP_TYPE_BOOLEAN_S300_COMPAT:
+ case HP_TYPE_BOOLEAN_VAX_COMPAT:
+ return FT_BOOLEAN;
+ case HP_TYPE_CHAR: /* C signed char, C++ plain char */
+
+ case HP_TYPE_WIDE_CHAR:
+ return FT_CHAR;
+ case HP_TYPE_INT:
+ if (typep.dntti.bitlength <= 8)
+ return FT_SIGNED_CHAR; /* C++ signed char */
+ if (typep.dntti.bitlength <= 16)
+ return FT_SHORT;
+ if (typep.dntti.bitlength <= 32)
+ return FT_INTEGER;
+ return FT_LONG_LONG;
+ case HP_TYPE_LONG:
+ if (typep.dntti.bitlength <= 8)
+ return FT_SIGNED_CHAR; /* C++ signed char. */
+ return FT_LONG;
+ case HP_TYPE_UNSIGNED_LONG:
+ if (typep.dntti.bitlength <= 8)
+ return FT_UNSIGNED_CHAR; /* C/C++ unsigned char */
+ if (typep.dntti.bitlength <= 16)
+ return FT_UNSIGNED_SHORT;
+ if (typep.dntti.bitlength <= 32)
+ return FT_UNSIGNED_LONG;
+ return FT_UNSIGNED_LONG_LONG;
+ case HP_TYPE_UNSIGNED_INT:
+ if (typep.dntti.bitlength <= 8)
+ return FT_UNSIGNED_CHAR;
+ if (typep.dntti.bitlength <= 16)
+ return FT_UNSIGNED_SHORT;
+ if (typep.dntti.bitlength <= 32)
+ return FT_UNSIGNED_INTEGER;
+ return FT_UNSIGNED_LONG_LONG;
+ case HP_TYPE_REAL:
+ case HP_TYPE_REAL_3000:
+ case HP_TYPE_DOUBLE:
+ if (typep.dntti.bitlength == 64)
+ return FT_DBL_PREC_FLOAT;
+ if (typep.dntti.bitlength == 128)
+ return FT_EXT_PREC_FLOAT;
+ return FT_FLOAT;
+ case HP_TYPE_COMPLEX:
+ case HP_TYPE_COMPLEXS3000:
+ if (typep.dntti.bitlength == 128)
+ return FT_DBL_PREC_COMPLEX;
+ if (typep.dntti.bitlength == 192)
+ return FT_EXT_PREC_COMPLEX;
+ return FT_COMPLEX;
+ case HP_TYPE_VOID:
+ return FT_VOID;
+ case HP_TYPE_STRING200:
+ case HP_TYPE_LONGSTRING200:
+ case HP_TYPE_FTN_STRING_SPEC:
+ case HP_TYPE_MOD_STRING_SPEC:
+ case HP_TYPE_MOD_STRING_3000:
+ case HP_TYPE_FTN_STRING_S300_COMPAT:
+ case HP_TYPE_FTN_STRING_VAX_COMPAT:
+ return FT_STRING;
+ case HP_TYPE_TEMPLATE_ARG:
+ return FT_TEMPLATE_ARG;
+ case HP_TYPE_TEXT:
+ case HP_TYPE_FLABEL:
+ case HP_TYPE_PACKED_DECIMAL:
+ case HP_TYPE_ANYPOINTER:
+ case HP_TYPE_GLOBAL_ANYPOINTER:
+ case HP_TYPE_LOCAL_ANYPOINTER:
+ default:
+ warning ("hpread_type_translate: unhandled type code.\n");
+ return FT_VOID;
+ }
+}
+
+/* Given a position in the DNTT, return a pointer to the
+ * already-built "struct type" (if any), for the type defined
+ * at that position.
+ */
+
+static struct type **
+hpread_lookup_type (hp_type, objfile)
+ dnttpointer hp_type;
+ struct objfile *objfile;
+{
+ unsigned old_len;
+ int index = hp_type.dnttp.index;
+ int size_changed = 0;
+
+ /* The immediate flag indicates this doesn't actually point to
+ * a type DNTT.
+ */
+ if (hp_type.dntti.immediate)
+ return NULL;
+
+ /* For each objfile, we maintain a "type vector".
+ * This an array of "struct type *"'s with one pointer per DNTT index.
+ * Given a DNTT index, we look in this array to see if we have
+ * already processed this DNTT and if it is a type definition.
+ * If so, then we can locate a pointer to the already-built
+ * "struct type", and not build it again.
+ *
+ * The need for this arises because our DNTT-walking code wanders
+ * around. In particular, it will encounter the same type multiple
+ * times (once for each object of that type). We don't want to
+ * built multiple "struct type"'s for the same thing.
+ *
+ * Having said this, I should point out that this type-vector is
+ * an expensive way to keep track of this. If most DNTT entries are
+ * 3 words, the type-vector will be 1/3 the size of the DNTT itself.
+ * Alternative solutions:
+ * - Keep a compressed or hashed table. Less memory, but more expensive
+ * to search and update.
+ * - (Suggested by JB): Overwrite the DNTT entry itself
+ * with the info. Create a new type code "ALREADY_BUILT", and modify
+ * the DNTT to have that type code and point to the already-built entry.
+ * -RT
+ */
+
+ if (index < LNTT_SYMCOUNT (objfile))
+ {
+ if (index >= TYPE_VECTOR_LENGTH (objfile))
+ {
+ old_len = TYPE_VECTOR_LENGTH (objfile);
+
+ /* See if we need to allocate a type-vector. */
+ if (old_len == 0)
+ {
+ TYPE_VECTOR_LENGTH(objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile);
+ TYPE_VECTOR (objfile) = (struct type **)
+ xmmalloc (objfile->md, TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
+ memset (&TYPE_VECTOR (objfile)[old_len], 0,
+ (TYPE_VECTOR_LENGTH (objfile) - old_len) *
+ sizeof (struct type *));
+ }
+
+ /* See if we need to resize type-vector. With my change to
+ * initially allocate a correct-size type-vector, this code
+ * should no longer trigger.
+ */
+ while (index >= TYPE_VECTOR_LENGTH (objfile)) {
+ TYPE_VECTOR_LENGTH (objfile) *= 2;
+ size_changed = 1;
+ }
+ if (size_changed) {
+ TYPE_VECTOR (objfile) = (struct type **)
+ xmrealloc (objfile -> md,
+ (char *) TYPE_VECTOR (objfile),
+ (TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
+
+ memset (&TYPE_VECTOR (objfile)[old_len], 0,
+ (TYPE_VECTOR_LENGTH (objfile) - old_len) *
+ sizeof (struct type *));
+ }
+
+ }
+ return &TYPE_VECTOR (objfile)[index];
+ }
+ else
+ return NULL;
+}
+
+/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
+ Note we'll just return the address of a GDB internal type if we already
+ have it lying around. */
+
+static struct type *
+hpread_alloc_type (hp_type, objfile)
+ dnttpointer hp_type;
+ struct objfile *objfile;
+{
+ struct type **type_addr;
+
+ type_addr = hpread_lookup_type (hp_type, objfile);
+ if (*type_addr == 0) {
+ *type_addr = alloc_type (objfile);
+
+ /* A hack - if we really are a C++ class symbol, then this default
+ * will get overriden later on.
+ */
+ TYPE_CPLUS_SPECIFIC (*type_addr)
+ = (struct cplus_struct_type *) &cplus_struct_default;
+ }
+
+ return *type_addr;
+}
+
+/* Read a native enumerated type and return it in GDB internal form. */
+
+static struct type *
+hpread_read_enum_type (hp_type, dn_bufp, objfile)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+{
+ struct type *type;
+ struct pending **symlist, *osyms, *syms;
+ struct pending *local_list = NULL;
+ int o_nsyms, nsyms = 0;
+ dnttpointer mem;
+ union dnttentry *memp;
+ char *name;
+ long n;
+ struct symbol *sym;
+
+ /* Allocate a GDB type. If we've already read in this enum type,
+ * it'll return the already built GDB type, so stop here.
+ * (Note: I added this check, to conform with what's done for
+ * struct, union, class.
+ * I assume this is OK. - RT)
+ */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+ return type;
+
+ /* HP C supports "sized enums", where a specifier such as "short" or
+ "char" can be used to get enums of different sizes. So don't assume
+ an enum is always 4 bytes long. pai/1997-08-21 */
+ TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8;
+
+ symlist = &file_symbols;
+ osyms = *symlist;
+ o_nsyms = osyms ? osyms->nsyms : 0;
+
+ /* Get a name for each member and add it to our list of members.
+ * The list of "mem" SOM records we are walking should all be
+ * SOM type DNTT_TYPE_MEMENUM (not checked).
+ */
+ mem = dn_bufp->denum.firstmem;
+ while (mem.word && mem.word != DNTTNIL)
+ {
+ memp = hpread_get_lntt (mem.dnttp.index, objfile);
+
+ name = VT (objfile) + memp->dmember.name;
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE (sym) = memp->dmember.value;
+ add_symbol_to_list (sym, symlist);
+ nsyms++;
+ mem = memp->dmember.nextmem;
+ }
+
+ /* Now that we know more about the enum, fill in more info. */
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the members and put them into the type.
+ The symbols can be found in the symlist that we put them on
+ to cause them to be defined. osyms contains the old value
+ of that symlist; everything up to there was defined by us.
+
+ Note that we preserve the order of the enum constants, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+ for (syms = *symlist, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+ if (syms == osyms)
+ j = o_nsyms;
+ for (; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ SYMBOL_TYPE (xsym) = type;
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ if (syms == osyms)
+ break;
+ }
+
+ return type;
+}
+
+/* Read and internalize a native function debug symbol. */
+
+static struct type *
+hpread_read_function_type (hp_type, dn_bufp, objfile, newblock)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+ int newblock;
+{
+ struct type *type, *type1;
+ struct pending *syms;
+ struct pending *local_list = NULL;
+ int nsyms = 0;
+ dnttpointer param;
+ union dnttentry *paramp;
+ char *name;
+ long n;
+ struct symbol *sym;
+ int record_args = 1;
+
+ /* See if we've already read in this type. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ record_args = 0; /* already read in, don't modify type */
+ }
+ else
+ {
+ /* Nope, so read it in and store it away. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
+ objfile));
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
+ objfile));
+ else /* expect DNTT_TYPE_FUNC_TEMPLATE */
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval,
+ objfile));
+ memcpy ((char *) type, (char *) type1, sizeof (struct type));
+
+ /* Mark it -- in the middle of processing */
+ TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+ }
+
+ /* Now examine each parameter noting its type, location, and a
+ wealth of other information. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+ param = dn_bufp->dfunc.firstparam;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+ param = dn_bufp->dfunctype.firstparam;
+ else /* expect DNTT_TYPE_FUNC_TEMPLATE */
+ param = dn_bufp->dfunc_template.firstparam;
+ while (param.word && param.word != DNTTNIL)
+ {
+ paramp = hpread_get_lntt (param.dnttp.index, objfile);
+ nsyms++;
+ param = paramp->dfparam.nextparam;
+
+ /* Get the name. */
+ name = VT (objfile) + paramp->dfparam.name;
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ (void) memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+
+ /* Figure out where it lives. */
+ if (paramp->dfparam.regparam)
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ else if (paramp->dfparam.indirect)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ else
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (paramp->dfparam.copyparam)
+ {
+ SYMBOL_VALUE (sym) = paramp->dfparam.location ;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ /* This is likely a pass-by-invisible reference parameter,
+ Hack on the symbol class to make GDB happy. */
+ /* ??rehrauer: This appears to be broken w/r/t to passing
+ C values of type float and struct. Perhaps this ought
+ to be highighted as a special case, but for now, just
+ allowing these to be LOC_ARGs seems to work fine.
+ */
+#if 0
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+ }
+ else
+ SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+ /* Get its type. */
+ SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+ /* Add it to the symbol list. */
+ /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+ * called on FPARAM symbols from the process_one_debug_symbol()
+ * level... so parameters are getting added twice! (this shows
+ * up in the symbol dump you get from "maint print symbols ...").
+ * Note 2 (RT) I took out the processing of FPARAM from the
+ * process_one_debug_symbol() level, so at the moment parameters are only
+ * being processed here. This seems to have no ill effect.
+ */
+ /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+ each fparam on the local_symbols list from here. Now we use the
+ local_list to which fparams are added below, and set the param_symbols
+ global to point to that at the end of this routine. */
+ /* elz: I added this new list of symbols which is local to the function.
+ this list is the one which is actually used to build the type for the
+ function rather than the gloabal list pointed to by symlist.
+ Using a global list to keep track of the parameters is wrong, because
+ this function is called recursively if one parameter happend to be
+ a function itself with more parameters in it. Adding parameters to the
+ same global symbol list would not work!
+ Actually it did work in case of cc compiled programs where you do
+ not check the parameter lists of the arguments. */
+ add_symbol_to_list (sym, &local_list);
+
+ }
+
+ /* If type was read in earlier, don't bother with modifying
+ the type struct */
+ if (!record_args)
+ goto finish;
+
+ /* Note how many parameters we found. */
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the parameters and
+ use them to fill parameter-type information into the function-type.
+ The parameter symbols can be found in the local_list that we just put them on. */
+ /* Note that we preserve the order of the parameters, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+
+ /* get the parameters types from the local list not the global list
+ so that the type can be correctly constructed for functions which
+ have function as parameters */
+ for (syms = local_list, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+ for (j=0; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+ TYPE_FIELD_BITPOS (type, n) = n;
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ }
+ /* Mark it as having been processed */
+ TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+ /* Check whether we need to fix-up a class type with this function's type */
+ if (fixup_class && (fixup_method == type))
+ {
+ fixup_class_method_type (fixup_class, fixup_method, objfile);
+ fixup_class = NULL;
+ fixup_method = NULL;
+ }
+
+ /* Set the param list of this level of the context stack
+ to our local list. Do this only if this function was
+ called for creating a new block, and not if it was called
+ simply to get the function type. This prevents recursive
+ invocations from trashing param_symbols. */
+finish:
+ if (newblock)
+ param_symbols = local_list;
+
+ return type;
+}
+
+
+/* Read and internalize a native DOC function debug symbol. */
+/* This is almost identical to hpread_read_function_type(), except
+ * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc.
+ * Since debug information for DOC functions is more likely to be
+ * volatile, please leave it this way.
+ */
+static struct type *
+hpread_read_doc_function_type (hp_type, dn_bufp, objfile, newblock)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+ int newblock;
+{
+ struct type *type, *type1;
+ struct pending *syms;
+ struct pending *local_list = NULL;
+ int nsyms = 0;
+ dnttpointer param;
+ union dnttentry *paramp;
+ char *name;
+ long n;
+ struct symbol *sym;
+ int record_args = 1;
+
+ /* See if we've already read in this type. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ record_args = 0; /* already read in, don't modify type */
+ }
+ else
+ {
+ /* Nope, so read it in and store it away. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval,
+ objfile));
+ memcpy ((char *) type, (char *) type1, sizeof (struct type));
+
+ /* Mark it -- in the middle of processing */
+ TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+ }
+
+ /* Now examine each parameter noting its type, location, and a
+ wealth of other information. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+ param = dn_bufp->ddocfunc.firstparam;
+ while (param.word && param.word != DNTTNIL)
+ {
+ paramp = hpread_get_lntt (param.dnttp.index, objfile);
+ nsyms++;
+ param = paramp->dfparam.nextparam;
+
+ /* Get the name. */
+ name = VT (objfile) + paramp->dfparam.name;
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ (void) memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = name;
+
+ /* Figure out where it lives. */
+ if (paramp->dfparam.regparam)
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ else if (paramp->dfparam.indirect)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ else
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (paramp->dfparam.copyparam)
+ {
+ SYMBOL_VALUE (sym) = paramp->dfparam.location ;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ /* This is likely a pass-by-invisible reference parameter,
+ Hack on the symbol class to make GDB happy. */
+ /* ??rehrauer: This appears to be broken w/r/t to passing
+ C values of type float and struct. Perhaps this ought
+ to be highighted as a special case, but for now, just
+ allowing these to be LOC_ARGs seems to work fine.
+ */
+#if 0
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+ }
+ else
+ SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+ /* Get its type. */
+ SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+ /* Add it to the symbol list. */
+ /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+ * called on FPARAM symbols from the process_one_debug_symbol()
+ * level... so parameters are getting added twice! (this shows
+ * up in the symbol dump you get from "maint print symbols ...").
+ * Note 2 (RT) I took out the processing of FPARAM from the
+ * process_one_debug_symbol() level, so at the moment parameters are only
+ * being processed here. This seems to have no ill effect.
+ */
+ /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+ each fparam on the local_symbols list from here. Now we use the
+ local_list to which fparams are added below, and set the param_symbols
+ global to point to that at the end of this routine. */
+
+ /* elz: I added this new list of symbols which is local to the function.
+ this list is the one which is actually used to build the type for the
+ function rather than the gloabal list pointed to by symlist.
+ Using a global list to keep track of the parameters is wrong, because
+ this function is called recursively if one parameter happend to be
+ a function itself with more parameters in it. Adding parameters to the
+ same global symbol list would not work!
+ Actually it did work in case of cc compiled programs where you do not check the
+ parameter lists of the arguments. */
+ add_symbol_to_list (sym, &local_list);
+ }
+
+ /* If type was read in earlier, don't bother with modifying
+ the type struct */
+ if (!record_args)
+ goto finish;
+
+ /* Note how many parameters we found. */
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the parameters and
+ use them to fill parameter-type information into the function-type.
+ The parameter symbols can be found in the local_list that we just put them on. */
+ /* Note that we preserve the order of the parameters, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+
+ /* get the parameters types from the local list not the global list
+ so that the type can be correctly constructed for functions which
+ have function as parameters
+ */
+ for (syms = local_list, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+ for (j = 0; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+ TYPE_FIELD_BITPOS (type, n) = n;
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ }
+
+ /* Mark it as having been processed */
+ TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+ /* Check whether we need to fix-up a class type with this function's type */
+ if (fixup_class && (fixup_method == type))
+ {
+ fixup_class_method_type (fixup_class, fixup_method, objfile);
+ fixup_class = NULL;
+ fixup_method = NULL;
+ }
+
+ /* Set the param list of this level of the context stack
+ to our local list. Do this only if this function was
+ called for creating a new block, and not if it was called
+ simply to get the function type. This prevents recursive
+ invocations from trashing param_symbols. */
+finish:
+ if (newblock)
+ param_symbols = local_list;
+
+ return type;
+}
+
+
+
+/* A file-level variable which keeps track of the current-template
+ * being processed. Set in hpread_read_struct_type() while processing
+ * a template type. Referred to in hpread_get_nth_templ_arg().
+ * Yes, this is a kludge, but it arises from the kludge that already
+ * exists in symtab.h, namely the fact that they encode
+ * "template argument n" with fundamental type FT_TEMPLATE_ARG and
+ * bitlength n. This means that deep in processing fundamental types
+ * I need to ask the question "what template am I in the middle of?".
+ * The alternative to stuffing a global would be to pass an argument
+ * down the chain of calls just for this purpose.
+ *
+ * There may be problems handling nested templates... tough.
+ */
+static struct type * current_template = NULL;
+
+/* Read in and internalize a structure definition.
+ * This same routine is called for struct, union, and class types.
+ * Also called for templates, since they build a very similar
+ * type entry as for class types.
+ */
+
+static struct type *
+hpread_read_struct_type (hp_type, dn_bufp, objfile)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+{
+ /* The data members get linked together into a list of struct nextfield's */
+ struct nextfield
+ {
+ struct nextfield *next;
+ struct field field;
+ unsigned char attributes; /* store visibility and virtuality info */
+# define ATTR_VIRTUAL 1
+# define ATTR_PRIVATE 2
+# define ATTR_PROTECT 3
+ };
+
+
+ /* The methods get linked together into a list of struct next_fn_field's */
+ struct next_fn_field
+ {
+ struct next_fn_field *next;
+ struct fn_fieldlist field;
+ struct fn_field fn_field;
+ int num_fn_fields;
+ };
+
+ /* The template args get linked together into a list of struct next_template's */
+ struct next_template
+ {
+ struct next_template *next;
+ struct template_arg arg;
+ };
+
+ /* The template instantiations get linked together into a list of these... */
+ struct next_instantiation
+ {
+ struct next_instantiation * next;
+ struct type * t;
+ };
+
+ struct type *type;
+ struct type *baseclass;
+ struct type *memtype;
+ struct nextfield *list = 0, *tmp_list = 0;
+ struct next_fn_field *fn_list = 0;
+ struct next_fn_field *fn_p;
+ struct next_template *t_new, *t_list = 0;
+ struct nextfield *new;
+ struct next_fn_field *fn_new;
+ struct next_instantiation *i_new, *i_list = 0;
+ int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0;
+ int n_base_classes = 0, n_templ_args = 0;
+ int ninstantiations = 0;
+ dnttpointer field, fn_field, parent;
+ union dnttentry *fieldp, *fn_fieldp, *parentp;
+ int i;
+ int static_member = 0;
+ int const_member = 0;
+ int volatile_member = 0;
+ unsigned long vtbl_offset;
+ int need_bitvectors = 0;
+ char * method_name = NULL;
+ char * method_alias = NULL;
+
+
+ /* Is it something we've already dealt with? */
+ type = hpread_alloc_type (hp_type, objfile);
+ if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+ (TYPE_CODE (type) == TYPE_CODE_UNION) ||
+ (TYPE_CODE (type) == TYPE_CODE_CLASS) ||
+ (TYPE_CODE (type) == TYPE_CODE_TEMPLATE))
+ return type;
+
+ /* Get the basic type correct. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+ {
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+ {
+ TYPE_CODE (type) = TYPE_CODE_UNION;
+ TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+ {
+ TYPE_CODE (type) = TYPE_CODE_CLASS;
+ TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8;
+
+ /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory
+ * rather than &cplus_struct_default.
+ */
+ allocate_cplus_struct_type(type);
+
+ /* Fill in declared-type.
+ * (The C++ compiler will emit TYPE_CODE_CLASS
+ * for all 3 of "class", "struct"
+ * "union", and we have to look at the "class_decl" field if we
+ * want to know how it was really declared)
+ */
+ /* (0==class, 1==union, 2==struct) */
+ TYPE_DECLARED_TYPE(type) = dn_bufp->dclass.class_decl;
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ /* Get the basic type correct. */
+ TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
+ allocate_cplus_struct_type(type);
+ TYPE_DECLARED_TYPE(type) = DECLARED_TYPE_TEMPLATE;
+ }
+ else
+ return type;
+
+
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+
+ /* For classes, read the parent list.
+ * Question (RT): Do we need to do this for templates also?
+ */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) {
+
+ /* First read the parent-list (classes from which we derive fields) */
+ parent = dn_bufp->dclass.parentlist;
+ while (parent.word && parent.word != DNTTNIL) {
+ parentp = hpread_get_lntt (parent.dnttp.index, objfile);
+
+ /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */
+
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ FIELD_BITSIZE (list->field) = 0;
+
+ /* The "classname" field is actually a DNTT pointer to the base class */
+ baseclass = hpread_type_lookup (parentp->dinheritance.classname,
+ objfile);
+ FIELD_TYPE (list->field) = baseclass;
+
+ list->field.name = type_name_no_tag(FIELD_TYPE (list->field));
+
+ list->attributes = 0;
+
+ /* Check for virtuality of base, and set the
+ * offset of the base subobject within the object.
+ * (Offset set to -1 for virtual bases (for now).)
+ */
+ if (parentp->dinheritance.Virtual)
+ {
+ B_SET(&(list->attributes), ATTR_VIRTUAL);
+ parentp->dinheritance.offset = -1;
+ }
+ else
+ FIELD_BITPOS (list->field) = parentp->dinheritance.offset;
+
+ /* Check visibility */
+ switch (parentp->dinheritance.visibility)
+ {
+ case 1:
+ B_SET(&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET(&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+
+ n_base_classes++;
+ nfields++;
+
+ parent = parentp->dinheritance.next;
+ }
+ }
+
+ /* For templates, read the template argument list.
+ * This must be done before processing the member list, because
+ * the member list may refer back to this. E.g.:
+ * template <class T1, class T2> class q2 {
+ * public:
+ * T1 a;
+ * T2 b;
+ * };
+ * We need to read the argument list "T1", "T2" first.
+ */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) {
+ /* Kludge alert: This stuffs a global "current_template" which
+ * is referred to by hpread_get_nth_templ_arg(). The global
+ * is cleared at the end of this routine.
+ */
+ current_template = type;
+
+ /* Read in the argument list */
+ field = dn_bufp->dtemplate.arglist;
+ while (field.word && field.word != DNTTNIL) {
+ /* Get this template argument*/
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+ if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG)
+ {
+ warning ("Invalid debug info: Template argument entry is of wrong kind");
+ break;
+ }
+ /* Bump the count */
+ n_templ_args++;
+ /* Allocate and fill in a struct next_template */
+ t_new = (struct next_template *) alloca (sizeof (struct next_template));
+ t_new->next = t_list;
+ t_list = t_new;
+ t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name;
+ t_list->arg.type = hpread_read_templ_arg_type(field, fieldp,
+ objfile, t_list->arg.name);
+ /* Walk to the next template argument */
+ field = fieldp->dtempl_arg.nextarg;
+ }
+ }
+
+ TYPE_NTEMPLATE_ARGS(type) = n_templ_args;
+
+ if (n_templ_args > 0)
+ TYPE_TEMPLATE_ARGS(type) = (struct template_arg *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct template_arg) * n_templ_args);
+ for (n = n_templ_args; t_list; t_list = t_list->next)
+ {
+ n -= 1;
+ TYPE_TEMPLATE_ARG(type, n) = t_list->arg;
+ }
+
+ /* Next read in and internalize all the fields/members. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+ field = dn_bufp->dstruct.firstfield;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+ field = dn_bufp->dunion.firstfield;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+ field = dn_bufp->dclass.memberlist;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ field = dn_bufp->dtemplate.memberlist;
+ else
+ field.word = DNTTNIL;
+
+ while (field.word && field.word != DNTTNIL)
+ {
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+ /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD
+ * or a DNTT_TYPE_GENFIELD record.
+ */
+ vtbl_offset = 0;
+ static_member = 0;
+ const_member = 0;
+ volatile_member = 0;
+
+ if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD) {
+
+ /* The type will be GENFIELD if the field is a method or
+ * a static member (or some other cases -- see below)
+ */
+
+ /* Follow a link to get to the record for the field. */
+ fn_field = fieldp->dgenfield.field;
+ fn_fieldp = hpread_get_lntt(fn_field.dnttp.index, objfile);
+
+ /* Virtual funcs are indicated by a VFUNC which points to the
+ * real entry
+ */
+ if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC) {
+ vtbl_offset = fn_fieldp->dvfunc.vtbl_offset;
+ fn_field = fn_fieldp->dvfunc.funcptr;
+ fn_fieldp = hpread_get_lntt(fn_field.dnttp.index, objfile);
+ }
+
+ /* A function's entry may be preceded by a modifier which
+ * labels it static/constant/volatile.
+ */
+ if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER) {
+ static_member = fn_fieldp->dmodifier.m_static;
+ const_member = fn_fieldp->dmodifier.m_const;
+ volatile_member = fn_fieldp->dmodifier.m_volatile;
+ fn_field = fn_fieldp->dmodifier.type;
+ fn_fieldp = hpread_get_lntt(fn_field.dnttp.index, objfile);
+ }
+
+ /* Check whether we have a method */
+ if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION)) {
+ /* Method found */
+
+ short ix = 0;
+
+ /* Look up function type of method */
+ memtype = hpread_type_lookup (fn_field, objfile);
+
+ /* Methods can be seen before classes in the SOM records.
+ If we are processing this class because it's a parameter of a
+ method, at this point the method's type is actually incomplete;
+ we'll have to fix it up later; mark the class for this. */
+
+ if (TYPE_INCOMPLETE (memtype))
+ {
+ TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+ if (fixup_class)
+ warning ("Two classes to fix up for method?? Type information may be incorrect for some classes.");
+ if (fixup_method)
+ warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes.");
+ fixup_class = type; /* remember this class has to be fixed up */
+ fixup_method = memtype; /* remember the method type to be used in fixup */
+ }
+
+ /* HP aCC generates operator names without the "operator" keyword, and
+ generates null strings as names for operators that are
+ user-defined type conversions to basic types (e.g. operator int ()).
+ So try to reconstruct name as best as possible. */
+
+ method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name);
+ method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias);
+
+ if (!method_name || /* no name */
+ !*method_name || /* or null name */
+ cplus_mangle_opname (method_name, DMGL_ANSI)) /* or name is an operator like "<" */
+ {
+ char * tmp_name = cplus_demangle (method_alias, DMGL_ANSI);
+ char * op_string = strstr (tmp_name, "operator");
+ method_name = xmalloc (strlen (op_string) + 1); /* don't overwrite VT! */
+ strcpy (method_name, op_string);
+ }
+
+ /* First check if a method of the same name has already been seen. */
+ fn_p = fn_list;
+ while (fn_p)
+ {
+ if (STREQ (fn_p->field.name, method_name))
+ break;
+ fn_p = fn_p->next;
+ }
+
+ /* If no such method was found, allocate a new entry in the list */
+ if (!fn_p)
+ {
+ /* Get space to record this member function */
+ /* Note: alloca used; this will disappear on routine exit */
+ fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field));
+ fn_new->next = fn_list;
+ fn_list = fn_new;
+
+ /* Fill in the fields of the struct nextfield */
+
+ /* Record the (unmangled) method name */
+ fn_list->field.name = method_name;
+ /* Initial space for overloaded methods */
+ /* Note: xmalloc is used; this will persist after this routine exits */
+ fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field)));
+ fn_list->field.length = 1; /* Init # of overloaded instances */
+ fn_list->num_fn_fields = 5; /* # of entries for which space allocated */
+ fn_p = fn_list;
+ ix = 0; /* array index for fn_field */
+ /* Bump the total count of the distinctly named methods */
+ n_fn_fields++;
+ }
+ else /* Another overloaded instance of an already seen method name */
+ {
+ if (++(fn_p->field.length) > fn_p->num_fn_fields)
+ {
+ /* Increase space allocated for overloaded instances */
+ fn_p->field.fn_fields
+ = (struct fn_field *) xrealloc (fn_p->field.fn_fields,
+ (fn_p->num_fn_fields + 5) * sizeof (struct fn_field));
+ fn_p->num_fn_fields += 5;
+ }
+ ix = fn_p->field.length -1; /* array index for fn_field */
+ }
+
+ /* "physname" is intended to be the name of this overloaded instance. */
+ if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+ method_alias &&
+ *method_alias) /* not a null string */
+ fn_p->field.fn_fields[ix].physname = method_alias;
+ else
+ fn_p->field.fn_fields[ix].physname = method_name;
+ /* What's expected here is the function type */
+ /* But mark it as NULL if the method was incompletely processed
+ We'll fix this up later when the method is fully processed */
+ if (TYPE_INCOMPLETE (memtype))
+ {
+ fn_p->field.fn_fields[ix].type = NULL;
+ fn_p->field.fn_fields[ix].args = NULL;
+ }
+ else
+ {
+ fn_p->field.fn_fields[ix].type = memtype;
+
+ /* The argument list */
+ fn_p->field.fn_fields[ix].type->type_specific.arg_types =
+ (struct type **) obstack_alloc(&objfile->type_obstack,
+ sizeof(struct type *) * (memtype->nfields + 1));
+ for (i = 0; i < memtype->nfields; i++)
+ fn_p->field.fn_fields[ix].type->type_specific.arg_types[i] = memtype->fields[i].type;
+ /* void termination */
+ fn_p->field.fn_fields[ix].type->type_specific.arg_types[memtype->nfields] = builtin_type_void;
+
+ /* pai: It's not clear why this args field has to be set. Perhaps
+ * it should be eliminated entirely. */
+ fn_p->field.fn_fields[ix].args =
+ (struct type **) obstack_alloc(&objfile->type_obstack,
+ sizeof(struct type *) * (memtype->nfields + 1));
+ for (i = 0; i < memtype->nfields; i++)
+ fn_p->field.fn_fields[ix].args[i] = memtype->fields[i].type;
+ /* null-terminated, unlike arg_types above e*/
+ fn_p->field.fn_fields[ix].args[memtype->nfields] = NULL;
+ }
+ /* For virtual functions, fill in the voffset field with the
+ * virtual table offset. (This is just copied over from the
+ * SOM record; not sure if it is what GDB expects here...).
+ * But if the function is a static method, set it to 1.
+ *
+ * Note that we have to add 1 because 1 indicates a static
+ * method, and 0 indicates a non-static, non-virtual method */
+
+ if (static_member)
+ fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC;
+ else
+ fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0;
+
+ /* Also fill in the fcontext field with the current
+ * class. (The latter isn't quite right: should be the baseclass
+ * that defines the virtual function... Note we do have
+ * a variable "baseclass" that we could stuff into the fcontext
+ * field, but "baseclass" isn't necessarily right either,
+ * since the virtual function could have been defined more
+ * than one level up).
+ */
+
+ if (vtbl_offset != 0)
+ fn_p->field.fn_fields[ix].fcontext = type;
+ else
+ fn_p->field.fn_fields[ix].fcontext = NULL;
+
+ /* Other random fields pertaining to this method */
+ fn_p->field.fn_fields[ix].is_const = const_member;
+ fn_p->field.fn_fields[ix].is_volatile = volatile_member; /* ?? */
+ switch (fieldp->dgenfield.visibility) {
+ case 1:
+ fn_p->field.fn_fields[ix].is_protected = 1;
+ fn_p->field.fn_fields[ix].is_private = 0;
+ break;
+ case 2:
+ fn_p->field.fn_fields[ix].is_protected = 0;
+ fn_p->field.fn_fields[ix].is_private = 1;
+ break;
+ default: /* public */
+ fn_p->field.fn_fields[ix].is_protected = 0;
+ fn_p->field.fn_fields[ix].is_private = 0;
+ }
+ fn_p->field.fn_fields[ix].is_stub = 0;
+
+ /* HP aCC emits both MEMFUNC and FUNCTION entries for a method;
+ if the class points to the FUNCTION, there is usually separate
+ code for the method; but if we have a MEMFUNC, the method has
+ been inlined (and there is usually no FUNCTION entry)
+ FIXME Not sure if this test is accurate. pai/1997-08-22 */
+ if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC))
+ fn_p->field.fn_fields[ix].is_inlined = 1;
+ else
+ fn_p->field.fn_fields[ix].is_inlined = 0;
+
+ fn_p->field.fn_fields[ix].dummy = 0;
+
+ /* Bump the total count of the member functions */
+ n_fn_fields_total++;
+
+ } else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR) {
+ /* This case is for static data members of classes */
+
+ /* pai:: FIXME -- check that "staticmem" bit is set */
+
+ /* Get space to record this static member */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+ FIELD_BITSIZE (list->field) = -1; /* indicates static member */
+ SET_FIELD_PHYSNAME (list->field, 0); /* initialize to empty */
+ memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+
+ FIELD_TYPE (list->field) = memtype;
+ list->attributes = 0;
+ switch (fieldp->dgenfield.visibility) {
+ case 1:
+ B_SET(&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET(&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+ nfields++;
+ }
+
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD)
+ {
+ /* FIELDs follow GENFIELDs for fields of anonymous unions.
+ Code below is replicated from the case for FIELDs further
+ below, except that fieldp is replaced by fn_fieldp */
+ if (!fn_fieldp->dfield.a_union)
+ warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set");
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->dfield.name;
+ FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset;
+ if (fn_fieldp->dfield.bitlength % 8)
+ list->field.bitsize = fn_fieldp->dfield.bitlength;
+ else
+ list->field.bitsize = 0;
+
+ memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile);
+ list->field.type = memtype;
+ list->attributes = 0;
+ switch (fn_fieldp->dfield.visibility) {
+ case 1:
+ B_SET(&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET(&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+ nfields++;
+ }
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+ {
+ /* Field of anonymous union; union is not inside a class */
+ if (!fn_fieldp->dsvar.a_union)
+ warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set");
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+ FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */
+ FIELD_BITSIZE (list->field) = 0; /* use length from type */
+ memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+ list->field.type = memtype;
+ list->attributes = 0;
+ /* No info to set visibility -- always public */
+ nfields++;
+ }
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR)
+ {
+ /* Field of anonymous union; union is not inside a class */
+ if (!fn_fieldp->ddvar.a_union)
+ warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set");
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->ddvar.name;
+ FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */
+ FIELD_BITSIZE (list->field) = 0; /* use length from type */
+ memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile);
+ list->field.type = memtype;
+ list->attributes = 0;
+ /* No info to set visibility -- always public */
+ nfields++;
+ }
+ else { /* Not a method, nor a static data member, nor an anon union field */
+
+ /* This case is for miscellaneous type entries (local enums,
+ local function templates, etc.) that can be present
+ inside a class. */
+
+ /* Enums -- will be handled by other code that takes care
+ of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so
+ it's not clear we could have handled them here at all. */
+ /* FUNC_TEMPLATE: is handled by other code (??). */
+ /* MEMACCESS: modified access for inherited member. Not
+ sure what to do with this, ignoriing it at present. */
+
+ /* What other entries can appear following a GENFIELD which
+ we do not handle above? (MODIFIER, VFUNC handled above.) */
+
+ if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) &&
+ (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) &&
+ (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE))
+ warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD",
+ fn_fieldp->dblock.kind);
+ }
+ /* walk to the next FIELD or GENFIELD */
+ field = fieldp->dgenfield.nextfield;
+
+ }
+ else if (fieldp->dblock.kind == DNTT_TYPE_FIELD) {
+
+ /* Ordinary structure/union/class field */
+ struct type * anon_union_type;
+
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fieldp->dfield.name;
+
+
+ /* A FIELD by itself (without a GENFIELD) can also be a static member */
+ if (fieldp->dfield.staticmem)
+ {
+ FIELD_BITPOS (list->field) = -1;
+ FIELD_BITSIZE (list->field) = 0;
+ }
+ else /* Non-static data member */
+ {
+ FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
+ if (fieldp->dfield.bitlength % 8)
+ FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
+ else
+ FIELD_BITSIZE (list->field) = 0;
+ }
+
+ memtype = hpread_type_lookup (fieldp->dfield.type, objfile);
+ FIELD_TYPE (list->field) = memtype;
+ list->attributes = 0;
+ switch (fieldp->dfield.visibility) {
+ case 1:
+ B_SET(&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET(&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+ nfields++;
+
+
+ /* Note 1: First, we have to check if the current field is an anonymous
+ union. If it is, then *its* fields are threaded along in the
+ nextfield chain. :-( This was supposed to help debuggers, but is
+ really just a nuisance since we deal with anonymous unions anyway by
+ checking that the name is null. So anyway, we skip over the fields
+ of the anonymous union. pai/1997-08-22 */
+ /* Note 2: In addition, the bitoffsets for the fields of the anon union
+ are relative to the enclosing struct, *NOT* relative to the anon
+ union! This is an even bigger nuisance -- we have to go in and munge
+ the anon union's type information appropriately. pai/1997-08-22 */
+
+ /* Both tasks noted above are done by a separate function. This takes us
+ to the next FIELD or GENFIELD, skipping anon unions, and recursively
+ processing intermediate types. */
+ field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile);
+
+ } else {
+ /* neither field nor genfield ?? is this possible?? */
+ /* pai:: FIXME walk to the next -- how? */
+ warning ("Internal error: unexpected DNTT kind %d encountered as field of struct");
+ warning ("Skipping remaining fields of struct");
+ break; /* get out of loop of fields */
+ }
+ }
+
+ /* If it's a template, read in the instantiation list */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) {
+ ninstantiations = 0;
+ field = dn_bufp->dtemplate.expansions;
+ while (field.word && field.word != DNTTNIL) {
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+ /* The expansions or nextexp should point to a tagdef */
+ if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF)
+ break;
+
+ i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation));
+ i_new->next = i_list;
+ i_list = i_new;
+ i_list->t = hpread_type_lookup (field, objfile);
+ ninstantiations++;
+
+ /* And the "type" field of that should point to a class */
+ field = fieldp->dtag.type;
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+ if (fieldp->dblock.kind != DNTT_TYPE_CLASS)
+ break;
+
+ /* Get the next expansion */
+ field = fieldp->dclass.nextexp;
+ }
+ }
+ TYPE_NINSTANTIATIONS(type) = ninstantiations;
+ if (ninstantiations > 0)
+ TYPE_INSTANTIATIONS(type) = (struct type **)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct type *) * ninstantiations);
+ for (n = ninstantiations; i_list; i_list = i_list->next)
+ {
+ n -= 1;
+ TYPE_INSTANTIATION(type, n) = i_list->t;
+ }
+
+
+ /* Copy the field-list to GDB's symbol table */
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_N_BASECLASSES (type) = n_base_classes;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
+ /* Copy the saved-up fields into the field vector. */
+ for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+ {
+ n -= 1;
+ TYPE_FIELD (type, n) = tmp_list->field;
+ }
+
+ /* Copy the "function-field-list" (i.e., the list of member
+ * functions in the class) to GDB's symbol table
+ */
+ TYPE_NFN_FIELDS (type) = n_fn_fields;
+ TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total;
+ TYPE_FN_FIELDLISTS(type) = (struct fn_fieldlist *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct fn_fieldlist) * n_fn_fields);
+ for (n = n_fn_fields; fn_list; fn_list = fn_list->next)
+ {
+ n -= 1;
+ TYPE_FN_FIELDLIST(type, n) = fn_list->field;
+ }
+
+ /* pai:: FIXME -- perhaps each bitvector should be created individually */
+ for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+ {
+ n -= 1;
+ if (tmp_list->attributes)
+ {
+ need_bitvectors = 1;
+ break;
+ }
+ }
+
+ if (need_bitvectors)
+ {
+ /* pai:: this step probably redundant */
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+ TYPE_FIELD_VIRTUAL_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ /* this field vector isn't actually used with HP aCC */
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+ while (nfields-- > 0)
+ {
+ if (B_TST(&(list->attributes),ATTR_VIRTUAL))
+ SET_TYPE_FIELD_VIRTUAL (type, nfields);
+ if (B_TST(&(list->attributes),ATTR_PRIVATE))
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+ if (B_TST(&(list->attributes),ATTR_PROTECT))
+ SET_TYPE_FIELD_PROTECTED (type, nfields);
+
+ list = list->next;
+ }
+ }
+ else
+ {
+ TYPE_FIELD_VIRTUAL_BITS(type) = NULL;
+ TYPE_FIELD_PROTECTED_BITS(type) = NULL;
+ TYPE_FIELD_PRIVATE_BITS(type) = NULL;
+ }
+
+ if (has_vtable(type))
+ {
+ /* Allocate space for class runtime information */
+ TYPE_RUNTIME_PTR(type) = (struct runtime_info *) xmalloc (sizeof(struct runtime_info));
+ /* Set flag for vtable */
+ TYPE_VTABLE(type) = 1;
+ /* The first non-virtual base class with a vtable. */
+ TYPE_PRIMARY_BASE(type) = primary_base_class(type);
+ /* The virtual base list. */
+ TYPE_VIRTUAL_BASE_LIST(type) = virtual_base_list(type);
+ }
+ else
+ TYPE_RUNTIME_PTR(type) = NULL;
+
+ /* If this is a local type (C++ - declared inside a function), record file name & line # */
+ if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */))
+ {
+ TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info));
+ TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1);
+ strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name);
+ if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0))
+ TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line;
+ else
+ TYPE_LOCALTYPE_LINE (type) = 0;
+ }
+ else
+ TYPE_LOCALTYPE_PTR (type) = NULL;
+
+ /* Clear the global saying what template we are in the middle of processing */
+ current_template = NULL;
+
+ return type;
+}
+
+/* Adjust the physnames for each static member of a struct
+ or class type to be something like "A::x"; then various
+ other pieces of code that do a lookup_symbol on the phyname
+ work correctly.
+ TYPE is a pointer to the struct/class type
+ NAME is a char * (string) which is the class/struct name
+ Void return */
+
+static void
+fix_static_member_physnames (type, class_name, objfile)
+ struct type * type;
+ char * class_name;
+ struct objfile * objfile;
+{
+ int i;
+
+ /* We fix the member names only for classes or structs */
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
+ return;
+
+ for (i=0; i < TYPE_NFIELDS (type); i++)
+ if (TYPE_FIELD_STATIC (type, i))
+ {
+ if (TYPE_FIELD_STATIC_PHYSNAME (type, i))
+ return; /* physnames are already set */
+
+ SET_FIELD_PHYSNAME (type->fields[i],
+ obstack_alloc (&objfile->type_obstack,
+ strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3));
+ strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name);
+ strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::");
+ strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i));
+ }
+}
+
+/* Fix-up the type structure for a CLASS so that the type entry
+ * for a method (previously marked with a null type in hpread_read_struct_type()
+ * is set correctly to METHOD.
+ * OBJFILE is as for other such functions.
+ * Void return. */
+
+static void
+fixup_class_method_type (class, method, objfile)
+ struct type * class;
+ struct type * method;
+ struct objfile * objfile;
+{
+ int i, j, k;
+
+ if (!class || !method || !objfile)
+ return;
+
+ /* Only for types that have methods */
+ if ((TYPE_CODE (class) != TYPE_CODE_CLASS) &&
+ (TYPE_CODE (class) != TYPE_CODE_UNION))
+ return;
+
+ /* Loop over all methods and find the one marked with a NULL type */
+ for (i = 0; i < TYPE_NFN_FIELDS (class); i++)
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++)
+ if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL)
+ {
+ /* Set the method type */
+ TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
+ /* The argument list */
+ (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types
+ = (struct type **) obstack_alloc(&objfile->type_obstack,
+ sizeof(struct type *) * (method->nfields + 1));
+ for (k = 0; k < method->nfields; k++)
+ (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[k] = method->fields[k].type;
+ /* void termination */
+ (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j))->type_specific.arg_types[method->nfields] = builtin_type_void;
+
+ /* pai: It's not clear why this args field has to be set. Perhaps
+ * it should be eliminated entirely. */
+ (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args
+ = (struct type **) obstack_alloc(&objfile->type_obstack,
+ sizeof(struct type *) * (method->nfields + 1));
+ for (k = 0; k < method->nfields; k++)
+ (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[k] = method->fields[k].type;
+ /* null-terminated, unlike arg_types above */
+ (TYPE_FN_FIELD (TYPE_FN_FIELDLIST1 (class, i), j)).args[method->nfields] = NULL;
+
+ /* Break out of both loops -- only one method to fix up in a class */
+ goto finish;
+ }
+
+finish:
+ TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE;
+}
+
+
+/* If we're in the middle of processing a template, get a pointer
+ * to the Nth template argument.
+ * An example may make this clearer:
+ * template <class T1, class T2> class q2 {
+ * public:
+ * T1 a;
+ * T2 b;
+ * };
+ * The type for "a" will be "first template arg" and
+ * the type for "b" will be "second template arg".
+ * We need to look these up in order to fill in "a" and "b"'s type.
+ * This is called from hpread_type_lookup().
+ */
+static struct type *
+hpread_get_nth_template_arg(objfile, n)
+ struct objfile *objfile;
+ int n;
+{
+ if (current_template != NULL)
+ return TYPE_TEMPLATE_ARG(current_template, n).type;
+ else
+ return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG);
+}
+
+/* Read in and internalize a TEMPL_ARG (template arg) symbol. */
+
+static struct type *
+hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+ char * name;
+{
+ struct type *type;
+
+ /* See if it's something we've already deal with. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG)
+ return type;
+
+ /* Nope. Fill in the appropriate fields. */
+ TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG;
+ TYPE_LENGTH (type) = 0;
+ TYPE_NFIELDS (type) = 0;
+ TYPE_NAME (type) = name;
+ return type;
+}
+
+/* Read in and internalize a set debug symbol. */
+
+static struct type *
+hpread_read_set_type (hp_type, dn_bufp, objfile)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+{
+ struct type *type;
+
+ /* See if it's something we've already deal with. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_SET)
+ return type;
+
+ /* Nope. Fill in the appropriate fields. */
+ TYPE_CODE (type) = TYPE_CODE_SET;
+ TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8;
+ TYPE_NFIELDS (type) = 0;
+ TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype,
+ objfile);
+ return type;
+}
+
+/* Read in and internalize an array debug symbol. */
+
+static struct type *
+hpread_read_array_type (hp_type, dn_bufp, objfile)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+{
+ struct type *type;
+
+ /* Allocate an array type symbol.
+ * Why no check for already-read here, like in the other
+ * hpread_read_xxx_type routines? Because it kept us
+ * from properly determining the size of the array!
+ */
+ type = hpread_alloc_type (hp_type, objfile);
+
+ TYPE_CODE (type) = TYPE_CODE_ARRAY;
+
+ /* Although the hp-symtab.h does not *require* this to be the case,
+ * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent.
+ * I.e., express both array-length and element-length in bits,
+ * or express both array-length and element-length in bytes.
+ */
+ if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) ||
+ (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes))) {
+ warning ("error in hpread_array_type.\n");
+ return;
+ } else if (dn_bufp->darray.arraylength == 0x7fffffff) {
+ /* The HP debug format represents char foo[]; as an array with
+ * length 0x7fffffff. Internally GDB wants to represent this
+ * as an array of length zero.
+ */
+ TYPE_LENGTH (type) = 0;
+ } else if (dn_bufp->darray.arrayisbytes)
+ TYPE_LENGTH (type) = dn_bufp->darray.arraylength;
+ else /* arraylength is in bits */
+ TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
+
+ TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
+ objfile);
+
+ /* The one "field" is used to store the subscript type */
+ /* Since C and C++ multi-dimensional arrays are simply represented
+ * as: array of array of ..., we only need one subscript-type
+ * per array. This subscript type is typically a subrange of integer.
+ * If this gets extended to support languages like Pascal, then
+ * we need to fix this to represent multi-dimensional arrays properly.
+ */
+ TYPE_NFIELDS (type) = 1;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct field));
+ TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
+ objfile);
+ return type;
+}
+
+/* Read in and internalize a subrange debug symbol. */
+static struct type *
+hpread_read_subrange_type (hp_type, dn_bufp, objfile)
+ dnttpointer hp_type;
+ union dnttentry *dn_bufp;
+ struct objfile *objfile;
+{
+ struct type *type;
+
+ /* Is it something we've already dealt with. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+ return type;
+
+ /* Nope, internalize it. */
+ TYPE_CODE (type) = TYPE_CODE_RANGE;
+ TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8;
+ TYPE_NFIELDS (type) = 2;
+ TYPE_FIELDS (type)
+ = (struct field *) obstack_alloc (&objfile->type_obstack,
+ 2 * sizeof (struct field));
+
+ if (dn_bufp->dsubr.dyn_low)
+ TYPE_FIELD_BITPOS (type, 0) = 0;
+ else
+ TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound;
+
+ if (dn_bufp->dsubr.dyn_high)
+ TYPE_FIELD_BITPOS (type, 1) = -1;
+ else
+ TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound;
+ TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype,
+ objfile);
+ return type;
+}
+
+/* struct type * hpread_type_lookup(hp_type, objfile)
+ * Arguments:
+ * hp_type: A pointer into the DNTT specifying what type we
+ * are about to "look up"., or else [for fundamental types
+ * like int, float, ...] an "immediate" structure describing
+ * the type.
+ * objfile: ?
+ * Return value: A pointer to a "struct type" (representation of a
+ * type in GDB's internal symbol table - see gdbtypes.h)
+ * Routine description:
+ * There are a variety of places when scanning the DNTT when we
+ * need to interpret a "type" field. The simplest and most basic
+ * example is when we're processing the symbol table record
+ * for a data symbol (a SVAR or DVAR record). That has
+ * a "type" field specifying the type of the data symbol. That
+ * "type" field is either an "immediate" type specification (for the
+ * fundamental types) or a DNTT pointer (for more complicated types).
+ * For the more complicated types, we may or may not have already
+ * processed the pointed-to type. (Multiple data symbols can of course
+ * share the same type).
+ * The job of hpread_type_lookup() is to process this "type" field.
+ * Most of the real work is done in subroutines. Here we interpret
+ * the immediate flag. If not immediate, chase the DNTT pointer to
+ * find our way to the SOM record describing the type, switch on
+ * the SOM kind, and then call an appropriate subroutine depending
+ * on what kind of type we are constructing. (e.g., an array type,
+ * a struct/class type, etc).
+ */
+static struct type *
+hpread_type_lookup (hp_type, objfile)
+ dnttpointer hp_type;
+ struct objfile *objfile;
+{
+ union dnttentry *dn_bufp;
+ struct type * tmp_type;
+
+ /* First see if it's a simple builtin type. */
+ if (hp_type.dntti.immediate)
+ /* If this is a template argument, the argument number is
+ * encoded in the bitlength. All other cases, just return
+ * GDB's representation of this fundamental type.
+ */
+ if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG)
+ return hpread_get_nth_template_arg(objfile, hp_type.dntti.bitlength);
+ else
+ return lookup_fundamental_type (objfile, hpread_type_translate (hp_type));
+
+ /* Not a builtin type. We'll have to read it in. */
+ if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
+ else
+ /* This is a fancy way of returning NULL */
+ return lookup_fundamental_type (objfile, FT_VOID);
+
+ switch (dn_bufp->dblock.kind)
+ {
+ case DNTT_TYPE_SRCFILE:
+ case DNTT_TYPE_MODULE:
+ case DNTT_TYPE_ENTRY:
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_END:
+ case DNTT_TYPE_IMPORT:
+ case DNTT_TYPE_LABEL:
+ case DNTT_TYPE_FPARAM:
+ case DNTT_TYPE_SVAR:
+ case DNTT_TYPE_DVAR:
+ case DNTT_TYPE_CONST:
+ case DNTT_TYPE_MEMENUM:
+ case DNTT_TYPE_VARIANT:
+ case DNTT_TYPE_FILE:
+ case DNTT_TYPE_WITH:
+ case DNTT_TYPE_COMMON:
+ case DNTT_TYPE_COBSTRUCT:
+ case DNTT_TYPE_XREF:
+ case DNTT_TYPE_SA:
+ case DNTT_TYPE_MACRO:
+ case DNTT_TYPE_BLOCKDATA:
+ case DNTT_TYPE_CLASS_SCOPE:
+ case DNTT_TYPE_MEMACCESS:
+ case DNTT_TYPE_INHERITANCE:
+ case DNTT_TYPE_OBJECT_ID:
+ case DNTT_TYPE_FRIEND_CLASS:
+ case DNTT_TYPE_FRIEND_FUNC:
+ /* These are not types - something went wrong. */
+ /* This is a fancy way of returning NULL */
+ return lookup_fundamental_type (objfile, FT_VOID);
+
+ case DNTT_TYPE_FUNCTION:
+ /* We wind up here when dealing with class member functions
+ * (called from hpread_read_struct_type(), i.e. when processing
+ * the class definition itself).
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_DOC_FUNCTION:
+ return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_TYPEDEF:
+ {
+ /* A typedef - chase it down by making a recursive call */
+ struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+ objfile);
+
+ /* The following came from the base hpread.c that we inherited.
+ * It is WRONG so I have commented it out. - RT
+ *...
+
+ char *suffix;
+ suffix = VT (objfile) + dn_bufp->dtype.name;
+ TYPE_NAME (structtype) = suffix;
+
+ * ... further explanation ....
+ *
+ * What we have here is a typedef pointing to a typedef.
+ * E.g.,
+ * typedef int foo;
+ * typedef foo fum;
+ *
+ * What we desire to build is (these are pictures
+ * of "struct type"'s):
+ *
+ * +---------+ +----------+ +------------+
+ * | typedef | | typedef | | fund. type |
+ * | type| -> | type| -> | |
+ * | "fum" | | "foo" | | "int" |
+ * +---------+ +----------+ +------------+
+ *
+ * What this commented-out code is doing is smashing the
+ * name of pointed-to-type to be the same as the pointed-from
+ * type. So we wind up with something like:
+ *
+ * +---------+ +----------+ +------------+
+ * | typedef | | typedef | | fund. type |
+ * | type| -> | type| -> | |
+ * | "fum" | | "fum" | | "fum" |
+ * +---------+ +----------+ +------------+
+ *
+ */
+
+ return structtype;
+ }
+
+ case DNTT_TYPE_TAGDEF:
+ {
+ /* Just a little different from above. We have to tack on
+ * an identifier of some kind (struct, union, enum, class, etc).
+ */
+ struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+ objfile);
+ char *prefix, *suffix;
+ suffix = VT (objfile) + dn_bufp->dtype.name;
+
+ /* Lookup the next type in the list. It should be a structure,
+ * union, class, enum, or template type.
+ * We will need to attach that to our name.
+ */
+ if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+ else {
+ complain (&hpread_type_lookup_complaint);
+ return;
+ }
+
+ if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT) {
+ prefix = "struct ";
+ } else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION) {
+ prefix = "union ";
+ } else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS) {
+ /* Further field for CLASS saying how it was really declared */
+ /* 0==class, 1==union, 2==struct */
+ if (dn_bufp->dclass.class_decl == 0)
+ prefix = "class ";
+ else if (dn_bufp->dclass.class_decl == 1)
+ prefix = "union ";
+ else if (dn_bufp->dclass.class_decl == 2)
+ prefix = "struct ";
+ else
+ prefix = "";
+ } else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM) {
+ prefix = "enum ";
+ } else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) {
+ prefix = "template ";
+ } else {
+ prefix = "";
+ }
+
+ /* Build the correct name. */
+ structtype->name
+ = (char *) obstack_alloc (&objfile->type_obstack,
+ strlen (prefix) + strlen (suffix) + 1);
+ TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix);
+ TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
+ TYPE_TAG_NAME (structtype) = suffix;
+
+ /* For classes/structs, we have to set the static member "physnames"
+ to point to strings like "Class::Member" */
+ if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT)
+ fix_static_member_physnames (structtype, suffix, objfile);
+
+ return structtype;
+ }
+
+ case DNTT_TYPE_POINTER:
+ /* Pointer type - call a routine in gdbtypes.c that constructs
+ * the appropriate GDB type.
+ */
+ return make_pointer_type (
+ hpread_type_lookup (dn_bufp->dptr.pointsto,
+ objfile),
+ NULL);
+
+ case DNTT_TYPE_REFERENCE:
+ /* C++ reference type - call a routine in gdbtypes.c that constructs
+ * the appropriate GDB type.
+ */
+ return make_reference_type (
+ hpread_type_lookup (dn_bufp->dreference.pointsto,
+ objfile),
+ NULL);
+
+ case DNTT_TYPE_ENUM:
+ return hpread_read_enum_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_SET:
+ return hpread_read_set_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_SUBRANGE:
+ return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_ARRAY:
+ return hpread_read_array_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_STRUCT:
+ case DNTT_TYPE_UNION:
+ return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_FIELD:
+ return hpread_type_lookup (dn_bufp->dfield.type, objfile);
+
+ case DNTT_TYPE_FUNCTYPE:
+ /* Here we want to read the function SOMs and return a
+ * type for it. We get here, for instance, when processing
+ * pointer-to-function type.
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_PTRMEM:
+ /* Declares a C++ pointer-to-data-member type.
+ * The "pointsto" field defines the class,
+ * while the "memtype" field defines the pointed-to-type.
+ */
+ {
+ struct type * ptrmemtype;
+ struct type * class_type;
+ struct type * memtype;
+ memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+ objfile),
+ class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+ objfile),
+ ptrmemtype = alloc_type(objfile);
+ smash_to_member_type(ptrmemtype, class_type, memtype);
+ return make_pointer_type(ptrmemtype, NULL);
+ }
+ break;
+
+ case DNTT_TYPE_PTRMEMFUNC:
+ /* Defines a C++ pointer-to-function-member type.
+ * The "pointsto" field defines the class,
+ * while the "memtype" field defines the pointed-to-type.
+ */
+ {
+ struct type * ptrmemtype;
+ struct type * class_type;
+ struct type * functype;
+ struct type * retvaltype;
+ int nargs;
+ int i;
+ struct type ** args_type;
+ class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+ objfile);
+ functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+ objfile);
+ retvaltype = TYPE_TARGET_TYPE (functype);
+ nargs = TYPE_NFIELDS (functype);
+ args_type = (struct type **) xmalloc ((nargs+1) * sizeof (struct type *));
+ for (i = 0; i < nargs; i++) {
+ args_type[i] = TYPE_FIELD_TYPE (functype, i);
+ }
+ args_type[nargs] = NULL;
+ ptrmemtype = alloc_type(objfile);
+ smash_to_method_type(ptrmemtype, class_type, retvaltype, args_type);
+ return make_pointer_type(ptrmemtype, NULL);
+ }
+ break;
+
+ case DNTT_TYPE_CLASS:
+ return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+ case DNTT_TYPE_GENFIELD:
+ /* Chase pointer from GENFIELD to FIELD, and make recursive
+ * call on that.
+ */
+ return hpread_type_lookup (dn_bufp->dgenfield.field, objfile);
+
+ case DNTT_TYPE_VFUNC:
+ /* C++ virtual function.
+ * We get here in the course of processing a class type which
+ * contains virtual functions. Just go through another level
+ * of indirection to get to the pointed-to function SOM.
+ */
+ return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile);
+
+ case DNTT_TYPE_MODIFIER:
+ /* Check the modifiers and then just make a recursive call on
+ * the "type" pointed to by the modifier DNTT.
+ *
+ * pai:: FIXME -- do we ever want to handle "m_duplicate" and
+ * "m_void" modifiers? Is static_flag really needed here?
+ * (m_static used for methods of classes, elsewhere).
+ */
+ tmp_type = make_cv_type (dn_bufp->dmodifier.m_const,
+ dn_bufp->dmodifier.m_volatile,
+ hpread_type_lookup (dn_bufp->dmodifier.type, objfile),
+ 0);
+ return tmp_type;
+
+
+ case DNTT_TYPE_MEMFUNC:
+ /* Member function. Treat like a function.
+ * I think we get here in the course of processing a
+ * pointer-to-member-function type...
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_DOC_MEMFUNC:
+ return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_TEMPLATE:
+ /* Template - sort of the header for a template definition,
+ * which like a class, points to a member list and also points
+ * to a TEMPLATE_ARG list of type-arguments.
+ */
+ return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+ case DNTT_TYPE_TEMPLATE_ARG:
+ {
+ char * name;
+ /* The TEMPLATE record points to an argument list of
+ * TEMPLATE_ARG records, each of which describes one
+ * of the type-arguments.
+ */
+ name = VT (objfile) + dn_bufp->dtempl_arg.name;
+ return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name);
+ }
+
+ case DNTT_TYPE_FUNC_TEMPLATE:
+ /* We wind up here when processing a TEMPLATE type,
+ * if the template has member function(s).
+ * Treat it like a FUNCTION.
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_LINK:
+ /* The LINK record is used to link up templates with instantiations.
+ * There is no type associated with the LINK record per se.
+ */
+ return lookup_fundamental_type (objfile, FT_VOID);
+
+ /* Also not yet handled... */
+ /* case DNTT_TYPE_DYN_ARRAY_DESC: */
+ /* case DNTT_TYPE_DESC_SUBRANGE: */
+ /* case DNTT_TYPE_BEGIN_EXT: */
+ /* case DNTT_TYPE_INLN: */
+ /* case DNTT_TYPE_INLN_LIST: */
+ /* case DNTT_TYPE_ALIAS: */
+ default:
+ /* A fancy way of returning NULL */
+ return lookup_fundamental_type (objfile, FT_VOID);
+ }
+}
+
+static sltpointer
+hpread_record_lines (subfile, s_idx, e_idx, objfile, offset)
+ struct subfile *subfile;
+ sltpointer s_idx, e_idx;
+ struct objfile *objfile;
+ CORE_ADDR offset;
+{
+ union sltentry *sl_bufp;
+
+ while (s_idx <= e_idx)
+ {
+ sl_bufp = hpread_get_slt (s_idx, objfile);
+ /* Only record "normal" entries in the SLT. */
+ if (sl_bufp->snorm.sltdesc == SLT_NORMAL
+ || sl_bufp->snorm.sltdesc == SLT_EXIT)
+ record_line (subfile, sl_bufp->snorm.line,
+ sl_bufp->snorm.address + offset);
+ else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+ record_line (subfile, sl_bufp->snormoff.line,
+ sl_bufp->snormoff.address + offset);
+ s_idx++;
+ }
+ return e_idx;
+}
+
+/* Given a function "f" which is a member of a class, find
+ * the classname that it is a member of. Used to construct
+ * the name (e.g., "c::f") which GDB will put in the
+ * "demangled name" field of the function's symbol.
+ * Called from hpread_process_one_debug_symbol()
+ * If "f" is not a member function, return NULL.
+ */
+char * class_of (functype)
+struct type * functype;
+{
+ struct type * first_param_type;
+ char * first_param_name;
+ struct type * pointed_to_type;
+ char * class_name;
+
+ /* Check that the function has a first argument "this",
+ * and that "this" is a pointer to a class. If not,
+ * functype is not a member function, so return NULL.
+ */
+ if (TYPE_NFIELDS(functype) == 0)
+ return NULL;
+ first_param_name = TYPE_FIELD_NAME (functype, 0);
+ if (first_param_name == NULL)
+ return NULL; /* paranoia */
+ if (strcmp(first_param_name, "this"))
+ return NULL;
+ first_param_type = TYPE_FIELD_TYPE (functype, 0);
+ if (first_param_type == NULL)
+ return NULL; /* paranoia */
+ if (TYPE_CODE(first_param_type) != TYPE_CODE_PTR)
+ return NULL;
+
+ /* Get the thing that "this" points to, check that
+ * it's a class, and get its class name.
+ */
+ pointed_to_type = TYPE_TARGET_TYPE(first_param_type);
+ if (pointed_to_type == NULL)
+ return NULL; /* paranoia */
+ if (TYPE_CODE(pointed_to_type) != TYPE_CODE_CLASS)
+ return NULL;
+ class_name = TYPE_NAME(pointed_to_type);
+ if (class_name == NULL)
+ return NULL; /* paranoia */
+
+ /* The class name may be of the form "class c", in which case
+ * we want to strip off the leading "class ".
+ */
+ if (strncmp(class_name, "class ", 6) == 0)
+ class_name += 6;
+
+ return class_name;
+}
+
+/* Internalize one native debug symbol.
+ * Called in a loop from hpread_expand_symtab().
+ * Arguments:
+ * dn_bufp:
+ * name:
+ * section_offsets:
+ * objfile:
+ * text_offset:
+ * text_size:
+ * filename:
+ * index: Index of this symbol
+ * at_module_boundary_p Pointer to boolean flag to control caller's loop.
+ */
+
+static void
+hpread_process_one_debug_symbol (dn_bufp, name, section_offsets, objfile,
+ text_offset, text_size, filename,
+ index, at_module_boundary_p
+ )
+ union dnttentry *dn_bufp;
+ char *name;
+ struct section_offsets *section_offsets;
+ struct objfile *objfile;
+ CORE_ADDR text_offset;
+ int text_size;
+ char *filename;
+ int index;
+ int *at_module_boundary_p;
+{
+ unsigned long desc;
+ int type;
+ CORE_ADDR valu;
+ int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA);
+ union dnttentry *dn_temp;
+ dnttpointer hp_type;
+ struct symbol *sym;
+ struct context_stack *new;
+ char * class_scope_name;
+ extern int is_in_import_list (); /* in somread.c */
+
+ /* Allocate one GDB debug symbol and fill in some default values. */
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->symbol_obstack);
+ SYMBOL_LANGUAGE (sym) = language_auto;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_LINE (sym) = 0;
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+
+ /* Just a trick in case the SOM debug symbol is a type definition.
+ * There are routines that are set up to build a GDB type symbol, given
+ * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type".
+ * This allows us to call those same routines.
+ */
+ hp_type.dnttp.extension = 1;
+ hp_type.dnttp.immediate = 0;
+ hp_type.dnttp.global = 0;
+ hp_type.dnttp.index = index;
+
+ /* This "type" is the type of SOM record.
+ * Switch on SOM type.
+ */
+ type = dn_bufp->dblock.kind;
+ switch (type)
+ {
+ case DNTT_TYPE_SRCFILE:
+ /* This type of symbol indicates from which source file or
+ * include file any following data comes. It may indicate:
+ *
+ * o The start of an entirely new source file (and thus
+ * a new module)
+ *
+ * o The start of a different source file due to #include
+ *
+ * o The end of an include file and the return to the original
+ * file. Thus if "foo.c" includes "bar.h", we see first
+ * a SRCFILE for foo.c, then one for bar.h, and then one for
+ * foo.c again.
+ *
+ * If it indicates the start of a new module then we must
+ * finish the symbol table of the previous module
+ * (if any) and start accumulating a new symbol table.
+ */
+
+ valu = text_offset;
+ if (!last_source_file ) {
+ /*
+ * A note on "last_source_file": this is a char* pointing
+ * to the actual file name. "start_symtab" sets it,
+ * "end_symtab" clears it.
+ *
+ * So if "last_source_file" is NULL, then either this is
+ * the first record we are looking at, or a previous call
+ * to "end_symtab()" was made to close out the previous
+ * module. Since we're now quitting the scan loop when we
+ * see a MODULE END record, we should never get here, except
+ * in the case that we're not using the quick look-up tables
+ * and have to use the old system as a fall-back.
+ */
+ start_symtab (name, NULL, valu);
+ record_debugformat ("HP");
+ SL_INDEX (objfile) = dn_bufp->dsfile.address;
+ }
+
+ else {
+ /* Either a new include file, or a SRCFILE record
+ * saying we are back in the main source (or out of
+ * a nested include file) again.
+ */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dsfile.address,
+ objfile, offset);
+ }
+
+ /* A note on "start_subfile". This routine will check
+ * the name we pass it and look for an existing subfile
+ * of that name. There's thus only one sub-file for the
+ * actual source (e.g. for "foo.c" in foo.c), despite the
+ * fact that we'll see lots of SRCFILE entries for foo.c
+ * inside foo.c.
+ */
+ start_subfile (name, NULL);
+ break;
+
+ case DNTT_TYPE_MODULE:
+ /*
+ * We no longer ignore DNTT_TYPE_MODULE symbols. The module
+ * represents the meaningful semantic structure of a compilation
+ * unit. We expect to start the psymtab-to-symtab expansion
+ * looking at a MODULE entry, and to end it at the corresponding
+ * END MODULE entry.
+ *
+ *--Begin outdated comments
+ *
+ * This record signifies the start of a new source module
+ * In C/C++ there is no explicit "module" construct in the language,
+ * but each compilation unit is implicitly a module and they
+ * do emit the DNTT_TYPE_MODULE records.
+ * The end of the module is marked by a matching DNTT_TYPE_END record.
+ *
+ * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record
+ * is it notices the DNTT_TYPE_END record for the previous
+ * module (see comments under DNTT_TYPE_END case), and then treats
+ * the next DNTT_TYPE_SRCFILE record as if it were the module-start record.
+ * (i.e., it makes a start_symtab() call).
+ * This scheme seems a little convoluted, but I'll leave it
+ * alone on the principle "if it ain't broke don't fix
+ * it". (RT).
+ *
+ *-- End outdated comments
+ */
+
+ valu = text_offset;
+ if (!last_source_file )
+ {
+ /* Start of a new module. We know this because "last_source_file"
+ * is NULL, which can only happen the first time or if we just
+ * made a call to end_symtab() to close out the previous module.
+ */
+ start_symtab (name, NULL, valu);
+ SL_INDEX (objfile) = dn_bufp->dmodule.address;
+ }
+ else
+ {
+ /* This really shouldn't happen if we're using the quick
+ * look-up tables, as it would mean we'd scanned past an
+ * END MODULE entry. But if we're not using the tables,
+ * we started the module on the SRCFILE entry, so it's ok.
+ * For now, accept this.
+ */
+ /* warning( "Error expanding psymtab, missed module end, found entry for %s",
+ * name );
+ */
+ *at_module_boundary_p = -1;
+ }
+
+ start_subfile (name, NULL);
+ break;
+
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_ENTRY:
+ /* A function or secondary entry point. */
+ valu = dn_bufp->dfunc.lowaddr + offset;
+
+ /* Record lines up to this point. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dfunc.address,
+ objfile, offset);
+
+ WITHIN_FUNCTION (objfile) = 1;
+ CURRENT_FUNCTION_VALUE (objfile) = valu;
+
+ /* Stack must be empty now. */
+ if (context_stack_depth != 0)
+ complain (&lbrac_unmatched_complaint, (char *) symnum);
+ new = push_context (0, valu);
+
+ /* Built a type for the function. This includes processing
+ * the symbol records for the function parameters.
+ */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1);
+
+ /* The "SYMBOL_NAME" field is expected to be the mangled name
+ * (if any), which we get from the "alias" field of the SOM record
+ * if that exists.
+ */
+ if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+ dn_bufp->dfunc.alias && /* has an alias */
+ *(char *)(VT (objfile) + dn_bufp->dfunc.alias)) /* not a null string */
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias;
+ else
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+ /* Special hack to get around HP compilers' insistence on
+ * reporting "main" as "_MAIN_" for C/C++ */
+ if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+ (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0))
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+ /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to
+ * be the demangled name.
+ */
+ if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
+ {
+ /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+ * calling the demangler in libiberty (cplus_demangle()) to
+ * do the job. This generally does the job, even though
+ * it's intended for the GNU compiler and not the aCC compiler
+ * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+ * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+ * Generally, we don't want params when we display
+ * a demangled name, but when I took out the DMGL_PARAMS,
+ * some things broke, so I'm leaving it in here, and
+ * working around the issue in stack.c. - RT
+ */
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) &&
+ (!SYMBOL_CPLUS_DEMANGLED_NAME(sym))) {
+
+ /* Well, the symbol name is mangled, but the
+ * demangler in libiberty failed so the demangled
+ * field is still NULL. Try to
+ * do the job ourselves based on the "name" field
+ * in the SOM record. A complication here is that
+ * the name field contains only the function name
+ * (like "f"), whereas we want the class qualification
+ * (as in "c::f"). Try to reconstruct that.
+ */
+ char * basename;
+ char * classname;
+ char * dem_name;
+ basename = VT (objfile) + dn_bufp->dfunc.name;
+ classname = class_of(SYMBOL_TYPE(sym));
+ if (classname) {
+ dem_name = xmalloc(strlen(basename)+strlen(classname)+3);
+ strcpy(dem_name, classname);
+ strcat(dem_name, "::");
+ strcat(dem_name, basename);
+ SYMBOL_CPLUS_DEMANGLED_NAME(sym) = dem_name;
+ SYMBOL_LANGUAGE (sym) = language_cplus;
+ }
+ }
+ }
+
+ /* Add the function symbol to the list of symbols in this blockvector */
+ if (dn_bufp->dfunc.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ new->name = sym;
+
+ /* Search forward to the next BEGIN and also read
+ * in the line info up to that point.
+ * Not sure why this is needed.
+ * In HP FORTRAN this code is harmful since there
+ * may not be a BEGIN after the FUNCTION.
+ * So I made it C/C++ specific. - RT
+ */
+ if (dn_bufp->dfunc.language == HP_LANGUAGE_C ||
+ dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) {
+ while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+ {
+ dn_bufp = hpread_get_lntt (++index, objfile);
+ if (dn_bufp->dblock.extension)
+ continue;
+ }
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dbegin.address,
+ objfile, offset);
+ SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+ }
+ record_line (current_subfile, SYMBOL_LINE (sym), valu);
+ break;
+
+ case DNTT_TYPE_DOC_FUNCTION:
+ valu = dn_bufp->ddocfunc.lowaddr + offset;
+
+ /* Record lines up to this point. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->ddocfunc.address,
+ objfile, offset);
+
+ WITHIN_FUNCTION (objfile) = 1;
+ CURRENT_FUNCTION_VALUE (objfile) = valu;
+ /* Stack must be empty now. */
+ if (context_stack_depth != 0)
+ complain (&lbrac_unmatched_complaint, (char *) symnum);
+ new = push_context (0, valu);
+
+ /* Built a type for the function. This includes processing
+ * the symbol records for the function parameters.
+ */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1);
+
+ /* The "SYMBOL_NAME" field is expected to be the mangled name
+ * (if any), which we get from the "alias" field of the SOM record
+ * if that exists.
+ */
+ if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+ dn_bufp->ddocfunc.alias && /* has an alias */
+ *(char *)(VT (objfile) + dn_bufp->ddocfunc.alias)) /* not a null string */
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias;
+ else
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+ /* Special hack to get around HP compilers' insistence on
+ * reporting "main" as "_MAIN_" for C/C++ */
+ if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+ (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0))
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+ if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) {
+
+ /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+ * calling the demangler in libiberty (cplus_demangle()) to
+ * do the job. This generally does the job, even though
+ * it's intended for the GNU compiler and not the aCC compiler
+ * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+ * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+ * Generally, we don't want params when we display
+ * a demangled name, but when I took out the DMGL_PARAMS,
+ * some things broke, so I'm leaving it in here, and
+ * working around the issue in stack.c. - RT
+ */
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+
+ if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) &&
+ (!SYMBOL_CPLUS_DEMANGLED_NAME(sym))) {
+
+ /* Well, the symbol name is mangled, but the
+ * demangler in libiberty failed so the demangled
+ * field is still NULL. Try to
+ * do the job ourselves based on the "name" field
+ * in the SOM record. A complication here is that
+ * the name field contains only the function name
+ * (like "f"), whereas we want the class qualification
+ * (as in "c::f"). Try to reconstruct that.
+ */
+ char * basename;
+ char * classname;
+ char * dem_name;
+ basename = VT (objfile) + dn_bufp->ddocfunc.name;
+ classname = class_of(SYMBOL_TYPE(sym));
+ if (classname) {
+ dem_name = xmalloc(strlen(basename)+strlen(classname)+3);
+ strcpy(dem_name, classname);
+ strcat(dem_name, "::");
+ strcat(dem_name, basename);
+ SYMBOL_CPLUS_DEMANGLED_NAME(sym) = dem_name;
+ SYMBOL_LANGUAGE (sym) = language_cplus;
+ }
+ }
+ }
+
+ /* Add the function symbol to the list of symbols in this blockvector */
+ if (dn_bufp->ddocfunc.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ new->name = sym;
+
+ /* Search forward to the next BEGIN and also read
+ * in the line info up to that point.
+ * Not sure why this is needed.
+ * In HP FORTRAN this code is harmful since there
+ * may not be a BEGIN after the FUNCTION.
+ * So I made it C/C++ specific. - RT
+ */
+ if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C ||
+ dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) {
+ while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+ {
+ dn_bufp = hpread_get_lntt (++index, objfile);
+ if (dn_bufp->dblock.extension)
+ continue;
+ }
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dbegin.address,
+ objfile, offset);
+ SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+ }
+ record_line (current_subfile, SYMBOL_LINE (sym), valu);
+ break;
+
+ case DNTT_TYPE_BEGIN:
+ /* Begin a new scope. */
+ if (context_stack_depth == 1 /* this means we're at function level */ &&
+ context_stack[0].name != NULL /* this means it's a function */ &&
+ context_stack[0].depth == 0 /* this means it's the first BEGIN
+ we've seen after the FUNCTION */
+ )
+ {
+ /* This is the first BEGIN after a FUNCTION.
+ * We ignore this one, since HP compilers always insert
+ * at least one BEGIN, i.e. it's:
+ *
+ * FUNCTION
+ * argument symbols
+ * BEGIN
+ * local symbols
+ * (possibly nested BEGIN ... END's if there are inner { } blocks)
+ * END
+ * END
+ *
+ * By ignoring this first BEGIN, the local symbols get treated
+ * as belonging to the function scope, and "print func::local_sym"
+ * works (which is what we want).
+ */
+
+ /* All we do here is increase the depth count associated with
+ * the FUNCTION entry in the context stack. This ensures that
+ * the next BEGIN we see (if any), representing a real nested { }
+ * block, will get processed.
+ */
+
+ context_stack[0].depth++;
+
+ } else {
+
+ /* Record lines up to this SLT pointer. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dbegin.address,
+ objfile, offset);
+ /* Calculate start address of new scope */
+ valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
+ valu += offset; /* Relocate for dynamic loading */
+ /* We use the scope start DNTT index as nesting depth identifier! */
+ desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile);
+ new = push_context (desc, valu);
+ }
+ break;
+
+ case DNTT_TYPE_END:
+ /* End a scope. */
+
+ /* Valid end kinds are:
+ * MODULE
+ * FUNCTION
+ * WITH
+ * COMMON
+ * BEGIN
+ * CLASS_SCOPE
+ */
+
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dend.address,
+ objfile, offset);
+ switch (dn_bufp->dend.endkind)
+ {
+ case DNTT_TYPE_MODULE:
+ /* Ending a module ends the symbol table for that module.
+ * Calling end_symtab() has the side effect of clearing the
+ * last_source_file pointer, which in turn signals
+ * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE
+ * record as a module-begin.
+ */
+ valu = text_offset + text_size + offset;
+
+ /* Tell our caller that we're done with expanding the
+ * debug information for a module.
+ */
+ *at_module_boundary_p = 1;
+
+ /* Don't do this, as our caller will do it!
+ *
+ * (void) end_symtab (valu, objfile, 0);
+ */
+ break;
+
+ case DNTT_TYPE_FUNCTION:
+ /* Ending a function, well, ends the function's scope. */
+ dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
+ objfile);
+ valu = dn_temp->dfunc.hiaddr + offset;
+ /* Insert func params into local list */
+ merge_symbol_lists (&param_symbols, &local_symbols);
+ new = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ WITHIN_FUNCTION (objfile) = 0; /* This may have to change for Pascal */
+ local_symbols = new->locals;
+ param_symbols = new->params;
+ break;
+
+ case DNTT_TYPE_BEGIN:
+ if (context_stack_depth == 1 &&
+ context_stack[0].name != NULL &&
+ context_stack[0].depth == 1)
+ {
+ /* This is the END corresponding to the
+ * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above.
+ */
+ context_stack[0].depth--;
+ } else {
+ /* Ending a local scope. */
+ valu = hpread_get_location (dn_bufp->dend.address, objfile);
+ /* Why in the hell is this needed? */
+ valu += offset + 9; /* Relocate for dynamic loading */
+ new = pop_context ();
+ desc = dn_bufp->dend.beginscope.dnttp.index;
+ if (desc != new->depth)
+ complain (&lbrac_mismatch_complaint, (char *) symnum);
+
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ local_symbols = new->locals;
+ param_symbols = new->params;
+ }
+ break;
+
+ case DNTT_TYPE_WITH:
+ /* Since we ignore the DNTT_TYPE_WITH that starts the scope,
+ * we can ignore the DNTT_TYPE_END that ends it.
+ */
+ break;
+
+ case DNTT_TYPE_COMMON:
+ /* End a FORTRAN common block. We don't currently handle these */
+ complain (&hpread_unhandled_end_common_complaint);
+ break;
+
+ case DNTT_TYPE_CLASS_SCOPE:
+
+ /* pai: FIXME Not handling nested classes for now -- must
+ * maintain a stack */
+ class_scope_name = NULL;
+
+#if 0
+ /* End a class scope */
+ valu = hpread_get_location (dn_bufp->dend.address, objfile);
+ /* Why in the hell is this needed? */
+ valu += offset + 9; /* Relocate for dynamic loading */
+ new = pop_context ();
+ desc = dn_bufp->dend.beginscope.dnttp.index;
+ if (desc != new->depth)
+ complain (&lbrac_mismatch_complaint, (char *) symnum);
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ local_symbols = new->locals;
+ param_symbols = new->params;
+#endif
+ break;
+
+ default:
+ complain (&hpread_unexpected_end_complaint);
+ break;
+ }
+ break;
+
+ /* DNTT_TYPE_IMPORT is not handled */
+
+ case DNTT_TYPE_LABEL:
+ SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
+ break;
+
+ case DNTT_TYPE_FPARAM:
+ /* Function parameters. */
+ /* Note 1: This code was present in the 4.16 sources, and then
+ removed, because fparams are handled in
+ hpread_read_function_type(). However, while fparam symbols
+ are indeed handled twice, this code here cannot be removed
+ because then they don't get added to the local symbol list of
+ the function's code block, which leads to a failure to look
+ up locals, "this"-relative member names, etc. So I've put
+ this code back in. pai/1997-07-21 */
+ /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols
+ in hpread_read_function_type(), so FPARAMS had to be handled
+ here. I changed the location to be the appropriate argument
+ kinds rather than LOC_LOCAL. pai/1997-08-08 */
+ /* Note 3: Well, the fix in Note 2 above broke argument printing
+ in traceback frames, and further it makes assumptions about the
+ order of the FPARAM entries from HP compilers (cc and aCC in particular
+ generate them in reverse orders -- fixing one breaks for the other).
+ So I've added code in hpread_read_function_type() to add fparams
+ to a param_symbols list for the current context level. These are
+ then merged into local_symbols when a function end is reached.
+ pai/1997-08-11 */
+
+ break; /* do nothing; handled in hpread_read_function_type() */
+
+#if 0 /* Old code */
+ if (dn_bufp->dfparam.regparam)
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ else if (dn_bufp->dfparam.indirect)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ else
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (dn_bufp->dfparam.copyparam)
+ {
+ SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ }
+ else
+ SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
+ add_symbol_to_list (sym, &fparam_symbols);
+ break;
+#endif
+
+ case DNTT_TYPE_SVAR:
+ /* Static variables. */
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+
+ /* Note: There is a case that arises with globals in shared
+ * libraries where we need to set the address to LOC_INDIRECT.
+ * This case is if you have a global "g" in one library, and
+ * it is referenced "extern <type> g;" in another library.
+ * If we're processing the symbols for the referencing library,
+ * we'll see a global "g", but in this case the address given
+ * in the symbol table contains a pointer to the real "g".
+ * We use the storage class LOC_INDIRECT to indicate this. RT
+ */
+ if (is_in_import_list (SYMBOL_NAME(sym), objfile))
+ SYMBOL_CLASS (sym) = LOC_INDIRECT;
+
+ SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
+
+ if (dn_bufp->dsvar.global)
+ add_symbol_to_list (sym, &global_symbols);
+
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+
+ else
+ add_symbol_to_list (sym, &file_symbols);
+
+ if (dn_bufp->dsvar.thread_specific)
+ {
+ /* Thread-local variable.
+ */
+ SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+ SYMBOL_BASEREG (sym) = CR27_REGNUM;
+
+ if( objfile->flags & OBJF_SHARED ) {
+ /*
+ * This variable is not only thread local but
+ * in a shared library.
+ *
+ * Alas, the shared lib structures are private
+ * to "somsolib.c". But C lets us point to one.
+ */
+ struct so_list *so;
+
+ if( objfile->obj_private == NULL )
+ error( "Internal error in reading shared library information." );
+
+ so = ((obj_private_data_t *)(objfile->obj_private))->so_info;
+ if( so == NULL )
+ error( "Internal error in reading shared library information." );
+
+ /* Thread-locals in shared libraries do NOT have the
+ * standard offset ("data_offset"), so we re-calculate
+ * where to look for this variable, using a call-back
+ * to interpret the private shared-library data.
+ */
+ SYMBOL_VALUE_ADDRESS(sym) = dn_bufp->dsvar.location +
+ so_lib_thread_start_addr( so );
+ }
+ }
+ break;
+
+ case DNTT_TYPE_DVAR:
+ /* Dynamic variables. */
+ if (dn_bufp->ddvar.regvar)
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ else
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+
+ SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile);
+ if (dn_bufp->ddvar.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case DNTT_TYPE_CONST:
+ /* A constant (pascal?). */
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_VALUE (sym) = dn_bufp->dconst.location;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile);
+ if (dn_bufp->dconst.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case DNTT_TYPE_TYPEDEF:
+ /* A typedef. We do want to process these, since a name is
+ * added to the namespace for the typedef'ed name.
+ */
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+ if (dn_bufp->dtype.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case DNTT_TYPE_TAGDEF:
+ {
+ int global = dn_bufp->dtag.global;
+ /* Structure, union, enum, template, or class tag definition */
+ /* We do want to process these, since a name is
+ * added to the namespace for the tag name (and if C++ class,
+ * for the typename also).
+ */
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+
+ /* The tag contains in its "type" field a pointer to the
+ * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM,
+ * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE
+ * record that actually defines the type.
+ */
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+ TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
+ TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
+ if (dn_bufp->dtag.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+
+ /* If this is a C++ class, then we additionally
+ * need to define a typedef for the
+ * class type. E.g., so that the name "c" becomes visible as
+ * a type name when the user says "class c { ... }".
+ * In order to figure this out, we need to chase down the "type"
+ * field to get to the DNTT_TYPE_CLASS record.
+ *
+ * We also add the typename for ENUM. Though this isn't
+ * strictly correct, it is necessary because of the debug info
+ * generated by the aCC compiler, in which we cannot
+ * distinguish between:
+ * enum e { ... };
+ * and
+ * typedef enum { ... } e;
+ * I.e., the compiler emits the same debug info for the above
+ * two cases, in both cases "e" appearing as a tagdef.
+ * Therefore go ahead and generate the typename so that
+ * "ptype e" will work in the above cases.
+ *
+ * We also add the typename for TEMPLATE, so as to allow "ptype t"
+ * when "t" is a template name.
+ */
+ if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile);
+ else {
+ complain (&hpread_tagdef_complaint);
+ return;
+ }
+ if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+ dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+ dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE) {
+ struct symbol *newsym;
+
+ newsym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (newsym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (newsym) = name;
+ SYMBOL_LANGUAGE (newsym) = language_auto;
+ SYMBOL_NAMESPACE (newsym) = VAR_NAMESPACE;
+ SYMBOL_LINE (newsym) = 0;
+ SYMBOL_VALUE (newsym) = 0;
+ SYMBOL_CLASS (newsym) = LOC_TYPEDEF;
+ SYMBOL_TYPE (newsym) = sym->type;
+ if (global)
+ add_symbol_to_list (newsym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (newsym, &local_symbols);
+ else
+ add_symbol_to_list (newsym, &file_symbols);
+ }
+ }
+ break;
+
+ case DNTT_TYPE_POINTER:
+ /* Declares a pointer type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_ENUM:
+ /* Declares an enum type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_MEMENUM:
+ /* Member of enum */
+ /* Ignored at this level, but hpread_read_enum_type() will take
+ * care of walking the list of enumeration members.
+ */
+ break;
+
+ case DNTT_TYPE_SET:
+ /* Declares a set type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_SUBRANGE:
+ /* Declares a subrange type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_ARRAY:
+ /* Declares an array type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_STRUCT:
+ case DNTT_TYPE_UNION:
+ /* Declares an struct/union type.
+ * Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_FIELD:
+ /* Structure/union/class field */
+ /* Ignored at this level, but hpread_read_struct_type() will take
+ * care of walking the list of structure/union/class members.
+ */
+ break;
+
+ /* DNTT_TYPE_VARIANT is not handled by GDB */
+
+ /* DNTT_TYPE_FILE is not handled by GDB */
+
+ case DNTT_TYPE_FUNCTYPE:
+ /* Function type */
+ /* Ignored at this level, handled within hpread_type_lookup() */
+ break;
+
+ case DNTT_TYPE_WITH:
+ /* This is emitted within methods to indicate "with <class>"
+ * scoping rules (i.e., indicate that the class data members
+ * are directly visible).
+ * However, since GDB already infers this by looking at the
+ * "this" argument, interpreting the DNTT_TYPE_WITH
+ * symbol record is unnecessary.
+ */
+ break;
+
+ case DNTT_TYPE_COMMON:
+ /* FORTRAN common. Not yet handled. */
+ complain (&hpread_unhandled_common_complaint);
+ break;
+
+ /* DNTT_TYPE_COBSTRUCT is not handled by GDB. */
+ /* DNTT_TYPE_XREF is not handled by GDB. */
+ /* DNTT_TYPE_SA is not handled by GDB. */
+ /* DNTT_TYPE_MACRO is not handled by GDB */
+
+ case DNTT_TYPE_BLOCKDATA:
+ /* Not sure what this is - part of FORTRAN support maybe?
+ * Anyway, not yet handled.
+ */
+ complain (&hpread_unhandled_blockdata_complaint);
+ break;
+
+ case DNTT_TYPE_CLASS_SCOPE:
+
+
+
+ /* The compiler brackets member functions with a CLASS_SCOPE/END
+ * pair of records, presumably to put them in a different scope
+ * from the module scope where they are normally defined.
+ * E.g., in the situation:
+ * void f() { ... }
+ * void c::f() { ...}
+ * The member function "c::f" will be bracketed by a CLASS_SCOPE/END.
+ * This causes "break f" at the module level to pick the
+ * the file-level function f(), not the member function
+ * (which needs to be referenced via "break c::f").
+ *
+ * Here we record the class name to generate the demangled names of
+ * member functions later.
+ *
+ * FIXME Not being used now for anything -- cplus_demangle seems
+ * enough for getting the class-qualified names of functions. We
+ * may need this for handling nested classes and types. */
+
+ /* pai: FIXME Not handling nested classes for now -- need to
+ * maintain a stack */
+
+ dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile);
+ if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF)
+ class_scope_name = VT (objfile) + dn_temp->dtag.name;
+ else
+ class_scope_name = NULL;
+
+#if 0
+
+ /* Begin a new scope. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dclass_scope.address,
+ objfile, offset);
+ valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile);
+ valu += offset; /* Relocate for dynamic loading */
+ desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile);
+ /* We use the scope start DNTT index as the nesting depth identifier! */
+ new = push_context (desc, valu);
+#endif
+ break;
+
+ case DNTT_TYPE_REFERENCE:
+ /* Declares a C++ reference type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_PTRMEM:
+ /* Declares a C++ pointer-to-data-member type. This does not
+ * need to be handled at this level; being a type description it
+ * is instead handled at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_PTRMEMFUNC:
+ /* Declares a C++ pointer-to-function-member type. This does not
+ * need to be handled at this level; being a type description it
+ * is instead handled at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_CLASS:
+ /* Declares a class type.
+ * Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_GENFIELD:
+ /* I believe this is used for class member functions */
+ /* Ignored at this level, but hpread_read_struct_type() will take
+ * care of walking the list of class members.
+ */
+ break;
+
+ case DNTT_TYPE_VFUNC:
+ /* Virtual function */
+ /* This does not have to be handled at this level; handled in
+ * the course of processing class symbols.
+ */
+ break;
+
+ case DNTT_TYPE_MEMACCESS:
+ /* DDE ignores this symbol table record.
+ * It has something to do with "modified access" to class members.
+ * I'll assume we can safely ignore it too.
+ */
+ break;
+
+ case DNTT_TYPE_INHERITANCE:
+ /* These don't have to be handled here, since they are handled
+ * within hpread_read_struct_type() in the process of constructing
+ * a class type.
+ */
+ break;
+
+ case DNTT_TYPE_FRIEND_CLASS:
+ case DNTT_TYPE_FRIEND_FUNC:
+ /* These can safely be ignored, as GDB doesn't need this
+ * info. DDE only uses it in "describe". We may later want
+ * to extend GDB's "ptype" to give this info, but for now
+ * it seems safe enough to ignore it.
+ */
+ break;
+
+ case DNTT_TYPE_MODIFIER:
+ /* Intended to supply "modified access" to a type */
+ /* From the way DDE handles this, it looks like it always
+ * modifies a type. Therefore it is safe to ignore it at this
+ * level, and handle it in hpread_type_lookup().
+ */
+ break;
+
+ case DNTT_TYPE_OBJECT_ID:
+ /* Just ignore this - that's all DDE does */
+ break;
+
+ case DNTT_TYPE_MEMFUNC:
+ /* Member function */
+ /* This does not have to be handled at this level; handled in
+ * the course of processing class symbols.
+ */
+ break;
+
+ case DNTT_TYPE_DOC_MEMFUNC:
+ /* Member function */
+ /* This does not have to be handled at this level; handled in
+ * the course of processing class symbols.
+ */
+ break;
+
+ case DNTT_TYPE_TEMPLATE:
+ /* Template - sort of the header for a template definition,
+ * which like a class, points to a member list and also points
+ * to a TEMPLATE_ARG list of type-arguments.
+ * We do not need to process TEMPLATE records at this level though.
+ */
+ break;
+
+ case DNTT_TYPE_TEMPLATE_ARG:
+ /* The TEMPLATE record points to an argument list of
+ * TEMPLATE_ARG records, each of which describes one
+ * of the type-arguments.
+ * We do not need to process TEMPLATE_ARG records at this level though.
+ */
+ break;
+
+ case DNTT_TYPE_FUNC_TEMPLATE:
+ /* This will get emitted for member functions of templates.
+ * But we don't need to process this record at this level though,
+ * we will process it in the course of processing a TEMPLATE
+ * record.
+ */
+ break;
+
+ case DNTT_TYPE_LINK:
+ /* The LINK record is used to link up templates with instantiations. */
+ /* It is not clear why this is needed, and furthermore aCC does
+ * not appear to generate this, so I think we can safely ignore it. - RT
+ */
+ break;
+
+ /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */
+ /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */
+ /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */
+ /* DNTT_TYPE_INLN is not handled by GDB */
+ /* DNTT_TYPE_INLN_LIST is not handled by GDB */
+ /* DNTT_TYPE_ALIAS is not handled by GDB */
+
+ default:
+ break;
+ }
+}
+
+/* Get nesting depth for a DNTT entry.
+ * DN_BUFP points to a DNTT entry.
+ * OBJFILE is the object file.
+ * REPORT_NESTED is a flag; if 0, real nesting depth is
+ * reported, if it is 1, the function simply returns a
+ * non-zero value if the nesting depth is anything > 0.
+ *
+ * Return value is an integer. 0 => not a local type / name
+ * positive return => type or name is local to some
+ * block or function.
+ */
+
+
+/* elz: ATTENTION: FIXME: NOTE: WARNING!!!!
+ this function now returns 0 right away. It was taking too much time
+ at start up. Now, though, the local types are not handled correctly.
+*/
+
+
+static int
+hpread_get_scope_depth (dn_bufp, objfile, report_nested)
+ union dnttentry * dn_bufp;
+ struct objfile * objfile;
+ int report_nested;
+{
+ register int index;
+ register union dnttentry * dn_tmp;
+ register short depth = 0;
+/****************************/
+ return 0;
+/****************************/
+
+ index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block));
+
+ while (--index >= 0)
+ {
+ dn_tmp = hpread_get_lntt (index, objfile);
+ switch (dn_tmp->dblock.kind)
+ {
+ case DNTT_TYPE_MODULE:
+ return depth;
+ case DNTT_TYPE_END:
+ /* index is signed int; dnttp.index is 29-bit unsigned int! */
+ index = (int) dn_tmp->dend.beginscope.dnttp.index;
+ break;
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_DOC_FUNCTION:
+ case DNTT_TYPE_WITH:
+ case DNTT_TYPE_COMMON:
+ case DNTT_TYPE_CLASS_SCOPE:
+ depth++;
+ if (report_nested)
+ return 1;
+ break;
+ default:
+ break;
+ }
+ }
+ return depth;
+}
+
+/* Adjust the bitoffsets for all fields of an anonymous union of
+ type TYPE by negative BITS. This handles HP aCC's hideous habit
+ of giving members of anonymous unions bit offsets relative to the
+ enclosing structure instead of relative to the union itself. */
+
+static void
+hpread_adjust_bitoffsets (type, bits)
+ struct type * type;
+ int bits;
+{
+ register int i;
+
+ /* This is done only for unions; caller had better check that
+ it is an anonymous one. */
+ if (TYPE_CODE (type) != TYPE_CODE_UNION)
+ return;
+
+ /* Adjust each field; since this is a union, there are no base
+ classes. Also no static membes. Also, no need for recursion as
+ the members of this union if themeselves structs or unions, have
+ the correct bitoffsets; if an anonymous union is a member of this
+ anonymous union, the code in hpread_read_struct_type() will
+ adjust for that. */
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ TYPE_FIELD_BITPOS (type, i) -= bits;
+}
+
+/* Because of quirks in HP compilers' treatment of anonymous unions inside
+ classes, we have to chase through a chain of threaded FIELD entries.
+ If we encounter an anonymous union in the chain, we must recursively skip over
+ that too.
+
+ This function does a "next" in the chain of FIELD entries, but transparently
+ skips over anonymous unions' fields (recursively).
+
+ Inputs are the number of times to do "next" at the top level, the dnttpointer
+ (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it,
+ and the ubiquitous objfile parameter. (Note: FIELDP is a **.) Return value
+ is a dnttpointer for the new field after all the skipped ones */
+
+static dnttpointer
+hpread_get_next_skip_over_anon_unions (skip_fields, field, fieldp, objfile)
+ int skip_fields;
+ dnttpointer field;
+ union dnttentry ** fieldp;
+ struct objfile * objfile;
+{
+ struct type * anon_type;
+ register int i;
+ int bitoffset;
+ char * name;
+
+ for (i=0; i < skip_fields; i++)
+ {
+ /* Get type of item we're looking at now; recursively processes the types
+ of these intermediate items we skip over, so they aren't lost. */
+ anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile);
+ anon_type = CHECK_TYPEDEF (anon_type);
+ bitoffset = (*fieldp)->dfield.bitoffset;
+ name = VT (objfile) + (*fieldp)->dfield.name;
+ /* First skip over one item to avoid stack death on recursion */
+ field = (*fieldp)->dfield.nextfield;
+ *fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+ /* Do we have another anonymous union? If so, adjust the bitoffsets
+ of its members and skip over its members. */
+ if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) &&
+ (!name || STREQ (name, "")))
+ {
+ hpread_adjust_bitoffsets (anon_type, bitoffset);
+ field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile);
+ }
+ }
+ return field;
+}
+
+
diff --git a/contrib/gdb/gdb/hpread.h b/contrib/gdb/gdb/hpread.h
new file mode 100644
index 0000000..7864dd6
--- /dev/null
+++ b/contrib/gdb/gdb/hpread.h
@@ -0,0 +1,150 @@
+/* hpread.h
+ * Common include file for:
+ * hp_symtab_read.c
+ * hp_psymtab_read.c
+ */
+
+/* Copyright 1993, 1996 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support. */
+
+#include "defs.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "hp-symtab.h"
+#include "syms.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "complaints.h"
+#include "gdb-stabs.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+
+/* Private information attached to an objfile which we use to find
+ and internalize the HP C debug symbols within that objfile. */
+
+struct hpread_symfile_info
+{
+ /* The contents of each of the debug sections (there are 4 of them). */
+ char *gntt;
+ char *lntt;
+ char *slt;
+ char *vt;
+
+ /* We keep the size of the $VT$ section for range checking. */
+ unsigned int vt_size;
+
+ /* Some routines still need to know the number of symbols in the
+ main debug sections ($LNTT$ and $GNTT$). */
+ unsigned int lntt_symcount;
+ unsigned int gntt_symcount;
+
+ /* To keep track of all the types we've processed. */
+ struct type **type_vector;
+ int type_vector_length;
+
+ /* Keeps track of the beginning of a range of source lines. */
+ sltpointer sl_index;
+
+ /* Some state variables we'll need. */
+ int within_function;
+
+ /* Keep track of the current function's address. We may need to look
+ up something based on this address. */
+ unsigned int current_function_value;
+};
+
+/* Accessor macros to get at the fields. */
+#define HPUX_SYMFILE_INFO(o) \
+ ((struct hpread_symfile_info *)((o)->sym_private))
+#define GNTT(o) (HPUX_SYMFILE_INFO(o)->gntt)
+#define LNTT(o) (HPUX_SYMFILE_INFO(o)->lntt)
+#define SLT(o) (HPUX_SYMFILE_INFO(o)->slt)
+#define VT(o) (HPUX_SYMFILE_INFO(o)->vt)
+#define VT_SIZE(o) (HPUX_SYMFILE_INFO(o)->vt_size)
+#define LNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->lntt_symcount)
+#define GNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->gntt_symcount)
+#define TYPE_VECTOR(o) (HPUX_SYMFILE_INFO(o)->type_vector)
+#define TYPE_VECTOR_LENGTH(o) (HPUX_SYMFILE_INFO(o)->type_vector_length)
+#define SL_INDEX(o) (HPUX_SYMFILE_INFO(o)->sl_index)
+#define WITHIN_FUNCTION(o) (HPUX_SYMFILE_INFO(o)->within_function)
+#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
+
+/* Given the native debug symbol SYM, set NAMEP to the name associated
+ with the debug symbol. Note we may be called with a debug symbol which
+ has no associated name, in that case we return an empty string.
+
+ Also note we "know" that the name for any symbol is always in the
+ same place. Hence we don't have to conditionalize on the symbol type. */
+#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \
+ if (! hpread_has_name ((SYM)->dblock.kind)) \
+ *NAMEP = ""; \
+ else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \
+ { \
+ complain (&string_table_offset_complaint, (char *) symnum); \
+ *NAMEP = ""; \
+ } \
+ else \
+ *NAMEP = (SYM)->dsfile.name + VT (OBJFILE)
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
+
+struct symloc
+{
+ /* The offset within the file symbol table of first local symbol for
+ this file. */
+
+ int ldsymoff;
+
+ /* Length (in bytes) of the section of the symbol table devoted to
+ this file's symbols (actually, the section bracketed may contain
+ more than just this file's symbols). If ldsymlen is 0, the only
+ reason for this thing's existence is the dependency list.
+ Nothing else will happen when it is read in. */
+
+ int ldsymlen;
+};
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
+#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+
+/* FIXME: Shouldn't this stuff be in a .h file somewhere? */
+/* Nonzero means give verbose info on gdb action. */
+extern int info_verbose;
+
+/* Complaints about the symbols we have encountered. */
+extern struct complaint string_table_offset_complaint;
+extern struct complaint lbrac_unmatched_complaint;
+extern struct complaint lbrac_mismatch_complaint;
+
+extern union sltentry *hpread_get_slt
+ PARAMS ((int, struct objfile *));
+
+extern union dnttentry *hpread_get_lntt
+ PARAMS ((int, struct objfile *));
+
+int hpread_has_name
+ PARAMS ((enum dntt_entry_type));
+
+/* end of hpread.h */
diff --git a/contrib/gdb/gdb/hpux-thread.c b/contrib/gdb/gdb/hpux-thread.c
new file mode 100644
index 0000000..36421f3
--- /dev/null
+++ b/contrib/gdb/gdb/hpux-thread.c
@@ -0,0 +1,641 @@
+/* Low level interface for debugging HPUX/DCE threads for GDB, the GNU debugger.
+ Copyright 1996, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This module implements a sort of half target that sits between the
+ machine-independent parts of GDB and the ptrace interface (infptrace.c) to
+ provide access to the HPUX user-mode thread implementation.
+
+ HPUX threads are true user-mode threads, which are invoked via the cma_*
+ and pthread_* (DCE and Posix respectivly) interfaces. These are mostly
+ implemented in user-space, with all thread context kept in various
+ structures that live in the user's heap. For the most part, the kernel has
+ no knowlege of these threads.
+
+ */
+
+#include "defs.h"
+
+#define _CMA_NOWRAPPERS_
+
+#include <cma_tcb_defs.h>
+#include <cma_deb_core.h>
+#include "gdbthread.h"
+#include "target.h"
+#include "inferior.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "gdbcore.h"
+
+extern int child_suppress_run;
+extern struct target_ops child_ops; /* target vector for inftarg.c */
+
+extern void _initialize_hpux_thread PARAMS ((void));
+
+struct string_map
+{
+ int num;
+ char *str;
+};
+
+static int hpux_thread_active = 0;
+
+static int main_pid; /* Real process ID */
+
+static CORE_ADDR P_cma__g_known_threads;
+static CORE_ADDR P_cma__g_current_thread;
+
+static struct cleanup * save_inferior_pid PARAMS ((void));
+
+static void restore_inferior_pid PARAMS ((int pid));
+
+static void hpux_thread_resume PARAMS ((int pid, int step,
+ enum target_signal signo));
+
+static void init_hpux_thread_ops PARAMS ((void));
+
+static struct target_ops hpux_thread_ops;
+
+/*
+
+LOCAL FUNCTION
+
+ save_inferior_pid - Save inferior_pid on the cleanup list
+ restore_inferior_pid - Restore inferior_pid from the cleanup list
+
+SYNOPSIS
+
+ struct cleanup *save_inferior_pid ()
+ void restore_inferior_pid (int pid)
+
+DESCRIPTION
+
+ These two functions act in unison to restore inferior_pid in
+ case of an error.
+
+NOTES
+
+ inferior_pid is a global variable that needs to be changed by many of
+ these routines before calling functions in procfs.c. In order to
+ guarantee that inferior_pid gets restored (in case of errors), you
+ need to call save_inferior_pid before changing it. At the end of the
+ function, you should invoke do_cleanups to restore it.
+
+ */
+
+
+static struct cleanup *
+save_inferior_pid ()
+{
+ return make_cleanup (restore_inferior_pid, inferior_pid);
+}
+
+static void
+restore_inferior_pid (pid)
+ int pid;
+{
+ inferior_pid = pid;
+}
+
+static int find_active_thread PARAMS ((void));
+
+static int cached_thread;
+static int cached_active_thread;
+static cma__t_int_tcb cached_tcb;
+
+static int
+find_active_thread ()
+{
+ static cma__t_int_tcb tcb;
+ CORE_ADDR tcb_ptr;
+
+ if (cached_active_thread != 0)
+ return cached_active_thread;
+
+ read_memory ((CORE_ADDR)P_cma__g_current_thread,
+ (char *)&tcb_ptr,
+ sizeof tcb_ptr);
+
+ read_memory (tcb_ptr, (char *)&tcb, sizeof tcb);
+
+ return (cma_thread_get_unique (&tcb.prolog.client_thread) << 16) | main_pid;
+}
+
+static cma__t_int_tcb * find_tcb PARAMS ((int thread));
+
+static cma__t_int_tcb *
+find_tcb (thread)
+ int thread;
+{
+ cma__t_known_object queue_header;
+ cma__t_queue *queue_ptr;
+
+ if (thread == cached_thread)
+ return &cached_tcb;
+
+ read_memory ((CORE_ADDR)P_cma__g_known_threads,
+ (char *)&queue_header,
+ sizeof queue_header);
+
+ for (queue_ptr = queue_header.queue.flink;
+ queue_ptr != (cma__t_queue *)P_cma__g_known_threads;
+ queue_ptr = cached_tcb.threads.flink)
+ {
+ cma__t_int_tcb *tcb_ptr;
+
+ tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb);
+
+ read_memory ((CORE_ADDR)tcb_ptr, (char *)&cached_tcb, sizeof cached_tcb);
+
+ if (cached_tcb.header.type == cma__c_obj_tcb)
+ if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread >> 16)
+ {
+ cached_thread = thread;
+ return &cached_tcb;
+ }
+ }
+
+ error ("Can't find TCB %d,%d", thread >> 16, thread & 0xffff);
+ return NULL;
+}
+
+/* Most target vector functions from here on actually just pass through to
+ inftarg.c, as they don't need to do anything specific for threads. */
+
+/* ARGSUSED */
+static void
+hpux_thread_open (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ child_ops.to_open (arg, from_tty);
+}
+
+/* Attach to process PID, then initialize for debugging it
+ and wait for the trace-trap that results from attaching. */
+
+static void
+hpux_thread_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ child_ops.to_attach (args, from_tty);
+
+ /* XXX - might want to iterate over all the threads and register them. */
+}
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+hpux_thread_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ child_ops.to_detach (args, from_tty);
+}
+
+/* Resume execution of process PID. If STEP is nozero, then
+ just single step it. If SIGNAL is nonzero, restart it with that
+ signal activated. We may have to convert pid from a thread-id to an LWP id
+ for procfs. */
+
+static void
+hpux_thread_resume (pid, step, signo)
+ int pid;
+ int step;
+ enum target_signal signo;
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ pid = inferior_pid = main_pid;
+
+#if 0
+ if (pid != -1)
+ {
+ pid = thread_to_lwp (pid, -2);
+ if (pid == -2) /* Inactive thread */
+ error ("This version of Solaris can't start inactive threads.");
+ }
+#endif
+
+ child_ops.to_resume (pid, step, signo);
+
+ cached_thread = 0;
+ cached_active_thread = 0;
+
+ do_cleanups (old_chain);
+}
+
+/* Wait for any threads to stop. We may have to convert PID from a thread id
+ to a LWP id, and vice versa on the way out. */
+
+static int
+hpux_thread_wait (pid, ourstatus)
+ int pid;
+ struct target_waitstatus *ourstatus;
+{
+ int rtnval;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = main_pid;
+
+ if (pid != -1)
+ pid = main_pid;
+
+ rtnval = child_ops.to_wait (pid, ourstatus);
+
+ rtnval = find_active_thread ();
+
+ do_cleanups (old_chain);
+
+ return rtnval;
+}
+
+static char regmap[NUM_REGS] =
+{
+ -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
+ 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
+
+ /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
+ -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
+
+ /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+ /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
+ 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
+ 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
+ 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
+ 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
+};
+
+static void
+hpux_thread_fetch_registers (regno)
+ int regno;
+{
+ cma__t_int_tcb tcb, *tcb_ptr;
+ struct cleanup *old_chain;
+ int i;
+ int first_regno, last_regno;
+
+ tcb_ptr = find_tcb (inferior_pid);
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = main_pid;
+
+ if (tcb_ptr->state == cma__c_state_running)
+ {
+ child_ops.to_fetch_registers (regno);
+
+ do_cleanups (old_chain);
+
+ return;
+ }
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+ }
+
+ for (regno = first_regno; regno <= last_regno; regno++)
+ {
+ if (regmap[regno] == -1)
+ child_ops.to_fetch_registers (regno);
+ else
+ {
+ unsigned char buf[MAX_REGISTER_RAW_SIZE];
+ CORE_ADDR sp;
+
+ sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160;
+
+ if (regno == FLAGS_REGNUM)
+ /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
+ memset (buf, '\000', REGISTER_RAW_SIZE (regno));
+ else if (regno == SP_REGNUM)
+ store_address (buf, sizeof sp, sp);
+ else if (regno == PC_REGNUM)
+ read_memory (sp - 20, buf, REGISTER_RAW_SIZE (regno));
+ else
+ read_memory (sp + regmap[regno], buf, REGISTER_RAW_SIZE (regno));
+
+ supply_register (regno, buf);
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+static void
+hpux_thread_store_registers (regno)
+ int regno;
+{
+ cma__t_int_tcb tcb, *tcb_ptr;
+ struct cleanup *old_chain;
+ int i;
+ int first_regno, last_regno;
+
+ tcb_ptr = find_tcb (inferior_pid);
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = main_pid;
+
+ if (tcb_ptr->state == cma__c_state_running)
+ {
+ child_ops.to_store_registers (regno);
+
+ do_cleanups (old_chain);
+
+ return;
+ }
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+ }
+
+ for (regno = first_regno; regno <= last_regno; regno++)
+ {
+ if (regmap[regno] == -1)
+ child_ops.to_store_registers (regno);
+ else
+ {
+ unsigned char buf[MAX_REGISTER_RAW_SIZE];
+ CORE_ADDR sp;
+
+ sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160;
+
+ if (regno == FLAGS_REGNUM)
+ child_ops.to_store_registers (regno); /* Let lower layer handle this... */
+ else if (regno == SP_REGNUM)
+ {
+ write_memory ((CORE_ADDR)&tcb_ptr->static_ctx.sp,
+ registers + REGISTER_BYTE (regno),
+ REGISTER_RAW_SIZE (regno));
+ tcb_ptr->static_ctx.sp = (cma__t_hppa_regs *)
+ (extract_address (registers + REGISTER_BYTE (regno), REGISTER_RAW_SIZE (regno)) + 160);
+ }
+ else if (regno == PC_REGNUM)
+ write_memory (sp - 20,
+ registers + REGISTER_BYTE (regno),
+ REGISTER_RAW_SIZE (regno));
+ else
+ write_memory (sp + regmap[regno],
+ registers + REGISTER_BYTE (regno),
+ REGISTER_RAW_SIZE (regno));
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+hpux_thread_prepare_to_store ()
+{
+ child_ops.to_prepare_to_store ();
+}
+
+static int
+hpux_thread_xfer_memory (memaddr, myaddr, len, dowrite, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int dowrite;
+ struct target_ops *target; /* ignored */
+{
+ int retval;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = main_pid;
+
+ retval = child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
+
+ do_cleanups (old_chain);
+
+ return retval;
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+hpux_thread_files_info (ignore)
+ struct target_ops *ignore;
+{
+ child_ops.to_files_info (ignore);
+}
+
+static void
+hpux_thread_kill_inferior ()
+{
+ child_ops.to_kill ();
+}
+
+static void
+hpux_thread_notice_signals (pid)
+ int pid;
+{
+ child_ops.to_notice_signals (pid);
+}
+
+/* Fork an inferior process, and start debugging it with /proc. */
+
+static void
+hpux_thread_create_inferior (exec_file, allargs, env)
+ char *exec_file;
+ char *allargs;
+ char **env;
+{
+ child_ops.to_create_inferior (exec_file, allargs, env);
+
+ if (hpux_thread_active)
+ {
+ main_pid = inferior_pid;
+
+ push_target (&hpux_thread_ops);
+
+ inferior_pid = find_active_thread ();
+
+ add_thread (inferior_pid);
+ }
+}
+
+/* This routine is called whenever a new symbol table is read in, or when all
+ symbol tables are removed. libthread_db can only be initialized when it
+ finds the right variables in libthread.so. Since it's a shared library,
+ those variables don't show up until the library gets mapped and the symbol
+ table is read in. */
+
+void
+hpux_thread_new_objfile (objfile)
+ struct objfile *objfile;
+{
+ struct minimal_symbol *ms;
+
+ if (!objfile)
+ {
+ hpux_thread_active = 0;
+
+ return;
+ }
+
+ ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
+
+ if (!ms)
+ return;
+
+ P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
+
+ ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
+
+ if (!ms)
+ return;
+
+ P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
+
+ hpux_thread_active = 1;
+}
+
+/* Clean up after the inferior dies. */
+
+static void
+hpux_thread_mourn_inferior ()
+{
+ child_ops.to_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
+
+static int
+hpux_thread_can_run ()
+{
+ return child_suppress_run;
+}
+
+static int
+hpux_thread_alive (pid)
+ int pid;
+{
+ return 1;
+}
+
+static void
+hpux_thread_stop ()
+{
+ child_ops.to_stop ();
+}
+
+/* Convert a pid to printable form. */
+
+char *
+hpux_pid_to_str (pid)
+ int pid;
+{
+ static char buf[100];
+
+ sprintf (buf, "Thread %d", pid >> 16);
+
+ return buf;
+}
+
+static void
+init_hpux_thread_ops ()
+{
+ hpux_thread_ops.to_shortname = "hpux-threads";
+ hpux_thread_ops.to_longname = "HPUX threads and pthread.";
+ hpux_thread_ops.to_doc = "HPUX threads and pthread support.";
+ hpux_thread_ops.to_open = hpux_thread_open;
+ hpux_thread_ops.to_attach = hpux_thread_attach;
+ hpux_thread_ops.to_detach = hpux_thread_detach;
+ hpux_thread_ops.to_resume = hpux_thread_resume;
+ hpux_thread_ops.to_wait = hpux_thread_wait;
+ hpux_thread_ops.to_fetch_registers = hpux_thread_fetch_registers;
+ hpux_thread_ops.to_store_registers = hpux_thread_store_registers;
+ hpux_thread_ops.to_prepare_to_store = hpux_thread_prepare_to_store;
+ hpux_thread_ops.to_xfer_memory = hpux_thread_xfer_memory;
+ hpux_thread_ops.to_files_info = hpux_thread_files_info;
+ hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ hpux_thread_ops.to_terminal_init = terminal_init_inferior;
+ hpux_thread_ops.to_terminal_inferior = terminal_inferior;
+ hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ hpux_thread_ops.to_terminal_ours = terminal_ours;
+ hpux_thread_ops.to_terminal_info = child_terminal_info;
+ hpux_thread_ops.to_kill = hpux_thread_kill_inferior;
+ hpux_thread_ops.to_create_inferior = hpux_thread_create_inferior;
+ hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior;
+ hpux_thread_ops.to_can_run = hpux_thread_can_run;
+ hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals;
+ hpux_thread_ops.to_thread_alive = hpux_thread_thread_alive;
+ hpux_thread_ops.to_stop = hpux_thread_stop;
+ hpux_thread_ops.to_stratum = process_stratum;
+ hpux_thread_ops.to_has_all_memory = 1;
+ hpux_thread_ops.to_has_memory = 1;
+ hpux_thread_ops.to_has_stack = 1;
+ hpux_thread_ops.to_has_registers = 1;
+ hpux_thread_ops.to_has_execution = 1;
+ hpux_thread_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_hpux_thread ()
+{
+ init_hpux_thread_ops ();
+ add_target (&hpux_thread_ops);
+
+ child_suppress_run = 1;
+}
diff --git a/contrib/gdb/gdb/i386-stub.c b/contrib/gdb/gdb/i386-stub.c
index ce53c48..768f00c 100644
--- a/contrib/gdb/gdb/i386-stub.c
+++ b/contrib/gdb/gdb/i386-stub.c
@@ -100,8 +100,8 @@
typedef void (*ExceptionHook)(int); /* pointer to function with int parm */
typedef void (*Function)(); /* pointer to a function */
-extern putDebugChar(); /* write a single character */
-extern getDebugChar(); /* read and return a single char */
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
extern Function exceptionHandler(); /* assign an exception handler */
extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */
@@ -120,8 +120,12 @@ void waitabit();
static const char hexchars[]="0123456789abcdef";
+/* Number of registers. */
+#define NUMREGS 16
+
/* Number of bytes of registers. */
-#define NUMREGBYTES 64
+#define NUMREGBYTES (NUMREGS * 4)
+
enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
PC /* also known as eip */,
PS /* also known as eflags */,
@@ -130,7 +134,7 @@ enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
/*
* these should not be static cuz they can be used outside this module
*/
-int registers[NUMREGBYTES/4];
+int registers[NUMREGS];
#define STACKSIZE 10000
int remcomStack[STACKSIZE/sizeof(int)];
@@ -525,7 +529,7 @@ char * buffer;
count = 0;
while (ch=buffer[count]) {
- if (! putDebugChar(ch)) return;
+ putDebugChar(ch);
checksum += ch;
count += 1;
}
@@ -736,6 +740,22 @@ void handle_exception(int exceptionVector)
hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES, 0);
strcpy(remcomOutBuffer,"OK");
break;
+ case 'P' : /* set the value of a single CPU register - return OK */
+ {
+ int regno;
+
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &regno) && *ptr++ == '=')
+ if (regno >= 0 && regno < NUMREGS)
+ {
+ hex2mem (ptr, (char *)&registers[regno], 4, 0);
+ strcpy(remcomOutBuffer,"OK");
+ break;
+ }
+
+ strcpy (remcomOutBuffer, "E01");
+ break;
+ }
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
case 'm' :
@@ -899,14 +919,6 @@ void breakpoint()
int waitlimit = 1000000;
-#if 0
-void
-bogon()
-{
- waitabit();
-}
-#endif
-
void
waitabit()
{
diff --git a/contrib/gdb/gdb/i386-tdep.c b/contrib/gdb/gdb/i386-tdep.c
index 47be4b3..1daa81d 100644
--- a/contrib/gdb/gdb/i386-tdep.c
+++ b/contrib/gdb/gdb/i386-tdep.c
@@ -1,5 +1,6 @@
/* Intel 386 target-dependent stuff.
- Copyright (C) 1988, 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1991, 1994, 1995, 1996, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "target.h"
#include "floatformat.h"
#include "symtab.h"
+#include "gdbcmd.h"
+#include "command.h"
static long i386_get_frame_setup PARAMS ((CORE_ADDR));
@@ -36,6 +39,23 @@ static void codestream_seek PARAMS ((CORE_ADDR));
static unsigned char codestream_fill PARAMS ((int));
+CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR, char *));
+
+static int gdb_print_insn_i386 (bfd_vma, disassemble_info *);
+
+void _initialize_i386_tdep PARAMS ((void));
+
+/* This is the variable the is set with "set disassembly-flavor",
+ and its legitimate values. */
+static char att_flavor[] = "att";
+static char intel_flavor[] = "intel";
+static char *valid_flavors[] = {
+ att_flavor,
+ intel_flavor,
+ NULL
+};
+static char *disassembly_flavor = att_flavor;
+
/* Stdio style buffering was used to minimize calls to ptrace, but this
buffering did not take into account that the code section being accessed
may not be an even number of buffers long (even if the buffer is only
@@ -209,6 +229,39 @@ i386_get_frame_setup (pc)
op = codestream_get (); /* update next opcode */
}
+ if (op == 0x68 || op == 0x6a)
+ {
+ /*
+ * this function may start with
+ *
+ * pushl constant
+ * call _probe
+ * addl $4, %esp
+ * followed by
+ * pushl %ebp
+ * etc.
+ */
+ int pos;
+ unsigned char buf[8];
+
+ /* Skip past the pushl instruction; it has either a one-byte
+ or a four-byte operand, depending on the opcode. */
+ pos = codestream_tell ();
+ if (op == 0x68)
+ pos += 4;
+ else
+ pos += 1;
+ codestream_seek (pos);
+
+ /* Read the following 8 bytes, which should be "call _probe" (6 bytes)
+ followed by "addl $4,%esp" (2 bytes). */
+ codestream_read (buf, sizeof (buf));
+ if (buf[0] == 0xe8 && buf[6] == 0xc4 && buf[7] == 0x4)
+ pos += sizeof (buf);
+ codestream_seek (pos);
+ op = codestream_get (); /* update next opcode */
+ }
+
if (op == 0x55) /* pushl %ebp */
{
/* check for movl %esp, %ebp - can be written two ways */
@@ -390,10 +443,11 @@ i386_frame_find_saved_regs (fip, fsrp)
struct frame_info *fip;
struct frame_saved_regs *fsrp;
{
- long locals;
+ long locals = -1;
unsigned char op;
CORE_ADDR dummy_bottom;
CORE_ADDR adr;
+ CORE_ADDR pc;
int i;
memset (fsrp, 0, sizeof *fsrp);
@@ -416,7 +470,9 @@ i386_frame_find_saved_regs (fip, fsrp)
return;
}
- locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
+ pc = get_pc_function_start (fip->pc);
+ if (pc != 0)
+ locals = i386_get_frame_setup (pc);
if (locals >= 0)
{
@@ -655,6 +711,32 @@ i386v4_sigtramp_saved_pc (frame)
}
#endif /* I386V4_SIGTRAMP_SAVED_PC */
+#ifdef STATIC_TRANSFORM_NAME
+/* SunPRO encodes the static variables. This is not related to C++ mangling,
+ it is done for C too. */
+
+char *
+sunpro_static_transform_name (name)
+ char *name;
+{
+ char *p;
+ if (IS_STATIC_TRANSFORM_NAME (name))
+ {
+ /* For file-local statics there will be a period, a bunch
+ of junk (the contents of which match a string given in the
+ N_OPT), a period and the name. For function-local statics
+ there will be a bunch of junk (which seems to change the
+ second character from 'A' to 'B'), a period, the name of the
+ function, and the name. So just skip everything before the
+ last period. */
+ p = strrchr (name, '.');
+ if (p != NULL)
+ name = p + 1;
+ }
+ return name;
+}
+#endif /* STATIC_TRANSFORM_NAME */
+
/* Stuff for WIN32 PE style DLL's but is pretty generic really. */
@@ -681,8 +763,32 @@ skip_trampoline_code (pc, name)
return 0; /* not a trampoline */
}
+static int
+gdb_print_insn_i386 (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info * info;
+{
+ if (disassembly_flavor == att_flavor)
+ return print_insn_i386_att (memaddr, info);
+ else if (disassembly_flavor == intel_flavor)
+ return print_insn_i386_intel (memaddr, info);
+}
+
void
_initialize_i386_tdep ()
{
- tm_print_insn = print_insn_i386;
+ tm_print_insn = gdb_print_insn_i386;
+ tm_print_insn_info.mach = bfd_lookup_arch (bfd_arch_i386, 0)->mach;
+
+ /* Add the variable that controls the disassembly flavor */
+ add_show_from_set(
+ add_set_enum_cmd ("disassembly-flavor", no_class,
+ valid_flavors,
+ (char *) &disassembly_flavor,
+ "Set the disassembly flavor, the valid values are \"att\" and \"intel\", \
+and the default value is \"att\".",
+ &setlist),
+ &showlist);
+
+
}
diff --git a/contrib/gdb/gdb/i386aix-nat.c b/contrib/gdb/gdb/i386aix-nat.c
index 133109e..20e656e 100644
--- a/contrib/gdb/gdb/i386aix-nat.c
+++ b/contrib/gdb/gdb/i386aix-nat.c
@@ -43,7 +43,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Does AIX define this in <errno.h>? */
extern int errno;
-#ifndef NO_SYS_REG_H
+#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif
@@ -51,6 +51,8 @@ extern int errno;
#include "target.h"
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
+
/* this table must line up with REGISTER_NAMES in tm-i386v.h */
/* symbols like 'EAX' come from <sys/reg.h> */
@@ -317,7 +319,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int reg_addr; /* ignored */
+ CORE_ADDR reg_addr; /* ignored */
{
if (which == 0)
diff --git a/contrib/gdb/gdb/i386b-nat.c b/contrib/gdb/gdb/i386b-nat.c
index d273cab..e784773 100644
--- a/contrib/gdb/gdb/i386b-nat.c
+++ b/contrib/gdb/gdb/i386b-nat.c
@@ -57,7 +57,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int ignore;
+ CORE_ADDR ignore;
{
struct md_core *core_reg = (struct md_core *)core_reg_sect;
@@ -125,6 +125,7 @@ i386_register_u_addr (blockend, regnum)
#endif /* !FETCH_INFERIOR_REGISTERS */
#ifdef FLOAT_INFO
+#include "expression.h"
#include "language.h" /* for local_hex_string */
#include "floatformat.h"
diff --git a/contrib/gdb/gdb/i386gnu-nat.c b/contrib/gdb/gdb/i386gnu-nat.c
index 63c3bd0..6ed92c1 100644
--- a/contrib/gdb/gdb/i386gnu-nat.c
+++ b/contrib/gdb/gdb/i386gnu-nat.c
@@ -1,5 +1,5 @@
/* Low level interface to I386 running the GNU Hurd
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "floatformat.h"
#include <stdio.h>
+#include <errno.h>
#include <mach.h>
#include <mach/message.h>
@@ -81,19 +82,23 @@ static int reg_offset[] =
void
gnu_fetch_registers (int reg)
{
+ struct proc *thread;
thread_state_t state;
- struct proc *thread = inf_tid_to_thread (current_inferior, inferior_pid);
- if (!thread)
+ inf_update_procs (current_inferior); /* Make sure we know about new threads. */
+
+ thread = inf_tid_to_thread (current_inferior, inferior_pid);
+ if (! thread)
error ("fetch inferior registers: %d: Invalid thread", inferior_pid);
state = proc_get_state (thread, 0);
if (! state)
- warning ("Couldn't fetch register %s.", reg_names[reg]);
+ warning ("Couldn't fetch register %s from %s (invalid thread).",
+ REGISTER_NAME (reg), proc_string (thread));
else if (reg >= 0)
{
- proc_debug (thread, "fetching register: %s", reg_names[reg]);
+ proc_debug (thread, "fetching register: %s", REGISTER_NAME (reg));
supply_register (reg, REG_ADDR(state, reg));
thread->fetched_regs |= (1 << reg);
}
@@ -116,15 +121,18 @@ void
gnu_store_registers (reg)
int reg;
{
+ struct proc *thread;
int was_aborted, was_valid;
thread_state_t state;
thread_state_data_t old_state;
- struct proc *thread = inf_tid_to_thread (current_inferior, inferior_pid);
+
+ inf_update_procs (current_inferior); /* Make sure we know about new threads. */
+ thread = inf_tid_to_thread (current_inferior, inferior_pid);
if (! thread)
error ("store inferior registers: %d: Invalid thread", inferior_pid);
- proc_debug (thread, "storing register %s.", reg_names[reg]);
+ proc_debug (thread, "storing register %s.", REGISTER_NAME (reg));
was_aborted = thread->aborted;
was_valid = thread->state_valid;
@@ -134,7 +142,8 @@ gnu_store_registers (reg)
state = proc_get_state (thread, 1);
if (! state)
- warning ("Couldn't store register %s.", reg_names[reg]);
+ warning ("Couldn't store register %s from %s (invalid thread).",
+ REGISTER_NAME (reg), proc_string (thread));
else
{
if (! was_aborted && was_valid)
@@ -149,7 +158,7 @@ gnu_store_registers (reg)
/* Register CHECK_REG has changed! Ack! */
{
warning ("Register %s changed after thread was aborted.",
- reg_names [check_reg]);
+ REGISTER_NAME (check_reg));
if (reg >= 0 && reg != check_reg)
/* Update gdb's copy of the register. */
supply_register (check_reg, REG_ADDR (state, check_reg));
@@ -160,7 +169,7 @@ gnu_store_registers (reg)
if (reg >= 0)
{
- proc_debug (thread, "storing register: %s", reg_names[reg]);
+ proc_debug (thread, "storing register: %s", REGISTER_NAME (reg));
STORE_REGS (state, reg, 1);
}
else
diff --git a/contrib/gdb/gdb/i386ly-tdep.c b/contrib/gdb/gdb/i386ly-tdep.c
index dcb4584..101f4ed 100644
--- a/contrib/gdb/gdb/i386ly-tdep.c
+++ b/contrib/gdb/gdb/i386ly-tdep.c
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "inferior.h"
#include "target.h"
+#include "gdbcore.h"
/* Return the PC of the caller from the call frame. Assumes the subr prologue
has already been executed, and the frame pointer setup. If this is the
diff --git a/contrib/gdb/gdb/i386m3-nat.c b/contrib/gdb/gdb/i386m3-nat.c
index bbaa022..c0257b1 100644
--- a/contrib/gdb/gdb/i386m3-nat.c
+++ b/contrib/gdb/gdb/i386m3-nat.c
@@ -219,12 +219,12 @@ store_inferior_registers (regno)
* Called by core-aout.c(fetch_core_registers)
*/
-unsigned int
+CORE_ADDR
register_addr (regno, blockend)
int regno;
- int blockend;
+ CORE_ADDR blockend;
{
- unsigned int addr;
+ CORE_ADDR addr;
if (regno < 0 || regno >= NUM_REGS)
error ("Invalid register number %d.", regno);
diff --git a/contrib/gdb/gdb/i386mach-nat.c b/contrib/gdb/gdb/i386mach-nat.c
index 1a5904a..f843d7f 100644
--- a/contrib/gdb/gdb/i386mach-nat.c
+++ b/contrib/gdb/gdb/i386mach-nat.c
@@ -36,7 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdb_stat.h"
#include <sys/core.h>
-
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
void
fetch_inferior_registers (regno)
@@ -118,7 +118,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int reg_addr; /* Unused in this version */
+ CORE_ADDR reg_addr; /* Unused in this version */
{
int val;
extern char registers[];
diff --git a/contrib/gdb/gdb/i386v-nat.c b/contrib/gdb/gdb/i386v-nat.c
index 38468a9..5618687 100644
--- a/contrib/gdb/gdb/i386v-nat.c
+++ b/contrib/gdb/gdb/i386v-nat.c
@@ -1,5 +1,5 @@
/* Intel 386 native support for SYSV systems (pre-SVR4).
- Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1988, 89, 91, 92, 94, 96, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,6 +18,15 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
+
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
+#else
+# ifdef HAVE_SYS_PTRACE_H
+# include <sys/ptrace.h>
+# endif
+#endif
+
#include "frame.h"
#include "inferior.h"
#include "language.h"
@@ -34,14 +43,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/ioctl.h>
#include <fcntl.h>
+
+/* FIXME: The following used to be just "#include <sys/debugreg.h>", but
+ * the the Linux 2.1.x kernel and glibc 2.0.x are not in sync; including
+ * <sys/debugreg.h> will result in an error. With luck, these losers
+ * will get their act together and we can trash this hack in the near future.
+ * --jsm 1998-10-21
+ */
+
#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
-#include <sys/debugreg.h>
+# ifdef HAVE_ASM_DEBUGREG_H
+# include <asm/debugreg.h>
+# else
+# include <sys/debugreg.h>
+# endif
#endif
#include <sys/file.h>
#include "gdb_stat.h"
-#ifndef NO_SYS_REG_H
+#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif
@@ -155,7 +176,7 @@ i386_insert_aligned_watchpoint (pid, waddr, addr, len, rw)
if (i > DR_LASTADDR)
return -1;
- read_write_bits = ((rw & 1) ? DR_RW_READ : 0) | ((rw & 2) ? DR_RW_WRITE : 0);
+ read_write_bits = (rw & 1) ? DR_RW_READ : DR_RW_WRITE;
if (len == 1)
len_bits = DR_LEN_1;
diff --git a/contrib/gdb/gdb/i386v4-nat.c b/contrib/gdb/gdb/i386v4-nat.c
index 98f7365..ea84c65 100644
--- a/contrib/gdb/gdb/i386v4-nat.c
+++ b/contrib/gdb/gdb/i386v4-nat.c
@@ -1,5 +1,5 @@
/* Native-dependent code for SVR4 Unix running on i386's, for GDB.
- Copyright 1988, 1989, 1991, 1992, 1996 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,6 +18,12 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "value.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
#ifdef HAVE_SYS_PROCFS_H
@@ -79,6 +85,16 @@ static int regmap[] =
DS, ES, FS, GS,
};
+/* Prototypes for local functions */
+
+void fill_gregset PARAMS ((gregset_t *, int));
+
+void supply_gregset PARAMS ((gregset_t *));
+
+void supply_fpregset PARAMS ((fpregset_t *));
+
+void fill_fpregset PARAMS ((fpregset_t *, int));
+
/* FIXME: These routine absolutely depends upon (NUM_REGS - NUM_FREGS)
being less than or equal to the number of registers that can be stored
@@ -135,8 +151,6 @@ void
supply_fpregset (fpregsetp)
fpregset_t *fpregsetp;
{
- register int regi;
-
/* FIXME: see m68k-tdep.c for an example, for the m68k. */
}
@@ -150,11 +164,6 @@ fill_fpregset (fpregsetp, regno)
fpregset_t *fpregsetp;
int regno;
{
- int regi;
- char *to;
- char *from;
- extern char registers[];
-
/* FIXME: see m68k-tdep.c for an example, for the m68k. */
}
diff --git a/contrib/gdb/gdb/i387-tdep.c b/contrib/gdb/gdb/i387-tdep.c
index 6b69405..869ab9a 100644
--- a/contrib/gdb/gdb/i387-tdep.c
+++ b/contrib/gdb/gdb/i387-tdep.c
@@ -1,5 +1,5 @@
/* Intel 387 floating point stuff.
- Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1991, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -24,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#include "floatformat.h"
+void i387_to_double PARAMS ((char *, char *));
+
+void double_to_i387 PARAMS ((char *, char *));
+
/* FIXME: Eliminate these routines when we have the time to change all
the callers. */
diff --git a/contrib/gdb/gdb/infcmd.c b/contrib/gdb/gdb/infcmd.c
index bbadf92..4add1f0 100644
--- a/contrib/gdb/gdb/infcmd.c
+++ b/contrib/gdb/gdb/infcmd.c
@@ -1,5 +1,6 @@
/* Memory-access and commands for "inferior" process, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1986, 87, 88, 89, 91, 92, 95, 96, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -19,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <signal.h>
-#include <sys/param.h>
#include "gdb_string.h"
#include "symtab.h"
#include "gdbtypes.h"
@@ -31,8 +31,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#include "target.h"
#include "language.h"
+#include "symfile.h"
+#include "objfiles.h"
-static void continue_command PARAMS ((char *, int));
+/* Functions exported for general use: */
+
+void nofp_registers_info PARAMS ((char *, int));
+
+void all_registers_info PARAMS ((char *, int));
+
+void registers_info PARAMS ((char *, int));
+
+/* Local functions: */
+
+void continue_command PARAMS ((char *, int));
static void until_next_command PARAMS ((int));
@@ -48,13 +60,9 @@ static void float_info PARAMS ((char *, int));
static void detach_command PARAMS ((char *, int));
-static void nofp_registers_info PARAMS ((char *, int));
-
-static void all_registers_info PARAMS ((char *, int));
-
-static void registers_info PARAMS ((char *, int));
-
+#if !defined (DO_REGISTERS_INFO)
static void do_registers_info PARAMS ((int, int));
+#endif
static void unset_environment_command PARAMS ((char *, int));
@@ -72,9 +80,9 @@ static void jump_command PARAMS ((char *, int));
static void step_1 PARAMS ((int, int, char *));
-static void nexti_command PARAMS ((char *, int));
+void nexti_command PARAMS ((char *, int));
-static void stepi_command PARAMS ((char *, int));
+void stepi_command PARAMS ((char *, int));
static void next_command PARAMS ((char *, int));
@@ -82,6 +90,14 @@ static void step_command PARAMS ((char *, int));
static void run_command PARAMS ((char *, int));
+void _initialize_infcmd PARAMS ((void));
+
+#define GO_USAGE "Usage: go <location>\n"
+
+#ifdef CALL_DUMMY_BREAKPOINT_OFFSET
+static void breakpoint_auto_delete_contents PARAMS ((PTR));
+#endif
+
#define ERROR_NO_INFERIOR \
if (!target_has_execution) error ("The program is not being run.");
@@ -187,19 +203,28 @@ run_command (args, from_tty)
dont_repeat ();
- if (inferior_pid)
+ if (inferior_pid != 0 && target_has_execution)
{
if (
!query ("The program being debugged has been started already.\n\
Start it from the beginning? "))
error ("Program not restarted.");
target_kill ();
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+ init_wait_for_inferior ();
}
clear_breakpoint_hit_counts ();
exec_file = (char *) get_exec_file (0);
+ /* Purge old solib objfiles. */
+ objfile_purge_solibs ();
+
+ do_run_cleanups (NULL);
+
/* The exec file is re-read every time we do a generic_mourn_inferior, so
we just have to worry about the symbol file. */
reread_symbols ();
@@ -234,8 +259,19 @@ Start it from the beginning? "))
target_create_inferior (exec_file, inferior_args,
environ_vector (inferior_environ));
}
-
+
+
static void
+run_no_args_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ execute_command("set args", from_tty);
+ run_command((char *)NULL, from_tty);
+}
+
+
+void
continue_command (proc_count_exp, from_tty)
char *proc_count_exp;
int from_tty;
@@ -299,7 +335,7 @@ next_command (count_string, from_tty)
/* Likewise, but step only one instruction. */
/* ARGSUSED */
-static void
+void
stepi_command (count_string, from_tty)
char *count_string;
int from_tty;
@@ -308,7 +344,7 @@ stepi_command (count_string, from_tty)
}
/* ARGSUSED */
-static void
+void
nexti_command (count_string, from_tty)
char *count_string;
int from_tty;
@@ -332,7 +368,8 @@ step_1 (skip_subroutines, single_inst, count_string)
if (!single_inst || skip_subroutines) /* leave si command alone */
{
enable_longjmp_breakpoint();
- cleanups = make_cleanup(disable_longjmp_breakpoint, 0);
+ cleanups = make_cleanup ((make_cleanup_func) disable_longjmp_breakpoint,
+ 0);
}
for (; count > 0; count--)
@@ -437,6 +474,21 @@ jump_command (arg, from_tty)
}
}
+ if (sfn != NULL)
+ {
+ fixup_symbol_section (sfn, 0);
+ if (section_is_overlay (SYMBOL_BFD_SECTION (sfn)) &&
+ !section_is_mapped (SYMBOL_BFD_SECTION (sfn)))
+ {
+ if (!query ("WARNING!!! Destination is in unmapped overlay! Jump anyway? "))
+ {
+ error ("Not confirmed.");
+ /* NOTREACHED */
+ }
+ }
+ }
+
+
addr = sal.pc;
if (from_tty)
@@ -450,6 +502,23 @@ jump_command (arg, from_tty)
proceed (addr, TARGET_SIGNAL_0, 0);
}
+
+/* Go to line or address in current procedure */
+static void
+go_command(line_no, from_tty)
+ char *line_no;
+ int from_tty;
+{
+ if (line_no == (char *)NULL || !*line_no)
+ printf_filtered(GO_USAGE);
+ else
+ {
+ tbreak_command(line_no, from_tty);
+ jump_command(line_no, from_tty);
+ }
+}
+
+
/* Continue program giving it specified signal. */
static void
@@ -500,13 +569,18 @@ signal_command (signum_exp, from_tty)
/* Call breakpoint_auto_delete on the current contents of the bpstat
pointed to by arg (which is really a bpstat *). */
-void
+
+#ifdef CALL_DUMMY_BREAKPOINT_OFFSET
+
+static void
breakpoint_auto_delete_contents (arg)
PTR arg;
{
breakpoint_auto_delete (*(bpstat *)arg);
}
+#endif /* CALL_DUMMY_BREAKPOINT_OFFSET */
+
/* Execute a "stack dummy", a piece of code stored in the stack
by the debugger to be executed in the inferior.
@@ -546,13 +620,13 @@ run_stack_dummy (addr, buffer)
struct breakpoint *bpt;
struct symtab_and_line sal;
+ INIT_SAL (&sal); /* initialize to zeroes */
#if CALL_DUMMY_LOCATION != AT_ENTRY_POINT
sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
#else
sal.pc = CALL_DUMMY_ADDRESS ();
#endif
- sal.symtab = NULL;
- sal.line = 0;
+ sal.section = find_pc_overlay (sal.pc);
/* Set up a FRAME for the dummy frame so we can pass it to
set_momentary_breakpoint. We need to give the breakpoint a
@@ -579,8 +653,10 @@ run_stack_dummy (addr, buffer)
}
#endif /* CALL_DUMMY_BREAKPOINT_OFFSET. */
+ disable_watchpoints_before_interactive_call_start ();
proceed_to_finish = 1; /* We want stop_registers, please... */
proceed (addr, TARGET_SIGNAL_0, 0);
+ enable_watchpoints_after_interactive_call_stop ();
discard_cleanups (old_cleanups);
@@ -694,7 +770,7 @@ finish_command (arg, from_tty)
breakpoint = set_momentary_breakpoint (sal, frame, bp_finish);
- old_chain = make_cleanup(delete_breakpoint, breakpoint);
+ old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
/* Find the function we will return from. */
@@ -718,6 +794,7 @@ finish_command (arg, from_tty)
struct type *value_type;
register value_ptr val;
CORE_ADDR funcaddr;
+ int struct_return;
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
if (!value_type)
@@ -728,15 +805,39 @@ finish_command (arg, from_tty)
funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
- val = value_being_returned (value_type, stop_registers,
- using_struct_return (value_of_variable (function, NULL),
+ struct_return = using_struct_return (value_of_variable (function, NULL),
+
funcaddr,
check_typedef (value_type),
- BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))));
-
- printf_filtered ("Value returned is $%d = ", record_latest_value (val));
- value_print (val, gdb_stdout, 0, Val_no_prettyprint);
- printf_filtered ("\n");
+ BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
+
+ if (!struct_return)
+ {
+ val = value_being_returned (value_type, stop_registers, struct_return);
+ printf_filtered ("Value returned is $%d = ", record_latest_value (val));
+ value_print (val, gdb_stdout, 0, Val_no_prettyprint);
+ printf_filtered ("\n");
+ }
+ else
+ {
+ /* elz: we cannot determine the contents of the structure because
+ it is on the stack, and we don't know where, since we did not
+ initiate the call, as opposed to the call_function_by_hand case */
+#ifdef VALUE_RETURNED_FROM_STACK
+ val = 0;
+ printf_filtered ("Value returned has type: %s.",
+ TYPE_NAME (value_type));
+ printf_filtered (" Cannot determine contents\n");
+#else
+ val = value_being_returned (value_type, stop_registers,
+ struct_return);
+ printf_filtered ("Value returned is $%d = ",
+ record_latest_value (val));
+ value_print (val, gdb_stdout, 0, Val_no_prettyprint);
+ printf_filtered ("\n");
+#endif
+
+ }
}
do_cleanups(old_chain);
}
@@ -768,7 +869,10 @@ program_info (args, from_tty)
while (num != 0)
{
if (num < 0)
- printf_filtered ("It stopped at a breakpoint that has since been deleted.\n");
+ {
+ printf_filtered ("It stopped at a breakpoint that has ");
+ printf_filtered ("since been deleted.\n");
+ }
else
printf_filtered ("It stopped at breakpoint %d.\n", num);
num = bpstat_num (&bs);
@@ -782,7 +886,10 @@ program_info (args, from_tty)
}
if (!from_tty)
- printf_filtered ("Type \"info stack\" or \"info registers\" for more information.\n");
+ {
+ printf_filtered ("Type \"info stack\" or \"info registers\" ");
+ printf_filtered ("for more information.\n");
+ }
}
static void
@@ -872,7 +979,8 @@ set_environment_command (arg, from_tty)
var = savestring (arg, p - arg);
if (nullset)
{
- printf_filtered ("Setting environment variable \"%s\" to null value.\n", var);
+ printf_filtered ("Setting environment variable ");
+ printf_filtered ("\"%s\" to null value.\n", var);
set_in_environ (inferior_environ, var, "");
}
else
@@ -935,11 +1043,11 @@ path_command (dirname, from_tty)
if (from_tty)
path_info ((char *)NULL, from_tty);
}
-
-/* The array of register names. */
-
-char *reg_names[] = REGISTER_NAMES;
+
+#ifdef REGISTER_NAMES
+char *gdb_register_names[] = REGISTER_NAMES;
+#endif
/* Print out the machine register regnum. If regnum is -1,
print all registers (fpregs == 1) or all non-float registers
(fpregs == 0).
@@ -979,16 +1087,16 @@ do_registers_info (regnum, fpregs)
/* If the register name is empty, it is undefined for this
processor, so don't display anything. */
- if (reg_names[i] == NULL || *(reg_names[i]) == '\0')
+ if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0')
continue;
- fputs_filtered (reg_names[i], gdb_stdout);
- print_spaces_filtered (15 - strlen (reg_names[i]), gdb_stdout);
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout);
/* Get the data in raw format. */
if (read_relative_register_raw_bytes (i, raw_buffer))
{
- printf_filtered ("Invalid register contents\n");
+ printf_filtered ("*value not available*\n");
continue;
}
@@ -1014,12 +1122,16 @@ do_registers_info (regnum, fpregs)
printf_filtered ("<invalid float>");
else
#endif
- val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0,
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
printf_filtered ("\t(raw 0x");
for (j = 0; j < REGISTER_RAW_SIZE (i); j++)
- printf_filtered ("%02x", (unsigned char)raw_buffer[j]);
+ {
+ register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
+ : REGISTER_RAW_SIZE (i) - 1 - j;
+ printf_filtered ("%02x", (unsigned char)raw_buffer[idx]);
+ }
printf_filtered (")");
}
@@ -1037,10 +1149,10 @@ do_registers_info (regnum, fpregs)
/* Else print as integer in hex and in decimal. */
else
{
- val_print (REGISTER_VIRTUAL_TYPE (i), raw_buffer, 0,
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
gdb_stdout, 'x', 1, 0, Val_pretty_default);
printf_filtered ("\t");
- val_print (REGISTER_VIRTUAL_TYPE (i), raw_buffer, 0,
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
}
@@ -1055,7 +1167,9 @@ do_registers_info (regnum, fpregs)
}
#endif /* no DO_REGISTERS_INFO. */
-static void
+extern int target_map_name_to_register PARAMS ((char *, int));
+
+void
registers_info (addr_exp, fpregs)
char *addr_exp;
int fpregs;
@@ -1082,10 +1196,13 @@ registers_info (addr_exp, fpregs)
while (*end != '\0' && *end != ' ' && *end != '\t')
++end;
numregs = ARCH_NUM_REGS;
- for (regnum = 0; regnum < numregs; regnum++)
- if (!strncmp (addr_exp, reg_names[regnum], end - addr_exp)
- && strlen (reg_names[regnum]) == end - addr_exp)
- goto found;
+
+ regnum = target_map_name_to_register (addr_exp, end - addr_exp);
+ if (regnum >= 0)
+ goto found;
+
+ regnum = numregs;
+
if (*addr_exp >= '0' && *addr_exp <= '9')
regnum = atoi (addr_exp); /* Take a number */
if (regnum >= numregs) /* Bad name, or bad number */
@@ -1100,7 +1217,7 @@ found:
} while (*addr_exp != '\0');
}
-static void
+void
all_registers_info (addr_exp, from_tty)
char *addr_exp;
int from_tty;
@@ -1108,13 +1225,14 @@ all_registers_info (addr_exp, from_tty)
registers_info (addr_exp, 1);
}
-static void
+void
nofp_registers_info (addr_exp, from_tty)
char *addr_exp;
int from_tty;
{
registers_info (addr_exp, 0);
}
+
/*
* TODO:
@@ -1137,7 +1255,12 @@ attach_command (args, from_tty)
char *args;
int from_tty;
{
+#ifdef SOLIB_ADD
extern int auto_solib_add;
+#endif
+
+ char * exec_file;
+ char * full_exec_path = NULL;
dont_repeat (); /* Not for the faint of heart */
@@ -1170,15 +1293,43 @@ attach_command (args, from_tty)
wait_for_inferior ();
#endif
+ /*
+ * If no exec file is yet known, try to determine it from the
+ * process itself.
+ */
+ exec_file = (char *) get_exec_file (0);
+ if (! exec_file) {
+ exec_file = target_pid_to_exec_file (inferior_pid);
+ if (exec_file) {
+ /* It's possible we don't have a full path, but rather just a
+ filename. Some targets, such as HP-UX, don't provide the
+ full path, sigh.
+
+ Attempt to qualify the filename against the source path.
+ (If that fails, we'll just fall back on the original
+ filename. Not much more we can do...)
+ */
+ if (!source_full_path_of (exec_file, &full_exec_path))
+ full_exec_path = savestring (exec_file, strlen (exec_file));
+
+ exec_file_attach (full_exec_path, from_tty);
+ symbol_file_command (full_exec_path, from_tty);
+ }
+ }
+
#ifdef SOLIB_ADD
if (auto_solib_add)
{
/* Add shared library symbols from the newly attached process, if any. */
- SOLIB_ADD ((char *)0, from_tty, (struct target_ops *)0);
+ SOLIB_ADD ((char *)0, from_tty, &current_target);
re_enable_breakpoints_in_shlibs ();
}
#endif
+ /* Take any necessary post-attaching actions for this platform.
+ */
+ target_post_attach (inferior_pid);
+
normal_stop ();
}
@@ -1200,6 +1351,9 @@ detach_command (args, from_tty)
{
dont_repeat (); /* Not for the faint of heart */
target_detach (args, from_tty);
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
}
/* ARGSUSED */
@@ -1209,9 +1363,9 @@ float_info (addr_exp, from_tty)
int from_tty;
{
#ifdef FLOAT_INFO
- FLOAT_INFO;
+ FLOAT_INFO;
#else
- printf_filtered ("No floating point info available for this processor.\n");
+ printf_filtered ("No floating point info available for this processor.\n");
#endif
}
@@ -1221,7 +1375,8 @@ unset_command (args, from_tty)
char *args;
int from_tty;
{
- printf_filtered ("\"unset\" must be followed by the name of an unset subcommand.\n");
+ printf_filtered ("\"unset\" must be followed by the name of ");
+ printf_filtered ("an unset subcommand.\n");
help_list (unsetlist, "unset ", -1, gdb_stdout);
}
@@ -1234,9 +1389,9 @@ _initialize_infcmd ()
"Set terminal for future runs of program being debugged.");
add_show_from_set
- (add_set_cmd ("args", class_run, var_string_noescape, (char *)&inferior_args,
-
-"Set arguments to give program being debugged when it is started.\n\
+ (add_set_cmd ("args", class_run, var_string_noescape,
+ (char *)&inferior_args,
+"Set argument list to give program being debugged when it is started.\n\
Follow this command with any number of args, to be passed to the program.",
&setlist),
&showlist);
@@ -1279,23 +1434,27 @@ fully linked executable files and separately compiled object files as needed.");
$cwd in the path means the current working directory.\n\
This path is equivalent to the $PATH shell variable. It is a list of\n\
directories, separated by colons. These directories are searched to find\n\
-fully linked executable files and separately compiled object files as needed.", &showlist);
+fully linked executable files and separately compiled object files as needed.",
+ &showlist);
c->completer = noop_completer;
add_com ("attach", class_run, attach_command,
"Attach to a process or file outside of GDB.\n\
This command attaches to another target, of the same type as your last\n\
-`target' command (`info files' will show your target stack).\n\
+\"target\" command (\"info files\" will show your target stack).\n\
The command may take as argument a process id or a device file.\n\
For a process id, you must have permission to send the process a signal,\n\
and it must have the same effective uid as the debugger.\n\
-When using \"attach\", you should use the \"file\" command to specify\n\
-the program running in the process, and to load its symbol table.");
+When using \"attach\" with a process id, the debugger finds the\n\
+program running in the process, looking first in the current working\n\
+directory, or (if not found there) using the source file search path\n\
+(see the \"directory\" command). You can also use the \"file\" command\n\
+to specify the program, and to load its symbol table.");
add_com ("detach", class_run, detach_command,
"Detach a process or file previously attached.\n\
-If a process, it is no longer traced, and it continues its execution. If you\n\
-were debugging a file, the file is closed and gdb no longer accesses it.");
+If a process, it is no longer traced, and it continues its execution. If\n\
+you were debugging a file, the file is closed and gdb no longer accesses it.");
add_com ("signal", class_run, signal_command,
"Continue program giving it signal specified by the argument.\n\
@@ -1321,6 +1480,8 @@ Like the \"step\" command as long as subroutine calls do not happen;\n\
when they do, the call is treated as one instruction.\n\
Argument N means do this N times (or till program stops for another reason).");
add_com_alias ("n", "next", class_run, 1);
+ if (xdb_commands)
+ add_com_alias("S", "next", class_run, 1);
add_com ("step", class_run, step_command,
"Step program until it reaches a different source line.\n\
@@ -1328,7 +1489,7 @@ Argument N means do this N times (or till program stops for another reason).");
add_com_alias ("s", "step", class_run, 1);
add_com ("until", class_run, until_command,
- "Execute until the program reaches a source line greater than the current\n\
+"Execute until the program reaches a source line greater than the current\n\
or a specified line or address or function (same args as break command).\n\
Execution will also stop upon exit from the current stack frame.");
add_com_alias ("u", "until", class_run, 1);
@@ -1338,6 +1499,16 @@ Execution will also stop upon exit from the current stack frame.");
Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
for an address to start at.");
+ add_com ("go", class_run, go_command,
+ "Usage: go <location>\n\
+Continue program being debugged, stopping at specified line or \n\
+address.\n\
+Give as argument either LINENUM or *ADDR, where ADDR is an \n\
+expression for an address to start at.\n\
+This command is a combination of tbreak and jump.");
+ if (xdb_commands)
+ add_com_alias("g", "g", class_run, 1);
+
add_com ("continue", class_run, continue_command,
"Continue program being debugged, after signal or breakpoint.\n\
If proceeding from breakpoint, a number N may be used as an argument,\n\
@@ -1354,13 +1525,20 @@ With no arguments, uses arguments last specified (with \"run\" or \"set args\").
To cancel previous arguments and run with no arguments,\n\
use \"set args\" without arguments.");
add_com_alias ("r", "run", class_run, 1);
+ if (xdb_commands)
+ add_com ("R", class_run, run_no_args_command,
+ "Start debugged program with no arguments.");
add_info ("registers", nofp_registers_info,
"List of integer registers and their contents, for selected stack frame.\n\
Register name as argument means describe only that register.");
+ if (xdb_commands)
+ add_com("lr", class_info, nofp_registers_info,
+ "List of integer registers and their contents, for selected stack frame.\n\
+ Register name as argument means describe only that register.");
add_info ("all-registers", all_registers_info,
-"List of all registers and their contents, for selected stack frame.\n\
+ "List of all registers and their contents, for selected stack frame.\n\
Register name as argument means describe only that register.");
add_info ("program", program_info,
diff --git a/contrib/gdb/gdb/inferior.h b/contrib/gdb/gdb/inferior.h
index e39f8b9..fa59c2a 100644
--- a/contrib/gdb/gdb/inferior.h
+++ b/contrib/gdb/gdb/inferior.h
@@ -1,6 +1,6 @@
/* Variables that describe the inferior process running under GDB:
Where it is, why it stopped, and how to step it.
- Copyright 1986, 1989, 1992 Free Software Foundation, Inc.
+ Copyright 1986, 1989, 1992, 1996, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -34,34 +34,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
control to the inferior which you don't want showing up in your
control variables. */
-struct inferior_status {
- enum target_signal stop_signal;
- CORE_ADDR stop_pc;
- bpstat stop_bpstat;
- int stop_step;
- int stop_stack_dummy;
- int stopped_by_random_signal;
- int trap_expected;
- CORE_ADDR step_range_start;
- CORE_ADDR step_range_end;
- CORE_ADDR step_frame_address;
- int step_over_calls;
- CORE_ADDR step_resume_break_address;
- int stop_after_trap;
- int stop_soon_quietly;
- CORE_ADDR selected_frame_address;
- int selected_level;
- char stop_registers[REGISTER_BYTES];
-
- /* These are here because if call_function_by_hand has written some
+struct inferior_status
+ {
+ enum target_signal stop_signal;
+ CORE_ADDR stop_pc;
+ bpstat stop_bpstat;
+ int stop_step;
+ int stop_stack_dummy;
+ int stopped_by_random_signal;
+ int trap_expected;
+ CORE_ADDR step_range_start;
+ CORE_ADDR step_range_end;
+ CORE_ADDR step_frame_address;
+ int step_over_calls;
+ CORE_ADDR step_resume_break_address;
+ int stop_after_trap;
+ int stop_soon_quietly;
+ CORE_ADDR selected_frame_address;
+ char stop_registers[REGISTER_BYTES];
+
+ /* These are here because if call_function_by_hand has written some
registers and then decides to call error(), we better not have changed
any registers. */
- char registers[REGISTER_BYTES];
+ char registers[REGISTER_BYTES];
- int breakpoint_proceeded;
- int restore_stack_info;
- int proceed_to_finish;
-};
+ int selected_level;
+ int breakpoint_proceeded;
+ int restore_stack_info;
+ int proceed_to_finish;
+ };
/* This macro gives the number of registers actually in use by the
inferior. This may be less than the total number of registers,
@@ -91,6 +92,27 @@ extern char *inferior_io_terminal;
extern int inferior_pid;
+/* This is only valid when inferior_pid is non-zero.
+
+ If this is 0, then exec events should be noticed and responded to
+ by the debugger (i.e., be reported to the user).
+
+ If this is > 0, then that many subsequent exec events should be
+ ignored (i.e., not be reported to the user).
+ */
+extern int inferior_ignoring_startup_exec_events;
+
+/* This is only valid when inferior_ignoring_startup_exec_events is
+ zero.
+
+ Some targets (stupidly) report more than one exec event per actual
+ call to an event() system call. If only the last such exec event
+ need actually be noticed and responded to by the debugger (i.e.,
+ be reported to the user), then this is the number of "leading"
+ exec events which should be ignored.
+ */
+extern int inferior_ignoring_leading_exec_events;
+
/* Inferior environment. */
extern struct environ *inferior_environ;
@@ -100,9 +122,10 @@ extern struct environ *inferior_environ;
extern char registers[];
/* Array of validity bits (one per register). Nonzero at position XXX_REGNUM
- means that `registers' contains a valid copy of inferior register XXX. */
+ means that `registers' contains a valid copy of inferior register XXX.
+ -1 if register value is not available. */
-extern char register_valid[NUM_REGS];
+extern SIGNED char register_valid[NUM_REGS];
extern void clear_proceed_status PARAMS ((void));
@@ -114,7 +137,7 @@ extern void generic_mourn_inferior PARAMS ((void));
extern void terminal_ours PARAMS ((void));
-extern int run_stack_dummy PARAMS ((CORE_ADDR, char [REGISTER_BYTES]));
+extern int run_stack_dummy PARAMS ((CORE_ADDR, char[REGISTER_BYTES]));
extern CORE_ADDR read_pc PARAMS ((void));
@@ -122,6 +145,8 @@ extern CORE_ADDR read_pc_pid PARAMS ((int));
extern void write_pc PARAMS ((CORE_ADDR));
+extern void write_pc_pid PARAMS ((CORE_ADDR, int));
+
extern CORE_ADDR read_sp PARAMS ((void));
extern void write_sp PARAMS ((CORE_ADDR));
@@ -149,7 +174,7 @@ extern void store_inferior_registers PARAMS ((int));
extern void fetch_inferior_registers PARAMS ((int));
-extern void solib_create_inferior_hook PARAMS ((void));
+extern void solib_create_inferior_hook PARAMS ((void));
extern void child_terminal_info PARAMS ((char *, int));
@@ -161,11 +186,23 @@ extern void terminal_inferior PARAMS ((void));
extern void terminal_init_inferior PARAMS ((void));
-/* From infptrace.c */
+extern void terminal_init_inferior_with_pgrp PARAMS ((int pgrp));
+
+/* From infptrace.c or infttrace.c */
extern int attach PARAMS ((int));
-void detach PARAMS ((int));
+#if !defined(REQUIRE_ATTACH)
+#define REQUIRE_ATTACH attach
+#endif
+
+#if !defined(REQUIRE_DETACH)
+#define REQUIRE_DETACH(pid,siggnal) detach (siggnal)
+#endif
+
+extern void detach PARAMS ((int));
+
+int ptrace_wait PARAMS ((int, int *));
extern void child_resume PARAMS ((int, int, enum target_signal));
@@ -175,15 +212,27 @@ extern void child_resume PARAMS ((int, int, enum target_signal));
extern int call_ptrace PARAMS ((int, int, PTRACE_ARG3_TYPE, int));
+extern void pre_fork_inferior PARAMS ((void));
+
/* From procfs.c */
-extern int proc_iterate_over_mappings PARAMS ((int (*) (int, CORE_ADDR)));
+extern int proc_iterate_over_mappings PARAMS ((int (*)(int, CORE_ADDR)));
+
+extern int procfs_first_available PARAMS ((void));
+
+extern int procfs_get_pid_fd PARAMS ((int));
/* From fork-child.c */
extern void fork_inferior PARAMS ((char *, char *, char **,
- void (*) (void),
- void (*) (int), char *));
+ void (*)(void),
+ void (*)(int),
+ void (*)(void),
+ char *));
+
+
+extern void
+clone_and_follow_inferior PARAMS ((int, int *));
extern void startup_inferior PARAMS ((int));
@@ -250,8 +299,8 @@ extern int stopped_by_random_signal;
minor way if this were changed to the address of the instruction and
that address plus one. But maybe not.). */
-extern CORE_ADDR step_range_start; /* Inclusive */
-extern CORE_ADDR step_range_end; /* Exclusive */
+extern CORE_ADDR step_range_start; /* Inclusive */
+extern CORE_ADDR step_range_end;/* Exclusive */
/* Stack frame address as of when stepping command was issued.
This is how we know when we step into a subroutine call,
@@ -310,15 +359,15 @@ extern int attach_flag;
On most machines just see if the name is sigtramp (and if we have
no name, assume we are not in sigtramp). */
#if !defined (IN_SIGTRAMP)
-# if defined (SIGTRAMP_START)
-# define IN_SIGTRAMP(pc, name) \
- ((pc) >= SIGTRAMP_START \
- && (pc) < SIGTRAMP_END \
+#if defined (SIGTRAMP_START)
+#define IN_SIGTRAMP(pc, name) \
+ ((pc) >= SIGTRAMP_START(pc) \
+ && (pc) < SIGTRAMP_END(pc) \
)
-# else
-# define IN_SIGTRAMP(pc, name) \
+#else
+#define IN_SIGTRAMP(pc, name) \
(name && STREQ ("_sigtramp", name))
-# endif
+#endif
#endif
/* Possible values for CALL_DUMMY_LOCATION. */
@@ -369,7 +418,7 @@ extern CORE_ADDR text_end;
allocate other kinds of code on the stack. */
#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \
- ((sp) INNER_THAN (pc) && (frame_address != 0) && (pc) INNER_THAN (frame_address))
+ (INNER_THAN ((sp), (pc)) && (frame_address != 0) && INNER_THAN ((pc), (frame_address)))
#endif /* On stack. */
#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT
@@ -379,4 +428,46 @@ extern CORE_ADDR text_end;
#endif /* At entry point. */
#endif /* No PC_IN_CALL_DUMMY. */
-#endif /* !defined (INFERIOR_H) */
+/* It's often not enough for our clients to know whether the PC is merely
+ somewhere within the call dummy. They may need to know whether the
+ call dummy has actually completed. (For example, wait_for_inferior
+ wants to know when it should truly stop because the call dummy has
+ completed. If we're single-stepping because of slow watchpoints,
+ then we may find ourselves stopped at the entry of the call dummy,
+ and want to continue stepping until we reach the end.)
+
+ Note that this macro is intended for targets (like HP-UX) which
+ require more than a single breakpoint in their call dummies, and
+ therefore cannot use the CALL_DUMMY_BREAKPOINT_OFFSET mechanism.
+
+ If a target does define CALL_DUMMY_BREAKPOINT_OFFSET, then this
+ default implementation of CALL_DUMMY_HAS_COMPLETED is sufficient.
+ Else, a target may wish to supply an implementation that works in
+ the presense of multiple breakpoints in its call dummy.
+ */
+#if !defined(CALL_DUMMY_HAS_COMPLETED)
+#define CALL_DUMMY_HAS_COMPLETED(pc, sp, frame_address) \
+ PC_IN_CALL_DUMMY((pc), (sp), (frame_address))
+#endif
+
+/* If STARTUP_WITH_SHELL is set, GDB's "run"
+ will attempts to start up the debugee under a shell.
+ This is in order for argument-expansion to occur. E.g.,
+ (gdb) run *
+ The "*" gets expanded by the shell into a list of files.
+ While this is a nice feature, it turns out to interact badly
+ with some of the catch-fork/catch-exec features we have added.
+ In particular, if the shell does any fork/exec's before
+ the exec of the target program, that can confuse GDB.
+ To disable this feature, set STARTUP_WITH_SHELL to 0.
+ To enable this feature, set STARTUP_WITH_SHELL to 1.
+ The catch-exec traps expected during start-up will
+ be 1 if target is not started up with a shell, 2 if it is.
+ - RT
+ If you disable this, you need to decrement
+ START_INFERIOR_TRAPS_EXPECTED in tm.h. */
+#define STARTUP_WITH_SHELL 1
+#if !defined(START_INFERIOR_TRAPS_EXPECTED)
+#define START_INFERIOR_TRAPS_EXPECTED 2
+#endif
+#endif /* !defined (INFERIOR_H) */
diff --git a/contrib/gdb/gdb/inflow.c b/contrib/gdb/gdb/inflow.c
index 62daa65..9033675 100644
--- a/contrib/gdb/gdb/inflow.c
+++ b/contrib/gdb/gdb/inflow.c
@@ -1,5 +1,5 @@
/* Low level interface to ptrace, for GDB when running under Unix.
- Copyright 1986, 1987, 1989, 1991, 1992, 1995 Free Software Foundation, Inc.
+ Copyright 1986-87, 1989, 1991-92, 1995, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "serial.h"
#include "terminal.h"
#include "target.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "gdb_string.h"
#include <signal.h>
@@ -38,6 +38,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define PROCESS_GROUP_TYPE pid_t
#endif
+#ifdef HAVE_TERMIO
+#define PROCESS_GROUP_TYPE int
+#endif
+
#ifdef HAVE_SGTTY
#ifdef SHORT_PGRP
/* This is only used for the ultra. Does it have pid_t? */
@@ -47,6 +51,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif
#endif /* sgtty */
+#if defined (SIGIO) && defined (FASYNC) && defined (FD_SET) && defined (F_SETOWN)
+static void
+handle_sigio PARAMS ((int));
+#endif
+
+static void
+pass_signal PARAMS ((int));
+
static void
kill_command PARAMS ((char *, int));
@@ -82,6 +94,7 @@ PROCESS_GROUP_TYPE inferior_process_group;
inferior only. If we have job control, that takes care of it. If not,
we save our handlers in these two variables and set SIGINT and SIGQUIT
to SIG_IGN. */
+
static void (*sigint_ours) ();
static void (*sigquit_ours) ();
@@ -94,7 +107,7 @@ static char *inferior_thisrun_terminal;
inferior's settings are in effect. Ignored if !gdb_has_a_terminal
(). */
-static int terminal_is_ours;
+int terminal_is_ours;
enum {yes, no, have_not_checked} gdb_has_a_terminal_flag = have_not_checked;
@@ -129,6 +142,9 @@ gdb_has_a_terminal ()
#ifdef HAVE_TERMIOS
our_process_group = tcgetpgrp (0);
#endif
+#ifdef HAVE_TERMIO
+ our_process_group = getpgrp ();
+#endif
#ifdef HAVE_SGTTY
ioctl (0, TIOCGPGRP, &our_process_group);
#endif
@@ -155,7 +171,8 @@ static void terminal_ours_1 PARAMS ((int));
before we actually run the inferior. */
void
-terminal_init_inferior ()
+terminal_init_inferior_with_pgrp (pgrp)
+ int pgrp;
{
if (gdb_has_a_terminal ())
{
@@ -164,18 +181,9 @@ terminal_init_inferior ()
if (inferior_ttystate)
free (inferior_ttystate);
inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
+
#ifdef PROCESS_GROUP_TYPE
-#ifdef PIDGET
- /* This is for Lynx, and should be cleaned up by having Lynx be
- a separate debugging target with a version of
- target_terminal_init_inferior which passes in the process
- group to a generic routine which does all the work (and the
- non-threaded child_terminal_init_inferior can just pass in
- inferior_pid to the same routine). */
- inferior_process_group = PIDGET (inferior_pid);
-#else
- inferior_process_group = inferior_pid;
-#endif
+ inferior_process_group = pgrp;
#endif
/* Make sure that next time we call terminal_inferior (which will be
@@ -185,6 +193,20 @@ terminal_init_inferior ()
}
}
+void
+terminal_init_inferior ()
+{
+#ifdef PROCESS_GROUP_TYPE
+ /* This is for Lynx, and should be cleaned up by having Lynx be a separate
+ debugging target with a version of target_terminal_init_inferior which
+ passes in the process group to a generic routine which does all the work
+ (and the non-threaded child_terminal_init_inferior can just pass in
+ inferior_pid to the same routine). */
+ /* We assume INFERIOR_PID is also the child's process group. */
+ terminal_init_inferior_with_pgrp (PIDGET (inferior_pid));
+#endif /* PROCESS_GROUP_TYPE */
+}
+
/* Put the inferior's terminal settings into effect.
This is preparation for starting or resuming the inferior. */
@@ -214,7 +236,9 @@ terminal_inferior ()
if (!job_control)
{
sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN);
+#ifdef SIGQUIT
sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN);
+#endif
}
/* If attach_flag is set, we don't know whether we are sharing a
@@ -307,6 +331,9 @@ terminal_ours_1 (output_only)
#ifdef HAVE_TERMIOS
inferior_process_group = tcgetpgrp (0);
#endif
+#ifdef HAVE_TERMIO
+ inferior_process_group = getpgrp ();
+#endif
#ifdef HAVE_SGTTY
ioctl (0, TIOCGPGRP, &inferior_process_group);
#endif
@@ -356,7 +383,9 @@ terminal_ours_1 (output_only)
if (!job_control)
{
signal (SIGINT, sigint_ours);
+#ifdef SIGQUIT
signal (SIGQUIT, sigquit_ours);
+#endif
}
#ifdef F_GETFL
@@ -478,7 +507,7 @@ new_tty ()
if (inferior_thisrun_terminal == 0)
return;
-#if !defined(__GO32__) && !defined(__WIN32__)
+#if !defined(__GO32__) && !defined(_WIN32)
#ifdef TIOCNOTTY
/* Disconnect the child process from our controlling terminal. On some
systems (SVR4 for example), this may cause a SIGTTOU, so temporarily
@@ -559,7 +588,9 @@ static void
pass_signal (signo)
int signo;
{
- kill (inferior_pid, SIGINT);
+#ifndef _WIN32
+ kill (PIDGET (inferior_pid), SIGINT);
+#endif
}
static void (*osig)();
@@ -599,8 +630,10 @@ handle_sigio (signo)
numfds = select (target_activity_fd + 1, &readfds, NULL, NULL, NULL);
if (numfds >= 0 && FD_ISSET (target_activity_fd, &readfds))
{
+#ifndef _WIN32
if ((*target_activity_function) ())
kill (inferior_pid, SIGINT);
+#endif
}
}
diff --git a/contrib/gdb/gdb/infptrace.c b/contrib/gdb/gdb/infptrace.c
index 28210e4..1db7223 100644
--- a/contrib/gdb/gdb/infptrace.c
+++ b/contrib/gdb/gdb/infptrace.c
@@ -1,5 +1,6 @@
/* Low level Unix child interface to ptrace, for GDB when running under Unix.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -34,13 +35,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <signal.h>
#include <sys/ioctl.h>
-#ifndef NO_PTRACE_H
-#ifdef PTRACE_IN_WRONG_PLACE
-#include <ptrace.h>
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
#else
-#include <sys/ptrace.h>
+# ifdef HAVE_SYS_PTRACE_H
+# include <sys/ptrace.h>
+# endif
#endif
-#endif /* NO_PTRACE_H */
#if !defined (PT_READ_I)
#define PT_READ_I 1 /* Read word from text space */
@@ -95,6 +96,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif /* KERNEL_U_ADDR_BSD. */
#endif /* !FETCH_INFERIOR_REGISTERS */
+#if !defined (CHILD_XFER_MEMORY)
+static void udot_info PARAMS ((char *, int));
+#endif
+
+#if !defined (FETCH_INFERIOR_REGISTERS)
+static void fetch_register PARAMS ((int));
+static void store_register PARAMS ((int));
+#endif
+
+void _initialize_kernel_u_addr PARAMS ((void));
+void _initialize_infptrace PARAMS ((void));
+
/* This function simply calls ptrace with the given arguments.
It exists so that all calls to ptrace are isolated in this
@@ -105,34 +118,112 @@ call_ptrace (request, pid, addr, data)
PTRACE_ARG3_TYPE addr;
int data;
{
- return ptrace (request, pid, addr, data
+ int pt_status = 0;
+
+#if 0
+ int saved_errno;
+
+ printf ("call_ptrace(request=%d, pid=%d, addr=0x%x, data=0x%x)",
+ request, pid, addr, data);
+#endif
+#if defined(PT_SETTRC)
+ /* If the parent can be told to attach to us, try to do it. */
+ if (request == PT_SETTRC) {
+ errno = 0;
+ pt_status = ptrace (PT_SETTRC, pid, addr, data
+#if defined (FIVE_ARG_PTRACE)
+ /* Deal with HPUX 8.0 braindamage. We never use the
+ calls which require the fifth argument. */
+ , 0
+#endif
+ );
+
+ if (errno) perror_with_name ("ptrace");
+#if 0
+ printf (" = %d\n", pt_status);
+#endif
+ if (pt_status < 0)
+ return pt_status;
+ else
+ return parent_attach_all (pid, addr, data);
+ }
+#endif
+
+#if defined(PT_CONTIN1)
+ /* On HPUX, PT_CONTIN1 is a form of continue that preserves pending
+ signals. If it's available, use it. */
+ if (request == PT_CONTINUE)
+ request = PT_CONTIN1;
+#endif
+
+#if defined(PT_SINGLE1)
+ /* On HPUX, PT_SINGLE1 is a form of step that preserves pending
+ signals. If it's available, use it. */
+ if (request == PT_STEP)
+ request = PT_SINGLE1;
+#endif
+
+#if 0
+ saved_errno = errno;
+ errno = 0;
+#endif
+ pt_status = ptrace (request, pid, addr, data
#if defined (FIVE_ARG_PTRACE)
/* Deal with HPUX 8.0 braindamage. We never use the
calls which require the fifth argument. */
, 0
#endif
);
+#if 0
+ if (errno)
+ printf (" [errno = %d]", errno);
+
+ errno = saved_errno;
+ printf (" = 0x%x\n", pt_status);
+#endif
+ return pt_status;
}
+
#if defined (DEBUG_PTRACE) || defined (FIVE_ARG_PTRACE)
/* For the rest of the file, use an extra level of indirection */
/* This lets us breakpoint usefully on call_ptrace. */
#define ptrace call_ptrace
#endif
+/* Wait for a process to finish, possibly running a target-specific
+ hook before returning. */
+
+int
+ptrace_wait (pid, status)
+ int pid;
+ int *status;
+{
+ int wstate;
+
+ wstate = wait (status);
+ target_post_wait (wstate, *status);
+ return wstate;
+}
+
void
kill_inferior ()
{
+ int status;
+
if (inferior_pid == 0)
return;
- /* ptrace PT_KILL only works if process is stopped!!! So stop it with
- a real signal first, if we can. FIXME: This is bogus. When the inferior
- is not stopped, GDB should just be waiting for it. Either the following
- line is unecessary, or there is some problem elsewhere in GDB which
- causes us to get here when the inferior is not stopped. */
- kill (inferior_pid, SIGKILL);
+
+ /* This once used to call "kill" to kill the inferior just in case
+ the inferior was still running. As others have noted in the past
+ (kingdon) there shouldn't be any way to get here if the inferior
+ is still running -- else there's a major problem elsewere in gdb
+ and it needs to be fixed.
+
+ The kill call causes problems under hpux10, so it's been removed;
+ if this causes problems we'll deal with them as they arise. */
ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0);
- wait ((int *)0);
+ ptrace_wait (0, &status);
target_mourn_inferior ();
}
@@ -166,8 +257,13 @@ child_resume (pid, step, signal)
instructions), so we don't have to worry about that here. */
if (step)
- ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
- target_signal_to_host (signal));
+ {
+ if (SOFTWARE_SINGLE_STEP_P)
+ abort(); /* Make sure this doesn't happen. */
+ else
+ ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
+ target_signal_to_host (signal));
+ }
else
ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1,
target_signal_to_host (signal));
@@ -262,12 +358,10 @@ fetch_register (regno)
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
- char buf[MAX_REGISTER_RAW_SIZE];
char mess[128]; /* For messages */
register int i;
-
- /* Offset of registers within the u area. */
- unsigned int offset;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char buf[MAX_REGISTER_RAW_SIZE];
if (CANNOT_FETCH_REGISTER (regno))
{
@@ -287,7 +381,7 @@ fetch_register (regno)
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
{
- sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
+ sprintf (mess, "reading register %s (#%d)", REGISTER_NAME (regno), regno);
perror_with_name (mess);
}
}
@@ -295,22 +389,25 @@ fetch_register (regno)
}
-/* Fetch all registers, or just one, from the child process. */
+/* Fetch register values from the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
void
fetch_inferior_registers (regno)
int regno;
{
- int numregs;
-
- if (regno == -1)
+ if (regno >= 0)
{
- numregs = ARCH_NUM_REGS;
- for (regno = 0; regno < numregs; regno++)
- fetch_register (regno);
+ fetch_register (regno);
}
else
- fetch_register (regno);
+ {
+ for (regno = 0; regno < ARCH_NUM_REGS; regno++)
+ {
+ fetch_register (regno);
+ }
+ }
}
/* Registers we shouldn't try to store. */
@@ -318,57 +415,57 @@ fetch_inferior_registers (regno)
#define CANNOT_STORE_REGISTER(regno) 0
#endif
-/* 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). */
+/* Store one register. */
-void
-store_inferior_registers (regno)
+static void
+store_register (regno)
int regno;
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
- char buf[80];
- register int i, numregs;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
- unsigned int offset = U_REGS_OFFSET;
+ if (CANNOT_STORE_REGISTER (regno))
+ {
+ return;
+ }
- if (regno >= 0)
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(PTRACE_XFER_TYPE))
{
- regaddr = register_addr (regno, offset);
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(PTRACE_XFER_TYPE))
+ errno = 0;
+ ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
+ *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i]);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
{
- errno = 0;
- ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
- *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i]);
- if (errno != 0)
- {
- sprintf (buf, "writing register number %d(%d)", regno, i);
- perror_with_name (buf);
- }
- regaddr += sizeof(PTRACE_XFER_TYPE);
+ sprintf (mess, "writing register %s (#%d)", REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
}
}
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (regno)
+ int regno;
+{
+ if (regno >= 0)
+ {
+ store_register (regno);
+ }
else
{
- numregs = ARCH_NUM_REGS;
- for (regno = 0; regno < numregs; regno++)
+ for (regno = 0; regno < ARCH_NUM_REGS; regno++)
{
- if (CANNOT_STORE_REGISTER (regno))
- continue;
- regaddr = register_addr (regno, offset);
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(PTRACE_XFER_TYPE))
- {
- errno = 0;
- ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
- *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i]);
- if (errno != 0)
- {
- sprintf (buf, "writing register number %d(%d)", regno, i);
- perror_with_name (buf);
- }
- regaddr += sizeof(PTRACE_XFER_TYPE);
- }
+ store_register (regno);
}
}
}
@@ -443,7 +540,7 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr,
buffer[i]);
if (errno)
- {
+ {
/* Using the appropriate one (I or D) is necessary for
Gould NP1, at least. */
errno = 0;
@@ -453,6 +550,9 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
if (errno)
return 0;
}
+#ifdef CLEAR_INSN_CACHE
+ CLEAR_INSN_CACHE();
+#endif
}
else
{
@@ -477,11 +577,15 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
static void
-udot_info ()
+udot_info (dummy1, dummy2)
+ char *dummy1;
+ int dummy2;
{
+#if defined (KERNEL_U_SIZE)
int udot_off; /* Offset into user struct */
int udot_val; /* Value from user struct at udot_off */
char mess[128]; /* For messages */
+#endif
if (!target_has_execution)
{
diff --git a/contrib/gdb/gdb/infrun.c b/contrib/gdb/gdb/infrun.c
index 90dbd8e..5fd8fc1 100644
--- a/contrib/gdb/gdb/infrun.c
+++ b/contrib/gdb/gdb/infrun.c
@@ -1,5 +1,5 @@
/* Target-struct-independent code to start (run) and stop an inferior process.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -29,18 +29,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "annotate.h"
+#include "symfile.h" /* for overlay functions */
#include <signal.h>
-/* unistd.h is needed to #define X_OK */
-#ifdef USG
-#include <unistd.h>
-#else
-#include <sys/file.h>
-#endif
-
/* Prototypes for local functions */
static void signals_info PARAMS ((char *, int));
@@ -53,7 +47,36 @@ static void sig_print_header PARAMS ((void));
static void resume_cleanups PARAMS ((int));
-static int hook_stop_stub PARAMS ((char *));
+static int hook_stop_stub PARAMS ((PTR));
+
+static void delete_breakpoint_current_contents PARAMS ((PTR));
+
+int inferior_ignoring_startup_exec_events = 0;
+int inferior_ignoring_leading_exec_events = 0;
+
+#ifdef HPUXHPPA
+/* wait_for_inferior and normal_stop use this to notify the user
+ when the inferior stopped in a different thread than it had been
+ running in. */
+static int switched_from_inferior_pid;
+#endif
+
+/* resume and wait_for_inferior use this to ensure that when
+ stepping over a hit breakpoint in a threaded application
+ only the thread that hit the breakpoint is stepped and the
+ other threads don't continue. This prevents having another
+ thread run past the breakpoint while it is temporarily
+ removed.
+
+ This is not thread-specific, so it isn't saved as part of
+ the infrun state.
+
+ Versions of gdb which don't use the "step == this thread steps
+ and others continue" model but instead use the "step == this
+ thread steps and others wait" shouldn't do this. */
+static int thread_step_needed = 0;
+
+void _initialize_infrun PARAMS ((void));
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
program. It needs to examine the jmp_buf argument and extract the PC
@@ -87,6 +110,15 @@ static int hook_stop_stub PARAMS ((char *));
#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0
#endif
+/* On SVR4 based systems, determining the callee's address is exceedingly
+ difficult and depends on the implementation of the run time loader.
+ If we are stepping at the source level, we single step until we exit
+ the run time loader code and reach the callee's address. */
+
+#ifndef IN_SOLIB_DYNSYM_RESOLVE_CODE
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0
+#endif
+
/* For SVR4 shared libraries, each call goes through a small piece of
trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
to nonzero if we are current stopped in one of these. */
@@ -102,6 +134,26 @@ static int hook_stop_stub PARAMS ((char *));
#define IN_SOLIB_RETURN_TRAMPOLINE(pc,name) 0
#endif
+/* This function returns TRUE if pc is the address of an instruction
+ that lies within the dynamic linker (such as the event hook, or the
+ dld itself).
+
+ This function must be used only when a dynamic linker event has
+ been caught, and the inferior is being stepped out of the hook, or
+ undefined results are guaranteed. */
+
+#ifndef SOLIB_IN_DYNAMIC_LINKER
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
+#endif
+
+/* On MIPS16, a function that returns a floating point value may call
+ a library helper function to copy the return value to a floating point
+ register. The IGNORE_HELPER_CALL macro returns non-zero if we
+ should ignore (i.e. step over) this function call. */
+#ifndef IGNORE_HELPER_CALL
+#define IGNORE_HELPER_CALL(pc) 0
+#endif
+
/* On some systems, the PC may be left pointing at an instruction that won't
actually be executed. This is usually indicated by a bit in the PSW. If
we find ourselves in such a state, then we step the target beyond the
@@ -151,9 +203,11 @@ static struct symbol *step_start_function;
static int trap_expected;
+#ifdef SOLIB_ADD
/* Nonzero if we want to give control to the user when we're notified
of shared library events by the dynamic linker. */
static int stop_on_solib_events;
+#endif
#ifdef HP_OS_BUG
/* Nonzero if the next time we try to continue the inferior, it will
@@ -195,14 +249,363 @@ static int breakpoints_failed;
static int stop_print_frame;
-#ifdef NO_SINGLE_STEP
-extern int one_stepped; /* From machine dependent code */
-extern void single_step (); /* Same. */
-#endif /* NO_SINGLE_STEP */
+static struct breakpoint *step_resume_breakpoint = NULL;
+static struct breakpoint *through_sigtramp_breakpoint = NULL;
+
+/* On some platforms (e.g., HP-UX), hardware watchpoints have bad
+ interactions with an inferior that is running a kernel function
+ (aka, a system call or "syscall"). wait_for_inferior therefore
+ may have a need to know when the inferior is in a syscall. This
+ is a count of the number of inferior threads which are known to
+ currently be running in a syscall. */
+static int number_of_threads_in_syscalls;
+
+/* This is used to remember when a fork, vfork or exec event
+ was caught by a catchpoint, and thus the event is to be
+ followed at the next resume of the inferior, and not
+ immediately. */
+static struct
+ {
+ enum target_waitkind kind;
+ struct
+ {
+ int parent_pid;
+ int saw_parent_fork;
+ int child_pid;
+ int saw_child_fork;
+ int saw_child_exec;
+ }
+ fork_event;
+ char *execd_pathname;
+ }
+pending_follow;
+
+/* Some platforms don't allow us to do anything meaningful with a
+ vforked child until it has exec'd. Vforked processes on such
+ platforms can only be followed after they've exec'd.
+
+ When this is set to 0, a vfork can be immediately followed,
+ and an exec can be followed merely as an exec. When this is
+ set to 1, a vfork event has been seen, but cannot be followed
+ until the exec is seen.
+
+ (In the latter case, inferior_pid is still the parent of the
+ vfork, and pending_follow.fork_event.child_pid is the child. The
+ appropriate process is followed, according to the setting of
+ follow-fork-mode.) */
+static int follow_vfork_when_exec;
+
+static char *follow_fork_mode_kind_names[] =
+{
+/* ??rehrauer: The "both" option is broken, by what may be a 10.20
+ kernel problem. It's also not terribly useful without a GUI to
+ help the user drive two debuggers. So for now, I'm disabling
+ the "both" option.
+ "parent", "child", "both", "ask" };
+ */
+ "parent", "child", "ask"};
+
+static char *follow_fork_mode_string = NULL;
+
+
+#if defined(HPUXHPPA)
+static void
+follow_inferior_fork (parent_pid, child_pid, has_forked, has_vforked)
+ int parent_pid;
+ int child_pid;
+ int has_forked;
+ int has_vforked;
+{
+ int followed_parent = 0;
+ int followed_child = 0;
+ int ima_clone = 0;
+
+ /* Which process did the user want us to follow? */
+ char *follow_mode =
+ savestring (follow_fork_mode_string, strlen (follow_fork_mode_string));
+
+ /* Or, did the user not know, and want us to ask? */
+ if (STREQ (follow_fork_mode_string, "ask"))
+ {
+ char requested_mode[100];
+
+ free (follow_mode);
+ error ("\"ask\" mode NYI");
+ follow_mode = savestring (requested_mode, strlen (requested_mode));
+ }
+
+ /* If we're to be following the parent, then detach from child_pid.
+ We're already following the parent, so need do nothing explicit
+ for it. */
+ if (STREQ (follow_mode, "parent"))
+ {
+ followed_parent = 1;
+
+ /* We're already attached to the parent, by default. */
+
+ /* Before detaching from the child, remove all breakpoints from
+ it. (This won't actually modify the breakpoint list, but will
+ physically remove the breakpoints from the child.) */
+ if (!has_vforked || !follow_vfork_when_exec)
+ {
+ detach_breakpoints (child_pid);
+ SOLIB_REMOVE_INFERIOR_HOOK (child_pid);
+ }
+
+ /* Detach from the child. */
+ dont_repeat ();
+
+ target_require_detach (child_pid, "", 1);
+ }
+
+ /* If we're to be following the child, then attach to it, detach
+ from inferior_pid, and set inferior_pid to child_pid. */
+ else if (STREQ (follow_mode, "child"))
+ {
+ char child_pid_spelling[100]; /* Arbitrary length. */
+
+ followed_child = 1;
+
+ /* Before detaching from the parent, detach all breakpoints from
+ the child. But only if we're forking, or if we follow vforks
+ as soon as they happen. (If we're following vforks only when
+ the child has exec'd, then it's very wrong to try to write
+ back the "shadow contents" of inserted breakpoints now -- they
+ belong to the child's pre-exec'd a.out.) */
+ if (!has_vforked || !follow_vfork_when_exec)
+ {
+ detach_breakpoints (child_pid);
+ }
+
+ /* Before detaching from the parent, remove all breakpoints from it. */
+ remove_breakpoints ();
+
+ /* Also reset the solib inferior hook from the parent. */
+ SOLIB_REMOVE_INFERIOR_HOOK (inferior_pid);
+
+ /* Detach from the parent. */
+ dont_repeat ();
+ target_detach (NULL, 1);
+
+ /* Attach to the child. */
+ inferior_pid = child_pid;
+ sprintf (child_pid_spelling, "%d", child_pid);
+ dont_repeat ();
+
+ target_require_attach (child_pid_spelling, 1);
+
+ /* Was there a step_resume breakpoint? (There was if the user
+ did a "next" at the fork() call.) If so, explicitly reset its
+ thread number.
+
+ step_resumes are a form of bp that are made to be per-thread.
+ Since we created the step_resume bp when the parent process
+ was being debugged, and now are switching to the child process,
+ from the breakpoint package's viewpoint, that's a switch of
+ "threads". We must update the bp's notion of which thread
+ it is for, or it'll be ignored when it triggers... */
+ if (step_resume_breakpoint &&
+ (!has_vforked || !follow_vfork_when_exec))
+ breakpoint_re_set_thread (step_resume_breakpoint);
+
+ /* Reinsert all breakpoints in the child. (The user may've set
+ breakpoints after catching the fork, in which case those
+ actually didn't get set in the child, but only in the parent.) */
+ if (!has_vforked || !follow_vfork_when_exec)
+ {
+ breakpoint_re_set ();
+ insert_breakpoints ();
+ }
+ }
+
+ /* If we're to be following both parent and child, then fork ourselves,
+ and attach the debugger clone to the child. */
+ else if (STREQ (follow_mode, "both"))
+ {
+ char pid_suffix[100]; /* Arbitrary length. */
+
+ /* Clone ourselves to follow the child. This is the end of our
+ involvement with child_pid; our clone will take it from here... */
+ dont_repeat ();
+ target_clone_and_follow_inferior (child_pid, &followed_child);
+ followed_parent = !followed_child;
+
+ /* We continue to follow the parent. To help distinguish the two
+ debuggers, though, both we and our clone will reset our prompts. */
+ sprintf (pid_suffix, "[%d] ", inferior_pid);
+ set_prompt (strcat (get_prompt (), pid_suffix));
+ }
+
+ /* The parent and child of a vfork share the same address space.
+ Also, on some targets the order in which vfork and exec events
+ are received for parent in child requires some delicate handling
+ of the events.
+
+ For instance, on ptrace-based HPUX we receive the child's vfork
+ event first, at which time the parent has been suspended by the
+ OS and is essentially untouchable until the child's exit or second
+ exec event arrives. At that time, the parent's vfork event is
+ delivered to us, and that's when we see and decide how to follow
+ the vfork. But to get to that point, we must continue the child
+ until it execs or exits. To do that smoothly, all breakpoints
+ must be removed from the child, in case there are any set between
+ the vfork() and exec() calls. But removing them from the child
+ also removes them from the parent, due to the shared-address-space
+ nature of a vfork'd parent and child. On HPUX, therefore, we must
+ take care to restore the bp's to the parent before we continue it.
+ Else, it's likely that we may not stop in the expected place. (The
+ worst scenario is when the user tries to step over a vfork() call;
+ the step-resume bp must be restored for the step to properly stop
+ in the parent after the call completes!)
+
+ Sequence of events, as reported to gdb from HPUX:
+
+ Parent Child Action for gdb to take
+ -------------------------------------------------------
+ 1 VFORK Continue child
+ 2 EXEC
+ 3 EXEC or EXIT
+ 4 VFORK */
+ if (has_vforked)
+ {
+ target_post_follow_vfork (parent_pid,
+ followed_parent,
+ child_pid,
+ followed_child);
+ }
+
+ pending_follow.fork_event.saw_parent_fork = 0;
+ pending_follow.fork_event.saw_child_fork = 0;
+
+ free (follow_mode);
+}
+
+static void
+follow_fork (parent_pid, child_pid)
+ int parent_pid;
+ int child_pid;
+{
+ follow_inferior_fork (parent_pid, child_pid, 1, 0);
+}
+
+
+/* Forward declaration. */
+static void follow_exec PARAMS ((int, char *));
+
+static void
+follow_vfork (parent_pid, child_pid)
+ int parent_pid;
+ int child_pid;
+{
+ follow_inferior_fork (parent_pid, child_pid, 0, 1);
+
+ /* Did we follow the child? Had it exec'd before we saw the parent vfork? */
+ if (pending_follow.fork_event.saw_child_exec && (inferior_pid == child_pid))
+ {
+ pending_follow.fork_event.saw_child_exec = 0;
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_exec (inferior_pid, pending_follow.execd_pathname);
+ free (pending_follow.execd_pathname);
+ }
+}
+#endif /* HPUXHPPA */
+
+static void
+follow_exec (pid, execd_pathname)
+ int pid;
+ char *execd_pathname;
+{
+#ifdef HPUXHPPA
+ int saved_pid = pid;
+ extern struct target_ops child_ops;
+
+ /* Did this exec() follow a vfork()? If so, we must follow the
+ vfork now too. Do it before following the exec. */
+ if (follow_vfork_when_exec &&
+ (pending_follow.kind == TARGET_WAITKIND_VFORKED))
+ {
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_vfork (inferior_pid, pending_follow.fork_event.child_pid);
+ follow_vfork_when_exec = 0;
+ saved_pid = inferior_pid;
+
+ /* Did we follow the parent? If so, we're done. If we followed
+ the child then we must also follow its exec(). */
+ if (inferior_pid == pending_follow.fork_event.parent_pid)
+ return;
+ }
+
+ /* This is an exec event that we actually wish to pay attention to.
+ Refresh our symbol table to the newly exec'd program, remove any
+ momentary bp's, etc.
+
+ If there are breakpoints, they aren't really inserted now,
+ since the exec() transformed our inferior into a fresh set
+ of instructions.
+
+ We want to preserve symbolic breakpoints on the list, since
+ we have hopes that they can be reset after the new a.out's
+ symbol table is read.
-extern void write_pc_pid PARAMS ((CORE_ADDR, int));
+ However, any "raw" breakpoints must be removed from the list
+ (e.g., the solib bp's), since their address is probably invalid
+ now.
+
+ And, we DON'T want to call delete_breakpoints() here, since
+ that may write the bp's "shadow contents" (the instruction
+ value that was overwritten witha TRAP instruction). Since
+ we now have a new a.out, those shadow contents aren't valid. */
+ update_breakpoints_after_exec ();
+
+ /* If there was one, it's gone now. We cannot truly step-to-next
+ statement through an exec(). */
+ step_resume_breakpoint = NULL;
+ step_range_start = 0;
+ step_range_end = 0;
+ /* If there was one, it's gone now. */
+ through_sigtramp_breakpoint = NULL;
+
+ /* What is this a.out's name? */
+ printf_unfiltered ("Executing new program: %s\n", execd_pathname);
+
+ /* We've followed the inferior through an exec. Therefore, the
+ inferior has essentially been killed & reborn. */
+ gdb_flush (gdb_stdout);
+ target_mourn_inferior ();
+ inferior_pid = saved_pid; /* Because mourn_inferior resets inferior_pid. */
+ push_target (&child_ops);
+
+ /* That a.out is now the one to use. */
+ exec_file_attach (execd_pathname, 0);
+
+ /* And also is where symbols can be found. */
+ symbol_file_command (execd_pathname, 0);
+
+ /* Reset the shared library package. This ensures that we get
+ a shlib event when the child reaches "_start", at which point
+ the dld will have had a chance to initialize the child. */
+ SOLIB_RESTART ();
+ SOLIB_CREATE_INFERIOR_HOOK (inferior_pid);
+
+ /* Reinsert all breakpoints. (Those which were symbolic have
+ been reset to the proper address in the new a.out, thanks
+ to symbol_file_command...) */
+ insert_breakpoints ();
+
+ /* The next resume of this inferior should bring it to the shlib
+ startup breakpoints. (If the user had also set bp's on
+ "main" from the old (parent) process, then they'll auto-
+ matically get reset there in the new process.) */
+#endif
+}
+
+/* Non-zero if we just simulating a single-step. This is needed
+ because we cannot remove the breakpoints in the inferior process
+ until after the `wait' in `wait_for_inferior'. */
+static int singlestep_breakpoints_inserted_p = 0;
+
/* Things to clean up if we QUIT out of resume (). */
/* ARGSUSED */
static void
@@ -212,6 +615,29 @@ resume_cleanups (arg)
normal_stop ();
}
+static char schedlock_off[] = "off";
+static char schedlock_on[] = "on";
+static char schedlock_step[] = "step";
+static char *scheduler_mode = schedlock_off;
+static char *scheduler_enums[] =
+{schedlock_off, schedlock_on, schedlock_step};
+
+static void
+set_schedlock_func (args, from_tty, c)
+ char *args;
+ int from_tty;
+ struct cmd_list_element *c;
+{
+ if (c->type == set_cmd)
+ if (!target_can_lock_scheduler)
+ {
+ scheduler_mode = schedlock_off;
+ error ("Target '%s' cannot support this command.",
+ target_shortname);
+ }
+}
+
+
/* Resume the inferior, but allow a QUIT. This is useful if the user
wants to interrupt some lengthy single-stepping operation
(for child processes, the SIGINT goes to the inferior, and so
@@ -225,7 +651,9 @@ resume (step, sig)
int step;
enum target_signal sig;
{
- struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
+ int should_resume = 1;
+ struct cleanup *old_cleanups = make_cleanup ((make_cleanup_func)
+ resume_cleanups, 0);
QUIT;
#ifdef CANNOT_STEP_BREAKPOINT
@@ -236,26 +664,111 @@ resume (step, sig)
step = 0;
#endif
-#ifdef NO_SINGLE_STEP
- if (step) {
- single_step(sig); /* Do it the hard way, w/temp breakpoints */
- step = 0; /* ...and don't ask hardware to do it. */
- }
-#endif
+ if (SOFTWARE_SINGLE_STEP_P && step)
+ {
+ /* Do it the hard way, w/temp breakpoints */
+ SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints*/ );
+ /* ...and don't ask hardware to do it. */
+ step = 0;
+ /* and do not pull these breakpoints until after a `wait' in
+ `wait_for_inferior' */
+ singlestep_breakpoints_inserted_p = 1;
+ }
/* Handle any optimized stores to the inferior NOW... */
#ifdef DO_DEFERRED_STORES
DO_DEFERRED_STORES;
#endif
+#ifdef HPUXHPPA
+ /* If there were any forks/vforks/execs that were caught and are
+ now to be followed, then do so. */
+ switch (pending_follow.kind)
+ {
+ case (TARGET_WAITKIND_FORKED):
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_fork (inferior_pid, pending_follow.fork_event.child_pid);
+ break;
+
+ case (TARGET_WAITKIND_VFORKED):
+ {
+ int saw_child_exec = pending_follow.fork_event.saw_child_exec;
+
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_vfork (inferior_pid, pending_follow.fork_event.child_pid);
+
+ /* Did we follow the child, but not yet see the child's exec event?
+ If so, then it actually ought to be waiting for us; we respond to
+ parent vfork events. We don't actually want to resume the child
+ in this situation; we want to just get its exec event. */
+ if (!saw_child_exec &&
+ (inferior_pid == pending_follow.fork_event.child_pid))
+ should_resume = 0;
+ }
+ break;
+
+ case (TARGET_WAITKIND_EXECD):
+ /* If we saw a vfork event but couldn't follow it until we saw
+ an exec, then now might be the time! */
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ /* follow_exec is called as soon as the exec event is seen. */
+ break;
+
+ default:
+ break;
+ }
+#endif /* HPUXHPPA */
+
/* Install inferior's terminal modes. */
target_terminal_inferior ();
- target_resume (-1, step, sig);
+ if (should_resume)
+ {
+#ifdef HPUXHPPA
+ if (thread_step_needed)
+ {
+ /* We stopped on a BPT instruction;
+ don't continue other threads and
+ just step this thread. */
+ thread_step_needed = 0;
+
+ if (!breakpoint_here_p (read_pc ()))
+ {
+ /* Breakpoint deleted: ok to do regular resume
+ where all the threads either step or continue. */
+ target_resume (-1, step, sig);
+ }
+ else
+ {
+ if (!step)
+ {
+ warning ("Internal error, changing continue to step.");
+ remove_breakpoints ();
+ breakpoints_inserted = 0;
+ trap_expected = 1;
+ step = 1;
+ }
+
+ target_resume (inferior_pid, step, sig);
+ }
+ }
+ else
+#endif /* HPUXHPPA */
+ {
+ /* Vanilla resume. */
+
+ if ((scheduler_mode == schedlock_on) ||
+ (scheduler_mode == schedlock_step && step != 0))
+ target_resume (inferior_pid, step, sig);
+ else
+ target_resume (-1, step, sig);
+ }
+ }
+
discard_cleanups (old_cleanups);
}
-
+
/* Clear out all variables saying what to do when inferior is continued.
First do this, then set the ones you want, then call `proceed'. */
@@ -301,43 +814,61 @@ proceed (addr, siggnal, step)
if (step < 0)
stop_after_trap = 1;
- if (addr == (CORE_ADDR)-1)
+ if (addr == (CORE_ADDR) - 1)
{
/* If there is a breakpoint at the address we will resume at,
step one instruction before inserting breakpoints
- so that we do not stop right away. */
+ so that we do not stop right away (and report a second
+ hit at this breakpoint). */
- if (breakpoint_here_p (read_pc ()))
+ if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
oneproc = 1;
-#ifdef STEP_SKIPS_DELAY
+#ifndef STEP_SKIPS_DELAY
+#define STEP_SKIPS_DELAY(pc) (0)
+#define STEP_SKIPS_DELAY_P (0)
+#endif
/* Check breakpoint_here_p first, because breakpoint_here_p is fast
(it just checks internal GDB data structures) and STEP_SKIPS_DELAY
is slow (it needs to read memory from the target). */
- if (breakpoint_here_p (read_pc () + 4)
+ if (STEP_SKIPS_DELAY_P
+ && breakpoint_here_p (read_pc () + 4)
&& STEP_SKIPS_DELAY (read_pc ()))
oneproc = 1;
-#endif /* STEP_SKIPS_DELAY */
}
else
- write_pc (addr);
+ {
+ write_pc (addr);
+
+ /* New address; we don't need to single-step a thread
+ over a breakpoint we just hit, 'cause we aren't
+ continuing from there.
+
+ It's not worth worrying about the case where a user
+ asks for a "jump" at the current PC--if they get the
+ hiccup of re-hiting a hit breakpoint, what else do
+ they expect? */
+ thread_step_needed = 0;
+ }
#ifdef PREPARE_TO_PROCEED
- /* In a multi-threaded task we may select another thread and then continue.
-
- In this case the thread that stopped at a breakpoint will immediately
- cause another stop, if it is not stepped over first. On the other hand,
- if (ADDR != -1) we only want to single step over the breakpoint if we did
- switch to another thread.
-
- If we are single stepping, don't do any of the above.
- (Note that in the current implementation single stepping another
- thread after a breakpoint and then continuing will cause the original
- breakpoint to be hit again, but you can always continue, so it's not
- a big deal.) */
-
- if (! step && PREPARE_TO_PROCEED (1) && breakpoint_here_p (read_pc ()))
- oneproc = 1;
+ /* In a multi-threaded task we may select another thread
+ and then continue or step.
+
+ But if the old thread was stopped at a breakpoint, it
+ will immediately cause another breakpoint stop without
+ any execution (i.e. it will report a breakpoint hit
+ incorrectly). So we must step over it first.
+
+ PREPARE_TO_PROCEED checks the current thread against the thread
+ that reported the most recent event. If a step-over is required
+ it returns TRUE and sets the current thread to the old thread. */
+ if (PREPARE_TO_PROCEED () && breakpoint_here_p (read_pc ()))
+ {
+ oneproc = 1;
+ thread_step_needed = 1;
+ }
+
#endif /* PREPARE_TO_PROCEED */
#ifdef HP_OS_BUG
@@ -365,6 +896,7 @@ proceed (addr, siggnal, step)
error ("Cannot insert breakpoints.\n\
The same program may be running in another process.");
}
+
breakpoints_inserted = 1;
}
@@ -398,8 +930,8 @@ The same program may be running in another process.");
static CORE_ADDR prev_pc;
static CORE_ADDR prev_func_start;
static char *prev_func_name;
-
+
/* Start remote-debugging of a machine over a serial link. */
void
@@ -407,7 +939,6 @@ start_remote ()
{
init_thread_list ();
init_wait_for_inferior ();
- clear_proceed_status ();
stop_soon_quietly = 1;
trap_expected = 0;
wait_for_inferior ();
@@ -428,19 +959,33 @@ init_wait_for_inferior ()
trap_expected_after_continue = 0;
#endif
breakpoints_inserted = 0;
- breakpoint_init_inferior ();
+ breakpoint_init_inferior (inf_starting);
/* Don't confuse first call to proceed(). */
stop_signal = TARGET_SIGNAL_0;
+
+ /* The first resume is not following a fork/vfork/exec. */
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS; /* I.e., none. */
+ pending_follow.fork_event.saw_parent_fork = 0;
+ pending_follow.fork_event.saw_child_fork = 0;
+ pending_follow.fork_event.saw_child_exec = 0;
+
+ /* See wait_for_inferior's handling of SYSCALL_ENTRY/RETURN events. */
+ number_of_threads_in_syscalls = 0;
+
+ clear_proceed_status ();
}
static void
delete_breakpoint_current_contents (arg)
PTR arg;
{
- struct breakpoint **breakpointp = (struct breakpoint **)arg;
+ struct breakpoint **breakpointp = (struct breakpoint **) arg;
if (*breakpointp != NULL)
- delete_breakpoint (*breakpointp);
+ {
+ delete_breakpoint (*breakpointp);
+ *breakpointp = NULL;
+ }
}
/* Wait for control to return from inferior to debugger.
@@ -455,7 +1000,7 @@ wait_for_inferior ()
struct cleanup *old_cleanups;
struct target_waitstatus w;
int another_trap;
- int random_signal;
+ int random_signal = 0;
CORE_ADDR stop_func_start;
CORE_ADDR stop_func_end;
char *stop_func_name;
@@ -468,16 +1013,24 @@ wait_for_inferior ()
int current_line;
struct symtab *current_symtab;
int handling_longjmp = 0; /* FIXME */
- struct breakpoint *step_resume_breakpoint = NULL;
- struct breakpoint *through_sigtramp_breakpoint = NULL;
int pid;
+ int saved_inferior_pid;
int update_step_sp = 0;
+ int stepping_through_solib_after_catch = 0;
+ bpstat stepping_through_solib_catchpoints = NULL;
+ int enable_hw_watchpoints_after_wait = 0;
+ int stepping_through_sigtramp = 0;
+ int new_thread_event;
+
+#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+ int stepped_after_stopped_by_watchpoint;
+#endif
old_cleanups = make_cleanup (delete_breakpoint_current_contents,
&step_resume_breakpoint);
make_cleanup (delete_breakpoint_current_contents,
&through_sigtramp_breakpoint);
- sal = find_pc_line(prev_pc, 0);
+ sal = find_pc_line (prev_pc, 0);
current_line = sal.line;
current_symtab = sal.symtab;
@@ -487,10 +1040,22 @@ wait_for_inferior ()
&& !handling_longjmp \
&& ((step_range_end && step_resume_breakpoint == NULL) \
|| trap_expected)) \
+ || stepping_through_solib_after_catch \
|| bpstat_should_step ())
+ ;
+ thread_step_needed = 0;
+
+#ifdef HPUXHPPA
+ /* We'll update this if & when we switch to a new thread. */
+ switched_from_inferior_pid = inferior_pid;
+#endif
while (1)
{
+ extern int overlay_cache_invalid; /* declared in symfile.h */
+
+ overlay_cache_invalid = 1;
+
/* We have to invalidate the registers BEFORE calling target_wait because
they can be loaded from the target while in target_wait. This makes
remote debugging a bit more efficient for those targets that provide
@@ -503,41 +1068,109 @@ wait_for_inferior ()
else
pid = target_wait (-1, &w);
+ /* Since we've done a wait, we have a new event. Don't carry
+ over any expectations about needing to step over a
+ breakpoint. */
+ thread_step_needed = 0;
+
+ /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event is
+ serviced in this loop, below. */
+ if (enable_hw_watchpoints_after_wait)
+ {
+ TARGET_ENABLE_HW_WATCHPOINTS (inferior_pid);
+ enable_hw_watchpoints_after_wait = 0;
+ }
+
+
#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
- have_waited:
+ stepped_after_stopped_by_watchpoint = 0;
#endif
+ /* Gross.
+
+ We goto this label from elsewhere in wait_for_inferior when we want
+ to continue the main loop without calling "wait" and trashing the
+ waitstatus contained in W. */
+ have_waited:
+
flush_cached_frames ();
/* If it's a new process, add it to the thread database */
- if (pid != inferior_pid
- && !in_thread_list (pid))
+ new_thread_event = ((pid != inferior_pid) && !in_thread_list (pid));
+
+ if (w.kind != TARGET_WAITKIND_EXITED
+ && w.kind != TARGET_WAITKIND_SIGNALLED
+ && new_thread_event)
{
- fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
add_thread (pid);
- /* We may want to consider not doing a resume here in order to give
- the user a chance to play with the new thread. It might be good
- to make that a user-settable option. */
- /* At this point, all threads are stopped (happens automatically in
- either the OS or the native code). Therefore we need to continue
- all threads in order to make progress. */
+#ifdef HPUXHPPA
+ fprintf_unfiltered (gdb_stderr, "[New %s]\n",
+ target_pid_or_tid_to_str (pid));
+
+#else
+ printf_filtered ("[New %s]\n", target_pid_to_str (pid));
+#endif
+
+#if 0
+ /* NOTE: This block is ONLY meant to be invoked in case of a
+ "thread creation event"! If it is invoked for any other
+ sort of event (such as a new thread landing on a breakpoint),
+ the event will be discarded, which is almost certainly
+ a bad thing!
+
+ To avoid this, the low-level module (eg. target_wait)
+ should call in_thread_list and add_thread, so that the
+ new thread is known by the time we get here. */
+
+ /* We may want to consider not doing a resume here in order
+ to give the user a chance to play with the new thread.
+ It might be good to make that a user-settable option. */
+
+ /* At this point, all threads are stopped (happens
+ automatically in either the OS or the native code).
+ Therefore we need to continue all threads in order to
+ make progress. */
target_resume (-1, 0, TARGET_SIGNAL_0);
continue;
+#endif
}
switch (w.kind)
{
case TARGET_WAITKIND_LOADED:
- /* Ignore it gracefully. */
- if (breakpoints_inserted)
+ /* Ignore gracefully during startup of the inferior, as it
+ might be the shell which has just loaded some objects,
+ otherwise add the symbols for the newly loaded objects. */
+#ifdef SOLIB_ADD
+ if (!stop_soon_quietly)
{
- mark_breakpoints_out ();
- insert_breakpoints ();
+ extern int auto_solib_add;
+
+ /* Remove breakpoints, SOLIB_ADD might adjust
+ breakpoint addresses via breakpoint_re_set. */
+ if (breakpoints_inserted)
+ remove_breakpoints ();
+
+ /* Check for any newly added shared libraries if we're
+ supposed to be adding them automatically. */
+ if (auto_solib_add)
+ {
+ /* Switch terminal for any messages produced by
+ breakpoint_re_set. */
+ target_terminal_ours_for_output ();
+ SOLIB_ADD (NULL, 0, NULL);
+ target_terminal_inferior ();
+ }
+
+ /* Reinsert breakpoints and continue. */
+ if (breakpoints_inserted)
+ insert_breakpoints ();
}
+#endif
resume (0, TARGET_SIGNAL_0);
continue;
@@ -549,21 +1182,19 @@ wait_for_inferior ()
target_terminal_ours (); /* Must do this before mourn anyway */
annotate_exited (w.value.integer);
if (w.value.integer)
- printf_filtered ("\nProgram exited with code 0%o.\n",
- (unsigned int)w.value.integer);
+ printf_filtered ("\nProgram exited with code 0%o.\n",
+ (unsigned int) w.value.integer);
else
printf_filtered ("\nProgram exited normally.\n");
/* Record the exit code in the convenience variable $_exitcode, so
that the user can inspect this again later. */
set_internalvar (lookup_internalvar ("_exitcode"),
- value_from_longest (builtin_type_int,
+ value_from_longest (builtin_type_int,
(LONGEST) w.value.integer));
gdb_flush (gdb_stdout);
target_mourn_inferior ();
-#ifdef NO_SINGLE_STEP
- one_stepped = 0;
-#endif
+ singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P*/
stop_print_frame = 0;
goto stop_stepping;
@@ -578,7 +1209,7 @@ wait_for_inferior ()
perhaps it means rms didn't understand unix waitstatuses?
For the moment I'm just kludging around this in remote.c
rather than trying to change it here --kingdon, 5 Dec 1994. */
- target_kill (); /* kill mourns as well */
+ target_kill (); /* kill mourns as well */
printf_filtered ("\nProgram terminated with signal ");
annotate_signal_name ();
@@ -592,18 +1223,242 @@ wait_for_inferior ()
printf_filtered ("The program no longer exists.\n");
gdb_flush (gdb_stdout);
-#ifdef NO_SINGLE_STEP
- one_stepped = 0;
-#endif
+ singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P*/
goto stop_stepping;
+ /* The following are the only cases in which we keep going;
+ the above cases end in a continue or goto. */
+ case TARGET_WAITKIND_FORKED:
+ stop_signal = TARGET_SIGNAL_TRAP;
+ pending_follow.kind = w.kind;
+
+ /* Ignore fork events reported for the parent; we're only
+ interested in reacting to forks of the child. Note that
+ we expect the child's fork event to be available if we
+ waited for it now. */
+ if (inferior_pid == pid)
+ {
+ pending_follow.fork_event.saw_parent_fork = 1;
+ pending_follow.fork_event.parent_pid = pid;
+ pending_follow.fork_event.child_pid = w.value.related_pid;
+ continue;
+ }
+ else
+ {
+ pending_follow.fork_event.saw_child_fork = 1;
+ pending_follow.fork_event.child_pid = pid;
+ pending_follow.fork_event.parent_pid = w.value.related_pid;
+ }
+
+ stop_pc = read_pc_pid (pid);
+ saved_inferior_pid = inferior_pid;
+ inferior_pid = pid;
+ stop_bpstat = bpstat_stop_status
+ (&stop_pc,
+#if DECR_PC_AFTER_BREAK
+ (prev_pc != stop_pc - DECR_PC_AFTER_BREAK
+ && CURRENTLY_STEPPING ())
+#else /* DECR_PC_AFTER_BREAK zero */
+ 0
+#endif /* DECR_PC_AFTER_BREAK zero */
+ );
+ random_signal = !bpstat_explains_signal (stop_bpstat);
+ inferior_pid = saved_inferior_pid;
+ goto process_event_stop_test;
+
+ /* If this a platform which doesn't allow a debugger to touch a
+ vfork'd inferior until after it exec's, then we'd best keep
+ our fingers entirely off the inferior, other than continuing
+ it. This has the unfortunate side-effect that catchpoints
+ of vforks will be ignored. But since the platform doesn't
+ allow the inferior be touched at vfork time, there's really
+ little choice. */
+ case TARGET_WAITKIND_VFORKED:
+ stop_signal = TARGET_SIGNAL_TRAP;
+ pending_follow.kind = w.kind;
+
+ /* Is this a vfork of the parent? If so, then give any
+ vfork catchpoints a chance to trigger now. (It's
+ dangerous to do so if the child canot be touched until
+ it execs, and the child has not yet exec'd. We probably
+ should warn the user to that effect when the catchpoint
+ triggers...) */
+ if (pid == inferior_pid)
+ {
+ pending_follow.fork_event.saw_parent_fork = 1;
+ pending_follow.fork_event.parent_pid = pid;
+ pending_follow.fork_event.child_pid = w.value.related_pid;
+ }
+
+ /* If we've seen the child's vfork event but cannot really touch
+ the child until it execs, then we must continue the child now.
+ Else, give any vfork catchpoints a chance to trigger now. */
+ else
+ {
+ pending_follow.fork_event.saw_child_fork = 1;
+ pending_follow.fork_event.child_pid = pid;
+ pending_follow.fork_event.parent_pid = w.value.related_pid;
+ target_post_startup_inferior (pending_follow.fork_event.child_pid);
+ follow_vfork_when_exec = !target_can_follow_vfork_prior_to_exec ();
+ if (follow_vfork_when_exec)
+ {
+ target_resume (pid, 0, TARGET_SIGNAL_0);
+ continue;
+ }
+ }
+
+ stop_pc = read_pc ();
+ stop_bpstat = bpstat_stop_status
+ (&stop_pc,
+#if DECR_PC_AFTER_BREAK
+ (prev_pc != stop_pc - DECR_PC_AFTER_BREAK
+ && CURRENTLY_STEPPING ())
+#else /* DECR_PC_AFTER_BREAK zero */
+ 0
+#endif /* DECR_PC_AFTER_BREAK zero */
+ );
+ random_signal = !bpstat_explains_signal (stop_bpstat);
+ goto process_event_stop_test;
+
+ case TARGET_WAITKIND_EXECD:
+ stop_signal = TARGET_SIGNAL_TRAP;
+
+ /* Is this a target which reports multiple exec events per actual
+ call to exec()? (HP-UX using ptrace does, for example.) If so,
+ ignore all but the last one. Just resume the exec'r, and wait
+ for the next exec event. */
+ if (inferior_ignoring_leading_exec_events)
+ {
+ inferior_ignoring_leading_exec_events--;
+ if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
+ ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.parent_pid);
+ target_resume (pid, 0, TARGET_SIGNAL_0);
+ continue;
+ }
+ inferior_ignoring_leading_exec_events =
+ target_reported_exec_events_per_exec_call () - 1;
+
+ pending_follow.execd_pathname = savestring (w.value.execd_pathname,
+ strlen (w.value.execd_pathname));
+
+ /* Did inferior_pid exec, or did a (possibly not-yet-followed)
+ child of a vfork exec?
+
+ ??rehrauer: This is unabashedly an HP-UX specific thing. On
+ HP-UX, events associated with a vforking inferior come in
+ threes: a vfork event for the child (always first), followed
+ a vfork event for the parent and an exec event for the child.
+ The latter two can come in either order.
+
+ If we get the parent vfork event first, life's good: We follow
+ either the parent or child, and then the child's exec event is
+ a "don't care".
+
+ But if we get the child's exec event first, then we delay
+ responding to it until we handle the parent's vfork. Because,
+ otherwise we can't satisfy a "catch vfork". */
+ if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
+ {
+ pending_follow.fork_event.saw_child_exec = 1;
+
+ /* On some targets, the child must be resumed before
+ the parent vfork event is delivered. A single-step
+ suffices. */
+ if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
+ target_resume (pid, 1, TARGET_SIGNAL_0);
+ /* We expect the parent vfork event to be available now. */
+ continue;
+ }
+
+ /* This causes the eventpoints and symbol table to be reset. Must
+ do this now, before trying to determine whether to stop. */
+ follow_exec (inferior_pid, pending_follow.execd_pathname);
+ free (pending_follow.execd_pathname);
+
+ stop_pc = read_pc_pid (pid);
+ saved_inferior_pid = inferior_pid;
+ inferior_pid = pid;
+ stop_bpstat = bpstat_stop_status
+ (&stop_pc,
+#if DECR_PC_AFTER_BREAK
+ (prev_pc != stop_pc - DECR_PC_AFTER_BREAK
+ && CURRENTLY_STEPPING ())
+#else /* DECR_PC_AFTER_BREAK zero */
+ 0
+#endif /* DECR_PC_AFTER_BREAK zero */
+ );
+ random_signal = !bpstat_explains_signal (stop_bpstat);
+ inferior_pid = saved_inferior_pid;
+ goto process_event_stop_test;
+
+ /* These syscall events are returned on HP-UX, as part of its
+ implementation of page-protection-based "hardware" watchpoints.
+ HP-UX has unfortunate interactions between page-protections and
+ some system calls. Our solution is to disable hardware watches
+ when a system call is entered, and reenable them when the syscall
+ completes. The downside of this is that we may miss the precise
+ point at which a watched piece of memory is modified. "Oh well."
+
+ Note that we may have multiple threads running, which may each
+ enter syscalls at roughly the same time. Since we don't have a
+ good notion currently of whether a watched piece of memory is
+ thread-private, we'd best not have any page-protections active
+ when any thread is in a syscall. Thus, we only want to reenable
+ hardware watches when no threads are in a syscall.
+
+ Also, be careful not to try to gather much state about a thread
+ that's in a syscall. It's frequently a losing proposition. */
+ case TARGET_WAITKIND_SYSCALL_ENTRY:
+ number_of_threads_in_syscalls++;
+ if (number_of_threads_in_syscalls == 1)
+ {
+ TARGET_DISABLE_HW_WATCHPOINTS (inferior_pid);
+ }
+ resume (0, TARGET_SIGNAL_0);
+ continue;
+
+ /* Before examining the threads further, step this thread to
+ get it entirely out of the syscall. (We get notice of the
+ event when the thread is just on the verge of exiting a
+ syscall. Stepping one instruction seems to get it back
+ into user code.)
+
+ Note that although the logical place to reenable h/w watches
+ is here, we cannot. We cannot reenable them before stepping
+ the thread (this causes the next wait on the thread to hang).
+
+ Nor can we enable them after stepping until we've done a wait.
+ Thus, we simply set the flag enable_hw_watchpoints_after_wait
+ here, which will be serviced immediately after the target
+ is waited on. */
+ case TARGET_WAITKIND_SYSCALL_RETURN:
+ target_resume (pid, 1, TARGET_SIGNAL_0);
+
+ if (number_of_threads_in_syscalls > 0)
+ {
+ number_of_threads_in_syscalls--;
+ enable_hw_watchpoints_after_wait =
+ (number_of_threads_in_syscalls == 0);
+ }
+ continue;
+
case TARGET_WAITKIND_STOPPED:
- /* This is the only case in which we keep going; the above cases
- end in a continue or goto. */
+ stop_signal = w.value.sig;
break;
}
- stop_signal = w.value.sig;
+ /* We may want to consider not doing a resume here in order to give
+ the user a chance to play with the new thread. It might be good
+ to make that a user-settable option. */
+
+ /* At this point, all threads are stopped (happens automatically in
+ either the OS or the native code). Therefore we need to continue
+ all threads in order to make progress. */
+ if (new_thread_event)
+ {
+ target_resume (-1, 0, TARGET_SIGNAL_0);
+ continue;
+ }
stop_pc = read_pc_pid (pid);
@@ -611,30 +1466,60 @@ wait_for_inferior ()
another thread. If so, then step that thread past the breakpoint,
and continue it. */
- if (stop_signal == TARGET_SIGNAL_TRAP
- && breakpoints_inserted
- && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+ if (stop_signal == TARGET_SIGNAL_TRAP)
{
- random_signal = 0;
- if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
+ if (SOFTWARE_SINGLE_STEP_P && singlestep_breakpoints_inserted_p)
+ random_signal = 0;
+ else if (breakpoints_inserted
+ && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
{
- /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */
- write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
-
- remove_breakpoints ();
- target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
- /* FIXME: What if a signal arrives instead of the single-step
- happening? */
-
- if (target_wait_hook)
- target_wait_hook (pid, &w);
+ random_signal = 0;
+ if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK,
+ pid))
+ {
+ int remove_status;
+
+ /* Saw a breakpoint, but it was hit by the wrong thread.
+ Just continue. */
+ write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
+
+ remove_status = remove_breakpoints ();
+ /* Did we fail to remove breakpoints? If so, try
+ to set the PC past the bp. (There's at least
+ one situation in which we can fail to remove
+ the bp's: On HP-UX's that use ttrace, we can't
+ change the address space of a vforking child
+ process until the child exits (well, okay, not
+ then either :-) or execs. */
+ if (remove_status != 0)
+ {
+ write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, pid);
+ }
+ else
+ { /* Single step */
+ target_resume (pid, 1, TARGET_SIGNAL_0);
+ /* FIXME: What if a signal arrives instead of the
+ single-step happening? */
+
+ if (target_wait_hook)
+ target_wait_hook (pid, &w);
+ else
+ target_wait (pid, &w);
+ insert_breakpoints ();
+ }
+
+ /* We need to restart all the threads now. */
+ target_resume (-1, 0, TARGET_SIGNAL_0);
+ continue;
+ }
else
- target_wait (pid, &w);
- insert_breakpoints ();
-
- /* We need to restart all the threads now. */
- target_resume (-1, 0, TARGET_SIGNAL_0);
- continue;
+ {
+ /* This breakpoint matches--either it is the right
+ thread or it's a generic breakpoint for all threads.
+ Remember that we'll need to step just _this_ thread
+ on any following user continuation! */
+ thread_step_needed = 1;
+ }
}
}
else
@@ -642,24 +1527,39 @@ wait_for_inferior ()
/* See if something interesting happened to the non-current thread. If
so, then switch to that thread, and eventually give control back to
- the user. */
+ the user.
- if (pid != inferior_pid)
+ Note that if there's any kind of pending follow (i.e., of a fork,
+ vfork or exec), we don't want to do this now. Rather, we'll let
+ the next resume handle it. */
+ if ((pid != inferior_pid) &&
+ (pending_follow.kind == TARGET_WAITKIND_SPURIOUS))
{
int printed = 0;
/* If it's a random signal for a non-current thread, notify user
- if he's expressed an interest. */
-
+ if he's expressed an interest. */
if (random_signal
&& signal_print[stop_signal])
{
+/* ??rehrauer: I don't understand the rationale for this code. If the
+ inferior will stop as a result of this signal, then the act of handling
+ the stop ought to print a message that's couches the stoppage in user
+ terms, e.g., "Stopped for breakpoint/watchpoint". If the inferior
+ won't stop as a result of the signal -- i.e., if the signal is merely
+ a side-effect of something GDB's doing "under the covers" for the
+ user, such as stepping threads over a breakpoint they shouldn't stop
+ for -- then the message seems to be a serious annoyance at best.
+
+ For now, remove the message altogether. */
+#if 0
printed = 1;
target_terminal_ours_for_output ();
printf_filtered ("\nProgram received signal %s, %s.\n",
target_signal_to_name (stop_signal),
target_signal_to_string (stop_signal));
gdb_flush (gdb_stdout);
+#endif
}
/* If it's not SIGTRAP and not a signal we want to stop for, then
@@ -689,7 +1589,14 @@ wait_for_inferior ()
through_sigtramp_breakpoint,
step_range_start, step_range_end,
step_frame_address, handling_longjmp,
- another_trap);
+ another_trap,
+ stepping_through_solib_after_catch,
+ stepping_through_solib_catchpoints,
+ stepping_through_sigtramp);
+
+#ifdef HPUXHPPA
+ switched_from_inferior_pid = inferior_pid;
+#endif
inferior_pid = pid;
@@ -700,30 +1607,57 @@ wait_for_inferior ()
&through_sigtramp_breakpoint,
&step_range_start, &step_range_end,
&step_frame_address, &handling_longjmp,
- &another_trap);
- printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
+ &another_trap,
+ &stepping_through_solib_after_catch,
+ &stepping_through_solib_catchpoints,
+ &stepping_through_sigtramp);
+
+ if (context_hook)
+ context_hook (pid_to_thread_id (pid));
+ printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
flush_cached_frames ();
}
-#ifdef NO_SINGLE_STEP
- if (one_stepped)
- single_step (0); /* This actually cleans up the ss */
-#endif /* NO_SINGLE_STEP */
-
+ if (SOFTWARE_SINGLE_STEP_P && singlestep_breakpoints_inserted_p)
+ {
+ /* Pull the single step breakpoints out of the target. */
+ SOFTWARE_SINGLE_STEP (0, 0);
+ singlestep_breakpoints_inserted_p = 0;
+ }
+
/* If PC is pointing at a nullified instruction, then step beyond
it so that the user won't be confused when GDB appears to be ready
to execute it. */
+#if 0 /* XXX DEBUG */
+ printf ("infrun.c:1607: pc = 0x%x\n", read_pc ());
+#endif
+ /* if (INSTRUCTION_NULLIFIED && CURRENTLY_STEPPING ()) */
if (INSTRUCTION_NULLIFIED)
{
- resume (1, 0);
- continue;
+ struct target_waitstatus tmpstatus;
+#if 0
+ all_registers_info ((char *) 0, 0);
+#endif
+ registers_changed ();
+ target_resume (pid, 1, TARGET_SIGNAL_0);
+
+ /* We may have received a signal that we want to pass to
+ the inferior; therefore, we must not clobber the waitstatus
+ in W. So we call wait ourselves, then continue the loop
+ at the "have_waited" label. */
+ if (target_wait_hook)
+ target_wait_hook (pid, &tmpstatus);
+ else
+ target_wait (pid, &tmpstatus);
+
+ goto have_waited;
}
#ifdef HAVE_STEPPABLE_WATCHPOINT
/* It may not be necessary to disable the watchpoint to stop over
- it. For example, the PA can (with some kernel cooperation)
+ it. For example, the PA can (with some kernel cooperation)
single step over a watchpoint without disabling the watchpoint. */
if (STOPPED_BY_WATCHPOINT (w))
{
@@ -756,16 +1690,19 @@ wait_for_inferior ()
write_pc (stop_pc - DECR_PC_AFTER_BREAK);
remove_breakpoints ();
- target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
+ registers_changed ();
+ target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
if (target_wait_hook)
target_wait_hook (pid, &w);
else
target_wait (pid, &w);
insert_breakpoints ();
+
/* FIXME-maybe: is this cleaner than setting a flag? Does it
handle things like signals arriving and other things happening
in combination correctly? */
+ stepped_after_stopped_by_watchpoint = 1;
goto have_waited;
}
#endif
@@ -776,6 +1713,7 @@ wait_for_inferior ()
#endif
stop_func_start = 0;
+ stop_func_end = 0;
stop_func_name = 0;
/* Don't care about return value; stop_func_start and stop_func_name
will both be 0 if it doesn't work. */
@@ -790,7 +1728,7 @@ wait_for_inferior ()
random_signal = 0;
stopped_by_random_signal = 0;
breakpoints_failed = 0;
-
+
/* Look at the cause of the stop, and decide what to do.
The alternatives are:
1) break; to really stop and return to the debugger,
@@ -798,19 +1736,19 @@ wait_for_inferior ()
(set another_trap to 1 to single step once)
3) set random_signal to 1, and the decision between 1 and 2
will be made according to the signal handling tables. */
-
+
/* First, distinguish signals caused by the debugger from signals
that have to do with the program's own actions.
Note that breakpoint insns may cause SIGTRAP or SIGILL
or SIGEMT, depending on the operating system version.
Here we detect when a SIGILL or SIGEMT is really a breakpoint
and change it to SIGTRAP. */
-
+
if (stop_signal == TARGET_SIGNAL_TRAP
|| (breakpoints_inserted &&
(stop_signal == TARGET_SIGNAL_ILL
|| stop_signal == TARGET_SIGNAL_EMT
- ))
+ ))
|| stop_soon_quietly)
{
if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
@@ -836,19 +1774,23 @@ wait_for_inferior ()
/* See if there is a breakpoint at the current PC. */
stop_bpstat = bpstat_stop_status
(&stop_pc,
-#if DECR_PC_AFTER_BREAK
- /* Notice the case of stepping through a jump
+ (DECR_PC_AFTER_BREAK ?
+ /* Notice the case of stepping through a jump
that lands just after a breakpoint.
Don't confuse that with hitting the breakpoint.
What we check for is that 1) stepping is going on
and 2) the pc before the last insn does not match
- the address of the breakpoint before the current pc. */
- (prev_pc != stop_pc - DECR_PC_AFTER_BREAK
- && CURRENTLY_STEPPING ())
-#else /* DECR_PC_AFTER_BREAK zero */
- 0
-#endif /* DECR_PC_AFTER_BREAK zero */
- );
+ the address of the breakpoint before the current pc
+ and 3) we didn't hit a breakpoint in a signal handler
+ without an intervening stop in sigtramp, which is
+ detected by a new stack pointer value below
+ any usual function calling stack adjustments. */
+ (CURRENTLY_STEPPING ()
+ && prev_pc != stop_pc - DECR_PC_AFTER_BREAK
+ && !(step_range_end
+ && INNER_THAN (read_sp (), (step_sp - 16)))) :
+ 0)
+ );
/* Following in case break condition called a
function. */
stop_print_frame = 1;
@@ -863,24 +1805,74 @@ wait_for_inferior ()
FRAME_FP (get_current_frame ()))
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|| (step_range_end && step_resume_breakpoint == NULL));
+
else
{
random_signal
= !(bpstat_explains_signal (stop_bpstat)
- /* End of a stack dummy. Some systems (e.g. Sony
+ /* End of a stack dummy. Some systems (e.g. Sony
news) give another signal besides SIGTRAP,
so check here as well as above. */
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
|| PC_IN_CALL_DUMMY (stop_pc, read_sp (),
FRAME_FP (get_current_frame ()))
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
- );
+ );
if (!random_signal)
stop_signal = TARGET_SIGNAL_TRAP;
}
}
+
+ /* When we reach this point, we've pretty much decided
+ that the reason for stopping must've been a random
+ (unexpected) signal. */
+
else
random_signal = 1;
+ /* If a fork, vfork or exec event was seen, then there are two
+ possible responses we can make:
+
+ 1. If a catchpoint triggers for the event (random_signal == 0),
+ then we must stop now and issue a prompt. We will resume
+ the inferior when the user tells us to.
+ 2. If no catchpoint triggers for the event (random_signal == 1),
+ then we must resume the inferior now and keep checking.
+
+ In either case, we must take appropriate steps to "follow" the
+ the fork/vfork/exec when the inferior is resumed. For example,
+ if follow-fork-mode is "child", then we must detach from the
+ parent inferior and follow the new child inferior.
+
+ In either case, setting pending_follow causes the next resume()
+ to take the appropriate following action. */
+ process_event_stop_test:
+ if (w.kind == TARGET_WAITKIND_FORKED)
+ {
+ if (random_signal) /* I.e., no catchpoint triggered for this. */
+ {
+ trap_expected = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ goto keep_going;
+ }
+ }
+ else if (w.kind == TARGET_WAITKIND_VFORKED)
+ {
+ if (random_signal) /* I.e., no catchpoint triggered for this. */
+ {
+ stop_signal = TARGET_SIGNAL_0;
+ goto keep_going;
+ }
+ }
+ else if (w.kind == TARGET_WAITKIND_EXECD)
+ {
+ pending_follow.kind = w.kind;
+ if (random_signal) /* I.e., no catchpoint triggered for this. */
+ {
+ trap_expected = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ goto keep_going;
+ }
+ }
/* For the program's own signals, act according to
the signal handling tables. */
@@ -889,9 +1881,9 @@ wait_for_inferior ()
{
/* Signal not for debugging purposes. */
int printed = 0;
-
+
stopped_by_random_signal = 1;
-
+
if (signal_print[stop_signal])
{
printed = 1;
@@ -919,9 +1911,16 @@ wait_for_inferior ()
if (signal_program[stop_signal] == 0)
stop_signal = TARGET_SIGNAL_0;
- /* I'm not sure whether this needs to be check_sigtramp2 or
- whether it could/should be keep_going. */
- goto check_sigtramp2;
+ /* If we're in the middle of a "next" command, let the code for
+ stepping over a function handle this. pai/1997-09-10
+
+ A previous comment here suggested it was possible to change
+ this to jump to keep_going in all cases. */
+
+ if (step_over_calls > 0)
+ goto step_over_function;
+ else
+ goto check_sigtramp2;
}
/* Handle cases caused by hitting a breakpoint. */
@@ -945,10 +1944,11 @@ wait_for_inferior ()
/* If we hit the breakpoint at longjmp, disable it for the
duration of this command. Then, install a temporary
breakpoint at the target of the jmp_buf. */
- disable_longjmp_breakpoint();
+ disable_longjmp_breakpoint ();
remove_breakpoints ();
breakpoints_inserted = 0;
- if (!GET_LONGJMP_TARGET(&jmp_buf_pc)) goto keep_going;
+ if (!GET_LONGJMP_TARGET (&jmp_buf_pc))
+ goto keep_going;
/* Need to blow away step-resume breakpoint, as it
interferes with us */
@@ -968,12 +1968,12 @@ wait_for_inferior ()
#if 0
/* FIXME - Need to implement nested temporary breakpoints */
if (step_over_calls > 0)
- set_longjmp_resume_breakpoint(jmp_buf_pc,
- get_current_frame());
+ set_longjmp_resume_breakpoint (jmp_buf_pc,
+ get_current_frame ());
else
-#endif /* 0 */
- set_longjmp_resume_breakpoint(jmp_buf_pc, NULL);
- handling_longjmp = 1; /* FIXME */
+#endif /* 0 */
+ set_longjmp_resume_breakpoint (jmp_buf_pc, NULL);
+ handling_longjmp = 1; /* FIXME */
goto keep_going;
case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
@@ -983,22 +1983,25 @@ wait_for_inferior ()
#if 0
/* FIXME - Need to implement nested temporary breakpoints */
if (step_over_calls
- && (FRAME_FP (get_current_frame ())
- INNER_THAN step_frame_address))
+ && (INNER_THAN (FRAME_FP (get_current_frame ()),
+ step_frame_address)))
{
another_trap = 1;
goto keep_going;
}
-#endif /* 0 */
- disable_longjmp_breakpoint();
- handling_longjmp = 0; /* FIXME */
+#endif /* 0 */
+ disable_longjmp_breakpoint ();
+ handling_longjmp = 0; /* FIXME */
if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME)
break;
/* else fallthrough */
case BPSTAT_WHAT_SINGLE:
if (breakpoints_inserted)
- remove_breakpoints ();
+ {
+ thread_step_needed = 1;
+ remove_breakpoints ();
+ }
breakpoints_inserted = 0;
another_trap = 1;
/* Still need to check other stuff, at least the case
@@ -1024,6 +2027,23 @@ wait_for_inferior ()
goto stop_stepping;
case BPSTAT_WHAT_STEP_RESUME:
+ /* This proably demands a more elegant solution, but, yeah
+ right...
+
+ This function's use of the simple variable
+ step_resume_breakpoint doesn't seem to accomodate
+ simultaneously active step-resume bp's, although the
+ breakpoint list certainly can.
+
+ If we reach here and step_resume_breakpoint is already
+ NULL, then apparently we have multiple active
+ step-resume bp's. We'll just delete the breakpoint we
+ stopped at, and carry on. */
+ if (step_resume_breakpoint == NULL)
+ {
+ step_resume_breakpoint =
+ bpstat_find_step_resume_breakpoint (stop_bpstat);
+ }
delete_breakpoint (step_resume_breakpoint);
step_resume_breakpoint = NULL;
break;
@@ -1039,8 +2059,9 @@ wait_for_inferior ()
another_trap = 1;
break;
-#ifdef SOLIB_ADD
case BPSTAT_WHAT_CHECK_SHLIBS:
+ case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK:
+#ifdef SOLIB_ADD
{
extern int auto_solib_add;
@@ -1057,12 +2078,15 @@ wait_for_inferior ()
{
/* Switch terminal for any messages produced by
breakpoint_re_set. */
- target_terminal_ours_for_output ();
+ target_terminal_ours_for_output ();
SOLIB_ADD (NULL, 0, NULL);
- re_enable_breakpoints_in_shlibs ();
- target_terminal_inferior ();
+ target_terminal_inferior ();
}
+ /* Try to reenable shared library breakpoints, additional
+ code segments in shared libraries might be mapped in now. */
+ re_enable_breakpoints_in_shlibs ();
+
/* If requested, stop when the dynamic linker notifies
gdb of events. This allows the user to get control
and place breakpoints in initializer routines for
@@ -1072,6 +2096,40 @@ wait_for_inferior ()
stop_print_frame = 0;
goto stop_stepping;
}
+
+ /* If we stopped due to an explicit catchpoint, then the
+ (see above) call to SOLIB_ADD pulled in any symbols
+ from a newly-loaded library, if appropriate.
+
+ We do want the inferior to stop, but not where it is
+ now, which is in the dynamic linker callback. Rather,
+ we would like it stop in the user's program, just after
+ the call that caused this catchpoint to trigger. That
+ gives the user a more useful vantage from which to
+ examine their program's state. */
+ else if (what.main_action == BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK)
+ {
+ /* ??rehrauer: If I could figure out how to get the
+ right return PC from here, we could just set a temp
+ breakpoint and resume. I'm not sure we can without
+ cracking open the dld's shared libraries and sniffing
+ their unwind tables and text/data ranges, and that's
+ not a terribly portable notion.
+
+ Until that time, we must step the inferior out of the
+ dld callback, and also out of the dld itself (and any
+ code or stubs in libdld.sl, such as "shl_load" and
+ friends) until we reach non-dld code. At that point,
+ we can stop stepping. */
+ bpstat_get_triggered_catchpoints (stop_bpstat,
+ &stepping_through_solib_catchpoints);
+ stepping_through_solib_after_catch = 1;
+
+ /* Be sure to lift all breakpoints, so the inferior does
+ actually step past this point... */
+ another_trap = 1;
+ break;
+ }
else
{
/* We want to step over this breakpoint, then keep going. */
@@ -1080,6 +2138,7 @@ wait_for_inferior ()
}
}
#endif
+ break;
case BPSTAT_WHAT_LAST:
/* Not a real code, but listed here to shut up gcc -Wall. */
@@ -1095,6 +2154,29 @@ wait_for_inferior ()
test for stepping. But, if not stepping,
do not stop. */
+ /* Are we stepping to get the inferior out of the dynamic
+ linker's hook (and possibly the dld itself) after catching
+ a shlib event? */
+ if (stepping_through_solib_after_catch)
+ {
+#if defined(SOLIB_ADD)
+ /* Have we reached our destination? If not, keep going. */
+ if (SOLIB_IN_DYNAMIC_LINKER (pid, stop_pc))
+ {
+ another_trap = 1;
+ goto keep_going;
+ }
+#endif
+ /* Else, stop and report the catchpoint(s) whose triggering
+ caused us to begin stepping. */
+ stepping_through_solib_after_catch = 0;
+ bpstat_clear (&stop_bpstat);
+ stop_bpstat = bpstat_copy (stepping_through_solib_catchpoints);
+ bpstat_clear (&stepping_through_solib_catchpoints);
+ stop_print_frame = 1;
+ goto stop_stepping;
+ }
+
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
/* This is the old way of detecting the end of the stack dummy.
An architecture which defines CALL_DUMMY_BREAKPOINT_OFFSET gets
@@ -1105,7 +2187,8 @@ wait_for_inferior ()
just stop silently, unless the user was doing an si/ni, in which
case she'd better know what she's doing. */
- if (PC_IN_CALL_DUMMY (stop_pc, read_sp (), FRAME_FP (get_current_frame ()))
+ if (CALL_DUMMY_HAS_COMPLETED (stop_pc, read_sp (),
+ FRAME_FP (get_current_frame ()))
&& !step_range_end)
{
stop_print_frame = 0;
@@ -1131,23 +2214,27 @@ wait_for_inferior ()
whether it could/should be keep_going. */
goto check_sigtramp2;
- /* If stepping through a line, keep going if still within it. */
+ /* If stepping through a line, keep going if still within it.
+
+ Note that step_range_end is the address of the first instruction
+ beyond the step range, and NOT the address of the last instruction
+ within it! */
if (stop_pc >= step_range_start
&& stop_pc < step_range_end
#if 0
-/* I haven't a clue what might trigger this clause, and it seems wrong anyway,
- so I've disabled it until someone complains. -Stu 10/24/95 */
+/* I haven't a clue what might trigger this clause, and it seems wrong
+ anyway, so I've disabled it until someone complains. -Stu 10/24/95 */
- /* The step range might include the start of the
+ /* The step range might include the start of the
function, so if we are at the start of the
step range and either the stack or frame pointers
just changed, we've stepped outside */
&& !(stop_pc == step_range_start
&& FRAME_FP (get_current_frame ())
- && (read_sp () INNER_THAN step_sp
+ && (INNER_THAN (read_sp (), step_sp)
|| FRAME_FP (get_current_frame ()) != step_frame_address))
#endif
-)
+ )
{
/* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal.
So definately need to check for sigtramp here. */
@@ -1156,6 +2243,13 @@ wait_for_inferior ()
/* We stepped out of the stepping range. */
+ /* If we are stepping at the source level and entered the runtime
+ loader dynamic symbol resolution code, we keep on single stepping
+ until we exit the run time loader code and reach the callee's
+ address. */
+ if (step_over_calls < 0 && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
+ goto keep_going;
+
/* We can't update step_sp every time through the loop, because
reading the stack pointer would slow down stepping too much.
But we can update it every time we leave the step range. */
@@ -1163,34 +2257,75 @@ wait_for_inferior ()
/* Did we just take a signal? */
if (IN_SIGTRAMP (stop_pc, stop_func_name)
- && !IN_SIGTRAMP (prev_pc, prev_func_name))
+ && !IN_SIGTRAMP (prev_pc, prev_func_name)
+ && INNER_THAN (read_sp (), step_sp))
{
/* We've just taken a signal; go until we are back to
the point where we took it and one more. */
- /* This code is needed at least in the following case:
- The user types "next" and then a signal arrives (before
- the "next" is done). */
+ /* Note: The test above succeeds not only when we stepped
+ into a signal handler, but also when we step past the last
+ statement of a signal handler and end up in the return stub
+ of the signal handler trampoline. To distinguish between
+ these two cases, check that the frame is INNER_THAN the
+ previous one below. pai/1997-09-11 */
- /* Note that if we are stopped at a breakpoint, then we need
- the step_resume breakpoint to override any breakpoints at
- the same location, so that we will still step over the
- breakpoint even though the signal happened. */
{
- struct symtab_and_line sr_sal;
+ CORE_ADDR current_frame = FRAME_FP (get_current_frame ());
- sr_sal.pc = prev_pc;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
- /* We could probably be setting the frame to
- step_frame_address; I don't think anyone thought to try it. */
- step_resume_breakpoint =
- set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
- if (breakpoints_inserted)
- insert_breakpoints ();
+ if (INNER_THAN (current_frame, step_frame_address))
+ {
+ /* We have just taken a signal; go until we are back to
+ the point where we took it and one more. */
+
+ /* This code is needed at least in the following case:
+ The user types "next" and then a signal arrives (before
+ the "next" is done). */
+
+ /* Note that if we are stopped at a breakpoint, then we need
+ the step_resume breakpoint to override any breakpoints at
+ the same location, so that we will still step over the
+ breakpoint even though the signal happened. */
+ struct symtab_and_line sr_sal;
+
+ INIT_SAL (&sr_sal);
+ sr_sal.symtab = NULL;
+ sr_sal.line = 0;
+ sr_sal.pc = prev_pc;
+ /* We could probably be setting the frame to
+ step_frame_address; I don't think anyone thought to
+ try it. */
+ step_resume_breakpoint =
+ set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+ }
+ else
+ {
+ /* We just stepped out of a signal handler and into
+ its calling trampoline.
+
+ Normally, we'd jump to step_over_function from
+ here, but for some reason GDB can't unwind the
+ stack correctly to find the real PC for the point
+ user code where the signal trampoline will return
+ -- FRAME_SAVED_PC fails, at least on HP-UX 10.20.
+ But signal trampolines are pretty small stubs of
+ code, anyway, so it's OK instead to just
+ single-step out. Note: assuming such trampolines
+ don't exhibit recursion on any platform... */
+ find_pc_partial_function (stop_pc, &stop_func_name,
+ &stop_func_start,
+ &stop_func_end);
+ /* Readjust stepping range */
+ step_range_start = stop_func_start;
+ step_range_end = stop_func_end;
+ stepping_through_sigtramp = 1;
+ }
}
+
/* If this is stepi or nexti, make sure that the stepping range
gets us past that instruction. */
if (step_range_end == 1)
@@ -1204,11 +2339,12 @@ wait_for_inferior ()
}
#if 0
- /* I disabled this test because it was too complicated and slow. The
- SKIP_PROLOGUE was especially slow, because it caused unnecessary
- prologue examination on various architectures. The code in the #else
- clause has been tested on the Sparc, Mips, PA, and Power
- architectures, so it's pretty likely to be correct. -Stu 10/24/95 */
+ /* I disabled this test because it was too complicated and slow.
+ The SKIP_PROLOGUE was especially slow, because it caused
+ unnecessary prologue examination on various architectures.
+ The code in the #else clause has been tested on the Sparc,
+ Mips, PA, and Power architectures, so it's pretty likely to
+ be correct. -Stu 10/24/95 */
/* See if we left the step range due to a subroutine call that
we should proceed to the end of. */
@@ -1227,61 +2363,64 @@ wait_for_inferior ()
SKIP_PROLOGUE (prologue_pc);
}
- if ((/* Might be a non-recursive call. If the symbols are missing
- enough that stop_func_start == prev_func_start even though
- they are really two functions, we will treat some calls as
- jumps. */
- stop_func_start != prev_func_start
-
- /* Might be a recursive call if either we have a prologue
- or the call instruction itself saves the PC on the stack. */
- || prologue_pc != stop_func_start
- || read_sp () != step_sp)
- && (/* PC is completely out of bounds of any known objfiles. Treat
+ if (!(INNER_THAN (step_sp, read_sp ())) /* don't mistake (sig)return
+ as a call */
+ && ( /* Might be a non-recursive call. If the symbols are missing
+ enough that stop_func_start == prev_func_start even though
+ they are really two functions, we will treat some calls as
+ jumps. */
+ stop_func_start != prev_func_start
+
+ /* Might be a recursive call if either we have a prologue
+ or the call instruction itself saves the PC on the stack. */
+ || prologue_pc != stop_func_start
+ || read_sp () != step_sp)
+ && ( /* PC is completely out of bounds of any known objfiles. Treat
like a subroutine call. */
- ! stop_func_start
+ !stop_func_start
- /* If we do a call, we will be at the start of a function... */
- || stop_pc == stop_func_start
+ /* If we do a call, we will be at the start of a function... */
+ || stop_pc == stop_func_start
- /* ...except on the Alpha with -O (and also Irix 5 and
+ /* ...except on the Alpha with -O (and also Irix 5 and
perhaps others), in which we might call the address
after the load of gp. Since prologues don't contain
calls, we can't return to within one, and we don't
jump back into them, so this check is OK. */
- || stop_pc < prologue_pc
+ || stop_pc < prologue_pc
- /* ...and if it is a leaf function, the prologue might
+ /* ...and if it is a leaf function, the prologue might
consist of gp loading only, so the call transfers to
the first instruction after the prologue. */
- || (stop_pc == prologue_pc
+ || (stop_pc == prologue_pc
- /* Distinguish this from the case where we jump back
+ /* Distinguish this from the case where we jump back
to the first instruction after the prologue,
within a function. */
&& stop_func_start != prev_func_start)
- /* If we end up in certain places, it means we did a subroutine
+ /* If we end up in certain places, it means we did a subroutine
call. I'm not completely sure this is necessary now that we
have the above checks with stop_func_start (and now that
find_pc_partial_function is pickier). */
- || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
+ || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
- /* If none of the above apply, it is a jump within a function,
+ /* If none of the above apply, it is a jump within a function,
or a return from a subroutine. The other case is longjmp,
which can no longer happen here as long as the
handling_longjmp stuff is working. */
- ))
+ ))
#else
- /* This test is a much more streamlined, (but hopefully correct)
+ /* This test is a much more streamlined, (but hopefully correct)
replacement for the code above. It's been tested on the Sparc,
Mips, PA, and Power architectures with good results. */
- if (stop_pc == stop_func_start /* Quick test */
- || in_prologue (stop_pc, stop_func_start)
- || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
- || stop_func_start == 0)
+ if (stop_pc == stop_func_start /* Quick test */
+ || (in_prologue (stop_pc, stop_func_start) &&
+ !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, stop_func_name))
+ || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
+ || stop_func_name == 0)
#endif
{
@@ -1296,7 +2435,7 @@ wait_for_inferior ()
break;
}
- if (step_over_calls > 0)
+ if (step_over_calls > 0 || IGNORE_HELPER_CALL (stop_pc))
/* We're doing a "next". */
goto step_over_function;
@@ -1314,11 +2453,12 @@ wait_for_inferior ()
if (tmp)
{
struct symtab_and_line xxx;
-
+ /* Why isn't this s_a_l called "sr_sal", like all of the
+ other s_a_l's where this code is duplicated? */
+ INIT_SAL (&xxx); /* initialize to zeroes */
xxx.pc = tmp;
- xxx.symtab = NULL;
- xxx.line = 0;
- step_resume_breakpoint =
+ xxx.section = find_pc_overlay (xxx.pc);
+ step_resume_breakpoint =
set_momentary_breakpoint (xxx, NULL, bp_step_resume);
insert_breakpoints ();
goto keep_going;
@@ -1339,26 +2479,62 @@ wait_for_inferior ()
goto step_into_function;
}
-step_over_function:
+ step_over_function:
/* A subroutine call has happened. */
{
/* Set a special breakpoint after the return */
struct symtab_and_line sr_sal;
- sr_sal.pc =
- ADDR_BITS_REMOVE
- (SAVED_PC_AFTER_CALL (get_current_frame ()));
+
+ INIT_SAL (&sr_sal);
sr_sal.symtab = NULL;
sr_sal.line = 0;
+
+ /* If we came here after encountering a signal in the middle of
+ a "next", use the stashed-away previous frame pc */
+ sr_sal.pc
+ = stopped_by_random_signal
+ ? prev_pc
+ : ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ()));
+
step_resume_breakpoint =
- set_momentary_breakpoint (sr_sal, get_current_frame (),
+ set_momentary_breakpoint (sr_sal,
+ stopped_by_random_signal ?
+ NULL : get_current_frame (),
bp_step_resume);
- step_resume_breakpoint->frame = step_frame_address;
+
+ /* We've just entered a callee, and we wish to resume until
+ it returns to the caller. Setting a step_resume bp on
+ the return PC will catch a return from the callee.
+
+ However, if the callee is recursing, we want to be
+ careful not to catch returns of those recursive calls,
+ but of THIS instance of the call.
+
+ To do this, we set the step_resume bp's frame to our
+ current caller's frame (step_frame_address, which is
+ set by the "next" or "until" command, before execution
+ begins).
+
+ But ... don't do it if we're single-stepping out of a
+ sigtramp, because the reason we're single-stepping is
+ precisely because unwinding is a problem (HP-UX 10.20,
+ e.g.) and the frame address is likely to be incorrect.
+ No danger of sigtramp recursion. */
+
+ if (stepping_through_sigtramp)
+ {
+ step_resume_breakpoint->frame = (CORE_ADDR) NULL;
+ stepping_through_sigtramp = 0;
+ }
+ else if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+ step_resume_breakpoint->frame = step_frame_address;
+
if (breakpoints_inserted)
insert_breakpoints ();
}
goto keep_going;
-step_into_function:
+ step_into_function:
/* Subroutine call with source code we should not step over.
Do step to the first line of code in it. */
{
@@ -1394,9 +2570,9 @@ step_into_function:
{
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = stop_func_start;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
+ sr_sal.section = find_pc_overlay (stop_func_start);
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
@@ -1413,7 +2589,7 @@ step_into_function:
/* We've wandered out of the step range. */
- sal = find_pc_line(stop_pc, 0);
+ sal = find_pc_line (stop_pc, 0);
if (step_range_end == 1)
{
@@ -1425,7 +2601,7 @@ step_into_function:
/* If we're in the return path from a shared library trampoline,
we want to proceed through the trampoline when stepping. */
- if (IN_SOLIB_RETURN_TRAMPOLINE(stop_pc, stop_func_name))
+ if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, stop_func_name))
{
CORE_ADDR tmp;
@@ -1438,9 +2614,9 @@ step_into_function:
/* And put the step-breakpoint there and go until there. */
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = tmp;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
@@ -1454,7 +2630,7 @@ step_into_function:
goto keep_going;
}
}
-
+
if (sal.line == 0)
{
/* We have no line number information. That means to stop
@@ -1465,7 +2641,7 @@ step_into_function:
break;
}
- if (stop_pc == sal.pc
+ if ((stop_pc == sal.pc)
&& (current_line != sal.line || current_symtab != sal.symtab))
{
/* We are at the start of a different line. So stop. Note that
@@ -1480,7 +2656,7 @@ step_into_function:
Optimize by setting the stepping range to the line.
(We might not be in the original line, but if we entered a
- new line in mid-statement, we continue stepping. This makes
+ new line in mid-statement, we continue stepping. This makes
things like for(;;) statements work better.) */
if (stop_func_end && sal.end >= stop_func_end)
@@ -1495,12 +2671,27 @@ step_into_function:
}
step_range_start = sal.pc;
step_range_end = sal.end;
+ step_frame_address = FRAME_FP (get_current_frame ());
+ current_line = sal.line;
+ current_symtab = sal.symtab;
+
+ /* In the case where we just stepped out of a function into the middle
+ of a line of the caller, continue stepping, but step_frame_address
+ must be modified to current frame */
+ {
+ CORE_ADDR current_frame = FRAME_FP (get_current_frame ());
+ if (!(INNER_THAN (current_frame, step_frame_address)))
+ step_frame_address = current_frame;
+ }
+
+
goto keep_going;
check_sigtramp2:
if (trap_expected
&& IN_SIGTRAMP (stop_pc, stop_func_name)
- && !IN_SIGTRAMP (prev_pc, prev_func_name))
+ && !IN_SIGTRAMP (prev_pc, prev_func_name)
+ && INNER_THAN (read_sp (), step_sp))
{
/* What has happened here is that we have just stepped the inferior
with a signal (because it is a signal which shouldn't make
@@ -1514,9 +2705,9 @@ step_into_function:
it says "exceedingly difficult"). */
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = prev_pc;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
/* We perhaps could set the frame if we kept track of what
the frame corresponding to prev_pc was. But we don't,
so don't. */
@@ -1534,9 +2725,20 @@ step_into_function:
It's really much cleaner to do a goto than a maze of if-else
conditions. */
+ /* ??rehrauer: ttrace on HP-UX theoretically allows one to debug
+ a vforked child beetween its creation and subsequent exit or
+ call to exec(). However, I had big problems in this rather
+ creaky exec engine, getting that to work. The fundamental
+ problem is that I'm trying to debug two processes via an
+ engine that only understands a single process with possibly
+ multiple threads.
+
+ Hence, this spot is known to have problems when
+ target_can_follow_vfork_prior_to_exec returns 1. */
+
/* Save the pc before execution, to compare with pc after stop. */
prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */
- prev_func_start = stop_func_start; /* Ok, since if DECR_PC_AFTER
+ prev_func_start = stop_func_start; /* Ok, since if DECR_PC_AFTER
BREAK is defined, the
original pc would not have
been at the start of a
@@ -1591,29 +2793,67 @@ step_into_function:
trap_expected = another_trap;
- if (stop_signal == TARGET_SIGNAL_TRAP)
+ /* Do not deliver SIGNAL_TRAP (except when the user
+ explicitly specifies that such a signal should be
+ delivered to the target program).
+
+ Typically, this would occure when a user is debugging a
+ target monitor on a simulator: the target monitor sets a
+ breakpoint; the simulator encounters this break-point and
+ halts the simulation handing control to GDB; GDB, noteing
+ that the break-point isn't valid, returns control back to
+ the simulator; the simulator then delivers the hardware
+ equivalent of a SIGNAL_TRAP to the program being
+ debugged. */
+
+ if (stop_signal == TARGET_SIGNAL_TRAP
+ && !signal_program[stop_signal])
stop_signal = TARGET_SIGNAL_0;
#ifdef SHIFT_INST_REGS
- /* I'm not sure when this following segment applies. I do know, now,
- that we shouldn't rewrite the regs when we were stopped by a
- random signal from the inferior process. */
+ /* I'm not sure when this following segment applies. I do know,
+ now, that we shouldn't rewrite the regs when we were stopped
+ by a random signal from the inferior process. */
/* FIXME: Shouldn't this be based on the valid bit of the SXIP?
(this is only used on the 88k). */
- if (!bpstat_explains_signal (stop_bpstat)
- && (stop_signal != TARGET_SIGNAL_CHLD)
- && !stopped_by_random_signal)
- SHIFT_INST_REGS();
+ if (!bpstat_explains_signal (stop_bpstat)
+ && (stop_signal != TARGET_SIGNAL_CHLD)
+ && !stopped_by_random_signal)
+ SHIFT_INST_REGS ();
#endif /* SHIFT_INST_REGS */
resume (CURRENTLY_STEPPING (), stop_signal);
}
}
- stop_stepping:
+stop_stepping:
if (target_has_execution)
{
+ /* Are we stopping for a vfork event? We only stop when we see
+ the child's event. However, we may not yet have seen the
+ parent's event. And, inferior_pid is still set to the parent's
+ pid, until we resume again and follow either the parent or child.
+
+ To ensure that we can really touch inferior_pid (aka, the
+ parent process) -- which calls to functions like read_pc
+ implicitly do -- wait on the parent if necessary. */
+ if ((pending_follow.kind == TARGET_WAITKIND_VFORKED)
+ && !pending_follow.fork_event.saw_parent_fork)
+ {
+ int parent_pid;
+
+ do
+ {
+ if (target_wait_hook)
+ parent_pid = target_wait_hook (-1, &w);
+ else
+ parent_pid = target_wait (-1, &w);
+ }
+ while (parent_pid != inferior_pid);
+ }
+
+
/* Assuming the inferior still exists, set these up for next
time, just like we did above if we didn't break out of the
loop. */
@@ -1623,7 +2863,73 @@ step_into_function:
}
do_cleanups (old_cleanups);
}
+
+/* This function returns TRUE if ep is an internal breakpoint
+ set to catch generic shared library (aka dynamically-linked
+ library) events. (This is *NOT* the same as a catchpoint for a
+ shlib event. The latter is something a user can set; this is
+ something gdb sets for its own use, and isn't ever shown to a
+ user.) */
+static int
+is_internal_shlib_eventpoint (ep)
+ struct breakpoint *ep;
+{
+ return
+ (ep->type == bp_shlib_event)
+ ;
+}
+
+/* This function returns TRUE if bs indicates that the inferior
+ stopped due to a shared library (aka dynamically-linked library)
+ event. */
+static int
+stopped_for_internal_shlib_event (bs)
+ bpstat bs;
+{
+ /* Note that multiple eventpoints may've caused the stop. Any
+ that are associated with shlib events will be accepted. */
+ for (; bs != NULL; bs = bs->next)
+ {
+ if ((bs->breakpoint_at != NULL)
+ && is_internal_shlib_eventpoint (bs->breakpoint_at))
+ return 1;
+ }
+
+ /* If we get here, then no candidate was found. */
+ return 0;
+}
+
+/* This function returns TRUE if bs indicates that the inferior
+ stopped due to a shared library (aka dynamically-linked library)
+ event caught by a catchpoint.
+
+ If TRUE, cp_p is set to point to the catchpoint.
+
+ Else, the value of cp_p is undefined. */
+static int
+stopped_for_shlib_catchpoint (bs, cp_p)
+ bpstat bs;
+ struct breakpoint **cp_p;
+{
+ /* Note that multiple eventpoints may've caused the stop. Any
+ that are associated with shlib events will be accepted. */
+ *cp_p = NULL;
+
+ for (; bs != NULL; bs = bs->next)
+ {
+ if ((bs->breakpoint_at != NULL)
+ && ep_is_shlib_catchpoint (bs->breakpoint_at))
+ {
+ *cp_p = bs->breakpoint_at;
+ return 1;
+ }
+ }
+
+ /* If we get here, then no candidate was found. */
+ return 0;
+}
+
/* Here to return control to GDB when the inferior stops for real.
Print appropriate messages, remove breakpoints, give terminal our modes.
@@ -1635,12 +2941,30 @@ step_into_function:
void
normal_stop ()
{
+
+#ifdef HPUXHPPA
+ /* As with the notification of thread events, we want to delay
+ notifying the user that we've switched thread context until
+ the inferior actually stops.
+
+ (Note that there's no point in saying anything if the inferior
+ has exited!) */
+ if ((switched_from_inferior_pid != inferior_pid) &&
+ target_has_execution)
+ {
+ target_terminal_ours_for_output ();
+ printf_filtered ("[Switched to %s]\n",
+ target_pid_or_tid_to_str (inferior_pid));
+ switched_from_inferior_pid = inferior_pid;
+ }
+#endif
+
/* Make sure that the current_frame's pc is correct. This
is a correction for setting up the frame info before doing
DECR_PC_AFTER_BREAK */
- if (target_has_execution && get_current_frame())
+ if (target_has_execution && get_current_frame ())
(get_current_frame ())->pc = read_pc ();
-
+
if (breakpoints_failed)
{
target_terminal_ours_for_output ();
@@ -1650,14 +2974,16 @@ The same program may be running in another process.\n");
}
if (target_has_execution && breakpoints_inserted)
- if (remove_breakpoints ())
- {
- target_terminal_ours_for_output ();
- printf_filtered ("Cannot remove breakpoints because program is no longer writable.\n\
-It might be running in another process.\n\
-Further execution is probably impossible.\n");
- }
-
+ {
+ if (remove_breakpoints ())
+ {
+ target_terminal_ours_for_output ();
+ printf_filtered ("Cannot remove breakpoints because ");
+ printf_filtered ("program is no longer writable.\n");
+ printf_filtered ("It might be running in another process.\n");
+ printf_filtered ("Further execution is probably impossible.\n");
+ }
+ }
breakpoints_inserted = 0;
/* Delete the breakpoint we stopped at, if it wants to be deleted.
@@ -1671,46 +2997,80 @@ Further execution is probably impossible.\n");
if (stopped_by_random_signal)
disable_current_display ();
+ /* Don't print a message if in the middle of doing a "step n"
+ operation for n > 1 */
if (step_multi && stop_step)
goto done;
target_terminal_ours ();
- if (stop_bpstat
- && stop_bpstat->breakpoint_at
- && stop_bpstat->breakpoint_at->type == bp_shlib_event)
- printf_filtered ("Stopped due to shared library event\n");
+ /* Did we stop because the user set the stop_on_solib_events
+ variable? (If so, we report this as a generic, "Stopped due
+ to shlib event" message.) */
+ if (stopped_for_internal_shlib_event (stop_bpstat))
+ {
+ printf_filtered ("Stopped due to shared library event\n");
+ }
/* Look up the hook_stop and run it if it exists. */
- if (stop_command->hook)
+ if (stop_command && stop_command->hook)
{
- catch_errors (hook_stop_stub, (char *)stop_command->hook,
+ catch_errors (hook_stop_stub, stop_command->hook,
"Error while running hook_stop:\n", RETURN_MASK_ALL);
}
if (!target_has_stack)
- goto done;
+ {
+
+ goto done;
+ }
+
+ /* Select innermost stack frame - i.e., current frame is frame 0,
+ and current location is based on that.
+ Don't do this on return from a stack dummy routine,
+ or if the program has exited. */
- /* Select innermost stack frame except on return from a stack dummy routine,
- or if the program has exited. Print it without a level number if
- we have changed functions or hit a breakpoint. Print source line
- if we have one. */
if (!stop_stack_dummy)
{
select_frame (get_current_frame (), 0);
+ /* Print current location without a level number, if
+ we have changed functions or hit a breakpoint.
+ Print source line if we have one.
+ bpstat_print() contains the logic deciding in detail
+ what to print, based on the event(s) that just occurred. */
+
if (stop_print_frame)
{
- int source_only;
-
- source_only = bpstat_print (stop_bpstat);
- source_only = source_only ||
- ( stop_step
- && step_frame_address == FRAME_FP (get_current_frame ())
- && step_start_function == find_pc_function (stop_pc));
-
- print_stack_frame (selected_frame, -1, source_only? -1: 1);
+ int bpstat_ret;
+ int source_flag;
+
+ bpstat_ret = bpstat_print (stop_bpstat);
+ /* bpstat_print() returned one of:
+ -1: Didn't print anything
+ 0: Printed preliminary "Breakpoint n, " message, desires
+ location tacked on
+ 1: Printed something, don't tack on location */
+
+ if (bpstat_ret == -1)
+ if (stop_step
+ && step_frame_address == FRAME_FP (get_current_frame ())
+ && step_start_function == find_pc_function (stop_pc))
+ source_flag = -1; /* finished step, just print source line */
+ else
+ source_flag = 1; /* print location and source line */
+ else if (bpstat_ret == 0) /* hit bpt, desire location */
+ source_flag = 1; /* print location and source line */
+ else /* bpstat_ret == 1, hit bpt, do not desire location */
+ source_flag = -1; /* just print source line */
+
+ /* The behavior of this routine with respect to the source
+ flag is:
+ -1: Print only source line
+ 0: Print only location
+ 1: Print location and source line */
+ show_and_print_stack_frame (selected_frame, -1, source_flag);
/* Display the auto-display expressions. */
do_displays ();
@@ -1728,37 +3088,44 @@ Further execution is probably impossible.\n");
POP_FRAME ends with a setting of the current frame, so we
can use that next. */
POP_FRAME;
- /* Set stop_pc to what it was before we called the function. Can't rely
- on restore_inferior_status because that only gets called if we don't
- stop in the called function. */
- stop_pc = read_pc();
+ /* Set stop_pc to what it was before we called the function.
+ Can't rely on restore_inferior_status because that only gets
+ called if we don't stop in the called function. */
+ stop_pc = read_pc ();
select_frame (get_current_frame (), 0);
}
- done:
+
+
+ TUIDO (((TuiOpaqueFuncPtr) tui_vCheckDataValues, selected_frame));
+
+done:
annotate_stopped ();
}
static int
hook_stop_stub (cmd)
- char *cmd;
+ PTR cmd;
{
- execute_user_command ((struct cmd_list_element *)cmd, 0);
+ execute_user_command ((struct cmd_list_element *) cmd, 0);
return (0);
}
-int signal_stop_state (signo)
+int
+signal_stop_state (signo)
int signo;
{
return signal_stop[signo];
}
-int signal_print_state (signo)
+int
+signal_print_state (signo)
int signo;
{
return signal_print[signo];
}
-int signal_pass_state (signo)
+int
+signal_pass_state (signo)
int signo;
{
return signal_program[signo];
@@ -1776,8 +3143,12 @@ sig_print_info (oursig)
enum target_signal oursig;
{
char *name = target_signal_to_name (oursig);
+ int name_padding = 13 - strlen (name);
+ if (name_padding <= 0)
+ name_padding = 0;
+
printf_filtered ("%s", name);
- printf_filtered ("%*.*s ", 13 - strlen (name), 13 - strlen (name),
+ printf_filtered ("%*.*s ", name_padding, name_padding,
" ");
printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
@@ -1808,7 +3179,7 @@ handle_command (args, from_tty)
/* Allocate and zero an array of flags for which signals to handle. */
- nsigs = (int)TARGET_SIGNAL_LAST;
+ nsigs = (int) TARGET_SIGNAL_LAST;
sigs = (unsigned char *) alloca (nsigs);
memset (sigs, 0, nsigs);
@@ -1819,7 +3190,7 @@ handle_command (args, from_tty)
{
nomem (0);
}
- old_chain = make_cleanup (freeargv, (char *) argv);
+ old_chain = make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
/* Walk through the args, looking for signal oursigs, signal names, and
actions. Signal numbers and signal names may be interspersed with
@@ -1829,7 +3200,9 @@ handle_command (args, from_tty)
while (*argv != NULL)
{
wordlen = strlen (*argv);
- for (digits = 0; isdigit ((*argv)[digits]); digits++) {;}
+ for (digits = 0; isdigit ((*argv)[digits]); digits++)
+ {;
+ }
allsigs = 0;
sigfirst = siglast = -1;
@@ -1877,17 +3250,18 @@ handle_command (args, from_tty)
}
else if (digits > 0)
{
- /* It is numeric. The numeric signal refers to our own internal
- signal numbering from target.h, not to host/target signal number.
- This is a feature; users really should be using symbolic names
- anyway, and the common ones like SIGHUP, SIGINT, SIGALRM, etc.
- will work right anyway. */
-
- sigfirst = siglast = (int) target_signal_from_command (atoi (*argv));
+ /* It is numeric. The numeric signal refers to our own
+ internal signal numbering from target.h, not to host/target
+ signal number. This is a feature; users really should be
+ using symbolic names anyway, and the common ones like
+ SIGHUP, SIGINT, SIGALRM, etc. will work right anyway. */
+
+ sigfirst = siglast = (int)
+ target_signal_from_command (atoi (*argv));
if ((*argv)[digits] == '-')
{
- siglast =
- (int) target_signal_from_command (atoi ((*argv) + digits + 1));
+ siglast = (int)
+ target_signal_from_command (atoi ((*argv) + digits + 1));
}
if (sigfirst > siglast)
{
@@ -1902,7 +3276,7 @@ handle_command (args, from_tty)
oursig = target_signal_from_name (*argv);
if (oursig != TARGET_SIGNAL_UNKNOWN)
{
- sigfirst = siglast = (int)oursig;
+ sigfirst = siglast = (int) oursig;
}
else
{
@@ -1916,41 +3290,41 @@ handle_command (args, from_tty)
for (signum = sigfirst; signum >= 0 && signum <= siglast; signum++)
{
- switch ((enum target_signal)signum)
+ switch ((enum target_signal) signum)
{
- case TARGET_SIGNAL_TRAP:
- case TARGET_SIGNAL_INT:
- if (!allsigs && !sigs[signum])
- {
- if (query ("%s is used by the debugger.\n\
+ case TARGET_SIGNAL_TRAP:
+ case TARGET_SIGNAL_INT:
+ if (!allsigs && !sigs[signum])
+ {
+ if (query ("%s is used by the debugger.\n\
Are you sure you want to change it? ",
- target_signal_to_name
- ((enum target_signal)signum)))
- {
- sigs[signum] = 1;
- }
- else
- {
- printf_unfiltered ("Not confirmed, unchanged.\n");
- gdb_flush (gdb_stdout);
- }
- }
- break;
- case TARGET_SIGNAL_0:
- case TARGET_SIGNAL_DEFAULT:
- case TARGET_SIGNAL_UNKNOWN:
- /* Make sure that "all" doesn't print these. */
- break;
- default:
- sigs[signum] = 1;
- break;
+ target_signal_to_name
+ ((enum target_signal) signum)))
+ {
+ sigs[signum] = 1;
+ }
+ else
+ {
+ printf_unfiltered ("Not confirmed, unchanged.\n");
+ gdb_flush (gdb_stdout);
+ }
+ }
+ break;
+ case TARGET_SIGNAL_0:
+ case TARGET_SIGNAL_DEFAULT:
+ case TARGET_SIGNAL_UNKNOWN:
+ /* Make sure that "all" doesn't print these. */
+ break;
+ default:
+ sigs[signum] = 1;
+ break;
}
}
argv++;
}
- target_notice_signals(inferior_pid);
+ target_notice_signals (inferior_pid);
if (from_tty)
{
@@ -1968,6 +3342,75 @@ Are you sure you want to change it? ",
do_cleanups (old_chain);
}
+static void
+xdb_handle_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char **argv;
+ struct cleanup *old_chain;
+
+ /* Break the command line up into args. */
+
+ argv = buildargv (args);
+ if (argv == NULL)
+ {
+ nomem (0);
+ }
+ old_chain = make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
+ if (argv[1] != (char *) NULL)
+ {
+ char *argBuf;
+ int bufLen;
+
+ bufLen = strlen (argv[0]) + 20;
+ argBuf = (char *) xmalloc (bufLen);
+ if (argBuf)
+ {
+ int validFlag = 1;
+ enum target_signal oursig;
+
+ oursig = target_signal_from_name (argv[0]);
+ memset (argBuf, 0, bufLen);
+ if (strcmp (argv[1], "Q") == 0)
+ sprintf (argBuf, "%s %s", argv[0], "noprint");
+ else
+ {
+ if (strcmp (argv[1], "s") == 0)
+ {
+ if (!signal_stop[oursig])
+ sprintf (argBuf, "%s %s", argv[0], "stop");
+ else
+ sprintf (argBuf, "%s %s", argv[0], "nostop");
+ }
+ else if (strcmp (argv[1], "i") == 0)
+ {
+ if (!signal_program[oursig])
+ sprintf (argBuf, "%s %s", argv[0], "pass");
+ else
+ sprintf (argBuf, "%s %s", argv[0], "nopass");
+ }
+ else if (strcmp (argv[1], "r") == 0)
+ {
+ if (!signal_print[oursig])
+ sprintf (argBuf, "%s %s", argv[0], "print");
+ else
+ sprintf (argBuf, "%s %s", argv[0], "noprint");
+ }
+ else
+ validFlag = 0;
+ }
+ if (validFlag)
+ handle_command (argBuf, from_tty);
+ else
+ printf_filtered ("Invalid signal handling flag.\n");
+ if (argBuf)
+ free (argBuf);
+ }
+ }
+ do_cleanups (old_chain);
+}
+
/* Print current contents of the tables set by the handle command.
It is possible we should just be printing signals actually used
by the current target (but for things to work right when switching
@@ -1998,8 +3441,8 @@ signals_info (signum_exp, from_tty)
printf_filtered ("\n");
/* These ugly casts brought to you by the native VAX compiler. */
for (oursig = TARGET_SIGNAL_FIRST;
- (int)oursig < (int)TARGET_SIGNAL_LAST;
- oursig = (enum target_signal)((int)oursig + 1))
+ (int) oursig < (int) TARGET_SIGNAL_LAST;
+ oursig = (enum target_signal) ((int) oursig + 1))
{
QUIT;
@@ -2033,7 +3476,7 @@ save_inferior_status (inf_status, restore_stack_info)
inf_status->step_over_calls = step_over_calls;
inf_status->stop_after_trap = stop_after_trap;
inf_status->stop_soon_quietly = stop_soon_quietly;
- /* Save original bpstat chain here; replace it with copy of chain.
+ /* Save original bpstat chain here; replace it with copy of chain.
If caller's caller is walking the chain, they'll be happier if we
hand them back the original chain when restore_i_s is called. */
inf_status->stop_bpstat = stop_bpstat;
@@ -2041,7 +3484,7 @@ save_inferior_status (inf_status, restore_stack_info)
inf_status->breakpoint_proceeded = breakpoint_proceeded;
inf_status->restore_stack_info = restore_stack_info;
inf_status->proceed_to_finish = proceed_to_finish;
-
+
memcpy (inf_status->stop_registers, stop_registers, REGISTER_BYTES);
read_register_bytes (0, inf_status->registers, REGISTER_BYTES);
@@ -2051,12 +3494,13 @@ save_inferior_status (inf_status, restore_stack_info)
return;
}
-struct restore_selected_frame_args {
+struct restore_selected_frame_args
+{
CORE_ADDR frame_address;
int level;
};
-static int restore_selected_frame PARAMS ((char *));
+static int restore_selected_frame PARAMS ((PTR));
/* Restore the selected frame. args is really a struct
restore_selected_frame_args * (declared as char * for catch_errors)
@@ -2065,10 +3509,10 @@ static int restore_selected_frame PARAMS ((char *));
static int
restore_selected_frame (args)
- char *args;
+ PTR args;
{
struct restore_selected_frame_args *fr =
- (struct restore_selected_frame_args *) args;
+ (struct restore_selected_frame_args *) args;
struct frame_info *frame;
int level = fr->level;
@@ -2077,14 +3521,22 @@ restore_selected_frame (args)
/* If inf_status->selected_frame_address is NULL, there was no
previously selected frame. */
if (frame == NULL ||
- FRAME_FP (frame) != fr->frame_address ||
+ /* FRAME_FP (frame) != fr->frame_address || */
+ /* elz: deleted this check as a quick fix to the problem that
+ for function called by hand gdb creates no internal frame
+ structure and the real stack and gdb's idea of stack are
+ different if nested calls by hands are made.
+
+ mvs: this worries me. */
level != 0)
{
warning ("Unable to restore previously selected frame.\n");
return 0;
}
+
select_frame (frame, fr->level);
- return(1);
+
+ return (1);
}
void
@@ -2138,16 +3590,40 @@ restore_inferior_status (inf_status)
RETURN_MASK_ERROR) == 0)
/* Error in restoring the selected frame. Select the innermost
frame. */
+
+
select_frame (get_current_frame (), 0);
+
}
}
+
+
+void
+set_follow_fork_mode_command (arg, from_tty, c)
+ char *arg;
+ int from_tty;
+ struct cmd_list_element *c;
+{
+ if (!STREQ (arg, "parent") &&
+ !STREQ (arg, "child") &&
+ !STREQ (arg, "both") &&
+ !STREQ (arg, "ask"))
+ error ("follow-fork-mode must be one of \"parent\", \"child\", \"both\" or \"ask\".");
+
+ if (follow_fork_mode_string != NULL)
+ free (follow_fork_mode_string);
+ follow_fork_mode_string = savestring (arg, strlen (arg));
+}
+
+
void
_initialize_infrun ()
{
register int i;
register int numsigs;
+ struct cmd_list_element *c;
add_info ("signals", signals_info,
"What debugger does when program gets various signals.\n\
@@ -2162,21 +3638,44 @@ from 1-15 are allowed for compatibility with old versions of GDB.\n\
Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
The special arg \"all\" is recognized to mean all signals except those\n\
used by the debugger, typically SIGTRAP and SIGINT.\n",
-"Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
+ "Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
\"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
Stop means reenter debugger if this signal happens (implies print).\n\
Print means print a message if this signal happens.\n\
Pass means let program see this signal; otherwise program doesn't know.\n\
Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
Pass and Stop may be combined.", NULL));
+ if (xdb_commands)
+ {
+ add_com ("lz", class_info, signals_info,
+ "What debugger does when program gets various signals.\n\
+Specify a signal as argument to print info on that signal only.");
+ add_com ("z", class_run, xdb_handle_command,
+ concat ("Specify how to handle a signal.\n\
+Args are signals and actions to apply to those signals.\n\
+Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
+from 1-15 are allowed for compatibility with old versions of GDB.\n\
+Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
+The special arg \"all\" is recognized to mean all signals except those\n\
+used by the debugger, typically SIGTRAP and SIGINT.\n",
+ "Recognized actions include \"s\" (toggles between stop and nostop), \n\
+\"r\" (toggles between print and noprint), \"i\" (toggles between pass and \
+nopass), \"Q\" (noprint)\n\
+Stop means reenter debugger if this signal happens (implies print).\n\
+Print means print a message if this signal happens.\n\
+Pass means let program see this signal; otherwise program doesn't know.\n\
+Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
+Pass and Stop may be combined.", NULL));
+ }
- stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command,
- "There is no `stop' command, but you can set a hook on `stop'.\n\
+ if (!dbx_commands)
+ stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command,
+ "There is no `stop' command, but you can set a hook on `stop'.\n\
This allows you to set a list of commands to be run each time execution\n\
of the program stops.", &cmdlist);
- numsigs = (int)TARGET_SIGNAL_LAST;
- signal_stop = (unsigned char *)
+ numsigs = (int) TARGET_SIGNAL_LAST;
+ signal_stop = (unsigned char *)
xmalloc (sizeof (signal_stop[0]) * numsigs);
signal_print = (unsigned char *)
xmalloc (sizeof (signal_print[0]) * numsigs);
@@ -2209,16 +3708,68 @@ of the program stops.", &cmdlist);
signal_print[TARGET_SIGNAL_POLL] = 0;
signal_stop[TARGET_SIGNAL_URG] = 0;
signal_print[TARGET_SIGNAL_URG] = 0;
+ signal_stop[TARGET_SIGNAL_WINCH] = 0;
+ signal_print[TARGET_SIGNAL_WINCH] = 0;
#ifdef SOLIB_ADD
add_show_from_set
(add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
- (char *) &stop_on_solib_events,
+ (char *) &stop_on_solib_events,
"Set stopping for shared library events.\n\
If nonzero, gdb will give control to the user when the dynamic linker\n\
notifies gdb of shared library events. The most common event of interest\n\
to the user would be loading/unloading of a new library.\n",
- &setlist),
+ &setlist),
&showlist);
#endif
+
+ c = add_set_enum_cmd ("follow-fork-mode",
+ class_run,
+ follow_fork_mode_kind_names,
+ (char *) &follow_fork_mode_string,
+/* ??rehrauer: The "both" option is broken, by what may be a 10.20
+ kernel problem. It's also not terribly useful without a GUI to
+ help the user drive two debuggers. So for now, I'm disabling
+ the "both" option. */
+/* "Set debugger response to a program call of fork \
+or vfork.\n\
+A fork or vfork creates a new process. follow-fork-mode can be:\n\
+ parent - the original process is debugged after a fork\n\
+ child - the new process is debugged after a fork\n\
+ both - both the parent and child are debugged after a fork\n\
+ ask - the debugger will ask for one of the above choices\n\
+For \"both\", another copy of the debugger will be started to follow\n\
+the new child process. The original debugger will continue to follow\n\
+the original parent process. To distinguish their prompts, the\n\
+debugger copy's prompt will be changed.\n\
+For \"parent\" or \"child\", the unfollowed process will run free.\n\
+By default, the debugger will follow the parent process.",
+*/
+ "Set debugger response to a program call of fork \
+or vfork.\n\
+A fork or vfork creates a new process. follow-fork-mode can be:\n\
+ parent - the original process is debugged after a fork\n\
+ child - the new process is debugged after a fork\n\
+ ask - the debugger will ask for one of the above choices\n\
+For \"parent\" or \"child\", the unfollowed process will run free.\n\
+By default, the debugger will follow the parent process.",
+ &setlist);
+/* c->function.sfunc = ;*/
+ add_show_from_set (c, &showlist);
+
+ set_follow_fork_mode_command ("parent", 0, NULL);
+
+ c = add_set_enum_cmd ("scheduler-locking", class_run,
+ scheduler_enums, /* array of string names */
+ (char *) &scheduler_mode, /* current mode */
+ "Set mode for locking scheduler during execution.\n\
+off == no locking (threads may preempt at any time)\n\
+on == full locking (no thread except the current thread may run)\n\
+step == scheduler locked during every single-step operation.\n\
+ In this mode, no other thread may run during a step command.\n\
+ Other threads may run while stepping over a function call ('next').",
+ &setlist);
+
+ c->function.sfunc = set_schedlock_func; /* traps on target vector */
+ add_show_from_set (c, &showlist);
}
diff --git a/contrib/gdb/gdb/inftarg.c b/contrib/gdb/gdb/inftarg.c
index 6e0e50a..af5cd3d 100644
--- a/contrib/gdb/gdb/inftarg.c
+++ b/contrib/gdb/gdb/inftarg.c
@@ -1,8 +1,9 @@
/* Target-vector operations for controlling Unix child processes, for GDB.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995
- Free Software Foundation, Inc.
+ Copyright 1990-1996, 1998, 1999 Free Software Foundation, Inc.
Contributed by Cygnus Support.
+## Contains temporary hacks..
+
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
@@ -23,13 +24,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "target.h"
-#include "wait.h"
#include "gdbcore.h"
#include "command.h"
+#include "gdb_stat.h"
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
+#ifdef HAVE_WAIT_H
+# include <wait.h>
+#else
+# ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+# endif
+#endif
+
+/* "wait.h" fills in the gaps left by <wait.h> */
+#include "wait.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+extern struct symtab_and_line *
+child_enable_exception_callback PARAMS ((enum exception_event_kind, int));
+
+extern struct exception_event_record *
+child_get_current_exception_event PARAMS ((void));
+
+extern void _initialize_inftarg PARAMS ((void));
+
static void
child_prepare_to_store PARAMS ((void));
@@ -37,6 +60,11 @@ child_prepare_to_store PARAMS ((void));
static int child_wait PARAMS ((int, struct target_waitstatus *));
#endif /* CHILD_WAIT */
+#if !defined(CHILD_POST_WAIT)
+void
+child_post_wait PARAMS ((int, int));
+#endif
+
static void child_open PARAMS ((char *, int));
static void
@@ -46,15 +74,32 @@ static void
child_detach PARAMS ((char *, int));
static void
+child_detach_from_process PARAMS ((int, char *, int, int));
+
+static void
child_attach PARAMS ((char *, int));
static void
-ptrace_me PARAMS ((void));
+child_attach_to_process PARAMS ((char *, int, int));
+
+#if !defined(CHILD_POST_ATTACH)
+extern void child_post_attach PARAMS ((int));
+#endif
+
+static void
+child_require_attach PARAMS ((char *, int));
+
+static void
+child_require_detach PARAMS ((int, char *, int));
static void
+ptrace_me PARAMS ((void));
+
+static void
ptrace_him PARAMS ((int));
-static void child_create_inferior PARAMS ((char *, char *, char **));
+static void
+child_create_inferior PARAMS ((char *, char *, char **));
static void
child_mourn_inferior PARAMS ((void));
@@ -62,25 +107,36 @@ child_mourn_inferior PARAMS ((void));
static int
child_can_run PARAMS ((void));
-static int child_thread_alive PARAMS ((int));
+static void
+child_stop PARAMS ((void));
+
+#ifndef CHILD_THREAD_ALIVE
+int child_thread_alive PARAMS ((int));
+#endif
+
+static void init_child_ops PARAMS ((void));
extern char **environ;
-/* Forward declaration */
-extern struct target_ops child_ops;
+struct target_ops child_ops;
-static int
-proc_wait (pid, status)
- int pid;
- int *status;
-{
-#ifndef __GO32__
- return wait (status);
-#endif
-}
+int child_suppress_run = 0; /* Non-zero if inftarg should pretend not to
+ be a runnable target. Used by targets
+ that can sit atop inftarg, such as HPUX
+ thread support. */
#ifndef CHILD_WAIT
+/*##*/
+/* Enable HACK for ttrace work. In
+ * infttrace.c/require_notification_of_events,
+ * this is set to 0 so that the loop in child_wait
+ * won't loop.
+ */
+int not_same_real_pid = 1;
+/*##*/
+
+
/* Wait for child to do something. Return pid of child, or -1 in case
of error; store status through argument pointer OURSTATUS. */
@@ -91,13 +147,19 @@ child_wait (pid, ourstatus)
{
int save_errno;
int status;
+ char * execd_pathname;
+ int exit_status;
+ int related_pid;
+ int syscall_id;
+ enum target_waitkind kind;
do {
set_sigint_trap(); /* Causes SIGINT to be passed on to the
attached process. */
set_sigio_trap ();
- pid = proc_wait (inferior_pid, &status);
+ pid = ptrace_wait (inferior_pid, &status);
+
save_errno = errno;
clear_sigio_trap ();
@@ -108,19 +170,98 @@ child_wait (pid, ourstatus)
{
if (save_errno == EINTR)
continue;
+
fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
safe_strerror (save_errno));
+
/* Claim it exited with unknown signal. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
return -1;
}
- } while (pid != inferior_pid); /* Some other child died or stopped */
+
+ /* Did it exit?
+ */
+ if (target_has_exited (pid, status, &exit_status))
+ {
+ /* ??rehrauer: For now, ignore this. */
+ continue;
+ }
+
+ if (!target_thread_alive (pid))
+ {
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ return pid;
+ }
+
+ if (target_has_forked (pid, &related_pid)
+ && ((pid == inferior_pid) || (related_pid == inferior_pid)))
+ {
+ ourstatus->kind = TARGET_WAITKIND_FORKED;
+ ourstatus->value.related_pid = related_pid;
+ return pid;
+ }
+
+ if (target_has_vforked (pid, &related_pid)
+ && ((pid == inferior_pid) || (related_pid == inferior_pid)))
+ {
+ ourstatus->kind = TARGET_WAITKIND_VFORKED;
+ ourstatus->value.related_pid = related_pid;
+ return pid;
+ }
+
+ if (target_has_execd (pid, &execd_pathname))
+ {
+ /* Are we ignoring initial exec events? (This is likely because
+ we're in the process of starting up the inferior, and another
+ (older) mechanism handles those.) If so, we'll report this
+ as a regular stop, not an exec.
+ */
+ if (inferior_ignoring_startup_exec_events)
+ {
+ inferior_ignoring_startup_exec_events--;
+ }
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXECD;
+ ourstatus->value.execd_pathname = execd_pathname;
+ return pid;
+ }
+ }
+
+ /* All we must do with these is communicate their occurrence
+ to wait_for_inferior...
+ */
+ if (target_has_syscall_event (pid, &kind, &syscall_id))
+ {
+ ourstatus->kind = kind;
+ ourstatus->value.syscall_id = syscall_id;
+ return pid;
+ }
+
+/*## } while (pid != inferior_pid); ##*/ /* Some other child died or stopped */
+/* hack for thread testing */
+ } while( (pid != inferior_pid) && not_same_real_pid );
+/*##*/
+
store_waitstatus (ourstatus, status);
return pid;
}
#endif /* CHILD_WAIT */
+#if !defined(CHILD_POST_WAIT)
+void
+child_post_wait (pid, wait_status)
+ int pid;
+ int wait_status;
+{
+ /* This version of Unix doesn't require a meaningful "post wait"
+ operation.
+ */
+}
+#endif
+
+
#ifndef CHILD_THREAD_ALIVE
/* Check to see if the given thread is alive.
@@ -128,7 +269,7 @@ child_wait (pid, ourstatus)
FIXME: Is kill() ever the right way to do this? I doubt it, but
for now we're going to try and be compatable with the old thread
code. */
-static int
+int
child_thread_alive (pid)
int pid;
{
@@ -137,12 +278,11 @@ child_thread_alive (pid)
#endif
-/* Attach to process PID, then initialize for debugging it. */
-
static void
-child_attach (args, from_tty)
- char *args;
- int from_tty;
+child_attach_to_process (args, from_tty, after_fork)
+ char * args;
+ int from_tty;
+ int after_fork;
{
if (!args)
error_no_arg ("process-id to attach");
@@ -153,8 +293,13 @@ child_attach (args, from_tty)
{
char *exec_file;
int pid;
+ char *dummy;
- pid = atoi (args);
+ dummy = args;
+ pid = strtol (args, &dummy, 0);
+ /* Some targets don't set errno on errors, grrr! */
+ if ((pid == 0) && (args == dummy))
+ error ("Illegal process-id: %s\n", args);
if (pid == getpid()) /* Trying to masturbate? */
error ("I refuse to debug myself!");
@@ -163,16 +308,23 @@ child_attach (args, from_tty)
{
exec_file = (char *) get_exec_file (0);
- if (exec_file)
- printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
+ if (after_fork)
+ printf_unfiltered ("Attaching after fork to %s\n",
target_pid_to_str (pid));
- else
- printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
+ else if (exec_file)
+ printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
+ target_pid_to_str (pid));
+ else
+ printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
gdb_flush (gdb_stdout);
}
- attach (pid);
+ if (!after_fork)
+ attach (pid);
+ else
+ REQUIRE_ATTACH (pid);
+
inferior_pid = pid;
push_target (&child_ops);
}
@@ -180,19 +332,41 @@ child_attach (args, from_tty)
}
-/* Take a program previously attached to and detaches it.
- The program resumes execution and will no longer stop
- on signals, etc. We'd better not have left any breakpoints
- in the program or it'll die when it hits one. For this
- to work, it may be necessary for the process to have been
- previously attached. It *might* work if the program was
- started via the normal ptrace (PTRACE_TRACEME). */
+/* Attach to process PID, then initialize for debugging it. */
static void
-child_detach (args, from_tty)
+child_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ child_attach_to_process (args, from_tty, 0);
+}
+
+#if !defined(CHILD_POST_ATTACH)
+void
+child_post_attach (pid)
+ int pid;
+{
+ /* This version of Unix doesn't require a meaningful "post attach"
+ operation by a debugger. */
+}
+#endif
+
+static void
+child_require_attach (args, from_tty)
char *args;
int from_tty;
{
+ child_attach_to_process (args, from_tty, 1);
+}
+
+static void
+child_detach_from_process (pid, args, from_tty, after_fork)
+ int pid;
+ char * args;
+ int from_tty;
+ int after_fork;
+{
#ifdef ATTACH_DETACH
{
int siggnal = 0;
@@ -202,22 +376,55 @@ child_detach (args, from_tty)
char *exec_file = get_exec_file (0);
if (exec_file == 0)
exec_file = "";
- printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
- target_pid_to_str (inferior_pid));
+ if (after_fork)
+ printf_unfiltered ("Detaching after fork from %s\n",
+ target_pid_to_str (pid));
+ else
+ printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
+ target_pid_to_str (pid));
gdb_flush (gdb_stdout);
}
if (args)
siggnal = atoi (args);
- detach (siggnal);
- inferior_pid = 0;
- unpush_target (&child_ops);
+ if (!after_fork)
+ detach (siggnal);
+ else
+ REQUIRE_DETACH (pid, siggnal);
}
#else
error ("This version of Unix does not support detaching a process.");
#endif
}
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+child_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ child_detach_from_process (inferior_pid, args, from_tty, 0);
+ inferior_pid = 0;
+ unpush_target (&child_ops);
+}
+
+static void
+child_require_detach (pid, args, from_tty)
+ int pid;
+ char * args;
+ int from_tty;
+{
+ child_detach_from_process (pid, args, from_tty, 1);
+}
+
+
/* Get ready to modify the registers array. On machines which store
individual registers, this doesn't need to do anything. On machines
which store all the registers in one fell swoop, this makes sure
@@ -264,18 +471,30 @@ ptrace_me ()
/* Stub function which causes the GDB that runs it, to start ptrace-ing
the child process. */
-static void
+static void
ptrace_him (pid)
int pid;
{
push_target (&child_ops);
-#ifdef START_INFERIOR_TRAPS_EXPECTED
+ /* On some targets, there must be some explicit synchronization
+ between the parent and child processes after the debugger
+ forks, and before the child execs the debuggee program. This
+ call basically gives permission for the child to exec.
+ */
+
+ target_acknowledge_created_inferior (pid);
+
+ /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
+ * and will be 1 or 2 depending on whether we're starting
+ * without or with a shell.
+ */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
-#else
- /* One trap to exec the shell, one to exec the program being debugged. */
- startup_inferior (2);
-#endif
+
+ /* On some targets, there must be some explicit actions taken after
+ the inferior has been started up.
+ */
+ target_post_startup_inferior (pid);
}
/* Start an inferior Unix child process and sets inferior_pid to its pid.
@@ -289,15 +508,305 @@ child_create_inferior (exec_file, allargs, env)
char *allargs;
char **env;
{
- fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL);
+
+#ifdef HPUXHPPA
+ char *tryname;
+ char *shell_file;
+ char *p;
+ char *p1;
+ char *path = getenv ("PATH");
+ int len;
+ struct stat statbuf;
+
+ /* On HP-UX, we have a possible bad interaction between
+ * the start-up-with-shell code and our catch-fork/catch-exec
+ * logic. To avoid the bad interaction, we start up with the
+ * C shell ("csh") and pass it the "-f" flag (fast start-up,
+ * don't run .cshrc code).
+ * See further comments in inferior.h toward the bottom
+ * (STARTUP_WITH_SHELL flag) and in fork-child.c
+ */
+
+ /* Rather than passing in a hard-wired path like "/bin/csh",
+ * we look down the PATH to find csh. I took this code from
+ * procfs.c, which is the file in the Sun-specific part of GDB
+ * analogous to inftarg.c. See procfs.c for more detailed
+ * comments. - RT
+ */
+ shell_file = "csh";
+ if (path == NULL)
+ path = "/bin:/usr/bin";
+ tryname = alloca (strlen (path) + strlen (shell_file) + 2);
+ for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
+ {
+ p1 = strchr (p, ':');
+ if (p1 != NULL)
+ len = p1 - p;
+ else
+ len = strlen (p);
+ strncpy (tryname, p, len);
+ tryname[len] = '\0';
+ strcat (tryname, "/");
+ strcat (tryname, shell_file);
+ if (access (tryname, X_OK) < 0)
+ continue;
+ if (stat (tryname, &statbuf) < 0)
+ continue;
+ if (!S_ISREG (statbuf.st_mode))
+ /* We certainly need to reject directories. I'm not quite
+ as sure about FIFOs, sockets, etc., but I kind of doubt
+ that people want to exec() these things. */
+ continue;
+ break;
+ }
+ if (p == NULL)
+ /* Not found. I replaced the error() which existed in procfs.c
+ * with simply passing in NULL and hoping fork_inferior()
+ * can deal with it. - RT
+ */
+ /* error ("Can't find shell %s in PATH", shell_file); */
+ shell_file = NULL;
+ else
+ shell_file = tryname;
+
+ fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL);
+#else
+ fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL);
+#endif
/* We are at the first instruction we care about. */
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}
+#if !defined(CHILD_POST_STARTUP_INFERIOR)
+void
+child_post_startup_inferior (pid)
+ int pid;
+{
+ /* This version of Unix doesn't require a meaningful "post startup inferior"
+ operation by a debugger.
+ */
+}
+#endif
+
+#if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR)
+void
+child_acknowledge_created_inferior (pid)
+ int pid;
+{
+ /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
+ operation by a debugger.
+ */
+}
+#endif
+
+
+void
+child_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ clone_and_follow_inferior (child_pid, followed_child);
+
+ /* Don't resume CHILD_PID; it's stopped where it ought to be, until
+ the decision gets made elsewhere how to continue it.
+ */
+}
+
+
+#if !defined(CHILD_POST_FOLLOW_INFERIOR_BY_CLONE)
+void
+child_post_follow_inferior_by_clone ()
+{
+ /* This version of Unix doesn't require a meaningful "post follow inferior"
+ operation by a clone debugger.
+ */
+}
+#endif
+
+#if !defined(CHILD_INSERT_FORK_CATCHPOINT)
+int
+child_insert_fork_catchpoint (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_REMOVE_FORK_CATCHPOINT)
+int
+child_remove_fork_catchpoint (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_INSERT_VFORK_CATCHPOINT)
+int
+child_insert_vfork_catchpoint (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support notification of vfork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_REMOVE_VFORK_CATCHPOINT)
+int
+child_remove_vfork_catchpoint (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support notification of vfork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_HAS_FORKED)
+int
+child_has_forked (pid, child_pid)
+ int pid;
+ int *child_pid;
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_HAS_VFORKED)
+int
+child_has_vforked (pid, child_pid)
+ int pid;
+ int * child_pid;
+{
+ /* This version of Unix doesn't support notification of vfork events.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
+int
+child_can_follow_vfork_prior_to_exec ()
+{
+ /* This version of Unix doesn't support notification of vfork events.
+ However, if it did, it probably wouldn't allow vforks to be followed
+ before the following exec.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_POST_FOLLOW_VFORK)
+void
+child_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child)
+ int parent_pid;
+ int followed_parent;
+ int child_pid;
+ int followed_child;
+{
+ /* This version of Unix doesn't require a meaningful "post follow vfork"
+ operation by a clone debugger.
+ */
+}
+#endif
+
+#if !defined(CHILD_INSERT_EXEC_CATCHPOINT)
+int
+child_insert_exec_catchpoint (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support notification of exec events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_REMOVE_EXEC_CATCHPOINT)
+int
+child_remove_exec_catchpoint (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support notification of exec events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_HAS_EXECD)
+int
+child_has_execd (pid, execd_pathname)
+ int pid;
+ char ** execd_pathname;
+{
+ /* This version of Unix doesn't support notification of exec events.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
+int
+child_reported_exec_events_per_exec_call ()
+{
+ /* This version of Unix doesn't support notification of exec events.
+ */
+ return 1;
+}
+#endif
+
+
+#if !defined(CHILD_HAS_SYSCALL_EVENT)
+int
+child_has_syscall_event (pid, kind, syscall_id)
+ int pid;
+ enum target_waitkind * kind;
+ int * syscall_id;
+{
+ /* This version of Unix doesn't support notification of syscall events.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_HAS_EXITED)
+int
+child_has_exited (pid, wait_status, exit_status)
+ int pid;
+ int wait_status;
+ int * exit_status;
+{
+ if (WIFEXITED (wait_status))
+ {
+ *exit_status = WEXITSTATUS (wait_status);
+ return 1;
+ }
+
+ if (WIFSIGNALED (wait_status))
+ {
+ *exit_status = 0; /* ?? Don't know what else to say here. */
+ return 1;
+ }
+
+ /* ?? Do we really need to consult the event state, too? Assume the
+ wait_state alone suffices.
+ */
+ return 0;
+}
+#endif
+
+
static void
child_mourn_inferior ()
{
+ /* FIXME: Should be in a header file */
+ extern void proc_remove_foreign PARAMS ((int));
+
unpush_target (&child_ops);
proc_remove_foreign (inferior_pid);
generic_mourn_inferior ();
@@ -306,7 +815,11 @@ child_mourn_inferior ()
static int
child_can_run ()
{
- return(1);
+ /* This variable is controlled by modules that sit atop inftarg that may layer
+ their own process structure atop that provided here. hpux-thread.c does
+ this because of the Hpux user-mode level thread model. */
+
+ return !child_suppress_run;
}
/* Send a SIGINT to the process group. This acts just like the user typed a
@@ -315,56 +828,120 @@ child_can_run ()
XXX - This may not be correct for all systems. Some may want to use
killpg() instead of kill (-pgrp). */
-void
+static void
child_stop ()
{
extern pid_t inferior_process_group;
kill (-inferior_process_group, SIGINT);
}
+
+#if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK)
+struct symtab_and_line *
+child_enable_exception_callback (kind, enable)
+ enum exception_event_kind kind;
+ int enable;
+{
+ return (struct symtab_and_line *) NULL;
+}
+#endif
+
+#if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT)
+struct exception_event_record *
+child_get_current_exception_event ()
+{
+ return (struct exception_event_record *) NULL;
+}
+#endif
+
+
+#if !defined(CHILD_PID_TO_EXEC_FILE)
+char *
+child_pid_to_exec_file (pid)
+ int pid;
+{
+ /* This version of Unix doesn't support translation of a process ID
+ to the filename of the executable file.
+ */
+ return NULL;
+}
+#endif
+
+char *
+child_core_file_to_sym_file (core)
+ char * core;
+{
+ /* The target stratum for a running executable need not support
+ this operation.
+ */
+ return NULL;
+}
+
+
-struct target_ops child_ops = {
- "child", /* to_shortname */
- "Unix child process", /* to_longname */
- "Unix child process (started by the \"run\" command).", /* to_doc */
- child_open, /* to_open */
- 0, /* to_close */
- child_attach, /* to_attach */
- child_detach, /* to_detach */
- child_resume, /* to_resume */
- child_wait, /* to_wait */
- fetch_inferior_registers, /* to_fetch_registers */
- store_inferior_registers, /* to_store_registers */
- child_prepare_to_store, /* to_prepare_to_store */
- child_xfer_memory, /* to_xfer_memory */
- child_files_info, /* to_files_info */
- memory_insert_breakpoint, /* to_insert_breakpoint */
- memory_remove_breakpoint, /* to_remove_breakpoint */
- terminal_init_inferior, /* to_terminal_init */
- terminal_inferior, /* to_terminal_inferior */
- terminal_ours_for_output, /* to_terminal_ours_for_output */
- terminal_ours, /* to_terminal_ours */
- child_terminal_info, /* to_terminal_info */
- kill_inferior, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- child_create_inferior, /* to_create_inferior */
- child_mourn_inferior, /* to_mourn_inferior */
- child_can_run, /* to_can_run */
- 0, /* to_notice_signals */
- child_thread_alive, /* to_thread_alive */
- child_stop, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC /* to_magic */
-};
+static void
+init_child_ops ()
+{
+ child_ops.to_shortname = "child";
+ child_ops.to_longname = "Unix child process";
+ child_ops.to_doc = "Unix child process (started by the \"run\" command).";
+ child_ops.to_open = child_open;
+ child_ops.to_attach = child_attach;
+ child_ops.to_post_attach = child_post_attach;
+ child_ops.to_require_attach = child_require_attach;
+ child_ops.to_detach = child_detach;
+ child_ops.to_require_detach = child_require_detach;
+ child_ops.to_resume = child_resume;
+ child_ops.to_wait = child_wait;
+ child_ops.to_post_wait = child_post_wait;
+ child_ops.to_fetch_registers = fetch_inferior_registers;
+ child_ops.to_store_registers = store_inferior_registers;
+ child_ops.to_prepare_to_store = child_prepare_to_store;
+ child_ops.to_xfer_memory = child_xfer_memory;
+ child_ops.to_files_info = child_files_info;
+ child_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_terminal_init = terminal_init_inferior;
+ child_ops.to_terminal_inferior = terminal_inferior;
+ child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ child_ops.to_terminal_ours = terminal_ours;
+ child_ops.to_terminal_info = child_terminal_info;
+ child_ops.to_kill = kill_inferior;
+ child_ops.to_create_inferior = child_create_inferior;
+ child_ops.to_post_startup_inferior = child_post_startup_inferior;
+ child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
+ child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior;
+ child_ops.to_post_follow_inferior_by_clone = child_post_follow_inferior_by_clone;
+ child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
+ child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
+ child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
+ child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
+ child_ops.to_has_forked = child_has_forked;
+ child_ops.to_has_vforked = child_has_vforked;
+ child_ops.to_can_follow_vfork_prior_to_exec = child_can_follow_vfork_prior_to_exec;
+ child_ops.to_post_follow_vfork = child_post_follow_vfork;
+ child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
+ child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
+ child_ops.to_has_execd = child_has_execd;
+ child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
+ child_ops.to_has_syscall_event = child_has_syscall_event;
+ child_ops.to_has_exited = child_has_exited;
+ child_ops.to_mourn_inferior = child_mourn_inferior;
+ child_ops.to_can_run = child_can_run;
+ child_ops.to_thread_alive = child_thread_alive;
+ child_ops.to_stop = child_stop;
+ child_ops.to_enable_exception_callback = child_enable_exception_callback;
+ child_ops.to_get_current_exception_event = child_get_current_exception_event;
+ child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
+ child_ops.to_core_file_to_sym_file = child_core_file_to_sym_file;
+ child_ops.to_stratum = process_stratum;
+ child_ops.to_has_all_memory = 1;
+ child_ops.to_has_memory = 1;
+ child_ops.to_has_stack = 1;
+ child_ops.to_has_registers = 1;
+ child_ops.to_has_execution = 1;
+ child_ops.to_magic = OPS_MAGIC;
+}
void
_initialize_inftarg ()
@@ -386,5 +963,6 @@ _initialize_inftarg ()
}
#endif
+ init_child_ops ();
add_target (&child_ops);
}
diff --git a/contrib/gdb/gdb/infttrace.c b/contrib/gdb/gdb/infttrace.c
new file mode 100644
index 0000000..61723df
--- /dev/null
+++ b/contrib/gdb/gdb/infttrace.c
@@ -0,0 +1,5674 @@
+/* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdb_string.h"
+#include "wait.h"
+#include "command.h"
+
+/* Some hackery to work around a use of the #define name NO_FLAGS
+ * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h).
+ */
+#ifdef NO_FLAGS
+#define INFTTRACE_TEMP_HACK NO_FLAGS
+#undef NO_FLAGS
+#endif
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+
+#include <sys/ttrace.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/mman.h>
+
+#ifndef NO_PTRACE_H
+#ifdef PTRACE_IN_WRONG_PLACE
+#include <ptrace.h>
+#else
+#include <sys/ptrace.h>
+#endif
+#endif /* NO_PTRACE_H */
+
+/* Second half of the hackery above. Non-ANSI C, so
+ * we can't use "#error", alas.
+ */
+#ifdef NO_FLAGS
+#if (NO_FLAGS != INFTTRACE_TEMP_HACK )
+ /* #error "Hackery to remove warning didn't work right" */
+#else
+ /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */
+#endif
+#else
+ /* #error "Didn't get expected re-definition of NO_FLAGS" */
+#define NO_FLAGS INFTTRACE_TEMP_HACK
+#endif
+
+#if !defined (PT_SETTRC)
+#define PT_SETTRC 0 /* Make process traceable by parent */
+#endif
+#if !defined (PT_READ_I)
+#define PT_READ_I 1 /* Read word from text space */
+#endif
+#if !defined (PT_READ_D)
+#define PT_READ_D 2 /* Read word from data space */
+#endif
+#if !defined (PT_READ_U)
+#define PT_READ_U 3 /* Read word from kernel user struct */
+#endif
+#if !defined (PT_WRITE_I)
+#define PT_WRITE_I 4 /* Write word to text space */
+#endif
+#if !defined (PT_WRITE_D)
+#define PT_WRITE_D 5 /* Write word to data space */
+#endif
+#if !defined (PT_WRITE_U)
+#define PT_WRITE_U 6 /* Write word to kernel user struct */
+#endif
+#if !defined (PT_CONTINUE)
+#define PT_CONTINUE 7 /* Continue after signal */
+#endif
+#if !defined (PT_STEP)
+#define PT_STEP 9 /* Set flag for single stepping */
+#endif
+#if !defined (PT_KILL)
+#define PT_KILL 8 /* Send child a SIGKILL signal */
+#endif
+
+#ifndef PT_ATTACH
+#define PT_ATTACH PTRACE_ATTACH
+#endif
+#ifndef PT_DETACH
+#define PT_DETACH PTRACE_DETACH
+#endif
+
+#include "gdbcore.h"
+#ifndef NO_SYS_FILE
+#include <sys/file.h>
+#endif
+
+/* This semaphore is used to coordinate the child and parent processes
+ after a fork(), and before an exec() by the child. See parent_attach_all
+ for details.
+ */
+typedef struct {
+ int parent_channel[2]; /* Parent "talks" to [1], child "listens" to [0] */
+ int child_channel[2]; /* Child "talks" to [1], parent "listens" to [0] */
+} startup_semaphore_t;
+
+#define SEM_TALK (1)
+#define SEM_LISTEN (0)
+
+static startup_semaphore_t startup_semaphore;
+
+/* See can_touch_threads_of_process for details. */
+static int vforking_child_pid = 0;
+static int vfork_in_flight = 0;
+
+/* To support PREPARE_TO_PROCEED (hppa_prepare_to_proceed).
+ */
+static pid_t old_gdb_pid = 0;
+static pid_t reported_pid = 0;
+static int reported_bpt = 0;
+
+/* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise.
+ */
+#define TT_OK( _status, _errno ) \
+ (((_status) == 1) && ((_errno) == 0))
+
+#define TTRACE_ARG_TYPE uint64_t
+
+/* When supplied as the "addr" operand, ttrace interprets this
+ to mean, "from the current address".
+ */
+#define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC)
+
+/* When supplied as the "addr", "data" or "addr2" operand for most
+ requests, ttrace interprets this to mean, "pay no heed to this
+ argument".
+ */
+#define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG)
+
+/* This is capable of holding the value of a 32-bit register. The
+ value is always left-aligned in the buffer; i.e., [0] contains
+ the most-significant byte of the register's value, and [sizeof(reg)]
+ contains the least-significant value.
+
+ ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and
+ that registers are 32-bits on HP-UX. The latter assumption changes
+ with PA2.0.
+ */
+typedef int register_value_t;
+
+/********************************************************************
+
+ How this works:
+
+ 1. Thread numbers
+
+ The rest of GDB sees threads as being things with different
+ "pid" (process id) values. See "thread.c" for details. The
+ separate threads will be seen and reacted to if infttrace passes
+ back different pid values (for _events_). See wait_for_inferior
+ in inftarg.c.
+
+ So infttrace is going to use thread ids externally, pretending
+ they are process ids, and keep track internally so that it can
+ use the real process id (and thread id) when calling ttrace.
+
+ The data structure that supports this is a linked list of the
+ current threads. Since at some date infttrace will have to
+ deal with multiple processes, each list element records its
+ corresponding pid, rather than having a single global.
+
+ Note that the list is only approximately current; that's ok, as
+ it's up to date when we need it (we hope!). Also, it can contain
+ dead threads, as there's no harm if it does.
+
+ The approach taken here is to bury the translation from external
+ to internal inside "call_ttrace" and a few other places.
+
+ There are some wrinkles:
+
+ o When GDB forks itself to create the debug target process,
+ there's only a pid of 0 around in the child, so the
+ TT_PROC_SETTRC operation uses a more direct call to ttrace;
+ Similiarly, the initial setting of the event mask happens
+ early as well, and so is also special-cased, and an attach
+ uses a real pid;
+
+ o We define an unthreaded application as having a "pseudo"
+ thread;
+
+ o To keep from confusing the rest of GDB, we don't switch
+ the PID for the pseudo thread to a TID. A table will help:
+
+ Rest of GDB sees these PIDs: pid tid1 tid2 tid3 ...
+
+ Our thread list stores: pid pid pid pid ...
+ tid0 tid1 tid2 tid3
+
+ Ttrace sees these TIDS: tid0 tid1 tid2 tid3 ...
+
+ Both pid and tid0 will map to tid0, as there are infttrace.c-internal
+ calls to ttrace using tid0.
+
+ 2. Step and Continue
+
+ Since we're implementing the "stop the world" model, sub-model
+ "other threads run during step", we have some stuff to do:
+
+ o User steps require continuing all threads other than the
+ one the user is stepping;
+
+ o Internal debugger steps (such as over a breakpoint or watchpoint,
+ but not out of a library load thunk) require stepping only
+ the selected thread; this means that we have to report the
+ step finish on that thread, which can lead to complications;
+
+ o When a thread is created, it is created running, rather
+ than stopped--so we have to stop it.
+
+ The OS doesn't guarantee the stopped thread list will be stable,
+ no does it guarantee where on the stopped thread list a thread
+ that is single-stepped will wind up: it's possible that it will
+ be off the list for a while, it's possible the step will complete
+ and it will be re-posted to the end...
+
+ This means we have to scan the stopped thread list, build up
+ a work-list, and then run down the work list; we can't do the
+ step/continue during the scan.
+
+ 3. Buffering events
+
+ Then there's the issue of waiting for an event. We do this by
+ noticing how many events are reported at the end of each wait.
+ From then on, we "fake" all resumes and steps, returning instantly,
+ and don't do another wait. Once all pending events are reported,
+ we can really resume again.
+
+ To keep this hidden, all the routines which know about tids and
+ pids or real events and simulated ones are static (file-local).
+
+ This code can make lots of calls to ttrace, in particular it
+ can spin down the list of thread states more than once. If this
+ becomes a performance hit, the spin could be done once and the
+ various "tsp" blocks saved, keeping all later spins in this
+ process.
+
+ The O/S doesn't promise to keep the list straight, and so we must
+ re-scan a lot. By observation, it looks like a single-step/wait
+ puts the stepped thread at the end of the list but doesn't change
+ it otherwise.
+
+****************************************************************
+*/
+
+/* Uncomment these to turn on various debugging output */
+/* #define THREAD_DEBUG */
+/* #define WAIT_BUFFER_DEBUG */
+/* #define PARANOIA */
+
+
+#define INFTTRACE_ALL_THREADS (-1)
+#define INFTTRACE_STEP (1)
+#define INFTTRACE_CONTINUE (0)
+
+/* FIX: this is used in inftarg.c/child_wait, in a hack.
+ */
+extern int not_same_real_pid;
+
+/* This is used to count buffered events.
+ */
+static unsigned int more_events_left = 0;
+
+/* Process state.
+ */
+typedef enum process_state_enum {
+ STOPPED,
+ FAKE_STEPPING,
+ FAKE_CONTINUE, /* For later use */
+ RUNNING,
+ FORKING,
+ VFORKING
+} process_state_t;
+
+static process_state_t process_state = STOPPED;
+
+/* User-specified stepping modality.
+ */
+typedef enum stepping_mode_enum {
+ DO_DEFAULT, /* ...which is a continue! */
+ DO_STEP,
+ DO_CONTINUE
+} stepping_mode_t;
+
+/* Action to take on an attach, depends on
+ * what kind (user command, fork, vfork).
+ *
+ * At the moment, this is either:
+ *
+ * o continue with a SIGTRAP signal, or
+ *
+ * o leave stopped.
+ */
+typedef enum attach_continue_enum {
+ DO_ATTACH_CONTINUE,
+ DONT_ATTACH_CONTINUE
+} attach_continue_t;
+
+/* This flag is true if we are doing a step-over-bpt
+ * with buffered events. We will have to be sure to
+ * report the right thread, as otherwise the spaghetti
+ * code in "infrun.c/wait_for_inferior" will get
+ * confused.
+ */
+static int doing_fake_step = 0;
+static lwpid_t fake_step_tid = 0;
+
+
+/****************************************************
+ * Thread information structure routines and types. *
+ ****************************************************
+ */
+typedef
+struct thread_info_struct
+{
+ int am_pseudo; /* This is a pseudo-thread for the process. */
+ int pid; /* Process ID */
+ lwpid_t tid; /* Thread ID */
+ int handled; /* 1 if a buffered event was handled. */
+ int seen; /* 1 if this thread was seen on a traverse. */
+ int terminated; /* 1 if thread has terminated. */
+ int have_signal; /* 1 if signal to be sent */
+ enum target_signal signal_value; /* Signal to send */
+ int have_start; /* 1 if alternate starting address */
+ stepping_mode_t stepping_mode; /* Whether to step or continue */
+ CORE_ADDR start; /* Where to start */
+ int have_state; /* 1 if the event state has been set */
+ ttstate_t last_stop_state;/* The most recently-waited event for this thread. */
+ struct thread_info_struct
+ *next; /* All threads are linked via this field. */
+ struct thread_info_struct
+ *next_pseudo; /* All pseudo-threads are linked via this field. */
+} thread_info;
+
+typedef
+struct thread_info_header_struct
+{
+ int count;
+ thread_info *head;
+ thread_info *head_pseudo;
+
+} thread_info_header;
+
+static thread_info_header thread_head = { 0, NULL, NULL };
+static thread_info_header deleted_threads = { 0, NULL, NULL };
+
+static saved_real_pid = 0;
+
+
+/*************************************************
+ * Debugging support functions *
+ *************************************************
+ */
+CORE_ADDR
+get_raw_pc( ttid )
+ lwpid_t ttid;
+{
+ unsigned long pc_val;
+ int offset;
+ int res;
+
+ offset = register_addr( PC_REGNUM, U_REGS_OFFSET );
+ res = read_from_register_save_state(
+ ttid,
+ (TTRACE_ARG_TYPE) offset,
+ (char *) &pc_val,
+ sizeof( pc_val ));
+ if( res <= 0 ) {
+ return (CORE_ADDR) pc_val;
+ }
+ else {
+ return (CORE_ADDR) 0;
+ }
+}
+
+static char *
+get_printable_name_of_stepping_mode( mode )
+ stepping_mode_t mode;
+{
+ switch( mode ) {
+ case DO_DEFAULT: return "DO_DEFAULT";
+ case DO_STEP: return "DO_STEP";
+ case DO_CONTINUE: return "DO_CONTINUE";
+ default: return "?unknown mode?";
+ }
+}
+
+/* This function returns a pointer to a string describing the
+ * ttrace event being reported.
+ */
+char *
+get_printable_name_of_ttrace_event (event)
+ ttevents_t event;
+{
+ /* This enumeration is "gappy", so don't use a table. */
+ switch (event) {
+
+ case TTEVT_NONE:
+ return "TTEVT_NONE";
+ case TTEVT_SIGNAL:
+ return "TTEVT_SIGNAL";
+ case TTEVT_FORK:
+ return "TTEVT_FORK";
+ case TTEVT_EXEC:
+ return "TTEVT_EXEC";
+ case TTEVT_EXIT:
+ return "TTEVT_EXIT";
+ case TTEVT_VFORK:
+ return "TTEVT_VFORK";
+ case TTEVT_SYSCALL_RETURN:
+ return "TTEVT_SYSCALL_RETURN";
+ case TTEVT_LWP_CREATE:
+ return "TTEVT_LWP_CREATE";
+ case TTEVT_LWP_TERMINATE:
+ return "TTEVT_LWP_TERMINATE";
+ case TTEVT_LWP_EXIT:
+ return "TTEVT_LWP_EXIT";
+ case TTEVT_LWP_ABORT_SYSCALL:
+ return "TTEVT_LWP_ABORT_SYSCALL";
+ case TTEVT_SYSCALL_ENTRY:
+ return "TTEVT_SYSCALL_ENTRY";
+ case TTEVT_SYSCALL_RESTART:
+ return "TTEVT_SYSCALL_RESTART";
+ default :
+ return "?new event?";
+ }
+}
+
+
+/* This function translates the ttrace request enumeration into
+ * a character string that is its printable (aka "human readable")
+ * name.
+ */
+char *
+get_printable_name_of_ttrace_request (request)
+ ttreq_t request;
+{
+ if (!IS_TTRACE_REQ (request))
+ return "?bad req?";
+
+ /* This enumeration is "gappy", so don't use a table. */
+ switch (request) {
+ case TT_PROC_SETTRC :
+ return "TT_PROC_SETTRC";
+ case TT_PROC_ATTACH :
+ return "TT_PROC_ATTACH";
+ case TT_PROC_DETACH :
+ return "TT_PROC_DETACH";
+ case TT_PROC_RDTEXT :
+ return "TT_PROC_RDTEXT";
+ case TT_PROC_WRTEXT :
+ return "TT_PROC_WRTEXT";
+ case TT_PROC_RDDATA :
+ return "TT_PROC_RDDATA";
+ case TT_PROC_WRDATA :
+ return "TT_PROC_WRDATA";
+ case TT_PROC_STOP :
+ return "TT_PROC_STOP";
+ case TT_PROC_CONTINUE :
+ return "TT_PROC_CONTINUE";
+ case TT_PROC_GET_PATHNAME :
+ return "TT_PROC_GET_PATHNAME";
+ case TT_PROC_GET_EVENT_MASK :
+ return "TT_PROC_GET_EVENT_MASK";
+ case TT_PROC_SET_EVENT_MASK :
+ return "TT_PROC_SET_EVENT_MASK";
+ case TT_PROC_GET_FIRST_LWP_STATE :
+ return "TT_PROC_GET_FIRST_LWP_STATE";
+ case TT_PROC_GET_NEXT_LWP_STATE :
+ return "TT_PROC_GET_NEXT_LWP_STATE";
+ case TT_PROC_EXIT :
+ return "TT_PROC_EXIT";
+ case TT_PROC_GET_MPROTECT :
+ return "TT_PROC_GET_MPROTECT";
+ case TT_PROC_SET_MPROTECT :
+ return "TT_PROC_SET_MPROTECT";
+ case TT_PROC_SET_SCBM :
+ return "TT_PROC_SET_SCBM";
+ case TT_LWP_STOP :
+ return "TT_LWP_STOP";
+ case TT_LWP_CONTINUE :
+ return "TT_LWP_CONTINUE";
+ case TT_LWP_SINGLE :
+ return "TT_LWP_SINGLE";
+ case TT_LWP_RUREGS :
+ return "TT_LWP_RUREGS";
+ case TT_LWP_WUREGS :
+ return "TT_LWP_WUREGS";
+ case TT_LWP_GET_EVENT_MASK :
+ return "TT_LWP_GET_EVENT_MASK";
+ case TT_LWP_SET_EVENT_MASK :
+ return "TT_LWP_SET_EVENT_MASK";
+ case TT_LWP_GET_STATE :
+ return "TT_LWP_GET_STATE";
+ default :
+ return "?new req?";
+ }
+}
+
+
+/* This function translates the process state enumeration into
+ * a character string that is its printable (aka "human readable")
+ * name.
+ */
+static char *
+get_printable_name_of_process_state (process_state)
+ process_state_t process_state;
+{
+ switch (process_state) {
+ case STOPPED:
+ return "STOPPED";
+ case FAKE_STEPPING:
+ return "FAKE_STEPPING";
+ case RUNNING:
+ return "RUNNING";
+ case FORKING:
+ return "FORKING";
+ case VFORKING:
+ return "VFORKING";
+ default:
+ return "?some unknown state?";
+ }
+}
+
+/* Set a ttrace thread state to a safe, initial state.
+ */
+static void
+clear_ttstate_t (tts)
+ ttstate_t * tts;
+{
+ tts->tts_pid = 0;
+ tts->tts_lwpid = 0;
+ tts->tts_user_tid = 0;
+ tts->tts_event = TTEVT_NONE;
+}
+
+/* Copy ttrace thread state TTS_FROM into TTS_TO.
+ */
+static void
+copy_ttstate_t (tts_to, tts_from)
+ ttstate_t * tts_to;
+ ttstate_t * tts_from;
+{
+ memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to));
+}
+
+/* Are there any live threads we know about?
+ */
+static int
+any_thread_records()
+{
+ return( thread_head.count > 0 );
+}
+
+/* Create, fill in and link in a thread descriptor.
+ */
+static thread_info *
+create_thread_info (pid, tid)
+ int pid;
+ lwpid_t tid;
+{
+ thread_info * new_p;
+ thread_info * p;
+ int thread_count_of_pid;
+
+ new_p = malloc( sizeof( thread_info ));
+ new_p->pid = pid;
+ new_p->tid = tid;
+ new_p->have_signal = 0;
+ new_p->have_start = 0;
+ new_p->have_state = 0;
+ clear_ttstate_t( &new_p->last_stop_state );
+ new_p->am_pseudo = 0;
+ new_p->handled = 0;
+ new_p->seen = 0;
+ new_p->terminated = 0;
+ new_p->next = NULL;
+ new_p->next_pseudo = NULL;
+ new_p->stepping_mode = DO_DEFAULT;
+
+ if( 0 == thread_head.count ) {
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "First thread, pid %d tid %d!\n", pid, tid );
+#endif
+ saved_real_pid = inferior_pid;
+ }
+ else {
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Subsequent thread, pid %d tid %d\n", pid, tid );
+#endif
+ }
+
+ /* Another day, another thread...
+ */
+ thread_head.count++;
+
+ /* The new thread always goes at the head of the list.
+ */
+ new_p->next = thread_head.head;
+ thread_head.head = new_p;
+
+ /* Is this the "pseudo" thread of a process? It is if there's
+ * no other thread for this process on the list. (Note that this
+ * accomodates multiple processes, such as we see even for simple
+ * cases like forking "non-threaded" programs.)
+ */
+ p = thread_head.head;
+ thread_count_of_pid = 0;
+ while (p)
+ {
+ if (p->pid == new_p->pid)
+ thread_count_of_pid++;
+ p = p->next;
+ }
+
+ /* Did we see any other threads for this pid? (Recall that we just
+ * added this thread to the list...)
+ */
+ if (thread_count_of_pid == 1)
+ {
+ new_p->am_pseudo = 1;
+ new_p->next_pseudo = thread_head.head_pseudo;
+ thread_head.head_pseudo = new_p;
+ }
+
+ return new_p;
+}
+
+/* Get rid of our thread info.
+ */
+static void
+clear_thread_info ()
+{
+ thread_info *p;
+ thread_info *q;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Clearing all thread info\n" );
+#endif
+
+ p = thread_head.head;
+ while( p ) {
+ q = p;
+ p = p->next;
+ free( q );
+ }
+
+ thread_head.head = NULL;
+ thread_head.head_pseudo = NULL;
+ thread_head.count = 0;
+
+ p = deleted_threads.head;
+ while( p ) {
+ q = p;
+ p = p->next;
+ free( q );
+ }
+
+ deleted_threads.head = NULL;
+ deleted_threads.head_pseudo = NULL;
+ deleted_threads.count = 0;
+
+ /* No threads, so can't have pending events.
+ */
+ more_events_left = 0;
+}
+
+/* Given a tid, find the thread block for it.
+ */
+static thread_info *
+find_thread_info (tid)
+ lwpid_t tid;
+{
+ thread_info *p;
+
+ for( p = thread_head.head; p; p = p->next ) {
+ if( p->tid == tid ) {
+ return p;
+ }
+ }
+
+ for( p = deleted_threads.head; p; p = p->next ) {
+ if( p->tid == tid ) {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+/* For any but the pseudo thread, this maps to the
+ * thread ID. For the pseudo thread, if you pass either
+ * the thread id or the PID, you get the pseudo thread ID.
+ *
+ * We have to be prepared for core gdb to ask about
+ * deleted threads. We do the map, but we don't like it.
+ */
+static lwpid_t
+map_from_gdb_tid( gdb_tid )
+ lwpid_t gdb_tid;
+{
+ thread_info *p;
+
+ /* First assume gdb_tid really is a tid, and try to find a
+ * matching entry on the threads list.
+ */
+ for( p = thread_head.head; p; p = p->next ) {
+ if( p->tid == gdb_tid )
+ return gdb_tid;
+ }
+
+ /* It doesn't appear to be a tid; perhaps it's really a pid?
+ * Try to find a "pseudo" thread entry on the threads list.
+ */
+ for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo)
+ {
+ if (p->pid == gdb_tid)
+ return p->tid;
+ }
+
+ /* Perhaps it's the tid of a deleted thread we may still
+ * have some knowledge of?
+ */
+ for( p = deleted_threads.head; p; p = p-> next ) {
+ if( p->tid == gdb_tid )
+ return gdb_tid;
+ }
+
+ /* Or perhaps it's the pid of a deleted process we may still
+ * have knowledge of?
+ */
+ for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo)
+ {
+ if (p->pid == gdb_tid)
+ return p->tid;
+ }
+
+ return 0; /* Error? */
+}
+
+/* Map the other way: from a real tid to the
+ * "pid" known by core gdb. This tid may be
+ * for a thread that just got deleted, so we
+ * also need to consider deleted threads.
+ */
+static lwpid_t
+map_to_gdb_tid( real_tid )
+ lwpid_t real_tid;
+{
+ thread_info *p;
+
+ for( p = thread_head.head; p; p = p->next ) {
+ if( p->tid == real_tid ) {
+ if( p->am_pseudo )
+ return p->pid;
+ else
+ return real_tid;
+ }
+ }
+
+ for( p = deleted_threads.head; p; p = p-> next ) {
+ if( p->tid == real_tid )
+ if( p->am_pseudo )
+ return p->pid; /* Error? */
+ else
+ return real_tid;
+ }
+
+ return 0; /* Error? Never heard of this thread! */
+}
+
+/* Do any threads have saved signals?
+ */
+static int
+saved_signals_exist ()
+{
+ thread_info *p;
+
+ for( p = thread_head.head; p; p = p->next ) {
+ if( p->have_signal ) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Is this the tid for the zero-th thread?
+ */
+static int
+is_pseudo_thread (tid)
+ lwpid_t tid;
+{
+ thread_info *p = find_thread_info( tid );
+ if( NULL == p || p->terminated )
+ return 0;
+ else
+ return p->am_pseudo;
+}
+
+/* Is this thread terminated?
+ */
+static int
+is_terminated (tid)
+ lwpid_t tid;
+{
+ thread_info *p = find_thread_info( tid );
+
+ if( NULL != p )
+ return p->terminated;
+
+ return 0;
+}
+
+/* Is this pid a real PID or a TID?
+ */
+static int
+is_process_id (pid)
+ int pid;
+{
+ lwpid_t tid;
+ thread_info * tinfo;
+ pid_t this_pid;
+ int this_pid_count;
+
+ /* What does PID really represent?
+ */
+ tid = map_from_gdb_tid (pid);
+ if (tid <= 0)
+ return 0; /* Actually, is probably an error... */
+
+ tinfo = find_thread_info (tid);
+
+ /* Does it appear to be a true thread?
+ */
+ if (! tinfo->am_pseudo)
+ return 0;
+
+ /* Else, it looks like it may be a process. See if there's any other
+ * threads with the same process ID, though. If there are, then TID
+ * just happens to be the first thread of several for this process.
+ */
+ this_pid = tinfo->pid;
+ this_pid_count = 0;
+ for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next)
+ {
+ if (tinfo->pid == this_pid)
+ this_pid_count++;
+ }
+
+ return (this_pid_count == 1);
+}
+
+
+/* Add a thread to our info. Prevent duplicate entries.
+ */
+static thread_info *
+add_tthread (pid, tid)
+ int pid;
+ lwpid_t tid;
+{
+ thread_info *p;
+
+ p = find_thread_info( tid );
+ if( NULL == p )
+ p = create_thread_info( pid, tid );
+
+ return p;
+}
+
+/* Notice that a thread was deleted.
+ */
+static void
+del_tthread (tid)
+ lwpid_t tid;
+{
+ thread_info *p;
+ thread_info *chase;
+
+ if( thread_head.count <= 0 ) {
+ error( "Internal error in thread database." );
+ return;
+ }
+
+ chase = NULL;
+ for( p = thread_head.head; p; p = p->next ) {
+ if( p->tid == tid ) {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Delete here: %d \n", tid );
+#endif
+
+ if( p->am_pseudo ) {
+ /*
+ * Deleting a main thread is ok if we're doing
+ * a parent-follow on a child; this is odd but
+ * not wrong. It apparently _doesn't_ happen
+ * on the child-follow, as we don't just delete
+ * the pseudo while keeping the rest of the
+ * threads around--instead, we clear out the whole
+ * thread list at once.
+ */
+ thread_info *q;
+ thread_info *q_chase;
+
+ q_chase = NULL;
+ for( q = thread_head.head_pseudo; q; q = q -> next ) {
+ if( q == p ) {
+ /* Remove from pseudo list.
+ */
+ if( q_chase == NULL )
+ thread_head.head_pseudo = p->next_pseudo;
+ else
+ q_chase-> next = p->next_pseudo;
+ }
+ else
+ q_chase = q;
+ }
+ }
+
+ /* Remove from live list.
+ */
+ thread_head.count--;
+
+ if( NULL == chase )
+ thread_head.head = p->next;
+ else
+ chase->next = p->next;
+
+ /* Add to deleted thread list.
+ */
+ p->next = deleted_threads.head;
+ deleted_threads.head = p;
+ deleted_threads.count++;
+ if( p->am_pseudo ) {
+ p->next_pseudo = deleted_threads.head_pseudo;
+ deleted_threads.head_pseudo = p;
+ }
+ p->terminated = 1;
+
+ return;
+ }
+
+ else
+ chase = p;
+ }
+}
+
+/* Get the pid for this tid. (Has to be a real TID!).
+ */
+static int
+get_pid_for (tid)
+ lwpid_t tid;
+{
+ thread_info *p;
+
+ for( p = thread_head.head; p; p = p->next ) {
+ if( p->tid == tid ) {
+ return p->pid;
+ }
+ }
+
+ for( p = deleted_threads.head; p; p = p->next ) {
+ if( p->tid == tid ) {
+ return p->pid;
+ }
+ }
+
+ return 0;
+}
+
+/* Note that this thread's current event has been handled.
+ */
+static void
+set_handled( pid, tid )
+ int pid;
+ lwpid_t tid;
+{
+ thread_info *p;
+
+ p = find_thread_info( tid );
+ if( NULL == p )
+ p = add_tthread( pid, tid );
+
+ p->handled = 1;
+}
+
+/* Was this thread's current event handled?
+ */
+static int
+was_handled( tid )
+ lwpid_t tid;
+{
+ thread_info *p;
+
+ p = find_thread_info( tid );
+ if( NULL != p )
+ return p->handled;
+
+ return 0; /* New threads have not been handled */
+}
+
+/* Set this thread to unhandled.
+ */
+static void
+clear_handled( tid )
+ lwpid_t tid;
+{
+ thread_info * p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "clear_handled %d\n", (int) tid );
+#endif
+
+ p = find_thread_info (tid);
+ if (p == NULL)
+ error ("Internal error: No thread state to clear?");
+
+ p->handled = 0;
+}
+
+/* Set all threads to unhandled.
+ */
+static void
+clear_all_handled ()
+{
+ thread_info *p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "clear_all_handled\n" );
+#endif
+
+ for( p = thread_head.head; p; p = p->next ) {
+ p->handled = 0;
+ }
+
+ for( p = deleted_threads.head; p; p = p->next ) {
+ p->handled = 0;
+ }
+}
+
+/* Set this thread to default stepping mode.
+ */
+static void
+clear_stepping_mode( tid )
+ lwpid_t tid;
+{
+ thread_info * p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "clear_stepping_mode %d\n", (int) tid );
+#endif
+
+ p = find_thread_info (tid);
+ if (p == NULL)
+ error ("Internal error: No thread state to clear?");
+
+ p->stepping_mode = DO_DEFAULT;
+}
+
+/* Set all threads to do default continue on resume.
+ */
+static void
+clear_all_stepping_mode ()
+{
+ thread_info *p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "clear_all_stepping_mode\n" );
+#endif
+
+ for( p = thread_head.head; p; p = p->next ) {
+ p->stepping_mode = DO_DEFAULT;
+ }
+
+ for( p = deleted_threads.head; p; p = p->next ) {
+ p->stepping_mode = DO_DEFAULT;
+ }
+}
+
+/* Set all threads to unseen on this pass.
+ */
+static void
+set_all_unseen ()
+{
+ thread_info *p;
+
+ for( p = thread_head.head; p; p = p->next ) {
+ p->seen = 0;
+ }
+}
+
+#if (defined( THREAD_DEBUG ) || defined( PARANOIA ))
+/* debugging routine.
+ */
+static void
+print_tthread (p)
+ thread_info * p;
+{
+ printf( " Thread pid %d, tid %d", p->pid, p->tid );
+ if( p->have_state )
+ printf( ", event is %s",
+ get_printable_name_of_ttrace_event( p->last_stop_state.tts_event ));
+
+ if( p->am_pseudo )
+ printf( ", pseudo thread" );
+
+ if( p->have_signal )
+ printf( ", have signal 0x%x", p->signal_value );
+
+ if( p->have_start )
+ printf( ", have start at 0x%x", p->start );
+
+ printf( ", step is %s", get_printable_name_of_stepping_mode( p->stepping_mode ));
+
+ if( p->handled )
+ printf( ", handled" );
+ else
+ printf( ", not handled" );
+
+ if( p->seen )
+ printf( ", seen" );
+ else
+ printf( ", not seen" );
+
+ printf( "\n" );
+}
+
+static void
+print_tthreads ()
+{
+ thread_info *p;
+
+ if( thread_head.count == 0 )
+ printf( "Thread list is empty\n" );
+ else {
+ printf( "Thread list has " );
+ if( thread_head.count == 1 )
+ printf( "1 entry:\n" );
+ else
+ printf( "%d entries:\n", thread_head.count );
+ for( p = thread_head.head; p; p = p->next ) {
+ print_tthread (p);
+ }
+ }
+
+ if( deleted_threads.count == 0 )
+ printf( "Deleted thread list is empty\n" );
+ else {
+ printf( "Deleted thread list has " );
+ if( deleted_threads.count == 1 )
+ printf( "1 entry:\n" );
+ else
+ printf( "%d entries:\n", deleted_threads.count );
+
+ for( p = deleted_threads.head; p; p = p->next ) {
+ print_tthread (p);
+ }
+ }
+}
+#endif
+
+/* Update the thread list based on the "seen" bits.
+ */
+static void
+update_thread_list ()
+{
+ thread_info *p;
+ thread_info *chase;
+
+ chase = NULL;
+ for( p = thread_head.head; p; p = p->next ) {
+ /* Is this an "unseen" thread which really happens to be a process?
+ If so, is it inferior_pid and is a vfork in flight? If yes to
+ all, then DON'T REMOVE IT! We're in the midst of moving a vfork
+ operation, which is a multiple step thing, to the point where we
+ can touch the parent again. We've most likely stopped to examine
+ the child at a late stage in the vfork, and if we're not following
+ the child, we'd best not treat the parent as a dead "thread"...
+ */
+ if( (!p->seen) && p->am_pseudo && vfork_in_flight
+ && (p->pid != vforking_child_pid))
+ p->seen = 1;
+
+ if( !p->seen ) {
+ /* Remove this one
+ */
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Delete unseen thread: %d \n", p->tid );
+#endif
+ del_tthread( p->tid );
+ }
+ }
+}
+
+
+
+/************************************************
+ * O/S call wrappers *
+ ************************************************
+ */
+
+/* This function simply calls ttrace with the given arguments.
+ * It exists so that all calls to ttrace are isolated. All
+ * parameters should be as specified by "man 2 ttrace".
+ *
+ * No other "raw" calls to ttrace should exist in this module.
+ */
+static int
+call_real_ttrace( request, pid, tid, addr, data, addr2 )
+ ttreq_t request;
+ pid_t pid;
+ lwpid_t tid;
+ TTRACE_ARG_TYPE addr, data, addr2;
+{
+ int tt_status;
+
+ errno = 0;
+ tt_status = ttrace( request, pid, tid, addr, data, addr2 );
+
+#ifdef THREAD_DEBUG
+ if (errno) {
+ /* Don't bother for a known benign error: if you ask for the
+ * first thread state, but there is only one thread and it's
+ * not stopped, ttrace complains.
+ *
+ * We have this inside the #ifdef because our caller will do
+ * this check for real.
+ */
+ if( request != TT_PROC_GET_FIRST_LWP_STATE
+ || errno != EPROTO ) {
+ if( debug_on )
+ printf( "TT fail for %s, with pid %d, tid %d, status %d \n",
+ get_printable_name_of_ttrace_request (request),
+ pid, tid, tt_status );
+ }
+ }
+#endif
+
+#if 0
+ /* ??rehrauer: It would probably be most robust to catch and report
+ * failed requests here. However, some clients of this interface
+ * seem to expect to catch & deal with them, so we'd best not.
+ */
+ if (errno) {
+ strcpy (reason_for_failure, "ttrace (");
+ strcat (reason_for_failure, get_printable_name_of_ttrace_request (request));
+ strcat (reason_for_failure, ")");
+ printf( "ttrace error, errno = %d\n", errno );
+ perror_with_name (reason_for_failure);
+ }
+#endif
+
+ return tt_status;
+}
+
+
+/* This function simply calls ttrace_wait with the given arguments.
+ * It exists so that all calls to ttrace_wait are isolated.
+ *
+ * No "raw" calls to ttrace_wait should exist elsewhere.
+ */
+static int
+call_real_ttrace_wait( pid, tid, option, tsp, tsp_size )
+ int pid;
+ lwpid_t tid;
+ ttwopt_t option;
+ ttstate_t *tsp;
+ size_t tsp_size;
+{
+ int ttw_status;
+ thread_info * tinfo = NULL;
+
+ errno = 0;
+ ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size);
+
+ if (errno) {
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "TW fail with pid %d, tid %d \n", pid, tid );
+#endif
+
+ perror_with_name ("ttrace wait");
+ }
+
+ return ttw_status;
+}
+
+
+/* A process may have one or more kernel threads, of which all or
+ none may be stopped. This function returns the ID of the first
+ kernel thread in a stopped state, or 0 if none are stopped.
+
+ This function can be used with get_process_next_stopped_thread_id
+ to iterate over the IDs of all stopped threads of this process.
+ */
+static lwpid_t
+get_process_first_stopped_thread_id (pid, thread_state)
+ int pid;
+ ttstate_t * thread_state;
+{
+ int tt_status;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_GET_FIRST_LWP_STATE,
+ (pid_t) pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) thread_state,
+ (TTRACE_ARG_TYPE) sizeof (*thread_state),
+ TT_NIL);
+
+ if (errno) {
+ if( errno == EPROTO) {
+ /* This is an error we can handle: there isn't any stopped
+ * thread. This happens when we're re-starting the application
+ * and it has only one thread. GET_NEXT handles the case of
+ * no more stopped threads well; GET_FIRST doesn't. (A ttrace
+ * "feature".)
+ */
+ tt_status = 1;
+ errno = 0;
+ return 0;
+ }
+ else
+ perror_with_name ("ttrace");
+ }
+
+ if( tt_status < 0 )
+ /* Failed somehow.
+ */
+ return 0;
+
+ return thread_state->tts_lwpid;
+}
+
+
+/* This function returns the ID of the "next" kernel thread in a
+ stopped state, or 0 if there are none. "Next" refers to the
+ thread following that of the last successful call to this
+ function or to get_process_first_stopped_thread_id, using
+ the value of thread_state returned by that call.
+
+ This function can be used with get_process_first_stopped_thread_id
+ to iterate over the IDs of all stopped threads of this process.
+ */
+static lwpid_t
+get_process_next_stopped_thread_id (pid, thread_state)
+ int pid;
+ ttstate_t * thread_state;
+{
+ int tt_status;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_GET_NEXT_LWP_STATE,
+ (pid_t) pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) thread_state,
+ (TTRACE_ARG_TYPE) sizeof (*thread_state),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ /* Failed
+ */
+ return 0;
+
+ else if( tt_status == 0 ) {
+ /* End of list, no next state. Don't return the
+ * tts_lwpid, as it's a meaningless "240".
+ *
+ * This is an HPUX "feature".
+ */
+ return 0;
+ }
+
+ return thread_state->tts_lwpid;
+}
+
+/* ??rehrauer: Eventually this function perhaps should be calling
+ pid_to_thread_id. However, that function currently does nothing
+ for HP-UX. Even then, I'm not clear whether that function
+ will return a "kernel" thread ID, or a "user" thread ID. If
+ the former, we can just call it here. If the latter, we must
+ map from the "user" tid to a "kernel" tid.
+
+ NOTE: currently not called.
+ */
+static lwpid_t
+get_active_tid_of_pid (pid)
+ int pid;
+{
+ ttstate_t thread_state;
+
+ return get_process_first_stopped_thread_id (pid, &thread_state);
+}
+
+/* This function returns 1 if tt_request is a ttrace request that
+ * operates upon all threads of a (i.e., the entire) process.
+ */
+int
+is_process_ttrace_request (tt_request)
+ ttreq_t tt_request;
+{
+ return IS_TTRACE_PROCREQ (tt_request);
+}
+
+
+/* This function translates a thread ttrace request into
+ * the equivalent process request for a one-thread process.
+ */
+static ttreq_t
+make_process_version( request )
+ ttreq_t request;
+{
+ if (!IS_TTRACE_REQ (request)) {
+ error( "Internal error, bad ttrace request made\n" );
+ return -1;
+ }
+
+ switch (request) {
+ case TT_LWP_STOP :
+ return TT_PROC_STOP;
+
+ case TT_LWP_CONTINUE :
+ return TT_PROC_CONTINUE;
+
+ case TT_LWP_GET_EVENT_MASK :
+ return TT_PROC_GET_EVENT_MASK;
+
+ case TT_LWP_SET_EVENT_MASK :
+ return TT_PROC_SET_EVENT_MASK;
+
+ case TT_LWP_SINGLE :
+ case TT_LWP_RUREGS :
+ case TT_LWP_WUREGS :
+ case TT_LWP_GET_STATE :
+ return -1; /* No equivalent */
+
+ default :
+ return request;
+ }
+}
+
+
+/* This function translates the "pid" used by the rest of
+ * gdb to a real pid and a tid. It then calls "call_real_ttrace"
+ * with the given arguments.
+ *
+ * In general, other parts of this module should call this
+ * function when they are dealing with external users, who only
+ * have tids to pass (but they call it "pid" for historical
+ * reasons).
+ */
+static int
+call_ttrace( request, gdb_tid, addr, data, addr2 )
+ ttreq_t request;
+ int gdb_tid;
+ TTRACE_ARG_TYPE addr, data, addr2;
+{
+ lwpid_t real_tid;
+ int real_pid;
+ ttreq_t new_request;
+ int tt_status;
+ char reason_for_failure [100]; /* Arbitrary size, should be big enough. */
+
+#ifdef THREAD_DEBUG
+ int is_interesting = 0;
+
+ if( TT_LWP_RUREGS == request ) {
+ is_interesting = 1; /* Adjust code here as desired */
+ }
+
+ if( is_interesting && 0 && debug_on ) {
+ if( !is_process_ttrace_request( request )) {
+ printf( "TT: Thread request, tid is %d", gdb_tid );
+ printf( "== SINGLE at %x", addr );
+ }
+ else {
+ printf( "TT: Process request, tid is %d\n", gdb_tid );
+ printf( "==! SINGLE at %x", addr );
+ }
+ }
+#endif
+
+ /* The initial SETTRC and SET_EVENT_MASK calls (and all others
+ * which happen before any threads get set up) should go
+ * directly to "call_real_ttrace", so they don't happen here.
+ *
+ * But hardware watchpoints do a SET_EVENT_MASK, so we can't
+ * rule them out....
+ */
+#ifdef THREAD_DEBUG
+ if( request == TT_PROC_SETTRC && debug_on )
+ printf( "Unexpected call for TT_PROC_SETTRC\n" );
+#endif
+
+ /* Sometimes we get called with a bogus tid (e.g., if a
+ * thread has terminated, we return 0; inftarg later asks
+ * whether the thread has exited/forked/vforked).
+ */
+ if( gdb_tid == 0 )
+ {
+ errno = ESRCH; /* ttrace's response would probably be "No such process". */
+ return -1;
+ }
+
+ /* All other cases should be able to expect that there are
+ * thread records.
+ */
+ if( !any_thread_records()) {
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ warning ("No thread records for ttrace call");
+#endif
+ errno = ESRCH; /* ttrace's response would be "No such process". */
+ return -1;
+ }
+
+ /* OK, now the task is to translate the incoming tid into
+ * a pid/tid pair.
+ */
+ real_tid = map_from_gdb_tid( gdb_tid );
+ real_pid = get_pid_for( real_tid );
+
+ /* Now check the result. "Real_pid" is NULL if our list
+ * didn't find it. We have some tricks we can play to fix
+ * this, however.
+ */
+ if( 0 == real_pid ) {
+ ttstate_t thread_state;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "No saved pid for tid %d\n", gdb_tid );
+#endif
+
+ if( is_process_ttrace_request( request )) {
+
+ /* Ok, we couldn't get a tid. Try to translate to
+ * the equivalent process operation. We expect this
+ * NOT to happen, so this is a desparation-type
+ * move. It can happen if there is an internal
+ * error and so no "wait()" call is ever done.
+ */
+ new_request = make_process_version( request );
+ if( new_request == -1 ) {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "...and couldn't make process version of thread operation\n" );
+#endif
+
+ /* Use hacky saved pid, which won't always be correct
+ * in the multi-process future. Use tid as thread,
+ * probably dooming this to failure. FIX!
+ */
+ if( saved_real_pid != 0 ) {
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "...using saved pid %d\n", saved_real_pid );
+#endif
+
+ real_pid = saved_real_pid;
+ real_tid = gdb_tid;
+ }
+
+ else
+ error( "Unable to perform thread operation" );
+ }
+
+ else {
+ /* Sucessfully translated this to a process request,
+ * which needs no thread value.
+ */
+ real_pid = gdb_tid;
+ real_tid = 0;
+ request = new_request;
+
+#ifdef THREAD_DEBUG
+ if( debug_on ) {
+ printf( "Translated thread request to process request\n" );
+ if( saved_real_pid == 0 )
+ printf( "...but there's no saved pid\n" );
+
+ else {
+ if( gdb_tid != saved_real_pid )
+ printf( "...but have the wrong pid (%d rather than %d)\n",
+ gdb_tid, saved_real_pid );
+ }
+ }
+#endif
+ } /* Translated to a process request */
+ } /* Is a process request */
+
+ else {
+ /* We have to have a thread. Ooops.
+ */
+ error( "Thread request with no threads (%s)",
+ get_printable_name_of_ttrace_request( request ));
+ }
+ }
+
+ /* Ttrace doesn't like to see tid values on process requests,
+ * even if we have the right one.
+ */
+ if (is_process_ttrace_request (request)) {
+ real_tid = 0;
+ }
+
+#ifdef THREAD_DEBUG
+ if( is_interesting && 0 && debug_on ) {
+ printf( " now tid %d, pid %d\n", real_tid, real_pid );
+ printf( " request is %s\n", get_printable_name_of_ttrace_request (request));
+ }
+#endif
+
+ /* Finally, the (almost) real call.
+ */
+ tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2);
+
+#ifdef THREAD_DEBUG
+ if(is_interesting && debug_on ) {
+ if( !TT_OK( tt_status, errno )
+ && !(tt_status == 0 & errno == 0))
+ printf( " got error (errno==%d, status==%d)\n", errno, tt_status );
+ }
+#endif
+
+ return tt_status;
+}
+
+
+/* Stop all the threads of a process.
+ *
+ * NOTE: use of TT_PROC_STOP can cause a thread with a real event
+ * to get a TTEVT_NONE event, discarding the old event. Be
+ * very careful, and only call TT_PROC_STOP when you mean it!
+ */
+static void
+stop_all_threads_of_process( real_pid )
+ pid_t real_pid;
+{
+ int ttw_status;
+
+ ttw_status = call_real_ttrace (TT_PROC_STOP,
+ (pid_t) real_pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ TT_NIL );
+ if (errno)
+ perror_with_name ("ttrace stop of other threads");
+}
+
+
+/* Under some circumstances, it's unsafe to attempt to stop, or even
+ query the state of, a process' threads.
+
+ In ttrace-based HP-UX, an example is a vforking child process. The
+ vforking parent and child are somewhat fragile, w/r/t what we can do
+ what we can do to them with ttrace, until after the child exits or
+ execs, or until the parent's vfork event is delivered. Until that
+ time, we must not try to stop the process' threads, or inquire how
+ many there are, or even alter its data segments, or it typically dies
+ with a SIGILL. Sigh.
+
+ This function returns 1 if this stopped process, and the event that
+ we're told was responsible for its current stopped state, cannot safely
+ have its threads examined.
+ */
+#define CHILD_VFORKED(evt,pid) \
+ (((evt) == TTEVT_VFORK) && ((pid) != inferior_pid))
+#define CHILD_URPED(evt,pid) \
+ ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid))
+#define PARENT_VFORKED(evt,pid) \
+ (((evt) == TTEVT_VFORK) && ((pid) == inferior_pid))
+
+static int
+can_touch_threads_of_process (pid, stopping_event)
+ int pid;
+ ttevents_t stopping_event;
+{
+ if (CHILD_VFORKED (stopping_event, pid))
+ {
+ vforking_child_pid = pid;
+ vfork_in_flight = 1;
+ }
+
+ else if (vfork_in_flight &&
+ (PARENT_VFORKED (stopping_event, pid) ||
+ CHILD_URPED (stopping_event, pid)))
+ {
+ vfork_in_flight = 0;
+ vforking_child_pid = 0;
+ }
+
+ return ! vfork_in_flight;
+}
+
+
+/* If we can find an as-yet-unhandled thread state of a
+ * stopped thread of this process return 1 and set "tsp".
+ * Return 0 if we can't.
+ *
+ * If this function is used when the threads of PIS haven't
+ * been stopped, undefined behaviour is guaranteed!
+ */
+static int
+select_stopped_thread_of_process (pid, tsp)
+ int pid;
+ ttstate_t * tsp;
+{
+ lwpid_t candidate_tid, tid;
+ ttstate_t candidate_tstate, tstate;
+
+ /* If we're not allowed to touch the process now, then just
+ * return the current value of *TSP.
+ *
+ * This supports "vfork". It's ok, really, to double the
+ * current event (the child EXEC, we hope!).
+ */
+ if (! can_touch_threads_of_process (pid, tsp->tts_event))
+ return 1;
+
+ /* Decide which of (possibly more than one) events to
+ * return as the first one. We scan them all so that
+ * we always return the result of a fake-step first.
+ */
+ candidate_tid = 0;
+ for (tid = get_process_first_stopped_thread_id (pid, &tstate);
+ tid != 0;
+ tid = get_process_next_stopped_thread_id (pid, &tstate))
+ {
+ /* TTEVT_NONE events are uninteresting to our clients. They're
+ * an artifact of our "stop the world" model--the thread is
+ * stopped because we stopped it.
+ */
+ if (tstate.tts_event == TTEVT_NONE) {
+ set_handled( pid, tstate.tts_lwpid );
+ }
+
+ /* Did we just single-step a single thread, without letting any
+ * of the others run? Is this an event for that thread?
+ *
+ * If so, we believe our client would prefer to see this event
+ * over any others. (Typically the client wants to just push
+ * one thread a little farther forward, and then go around
+ * checking for what all threads are doing.)
+ */
+ else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid))
+ {
+#ifdef WAIT_BUFFER_DEBUG
+ /* It's possible here to see either a SIGTRAP (due to
+ * successful completion of a step) or a SYSCALL_ENTRY
+ * (due to a step completion with active hardware
+ * watchpoints).
+ */
+ if( debug_on )
+ printf( "Ending fake step with tid %d, state %s\n",
+ tstate.tts_lwpid,
+ get_printable_name_of_ttrace_event( tstate.tts_event ));
+#endif
+
+ /* Remember this one, and throw away any previous
+ * candidate.
+ */
+ candidate_tid = tstate.tts_lwpid;
+ candidate_tstate = tstate;
+ }
+
+#ifdef FORGET_DELETED_BPTS
+
+ /* We can't just do this, as if we do, and then wind
+ * up the loop with no unhandled events, we need to
+ * handle that case--the appropriate reaction is to
+ * just continue, but there's no easy way to do that.
+ *
+ * Better to put this in the ttrace_wait call--if, when
+ * we fake a wait, we update our events based on the
+ * breakpoint_here_pc call and find there are no more events,
+ * then we better continue and so on.
+ *
+ * Or we could put it in the next/continue fake.
+ * But it has to go in the buffering code, not in the
+ * real go/wait code.
+ */
+ else if( (TTEVT_SIGNAL == tstate.tts_event)
+ && (5 == tstate.tts_u.tts_signal.tts_signo)
+ && (0 != get_raw_pc( tstate.tts_lwpid ))
+ && ! breakpoint_here_p( get_raw_pc( tstate.tts_lwpid )) ) {
+ /*
+ * If the user deleted a breakpoint while this
+ * breakpoint-hit event was buffered, we can forget
+ * it now.
+ */
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Forgetting deleted bp hit for thread %d\n",
+ tstate.tts_lwpid );
+#endif
+
+ set_handled( pid, tstate.tts_lwpid );
+ }
+#endif
+
+ /* Else, is this the first "unhandled" event? If so,
+ * we believe our client wants to see it (if we don't
+ * see a fake-step later on in the scan).
+ */
+ else if( !was_handled( tstate.tts_lwpid ) && candidate_tid == 0 ) {
+ candidate_tid = tstate.tts_lwpid;
+ candidate_tstate = tstate;
+ }
+
+ /* This is either an event that has already been "handled",
+ * and thus we believe is uninteresting to our client, or we
+ * already have a candidate event. Ignore it...
+ */
+ }
+
+ /* What do we report?
+ */
+ if( doing_fake_step ) {
+ if( candidate_tid == fake_step_tid ) {
+ /* Fake step.
+ */
+ tstate = candidate_tstate;
+ }
+ else {
+ warning( "Internal error: fake-step failed to complete." );
+ return 0;
+ }
+ }
+ else if( candidate_tid != 0 ) {
+ /* Found a candidate unhandled event.
+ */
+ tstate = candidate_tstate;
+ }
+ else if( tid != 0 ) {
+ warning( "Internal error in call of ttrace_wait." );
+ return 0;
+ }
+ else {
+ warning ("Internal error: no unhandled thread event to select");
+ return 0;
+ }
+
+ copy_ttstate_t (tsp, &tstate);
+ return 1;
+} /* End of select_stopped_thread_of_process */
+
+#ifdef PARANOIA
+/* Check our internal thread data against the real thing.
+ */
+static void
+check_thread_consistency( real_pid )
+ pid_t real_pid;
+{
+ int tid; /* really lwpid_t */
+ ttstate_t tstate;
+ thread_info *p;
+
+ /* Spin down the O/S list of threads, checking that they
+ * match what we've got.
+ */
+ for (tid = get_process_first_stopped_thread_id( real_pid, &tstate );
+ tid != 0;
+ tid = get_process_next_stopped_thread_id( real_pid, &tstate )) {
+
+ p = find_thread_info( tid );
+
+ if( NULL == p ) {
+ warning( "No internal thread data for thread %d.", tid );
+ continue;
+ }
+
+ if( !p->seen ) {
+ warning( "Inconsistent internal thread data for thread %d.", tid );
+ }
+
+ if( p->terminated ) {
+ warning( "Thread %d is not terminated, internal error.", tid );
+ continue;
+ }
+
+
+#define TT_COMPARE( fld ) \
+ tstate.fld != p->last_stop_state.fld
+
+ if( p->have_state ) {
+ if( TT_COMPARE( tts_pid )
+ || TT_COMPARE( tts_lwpid )
+ || TT_COMPARE( tts_user_tid )
+ || TT_COMPARE( tts_event )
+ || TT_COMPARE( tts_flags )
+ || TT_COMPARE( tts_scno )
+ || TT_COMPARE( tts_scnargs )) {
+ warning( "Internal thread data for thread %d is wrong.", tid );
+ continue;
+ }
+ }
+ }
+}
+#endif /* PARANOIA */
+
+
+/* This function wraps calls to "call_real_ttrace_wait" so
+ * that a actual wait is only done when all pending events
+ * have been reported.
+ *
+ * Note that typically it is called with a pid of "0", i.e.
+ * the "don't care" value.
+ *
+ * Return value is the status of the pseudo wait.
+ */
+static int
+call_ttrace_wait( pid, option, tsp, tsp_size )
+ int pid;
+ ttwopt_t option;
+ ttstate_t *tsp;
+ size_t tsp_size;
+{
+ /* This holds the actual, for-real, true process ID.
+ */
+ static int real_pid;
+
+ /* As an argument to ttrace_wait, zero pid
+ * means "Any process", and zero tid means
+ * "Any thread of the specified process".
+ */
+ int wait_pid = 0;
+ lwpid_t wait_tid = 0;
+ lwpid_t real_tid;
+
+ int ttw_status = 0; /* To be returned */
+
+ thread_info * tinfo = NULL;
+
+ if( pid != 0 ) {
+ /* Unexpected case.
+ */
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "TW: Pid to wait on is %d\n", pid );
+#endif
+
+ if( !any_thread_records())
+ error( "No thread records for ttrace call w. specific pid" );
+
+ /* OK, now the task is to translate the incoming tid into
+ * a pid/tid pair.
+ */
+ real_tid = map_from_gdb_tid( pid );
+ real_pid = get_pid_for( real_tid );
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "==TW: real pid %d, real tid %d\n", real_pid, real_tid );
+#endif
+ }
+
+
+ /* Sanity checks and set-up.
+ * Process State
+ *
+ * Stopped Running Fake-step (v)Fork
+ * \________________________________________
+ * |
+ * No buffered events | error wait wait wait
+ * |
+ * Buffered events | debuffer error wait debuffer (?)
+ *
+ */
+ if( more_events_left == 0 ) {
+
+ if( process_state == RUNNING ) {
+ /* OK--normal call of ttrace_wait with no buffered events.
+ */
+ ;
+ }
+ else if( process_state == FAKE_STEPPING ) {
+ /* Ok--call of ttrace_wait to support
+ * fake stepping with no buffered events.
+ *
+ * But we better be fake-stepping!
+ */
+ if( !doing_fake_step ) {
+ warning( "Inconsistent thread state." );
+ }
+ }
+ else if( (process_state == FORKING)
+ || (process_state == VFORKING)) {
+ /* Ok--there are two processes, so waiting
+ * for the second while the first is stopped
+ * is ok. Handled bits stay as they were.
+ */
+ ;
+ }
+ else if( process_state == STOPPED ) {
+ warning( "Process not running at wait call." );
+ }
+ else
+ /* No known state.
+ */
+ warning( "Inconsistent process state." );
+ }
+
+ else {
+ /* More events left
+ */
+ if( process_state == STOPPED ) {
+ /* OK--buffered events being unbuffered.
+ */
+ ;
+ }
+ else if( process_state == RUNNING ) {
+ /* An error--shouldn't have buffered events
+ * when running.
+ */
+ warning( "Trying to continue with buffered events:" );
+ }
+ else if( process_state == FAKE_STEPPING ) {
+ /*
+ * Better be fake-stepping!
+ */
+ if( !doing_fake_step ) {
+ warning( "Losing buffered thread events!\n" );
+ }
+ }
+ else if( (process_state == FORKING)
+ || (process_state == VFORKING)) {
+ /* Ok--there are two processes, so waiting
+ * for the second while the first is stopped
+ * is ok. Handled bits stay as they were.
+ */
+ ;
+ }
+ else
+ warning( "Process in unknown state with buffered events." );
+ }
+
+ /* Sometimes we have to wait for a particular thread
+ * (if we're stepping over a bpt). In that case, we
+ * _know_ it's going to complete the single-step we
+ * asked for (because we're only doing the step under
+ * certain very well-understood circumstances), so it
+ * can't block.
+ */
+ if( doing_fake_step ) {
+ wait_tid = fake_step_tid;
+ wait_pid = get_pid_for( fake_step_tid );
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Doing a wait after a fake-step for %d, pid %d\n",
+ wait_tid, wait_pid );
+#endif
+ }
+
+ if( more_events_left == 0 /* No buffered events, need real ones. */
+ || process_state != STOPPED ) {
+ /* If there are no buffered events, and so we need
+ * real ones, or if we are FORKING, VFORKING,
+ * FAKE_STEPPING or RUNNING, and thus have to do
+ * a real wait, then do a real wait.
+ */
+
+#ifdef WAIT_BUFFER_DEBUG
+ /* Normal case... */
+ if( debug_on )
+ printf( "TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid );
+#endif
+
+ /* The actual wait call.
+ */
+ ttw_status = call_real_ttrace_wait( wait_pid, wait_tid, option, tsp, tsp_size);
+
+ /* Note that the routines we'll call will be using "call_real_ttrace",
+ * not "call_ttrace", and thus need the real pid rather than the pseudo-tid
+ * the rest of the world uses (which is actually the tid).
+ */
+ real_pid = tsp->tts_pid;
+
+ /* For most events: Stop the world!
+ *
+ * It's sometimes not safe to stop all threads of a process.
+ * Sometimes it's not even safe to ask for the thread state
+ * of a process!
+ */
+ if (can_touch_threads_of_process (real_pid, tsp->tts_event))
+ {
+ /* If we're really only stepping a single thread, then don't
+ * try to stop all the others -- we only do this single-stepping
+ * business when all others were already stopped...and the stop
+ * would mess up other threads' events.
+ *
+ * Similiarly, if there are other threads with events,
+ * don't do the stop.
+ */
+ if( !doing_fake_step ) {
+ if( more_events_left > 0 )
+ warning( "Internal error in stopping process" );
+
+ stop_all_threads_of_process (real_pid);
+
+ /* At this point, we could scan and update_thread_list(),
+ * and only use the local list for the rest of the
+ * module! We'd get rid of the scans in the various
+ * continue routines (adding one in attach). It'd
+ * be great--UPGRADE ME!
+ */
+ }
+ }
+
+#ifdef PARANOIA
+ else if( debug_on ) {
+ if( more_events_left > 0 )
+ printf( "== Can't stop process; more events!\n" );
+ else
+ printf( "== Can't stop process!\n" );
+ }
+#endif
+
+ process_state = STOPPED;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Process set to STOPPED\n" );
+#endif
+ }
+
+ else {
+ /* Fake a call to ttrace_wait. The process must be
+ * STOPPED, as we aren't going to do any wait.
+ */
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "TW: fake it\n" );
+#endif
+
+ if( process_state != STOPPED ) {
+ warning( "Process not stopped at wait call, in state '%s'.\n",
+ get_printable_name_of_process_state( process_state ));
+ }
+
+ if( doing_fake_step )
+ error( "Internal error in stepping over breakpoint" );
+
+ ttw_status = 0; /* Faking it is always successful! */
+ } /* End of fake or not? if */
+
+ /* Pick an event to pass to our caller. Be paranoid.
+ */
+ if( !select_stopped_thread_of_process( real_pid, tsp ))
+ warning( "Can't find event, using previous event." );
+
+ else if( tsp->tts_event == TTEVT_NONE )
+ warning( "Internal error: no thread has a real event." );
+
+ else if( doing_fake_step ) {
+ if( fake_step_tid != tsp->tts_lwpid )
+ warning( "Internal error in stepping over breakpoint." );
+
+ /* This wait clears the (current) fake-step if there was one.
+ */
+ doing_fake_step = 0;
+ fake_step_tid = 0;
+ }
+
+ /* We now have a correct tsp and ttw_status for the thread
+ * which we want to report. So it's "handled"! This call
+ * will add it to our list if it's not there already.
+ */
+ set_handled( real_pid, tsp->tts_lwpid );
+
+ /* Save a copy of the ttrace state of this thread, in our local
+ thread descriptor.
+
+ This caches the state. The implementation of queries like
+ target_has_execd can then use this cached state, rather than
+ be forced to make an explicit ttrace call to get it.
+
+ (Guard against the condition that this is the first time we've
+ waited on, i.e., seen this thread, and so haven't yet entered
+ it into our list of threads.)
+ */
+ tinfo = find_thread_info (tsp->tts_lwpid);
+ if (tinfo != NULL) {
+ copy_ttstate_t (&tinfo->last_stop_state, tsp);
+ tinfo->have_state = 1;
+ }
+
+ return ttw_status;
+} /* call_ttrace_wait */
+
+#if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
+int
+child_reported_exec_events_per_exec_call ()
+{
+ return 1; /* ttrace reports the event once per call. */
+}
+#endif
+
+
+
+/* Our implementation of hardware watchpoints involves making memory
+ pages write-protected. We must remember a page's original permissions,
+ and we must also know when it is appropriate to restore a page's
+ permissions to its original state.
+
+ We use a "dictionary" of hardware-watched pages to do this. Each
+ hardware-watched page is recorded in the dictionary. Each page's
+ dictionary entry contains the original permissions and a reference
+ count. Pages are hashed into the dictionary by their start address.
+
+ When hardware watchpoint is set on page X for the first time, page X
+ is added to the dictionary with a reference count of 1. If other
+ hardware watchpoints are subsequently set on page X, its reference
+ count is incremented. When hardware watchpoints are removed from
+ page X, its reference count is decremented. If a page's reference
+ count drops to 0, it's permissions are restored and the page's entry
+ is thrown out of the dictionary.
+ */
+typedef struct memory_page {
+ CORE_ADDR page_start;
+ int reference_count;
+ int original_permissions;
+ struct memory_page * next;
+ struct memory_page * previous;
+} memory_page_t;
+
+#define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT 128
+
+static struct {
+ LONGEST page_count;
+ int page_size;
+ int page_protections_allowed;
+ /* These are just the heads of chains of actual page descriptors. */
+ memory_page_t buckets [MEMORY_PAGE_DICTIONARY_BUCKET_COUNT];
+} memory_page_dictionary;
+
+
+static void
+require_memory_page_dictionary ()
+{
+ int i;
+
+ /* Is the memory page dictionary ready for use? If so, we're done. */
+ if (memory_page_dictionary.page_count >= (LONGEST) 0)
+ return;
+
+ /* Else, initialize it. */
+ memory_page_dictionary.page_count = (LONGEST) 0;
+
+ for (i=0; i<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++)
+ {
+ memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0;
+ memory_page_dictionary.buckets[i].reference_count = 0;
+ memory_page_dictionary.buckets[i].next = NULL;
+ memory_page_dictionary.buckets[i].previous = NULL;
+ }
+}
+
+
+static void
+retire_memory_page_dictionary ()
+{
+ memory_page_dictionary.page_count = (LONGEST) -1;
+}
+
+
+/* Write-protect the memory page that starts at this address.
+
+ Returns the original permissions of the page.
+ */
+static int
+write_protect_page (pid, page_start)
+ int pid;
+ CORE_ADDR page_start;
+{
+ int tt_status;
+ int original_permissions;
+ int new_permissions;
+
+ tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) &original_permissions);
+ if (errno || (tt_status < 0))
+ {
+ return 0; /* What else can we do? */
+ }
+
+ /* We'll also write-protect the page now, if that's allowed. */
+ if (memory_page_dictionary.page_protections_allowed)
+ {
+ new_permissions = original_permissions & ~PROT_WRITE;
+ tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
+ (TTRACE_ARG_TYPE) new_permissions);
+ if (errno || (tt_status < 0))
+ {
+ return 0; /* What else can we do? */
+ }
+ }
+
+ return original_permissions;
+}
+
+
+/* Unwrite-protect the memory page that starts at this address, restoring
+ (what we must assume are) its original permissions.
+ */
+static void
+unwrite_protect_page (pid, page_start, original_permissions)
+ int pid;
+ CORE_ADDR page_start;
+ int original_permissions;
+{
+ int tt_status;
+
+ tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
+ (TTRACE_ARG_TYPE) original_permissions);
+ if (errno || (tt_status < 0))
+ {
+ return; /* What else can we do? */
+ }
+}
+
+
+/* Memory page-protections are used to implement "hardware" watchpoints
+ on HP-UX.
+
+ For every memory page that is currently being watched (i.e., that
+ presently should be write-protected), write-protect it.
+ */
+void
+hppa_enable_page_protection_events (pid)
+ int pid;
+{
+ int bucket;
+
+ memory_page_dictionary.page_protections_allowed = 1;
+
+ for (bucket=0; bucket<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
+ {
+ memory_page_t * page;
+
+ page = memory_page_dictionary.buckets[bucket].next;
+ while (page != NULL)
+ {
+ page->original_permissions = write_protect_page (pid, page->page_start);
+ page = page->next;
+ }
+ }
+}
+
+
+/* Memory page-protections are used to implement "hardware" watchpoints
+ on HP-UX.
+
+ For every memory page that is currently being watched (i.e., that
+ presently is or should be write-protected), un-write-protect it.
+ */
+void
+hppa_disable_page_protection_events (pid)
+ int pid;
+{
+ int bucket;
+
+ for (bucket=0; bucket<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
+ {
+ memory_page_t * page;
+
+ page = memory_page_dictionary.buckets[bucket].next;
+ while (page != NULL)
+ {
+ unwrite_protect_page (pid, page->page_start, page->original_permissions);
+ page = page->next;
+ }
+ }
+
+ memory_page_dictionary.page_protections_allowed = 0;
+}
+
+/* Count the number of outstanding events. At this
+ * point, we have selected one thread and its event
+ * as the one to be "reported" upwards to core gdb.
+ * That thread is already marked as "handled".
+ *
+ * Note: we could just scan our own thread list. FIXME!
+ */
+static int
+count_unhandled_events( real_pid, real_tid )
+ int real_pid;
+ lwpid_t real_tid;
+{
+ ttstate_t tstate;
+ lwpid_t ttid;
+ int events_left;
+
+ /* Ok, find out how many threads have real events to report.
+ */
+ events_left = 0;
+ ttid = get_process_first_stopped_thread_id( real_pid, &tstate );
+
+#ifdef THREAD_DEBUG
+ if( debug_on ) {
+ if( ttid == 0 )
+ printf( "Process %d has no threads\n", real_pid );
+ else
+ printf( "Process %d has these threads:\n", real_pid );
+ }
+#endif
+
+ while (ttid > 0 ) {
+ if( tstate.tts_event != TTEVT_NONE
+ && !was_handled( ttid )) {
+ /* TTEVT_NONE implies we just stopped it ourselves
+ * because we're the stop-the-world guys, so it's
+ * not an event from our point of view.
+ *
+ * If "was_handled" is true, this is an event we
+ * already handled, so don't count it.
+ *
+ * Note that we don't count the thread with the
+ * currently-reported event, as it's already marked
+ * as handled.
+ */
+ events_left++;
+ }
+
+#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
+ if( debug_on ) {
+ if( ttid == real_tid )
+ printf( "*" ); /* Thread we're reporting */
+ else
+ printf( " " );
+
+ if( tstate.tts_event != TTEVT_NONE )
+ printf( "+" ); /* Thread with a real event */
+ else
+ printf( " " );
+
+ if( was_handled( ttid ))
+ printf( "h" ); /* Thread has been handled */
+ else
+ printf( " " );
+
+ printf( " %d, with event %s", ttid,
+ get_printable_name_of_ttrace_event( tstate.tts_event ));
+
+ if( tstate.tts_event == TTEVT_SIGNAL
+ && 5 == tstate.tts_u.tts_signal.tts_signo ) {
+ CORE_ADDR pc_val;
+
+ pc_val = get_raw_pc( ttid );
+
+ if( pc_val > 0 )
+ printf( " breakpoint at 0x%x\n", pc_val );
+ else
+ printf( " bpt, can't fetch pc.\n" );
+ }
+ else
+ printf( "\n" );
+ }
+#endif
+
+ ttid = get_process_next_stopped_thread_id (real_pid, &tstate);
+ }
+
+#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
+ if( debug_on )
+ if( events_left > 0 )
+ printf( "There are thus %d pending events\n", events_left );
+#endif
+
+ return events_left;
+}
+
+/* This function is provided as a sop to clients that are calling
+ * ptrace_wait to wait for a process to stop. (see the
+ * implementation of child_wait.) Return value is the pid for
+ * the event that ended the wait.
+ *
+ * Note: used by core gdb and so uses the pseudo-pid (really tid).
+ */
+int
+ptrace_wait (pid, status)
+ int pid;
+ int *status;
+{
+ ttstate_t tsp;
+ int ttwait_return;
+ int real_pid;
+ ttstate_t state;
+ lwpid_t real_tid;
+ int return_pid;
+
+ /* The ptrace implementation of this also ignores pid.
+ */
+ *status = 0;
+
+ ttwait_return = call_ttrace_wait( 0, TTRACE_WAITOK, &tsp, sizeof (tsp) );
+ if (ttwait_return < 0)
+ {
+ /* ??rehrauer: It appears that if our inferior exits and we
+ haven't asked for exit events, that we're not getting any
+ indication save a negative return from ttrace_wait and an
+ errno set to ESRCH?
+ */
+ if (errno == ESRCH)
+ {
+ *status = 0; /* WIFEXITED */
+ return inferior_pid;
+ }
+
+ warning( "Call of ttrace_wait returned with errno %d.",
+ errno );
+ *status = ttwait_return;
+ return inferior_pid;
+ }
+
+ real_pid = tsp.tts_pid;
+ real_tid = tsp.tts_lwpid;
+
+ /* One complication is that the "tts_event" structure has
+ * a set of flags, and more than one can be set. So we
+ * either have to force an order (as we do here), or handle
+ * more than one flag at a time.
+ */
+ if (tsp.tts_event & TTEVT_LWP_CREATE) {
+
+ /* Unlike what you might expect, this event is reported in
+ * the _creating_ thread, and the _created_ thread (whose tid
+ * we have) is still running. So we have to stop it. This
+ * has already been done in "call_ttrace_wait", but should we
+ * ever abandon the "stop-the-world" model, here's the command
+ * to use:
+ *
+ * call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL );
+ *
+ * Note that this would depend on being called _after_ "add_tthread"
+ * below for the tid-to-pid translation to be done in "call_ttrace".
+ */
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "New thread: pid %d, tid %d, creator tid %d\n",
+ real_pid, tsp.tts_u.tts_thread.tts_target_lwpid,
+ real_tid );
+#endif
+
+ /* Now we have to return the tid of the created thread, not
+ * the creating thread, or "wait_for_inferior" won't know we
+ * have a new "process" (thread). Plus we should record it
+ * right, too.
+ */
+ real_tid = tsp.tts_u.tts_thread.tts_target_lwpid;
+
+ add_tthread( real_pid, real_tid );
+ }
+
+ else if( (tsp.tts_event & TTEVT_LWP_TERMINATE )
+ || (tsp.tts_event & TTEVT_LWP_EXIT) ) {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Thread dies: %d\n", real_tid );
+#endif
+
+ del_tthread( real_tid );
+ }
+
+ else if (tsp.tts_event & TTEVT_EXEC) {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Pid %d has zero'th thread %d; inferior pid is %d\n",
+ real_pid, real_tid, inferior_pid );
+#endif
+
+ add_tthread( real_pid, real_tid );
+ }
+
+#ifdef THREAD_DEBUG
+ else if( debug_on ) {
+ printf( "Process-level event %s, using tid %d\n",
+ get_printable_name_of_ttrace_event( tsp.tts_event ),
+ real_tid );
+
+ /* OK to do this, as "add_tthread" won't add
+ * duplicate entries. Also OK not to do it,
+ * as this event isn't one which can change the
+ * thread state.
+ */
+ add_tthread( real_pid, real_tid );
+ }
+#endif
+
+
+ /* How many events are left to report later?
+ * In a non-stop-the-world model, this isn't needed.
+ *
+ * Note that it's not always safe to query the thread state of a process,
+ * which is what count_unhandled_events does. (If unsafe, we're left with
+ * no other resort than to assume that no more events remain...)
+ */
+ if (can_touch_threads_of_process (real_pid, tsp.tts_event))
+ more_events_left = count_unhandled_events( real_pid, real_tid );
+
+ else {
+ if( more_events_left > 0 )
+ warning( "Vfork or fork causing loss of %d buffered events.",
+ more_events_left );
+
+ more_events_left = 0;
+ }
+
+ /* Attempt to translate the ttrace_wait-returned status into the
+ ptrace equivalent.
+
+ ??rehrauer: This is somewhat fragile. We really ought to rewrite
+ clients that expect to pick apart a ptrace wait status, to use
+ something a little more abstract.
+ */
+ if ( (tsp.tts_event & TTEVT_EXEC)
+ || (tsp.tts_event & TTEVT_FORK)
+ || (tsp.tts_event & TTEVT_VFORK))
+ {
+ /* Forks come in pairs (parent and child), so core gdb
+ * will do two waits. Be ready to notice this.
+ */
+ if (tsp.tts_event & TTEVT_FORK)
+ {
+ process_state = FORKING;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Process set to FORKING\n" );
+#endif
+ }
+ else if (tsp.tts_event & TTEVT_VFORK)
+ {
+ process_state = VFORKING;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Process set to VFORKING\n" );
+#endif
+ }
+
+ /* Make an exec or fork look like a breakpoint. Definitely a hack,
+ but I don't think non HP-UX-specific clients really carefully
+ inspect the first events they get after inferior startup, so
+ it probably almost doesn't matter what we claim this is.
+ */
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "..a process 'event'\n" );
+#endif
+
+ /* Also make fork and exec events look like bpts, so they can be caught.
+ */
+ *status = 0177 | (_SIGTRAP << 8);
+ }
+
+ /* Special-cases: We ask for syscall entry and exit events to implement
+ "fast" (aka "hardware") watchpoints.
+
+ When we get a syscall entry, we want to disable page-protections,
+ and resume the inferior; this isn't an event we wish for
+ wait_for_inferior to see. Note that we must resume ONLY the
+ thread that reported the syscall entry; we don't want to allow
+ other threads to run with the page protections off, as they might
+ then be able to write to watch memory without it being caught.
+
+ When we get a syscall exit, we want to reenable page-protections,
+ but we don't want to resume the inferior; this is an event we wish
+ wait_for_inferior to see. Make it look like the signal we normally
+ get for a single-step completion. This should cause wait_for_inferior
+ to evaluate whether any watchpoint triggered.
+
+ Or rather, that's what we'd LIKE to do for syscall exit; we can't,
+ due to some HP-UX "features". Some syscalls have problems with
+ write-protections on some pages, and some syscalls seem to have
+ pending writes to those pages at the time we're getting the return
+ event. So, we'll single-step the inferior to get out of the syscall,
+ and then reenable protections.
+
+ Note that we're intentionally allowing the syscall exit case to
+ fall through into the succeeding cases, as sometimes we single-
+ step out of one syscall only to immediately enter another...
+ */
+ else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY)
+ || (tsp.tts_event & TTEVT_SYSCALL_RETURN))
+ {
+ /* Make a syscall event look like a breakpoint. Same comments
+ as for exec & fork events.
+ */
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "..a syscall 'event'\n" );
+#endif
+
+ /* Also make syscall events look like bpts, so they can be caught.
+ */
+ *status = 0177 | (_SIGTRAP << 8);
+ }
+
+ else if ((tsp.tts_event & TTEVT_LWP_CREATE)
+ || (tsp.tts_event & TTEVT_LWP_TERMINATE)
+ || (tsp.tts_event & TTEVT_LWP_EXIT))
+ {
+ /* Make a thread event look like a breakpoint. Same comments
+ * as for exec & fork events.
+ */
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "..a thread 'event'\n" );
+#endif
+
+ /* Also make thread events look like bpts, so they can be caught.
+ */
+ *status = 0177 | (_SIGTRAP << 8);
+ }
+
+ else if ((tsp.tts_event & TTEVT_EXIT))
+ { /* WIFEXITED */
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "..an exit\n" );
+#endif
+
+ /* Prevent rest of gdb from thinking this is
+ * a new thread if for some reason it's never
+ * seen the main thread before.
+ */
+ inferior_pid = map_to_gdb_tid( real_tid ); /* HACK, FIX */
+
+ *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode);
+ }
+
+ else if (tsp.tts_event & TTEVT_SIGNAL)
+ { /* WIFSTOPPED */
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo );
+#endif
+
+ *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8);
+ }
+
+ else
+ { /* !WIFSTOPPED */
+
+ /* This means the process or thread terminated. But we should've
+ caught an explicit exit/termination above. So warn (this is
+ really an internal error) and claim the process or thread
+ terminated with a SIGTRAP.
+ */
+
+ warning ("process_wait: unknown process state");
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Process-level event %s, using tid %d\n",
+ get_printable_name_of_ttrace_event( tsp.tts_event ),
+ real_tid );
+#endif
+
+ *status = _SIGTRAP;
+ }
+
+ target_post_wait (tsp.tts_pid, *status);
+
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Done waiting, pid is %d, tid %d\n", real_pid, real_tid );
+#endif
+
+ /* All code external to this module uses the tid, but calls
+ * it "pid". There's some tweaking so that the outside sees
+ * the first thread as having the same number as the starting
+ * pid.
+ */
+ return_pid = map_to_gdb_tid( real_tid );
+
+ /* Remember this for later use in "hppa_prepare_to_proceed".
+ */
+ old_gdb_pid = inferior_pid;
+ reported_pid = return_pid;
+ reported_bpt = ((tsp.tts_event & TTEVT_SIGNAL) && (5 == tsp.tts_u.tts_signal.tts_signo));
+
+ if( real_tid == 0 || return_pid == 0 ) {
+ warning( "Internal error: process-wait failed." );
+ }
+
+ return return_pid;
+}
+
+
+/* This function causes the caller's process to be traced by its
+ parent. This is intended to be called after GDB forks itself,
+ and before the child execs the target. Despite the name, it
+ is called by the child.
+
+ Note that HP-UX ttrace is rather funky in how this is done.
+ If the parent wants to get the initial exec event of a child,
+ it must set the ttrace event mask of the child to include execs.
+ (The child cannot do this itself.) This must be done after the
+ child is forked, but before it execs.
+
+ To coordinate the parent and child, we implement a semaphore using
+ pipes. After SETTRC'ing itself, the child tells the parent that
+ it is now traceable by the parent, and waits for the parent's
+ acknowledgement. The parent can then set the child's event mask,
+ and notify the child that it can now exec.
+
+ (The acknowledgement by parent happens as a result of a call to
+ child_acknowledge_created_inferior.)
+ */
+int
+parent_attach_all ()
+{
+ int tt_status;
+
+ /* We need a memory home for a constant, to pass it to ttrace.
+ The value of the constant is arbitrary, so long as both
+ parent and child use the same value. Might as well use the
+ "magic" constant provided by ttrace...
+ */
+ uint64_t tc_magic_child = TT_VERSION;
+ uint64_t tc_magic_parent = 0;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_SETTRC,
+ (int) TT_NIL,
+ (lwpid_t) TT_NIL,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) TT_VERSION,
+ TT_NIL );
+
+ if (tt_status < 0)
+ return tt_status;
+
+ /* Notify the parent that we're potentially ready to exec(). */
+ write (startup_semaphore.child_channel[SEM_TALK],
+ &tc_magic_child,
+ sizeof (tc_magic_child));
+
+ /* Wait for acknowledgement from the parent. */
+ read (startup_semaphore.parent_channel[SEM_LISTEN],
+ &tc_magic_parent,
+ sizeof (tc_magic_parent));
+
+ if (tc_magic_child != tc_magic_parent)
+ warning ("mismatched semaphore magic");
+
+ /* Discard our copy of the semaphore. */
+ (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.parent_channel[SEM_TALK]);
+ (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.child_channel[SEM_TALK]);
+
+ return tt_status;
+}
+
+/* Despite being file-local, this routine is dealing with
+ * actual process IDs, not thread ids. That's because it's
+ * called before the first "wait" call, and there's no map
+ * yet from tids to pids.
+ *
+ * When it is called, a forked child is running, but waiting on
+ * the semaphore. If you stop the child and re-start it,
+ * things get confused, so don't do that! An attached child is
+ * stopped.
+ *
+ * Since this is called after either attach or run, we
+ * have to be the common part of both.
+ */
+static void
+require_notification_of_events ( real_pid )
+ int real_pid;
+{
+ int tt_status;
+ ttevent_t notifiable_events;
+
+ lwpid_t tid;
+ ttstate_t thread_state;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Require notif, pid is %d\n", real_pid );
+#endif
+
+ /* Temporary HACK: tell inftarg.c/child_wait to not
+ * loop until pids are the same.
+ */
+ not_same_real_pid = 0;
+
+ sigemptyset (&notifiable_events.tte_signals);
+ notifiable_events.tte_opts = TTEO_NONE;
+
+ /* This ensures that forked children inherit their parent's
+ * event mask, which we're setting here.
+ *
+ * NOTE: if you debug gdb with itself, then the ultimate
+ * debuggee gets flags set by the outermost gdb, as
+ * a child of a child will still inherit.
+ */
+ notifiable_events.tte_opts |= TTEO_PROC_INHERIT;
+
+ notifiable_events.tte_events = TTEVT_DEFAULT;
+ notifiable_events.tte_events |= TTEVT_SIGNAL;
+ notifiable_events.tte_events |= TTEVT_EXEC;
+ notifiable_events.tte_events |= TTEVT_EXIT;
+ notifiable_events.tte_events |= TTEVT_FORK;
+ notifiable_events.tte_events |= TTEVT_VFORK;
+ notifiable_events.tte_events |= TTEVT_LWP_CREATE;
+ notifiable_events.tte_events |= TTEVT_LWP_EXIT;
+ notifiable_events.tte_events |= TTEVT_LWP_TERMINATE;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_SET_EVENT_MASK,
+ real_pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) &notifiable_events,
+ (TTRACE_ARG_TYPE) sizeof (notifiable_events),
+ TT_NIL);
+}
+
+static void
+require_notification_of_exec_events ( real_pid )
+ int real_pid;
+{
+ int tt_status;
+ ttevent_t notifiable_events;
+
+ lwpid_t tid;
+ ttstate_t thread_state;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Require notif, pid is %d\n", real_pid );
+#endif
+
+ /* Temporary HACK: tell inftarg.c/child_wait to not
+ * loop until pids are the same.
+ */
+ not_same_real_pid = 0;
+
+ sigemptyset (&notifiable_events.tte_signals);
+ notifiable_events.tte_opts = TTEO_NOSTRCCHLD;
+
+ /* This ensures that forked children don't inherit their parent's
+ * event mask, which we're setting here.
+ */
+ notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT;
+
+ notifiable_events.tte_events = TTEVT_DEFAULT;
+ notifiable_events.tte_events |= TTEVT_EXEC;
+ notifiable_events.tte_events |= TTEVT_EXIT;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_SET_EVENT_MASK,
+ real_pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) &notifiable_events,
+ (TTRACE_ARG_TYPE) sizeof (notifiable_events),
+ TT_NIL);
+}
+
+
+/* This function is called by the parent process, with pid being the
+ * ID of the child process, after the debugger has forked.
+ */
+void
+child_acknowledge_created_inferior (pid)
+ int pid;
+{
+ /* We need a memory home for a constant, to pass it to ttrace.
+ The value of the constant is arbitrary, so long as both
+ parent and child use the same value. Might as well use the
+ "magic" constant provided by ttrace...
+ */
+ uint64_t tc_magic_parent = TT_VERSION;
+ uint64_t tc_magic_child = 0;
+
+ /* Wait for the child to tell us that it has forked. */
+ read (startup_semaphore.child_channel[SEM_LISTEN],
+ &tc_magic_child,
+ sizeof(tc_magic_child));
+
+ /* Clear thread info now. We'd like to do this in
+ * "require...", but that messes up attach.
+ */
+ clear_thread_info();
+
+ /* Tell the "rest of gdb" that the initial thread exists.
+ * This isn't really a hack. Other thread-based versions
+ * of gdb (e.g. gnu-nat.c) seem to do the same thing.
+ *
+ * Q: Why don't we also add this thread to the local
+ * list via "add_tthread"?
+ *
+ * A: Because we don't know the tid, and can't stop the
+ * the process safely to ask what it is. Anyway, we'll
+ * add it when it gets the EXEC event.
+ */
+ add_thread( pid ); /* in thread.c */
+
+ /* We can now set the child's ttrace event mask.
+ */
+ require_notification_of_exec_events (pid);
+
+ /* Tell ourselves that the process is running.
+ */
+ process_state = RUNNING;
+
+ /* Notify the child that it can exec. */
+ write (startup_semaphore.parent_channel[SEM_TALK],
+ &tc_magic_parent,
+ sizeof (tc_magic_parent));
+
+ /* Discard our copy of the semaphore. */
+ (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.parent_channel[SEM_TALK]);
+ (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.child_channel[SEM_TALK]);
+}
+
+
+/*
+ * arrange for notification of all events by
+ * calling require_notification_of_events.
+ */
+void
+child_post_startup_inferior ( real_pid)
+ int real_pid;
+{
+ require_notification_of_events (real_pid);
+}
+
+/* From here on, we should expect tids rather than pids.
+ */
+static void
+hppa_enable_catch_fork (tid)
+ int tid;
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL );
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Add forks to that set. */
+ ttrace_events.tte_events |= TTEVT_FORK;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "enable fork, tid is %d\n", tid );
+#endif
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+static void
+hppa_disable_catch_fork (tid)
+ int tid;
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Remove forks from that set. */
+ ttrace_events.tte_events &= ~TTEVT_FORK;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf("disable fork, tid is %d\n", tid );
+#endif
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+#if defined(CHILD_INSERT_FORK_CATCHPOINT)
+int
+child_insert_fork_catchpoint (tid)
+ int tid;
+{
+ /* Enable reporting of fork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_REMOVE_FORK_CATCHPOINT)
+int
+child_remove_fork_catchpoint (tid)
+ int tid;
+{
+ /* Disable reporting of fork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+static void
+hppa_enable_catch_vfork (tid)
+ int tid;
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Add vforks to that set. */
+ ttrace_events.tte_events |= TTEVT_VFORK;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf("enable vfork, tid is %d\n", tid );
+#endif
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+static void
+hppa_disable_catch_vfork (tid)
+ int tid;
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled. */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Remove vforks from that set. */
+ ttrace_events.tte_events &= ~TTEVT_VFORK;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf("disable vfork, tid is %d\n", tid );
+#endif
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
+int
+child_insert_vfork_catchpoint (tid)
+ int tid;
+{
+ /* Enable reporting of vfork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_REMOVE_VFORK_CATCHPOINT)
+int
+child_remove_vfork_catchpoint (tid)
+ int tid;
+{
+ /* Disable reporting of vfork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+#if defined(CHILD_HAS_FORKED)
+
+/* Q: Do we need to map the returned process ID to a thread ID?
+ *
+ * A: I don't think so--here we want a _real_ pid. Any later
+ * operations will call "require_notification_of_events" and
+ * start the mapping.
+ */
+int
+child_has_forked (tid, childpid)
+ int tid;
+ int *childpid;
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info * tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (tid));
+ if (tinfo != NULL) {
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+ }
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ if (ttrace_state.tts_event & TTEVT_FORK)
+ {
+ *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_HAS_VFORKED)
+
+/* See child_has_forked for pid discussion.
+ */
+int
+child_has_vforked (tid, childpid)
+ int tid;
+ int * childpid;
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info * tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (tid));
+ if (tinfo != NULL)
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ if (ttrace_state.tts_event & TTEVT_VFORK)
+ {
+ *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
+int
+child_can_follow_vfork_prior_to_exec ()
+{
+ /* ttrace does allow this.
+
+ ??rehrauer: However, I had major-league problems trying to
+ convince wait_for_inferior to handle that case. Perhaps when
+ it is rewritten to grok multiple processes in an explicit way...
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+int
+child_insert_exec_catchpoint (tid)
+ int tid;
+{
+ /* Enable reporting of exec events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_REMOVE_EXEC_CATCHPOINT)
+int
+child_remove_exec_catchpoint (tid)
+ int tid;
+{
+ /* Disable reporting of execevents from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_HAS_EXECD)
+int
+child_has_execd (tid, execd_pathname)
+ int tid;
+ char ** execd_pathname;
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info * tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (tid));
+ if (tinfo != NULL)
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ tid,
+ (TTRACE_ARG_TYPE) &ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ if (ttrace_state.tts_event & TTEVT_EXEC)
+ {
+ /* See child_pid_to_exec_file in this file: this is a macro.
+ */
+ char * exec_file = target_pid_to_exec_file (tid);
+
+ *execd_pathname = savestring (exec_file, strlen (exec_file));
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_HAS_SYSCALL_EVENT)
+int
+child_has_syscall_event (pid, kind, syscall_id)
+ int pid;
+ enum target_waitkind * kind;
+ int * syscall_id;
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info * tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (pid));
+ if (tinfo != NULL)
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ pid,
+ (TTRACE_ARG_TYPE) &ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ *kind = TARGET_WAITKIND_SPURIOUS; /* Until proven otherwise... */
+ *syscall_id = -1;
+
+ if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY)
+ *kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+ else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN)
+ *kind = TARGET_WAITKIND_SYSCALL_RETURN;
+ else
+ return 0;
+
+ *syscall_id = ttrace_state.tts_scno;
+ return 1;
+}
+#endif
+
+
+
+#if defined(CHILD_THREAD_ALIVE)
+
+/* Check to see if the given thread is alive.
+ *
+ * We'll trust the thread list, as the more correct
+ * approach of stopping the process and spinning down
+ * the OS's thread list is _very_ expensive.
+ *
+ * May need a FIXME for that reason.
+ */
+int
+child_thread_alive (gdb_tid)
+ lwpid_t gdb_tid;
+{
+ lwpid_t tid;
+
+ /* This spins down the lists twice.
+ * Possible peformance improvement here!
+ */
+ tid = map_from_gdb_tid( gdb_tid );
+ return !is_terminated( tid );
+}
+
+#endif
+
+
+
+/* This function attempts to read the specified number of bytes from the
+ save_state_t that is our view into the hardware registers, starting at
+ ss_offset, and ending at ss_offset + sizeof_buf - 1
+
+ If this function succeeds, it deposits the fetched bytes into buf,
+ and returns 0.
+
+ If it fails, it returns a negative result. The contents of buf are
+ undefined it this function fails.
+ */
+int
+read_from_register_save_state (tid, ss_offset, buf, sizeof_buf)
+ int tid;
+ TTRACE_ARG_TYPE ss_offset;
+ char * buf;
+ int sizeof_buf;
+{
+ int tt_status;
+ register_value_t register_value = 0;
+
+ tt_status = call_ttrace (TT_LWP_RUREGS,
+ tid,
+ ss_offset,
+ (TTRACE_ARG_TYPE) sizeof_buf,
+ (TTRACE_ARG_TYPE) buf);
+
+ if( tt_status == 1 )
+ /* Map ttrace's version of success to our version.
+ * Sometime ttrace returns 0, but that's ok here.
+ */
+ return 0;
+
+ return tt_status;
+}
+
+
+/* This function attempts to write the specified number of bytes to the
+ save_state_t that is our view into the hardware registers, starting at
+ ss_offset, and ending at ss_offset + sizeof_buf - 1
+
+ If this function succeeds, it deposits the bytes in buf, and returns 0.
+
+ If it fails, it returns a negative result. The contents of the save_state_t
+ are undefined it this function fails.
+ */
+int
+write_to_register_save_state (tid, ss_offset, buf, sizeof_buf)
+ int tid;
+ TTRACE_ARG_TYPE ss_offset;
+ char * buf;
+ int sizeof_buf;
+{
+ int tt_status;
+ register_value_t register_value = 0;
+
+ tt_status = call_ttrace (TT_LWP_WUREGS,
+ tid,
+ ss_offset,
+ (TTRACE_ARG_TYPE) sizeof_buf,
+ (TTRACE_ARG_TYPE) buf);
+ return tt_status;
+}
+
+
+/* This function is a sop to the largeish number of direct calls
+ to call_ptrace that exist in other files. Rather than create
+ functions whose name abstracts away from ptrace, and change all
+ the present callers of call_ptrace, we'll do the expedient (and
+ perhaps only practical) thing.
+
+ Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced
+ process. Thus, we must translate all ptrace requests into their
+ process-specific, ttrace equivalents.
+ */
+int
+call_ptrace (pt_request, gdb_tid, addr, data)
+ int pt_request;
+ int gdb_tid;
+ PTRACE_ARG3_TYPE addr;
+ int data;
+{
+ ttreq_t tt_request;
+ TTRACE_ARG_TYPE tt_addr = (TTRACE_ARG_TYPE) addr;
+ TTRACE_ARG_TYPE tt_data = (TTRACE_ARG_TYPE) data;
+ TTRACE_ARG_TYPE tt_addr2 = TT_NIL;
+ int tt_status;
+ register_value_t register_value;
+ int read_buf;
+
+ /* Perform the necessary argument translation. Note that some
+ cases are funky enough in the ttrace realm that we handle them
+ very specially.
+ */
+ switch (pt_request) {
+ /* The following cases cannot conveniently be handled conveniently
+ by merely adjusting the ptrace arguments and feeding into the
+ generic call to ttrace at the bottom of this function.
+
+ Note that because all branches of this switch end in "return",
+ there's no need for any "break" statements.
+ */
+ case PT_SETTRC :
+ return parent_attach_all ();
+
+ case PT_RUREGS :
+ tt_status = read_from_register_save_state (gdb_tid,
+ tt_addr,
+ &register_value,
+ sizeof (register_value));
+ if (tt_status < 0)
+ return tt_status;
+ return register_value;
+
+ case PT_WUREGS :
+ register_value = (int) tt_data;
+ tt_status = write_to_register_save_state (gdb_tid,
+ tt_addr,
+ &register_value,
+ sizeof (register_value));
+ return tt_status;
+ break;
+
+ case PT_READ_I :
+ tt_status = call_ttrace (TT_PROC_RDTEXT, /* Implicit 4-byte xfer becomes block-xfer. */
+ gdb_tid,
+ tt_addr,
+ (TTRACE_ARG_TYPE) 4,
+ (TTRACE_ARG_TYPE) &read_buf);
+ if (tt_status < 0)
+ return tt_status;
+ return read_buf;
+
+ case PT_READ_D :
+ tt_status = call_ttrace (TT_PROC_RDDATA, /* Implicit 4-byte xfer becomes block-xfer. */
+ gdb_tid,
+ tt_addr,
+ (TTRACE_ARG_TYPE) 4,
+ (TTRACE_ARG_TYPE) &read_buf);
+ if (tt_status < 0)
+ return tt_status;
+ return read_buf;
+
+ case PT_ATTACH :
+ tt_status = call_real_ttrace (TT_PROC_ATTACH,
+ map_from_gdb_tid (gdb_tid),
+ (lwpid_t) TT_NIL,
+ tt_addr,
+ (TTRACE_ARG_TYPE) TT_VERSION,
+ tt_addr2);
+ if (tt_status < 0)
+ return tt_status;
+ return tt_status;
+
+ /* The following cases are handled by merely adjusting the ptrace
+ arguments and feeding into the generic call to ttrace.
+ */
+ case PT_DETACH :
+ tt_request = TT_PROC_DETACH;
+ break;
+
+ case PT_WRITE_I :
+ tt_request = TT_PROC_WRTEXT; /* Translates 4-byte xfer to block-xfer. */
+ tt_data = 4; /* This many bytes. */
+ tt_addr2 = (TTRACE_ARG_TYPE) &data; /* Address of xfer source. */
+ break;
+
+ case PT_WRITE_D :
+ tt_request = TT_PROC_WRDATA; /* Translates 4-byte xfer to block-xfer. */
+ tt_data = 4; /* This many bytes. */
+ tt_addr2 = (TTRACE_ARG_TYPE) &data; /* Address of xfer source. */
+ break;
+
+ case PT_RDTEXT :
+ tt_request = TT_PROC_RDTEXT;
+ break;
+
+ case PT_RDDATA :
+ tt_request = TT_PROC_RDDATA;
+ break;
+
+ case PT_WRTEXT :
+ tt_request = TT_PROC_WRTEXT;
+ break;
+
+ case PT_WRDATA :
+ tt_request = TT_PROC_WRDATA;
+ break;
+
+ case PT_CONTINUE :
+ tt_request = TT_PROC_CONTINUE;
+ break;
+
+ case PT_STEP :
+ tt_request = TT_LWP_SINGLE; /* Should not be making this request? */
+ break;
+
+ case PT_KILL :
+ tt_request = TT_PROC_EXIT;
+ break;
+
+ case PT_GET_PROCESS_PATHNAME :
+ tt_request = TT_PROC_GET_PATHNAME;
+ break;
+
+ default :
+ tt_request = pt_request; /* Let ttrace be the one to complain. */
+ break;
+ }
+
+ return call_ttrace (tt_request,
+ gdb_tid,
+ tt_addr,
+ tt_data,
+ tt_addr2);
+}
+
+/* Kill that pesky process!
+ */
+void
+kill_inferior ()
+{
+ int tid;
+ int wait_status;
+ thread_info * t;
+ thread_info **paranoia;
+ int para_count, i;
+
+ if (inferior_pid == 0)
+ return;
+
+ /* Walk the list of "threads", some of which are "pseudo threads",
+ aka "processes". For each that is NOT inferior_pid, stop it,
+ and detach it.
+
+ You see, we may not have just a single process to kill. If we're
+ restarting or quitting or detaching just after the inferior has
+ forked, then we've actually two processes to clean up.
+
+ But we can't just call target_mourn_inferior() for each, since that
+ zaps the target vector.
+ */
+
+ paranoia = (thread_info **) malloc( thread_head.count *
+ sizeof(thread_info *));
+ para_count = 0;
+
+ t = thread_head.head;
+ while (t) {
+
+ paranoia[ para_count ] = t;
+ for( i = 0; i < para_count; i++ ){
+ if( t->next == paranoia[i] ) {
+ warning( "Bad data in gdb's thread data; repairing." );
+ t->next = 0;
+ }
+ }
+ para_count++;
+
+ if (t->am_pseudo && (t->pid != inferior_pid))
+ {
+ /* TT_PROC_STOP doesn't require a subsequent ttrace_wait, as it
+ * generates no event.
+ */
+ call_ttrace (TT_PROC_STOP,
+ t->pid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+
+ call_ttrace (TT_PROC_DETACH,
+ t->pid,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) TARGET_SIGNAL_0,
+ TT_NIL);
+ }
+ t = t->next;
+ }
+
+ free( paranoia );
+
+ call_ttrace (TT_PROC_STOP,
+ inferior_pid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+ target_mourn_inferior ();
+ clear_thread_info();
+}
+
+
+#ifndef CHILD_RESUME
+
+/* Sanity check a thread about to be continued.
+ */
+static void
+thread_dropping_event_check( p )
+ thread_info *p;
+{
+ if( !p->handled ) {
+ /*
+ * This seems to happen when we "next" over a
+ * "fork()" while following the parent. If it's
+ * the FORK event, that's ok. If it's a SIGNAL
+ * in the unfollowed child, that's ok to--but
+ * how can we know that's what's going on?
+ *
+ * FIXME!
+ */
+ if( p->have_state ) {
+ if( p->last_stop_state.tts_event == TTEVT_FORK ) {
+ /* Ok */
+ ;
+ }
+ else if( p->last_stop_state.tts_event == TTEVT_SIGNAL ) {
+ /* Ok, close eyes and let it happen.
+ */
+ ;
+ }
+ else {
+ /* This shouldn't happen--we're dropping a
+ * real event.
+ */
+ warning( "About to continue process %d, thread %d with unhandled event %s.",
+ p->pid, p->tid,
+ get_printable_name_of_ttrace_event(
+ p->last_stop_state.tts_event ));
+
+#ifdef PARANOIA
+ if( debug_on )
+ print_tthread( p );
+#endif
+ }
+ }
+ else {
+ /* No saved state, have to assume it failed.
+ */
+ warning( "About to continue process %d, thread %d with unhandled event.",
+ p->pid, p->tid );
+#ifdef PARANOIA
+ if( debug_on )
+ print_tthread( p );
+#endif
+ }
+ }
+
+} /* thread_dropping_event_check */
+
+/* Use a loop over the threads to continue all the threads but
+ * the one specified, which is to be stepped.
+ */
+static void
+threads_continue_all_but_one( gdb_tid, signal )
+ lwpid_t gdb_tid;
+ int signal;
+{
+ thread_info *p;
+ int thread_signal;
+ lwpid_t real_tid;
+ lwpid_t scan_tid;
+ ttstate_t state;
+ int real_pid;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Using loop over threads to step/resume with signals\n" );
+#endif
+
+ /* First update the thread list.
+ */
+ set_all_unseen();
+ real_tid = map_from_gdb_tid( gdb_tid );
+ real_pid = get_pid_for( real_tid );
+
+ scan_tid = get_process_first_stopped_thread_id( real_pid, &state );
+ while ( 0 != scan_tid ) {
+
+#ifdef THREAD_DEBUG
+ /* FIX: later should check state is stopped;
+ * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED
+ */
+ if( debug_on )
+ if( state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED )
+ printf( "About to continue non-stopped thread %d\n", scan_tid );
+#endif
+
+ p = find_thread_info( scan_tid );
+ if( NULL == p ) {
+ add_tthread( real_pid, scan_tid );
+ p = find_thread_info( scan_tid );
+
+ /* This is either a newly-created thread or the
+ * result of a fork; in either case there's no
+ * actual event to worry about.
+ */
+ p->handled = 1;
+
+ if( state.tts_event != TTEVT_NONE ) {
+ /* Oops, do need to worry!
+ */
+ warning( "Unexpected thread with \"%s\" event.",
+ get_printable_name_of_ttrace_event( state.tts_event ));
+ }
+ }
+ else if( scan_tid != p->tid )
+ error( "Bad data in thread database." );
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ if( p->terminated )
+ printf( "Why are we continuing a dead thread?\n" );
+#endif
+
+ p->seen = 1;
+
+ scan_tid = get_process_next_stopped_thread_id( real_pid, &state );
+ }
+
+ /* Remove unseen threads.
+ */
+ update_thread_list();
+
+ /* Now run down the thread list and continue or step.
+ */
+ for( p = thread_head.head; p; p = p->next ) {
+
+ /* Sanity check.
+ */
+ thread_dropping_event_check( p );
+
+ /* Pass the correct signals along.
+ */
+ if( p->have_signal ) {
+ thread_signal = p->signal_value;
+ p->have_signal = 0;
+ }
+ else
+ thread_signal = 0;
+
+ if( p->tid != real_tid ) {
+ /*
+ * Not the thread of interest, so continue it
+ * as the user expects.
+ */
+ if( p->stepping_mode == DO_STEP ) {
+ /* Just step this thread.
+ */
+ call_ttrace(
+ TT_LWP_SINGLE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
+ TT_NIL );
+ }
+ else {
+ /* Regular continue (default case).
+ */
+ call_ttrace(
+ TT_LWP_CONTINUE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host( thread_signal ),
+ TT_NIL );
+ }
+ }
+ else {
+ /* Step the thread of interest.
+ */
+ call_ttrace(
+ TT_LWP_SINGLE,
+ real_tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
+ TT_NIL );
+ }
+ } /* Loop over threads */
+} /* End threads_continue_all_but_one */
+
+/* Use a loop over the threads to continue all the threads.
+ * This is done when a signal must be sent to any of the threads.
+ */
+static void
+threads_continue_all_with_signals( gdb_tid, signal )
+ lwpid_t gdb_tid;
+ int signal;
+{
+ thread_info *p;
+ int thread_signal;
+ lwpid_t real_tid;
+ lwpid_t scan_tid;
+ ttstate_t state;
+ int real_pid;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Using loop over threads to resume with signals\n" );
+#endif
+
+ /* Scan and update thread list.
+ */
+ set_all_unseen();
+ real_tid = map_from_gdb_tid( gdb_tid );
+ real_pid = get_pid_for( real_tid );
+
+ scan_tid = get_process_first_stopped_thread_id( real_pid, &state );
+ while ( 0 != scan_tid ) {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ if( state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED )
+ warning( "About to continue non-stopped thread %d\n", scan_tid );
+#endif
+
+ p = find_thread_info( scan_tid );
+ if( NULL == p ) {
+ add_tthread( real_pid, scan_tid );
+ p = find_thread_info( scan_tid );
+
+ /* This is either a newly-created thread or the
+ * result of a fork; in either case there's no
+ * actual event to worry about.
+ */
+ p->handled = 1;
+
+ if( state.tts_event != TTEVT_NONE ) {
+ /* Oops, do need to worry!
+ */
+ warning( "Unexpected thread with \"%s\" event.",
+ get_printable_name_of_ttrace_event( state.tts_event ));
+ }
+ }
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ if( p->terminated )
+ printf( "Why are we continuing a dead thread? (1)\n" );
+#endif
+
+ p->seen = 1;
+
+ scan_tid = get_process_next_stopped_thread_id( real_pid, &state );
+ }
+
+ /* Remove unseen threads from our list.
+ */
+ update_thread_list();
+
+ /* Continue the threads.
+ */
+ for( p = thread_head.head; p; p = p->next ) {
+
+ /* Sanity check.
+ */
+ thread_dropping_event_check( p );
+
+ /* Pass the correct signals along.
+ */
+ if( p->tid == real_tid ) {
+ thread_signal = signal;
+ p->have_signal = 0;
+ }
+ else if( p->have_signal ) {
+ thread_signal = p->signal_value;
+ p->have_signal = 0;
+ }
+ else
+ thread_signal = 0;
+
+ if( p->stepping_mode == DO_STEP ) {
+ call_ttrace(
+ TT_LWP_SINGLE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
+ TT_NIL );
+ }
+ else {
+ /* Continue this thread (default case).
+ */
+ call_ttrace(
+ TT_LWP_CONTINUE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host( thread_signal ),
+ TT_NIL );
+ }
+ }
+} /* End threads_continue_all_with_signals */
+
+/* Step one thread only.
+ */
+static void
+thread_fake_step( tid, signal )
+ lwpid_t tid;
+ enum target_signal signal;
+{
+ thread_info *p;
+
+#ifdef THREAD_DEBUG
+ if( debug_on ) {
+ printf( "Doing a fake-step over a bpt, etc. for %d\n", tid );
+
+ if( is_terminated( tid ))
+ printf( "Why are we continuing a dead thread? (4)\n" );
+ }
+#endif
+
+ if( doing_fake_step )
+ warning( "Step while step already in progress." );
+
+ /* See if there's a saved signal value for this
+ * thread to be passed on, but no current signal.
+ */
+ p = find_thread_info( tid );
+ if( p != NULL ) {
+ if( p->have_signal && signal == NULL ) {
+ /* Pass on a saved signal.
+ */
+ signal = p->signal_value;
+ }
+
+ p->have_signal = 0;
+ }
+
+ if( !p->handled )
+ warning( "Internal error: continuing unhandled thread." );
+
+ call_ttrace( TT_LWP_SINGLE,
+ tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (signal),
+ TT_NIL );
+
+ /* Do bookkeeping so "call_ttrace_wait" knows it has to wait
+ * for this thread only, and clear any saved signal info.
+ */
+ doing_fake_step = 1;
+ fake_step_tid = tid;
+
+} /* End thread_fake_step */
+
+/* Continue one thread when a signal must be sent to it.
+ */
+static void
+threads_continue_one_with_signal( gdb_tid, signal )
+ lwpid_t gdb_tid;
+ int signal;
+{
+ thread_info *p;
+ lwpid_t real_tid;
+ int real_pid;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Continuing one thread with a signal\n" );
+#endif
+
+ real_tid = map_from_gdb_tid( gdb_tid );
+ real_pid = get_pid_for( real_tid );
+
+ p = find_thread_info( real_tid );
+ if( NULL == p ) {
+ add_tthread( real_pid, real_tid );
+ }
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ if( p->terminated )
+ printf( "Why are we continuing a dead thread? (2)\n" );
+#endif
+
+ if( !p->handled )
+ warning( "Internal error: continuing unhandled thread." );
+
+ p->have_signal = 0;
+
+ call_ttrace( TT_LWP_CONTINUE,
+ gdb_tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
+ TT_NIL );
+}
+#endif
+
+#ifndef CHILD_RESUME
+
+/* Resume execution of the inferior process.
+ *
+ * This routine is in charge of setting the "handled" bits.
+ *
+ * If STEP is zero, continue it.
+ * If STEP is nonzero, single-step it.
+ *
+ * If SIGNAL is nonzero, give it that signal.
+ *
+ * If TID is -1, apply to all threads.
+ * If TID is not -1, apply to specified thread.
+ *
+ * STEP
+ * \ !0 0
+ * TID \________________________________________________
+ * |
+ * -1 | Step current Continue all threads
+ * | thread and (but which gets any
+ * | continue others signal?--We look at
+ * | "inferior_pid")
+ * |
+ * N | Step _this_ thread Continue _this_ thread
+ * | and leave others and leave others
+ * | stopped; internally stopped; used only for
+ * | used by gdb, never hardware watchpoints
+ * | a user command. and attach, never a
+ * | user command.
+ */
+void
+child_resume( gdb_tid, step, signal )
+ lwpid_t gdb_tid;
+ int step;
+ enum target_signal signal;
+{
+ int resume_all_threads;
+ lwpid_t tid;
+ process_state_t new_process_state;
+
+ resume_all_threads =
+ (gdb_tid == INFTTRACE_ALL_THREADS) ||
+ (vfork_in_flight);
+
+ if (resume_all_threads) {
+ /* Resume all threads, but first pick a tid value
+ * so we can get the pid when in call_ttrace doing
+ * the map.
+ */
+ if (vfork_in_flight)
+ tid = vforking_child_pid;
+ else
+ tid = map_from_gdb_tid( inferior_pid );
+ }
+ else
+ tid = map_from_gdb_tid( gdb_tid );
+
+#ifdef THREAD_DEBUG
+ if( debug_on ) {
+ if( more_events_left )
+ printf( "More events; " );
+
+ if( signal != 0 )
+ printf( "Sending signal %d; ", signal );
+
+ if( resume_all_threads ) {
+ if( step == 0 )
+ printf( "Continue process %d\n", tid );
+ else
+ printf( "Step/continue thread %d\n", tid );
+ }
+ else {
+ if( step == 0 )
+ printf( "Continue thread %d\n", tid );
+ else
+ printf( "Step just thread %d\n", tid );
+ }
+
+ if( vfork_in_flight )
+ printf( "Vfork in flight\n" );
+ }
+#endif
+
+ if( process_state == RUNNING )
+ warning( "Internal error in resume logic; doing resume or step anyway." );
+
+ if( !step /* Asked to continue... */
+ && resume_all_threads /* whole process.. */
+ && signal != 0 /* with a signal... */
+ && more_events_left > 0 ) { /* but we can't yet--save it! */
+
+ /* Continue with signal means we have to set the pending
+ * signal value for this thread.
+ */
+ thread_info *k;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Saving signal %d for thread %d\n", signal, tid );
+#endif
+
+ k = find_thread_info( tid );
+ if( k != NULL ) {
+ k->have_signal = 1;
+ k->signal_value = signal;
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ if( k->terminated )
+ printf( "Why are we continuing a dead thread? (3)\n" );
+#endif
+
+ }
+
+#ifdef THREAD_DEBUG
+ else if( debug_on ) {
+ printf( "No thread info for tid %d\n", tid );
+ }
+#endif
+ }
+
+ /* Are we faking this "continue" or "step"?
+ *
+ * We used to do steps by continuing all the threads for
+ * which the events had been handled already. While
+ * conceptually nicer (hides it all in a lower level), this
+ * can lead to starvation and a hang (e.g. all but one thread
+ * are unhandled at a breakpoint just before a "join" operation,
+ * and one thread is in the join, and the user wants to step that
+ * thread).
+ */
+ if( resume_all_threads /* Whole process, therefore user command */
+ && more_events_left > 0 ) { /* But we can't do this yet--fake it! */
+ thread_info *p;
+
+ if( !step ) {
+ /* No need to do any notes on a per-thread
+ * basis--we're done!
+ */
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Faking a process resume.\n" );
+#endif
+
+ return;
+ }
+ else {
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Faking a process step.\n" );
+#endif
+
+ }
+
+ p = find_thread_info( tid );
+ if( p == NULL ) {
+ warning( "No thread information for tid %d, 'next' command ignored.\n", tid );
+ return;
+ }
+ else {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ if( p->terminated )
+ printf( "Why are we continuing a dead thread? (3.5)\n" );
+#endif
+
+ if( p->stepping_mode != DO_DEFAULT ) {
+ warning( "Step or continue command applied to thread which is already stepping or continuing; command ignored." );
+
+ return;
+ }
+
+ if( step )
+ p->stepping_mode = DO_STEP;
+ else
+ p->stepping_mode = DO_CONTINUE;
+
+ return;
+ } /* Have thread info */
+ } /* Must fake step or go */
+
+ /* Execept for fake-steps, from here on we know we are
+ * going to wind up with a running process which will
+ * need a real wait.
+ */
+ new_process_state = RUNNING;
+
+ /* An address of TT_USE_CURRENT_PC tells ttrace to continue from where
+ * it was. (If GDB wanted it to start some other way, we have already
+ * written a new PC value to the child.)
+ *
+ * If this system does not support PT_STEP, a higher level function will
+ * have called single_step() to transmute the step request into a
+ * continue request (by setting breakpoints on all possible successor
+ * instructions), so we don't have to worry about that here.
+ */
+ if (step) {
+ if( resume_all_threads ) {
+ /*
+ * Regular user step: other threads get a "continue".
+ */
+ threads_continue_all_but_one( tid, signal );
+ clear_all_handled();
+ clear_all_stepping_mode();
+ }
+
+ else {
+ /* "Fake step": gdb is stepping one thread over a
+ * breakpoint, watchpoint, or out of a library load
+ * event, etc. The rest just stay where they are.
+ *
+ * Also used when there are pending events: we really
+ * step the current thread, but leave the rest stopped.
+ * Users can't request this, but "wait_for_inferior"
+ * does--a lot!
+ */
+ thread_fake_step( tid, signal );
+
+ /* Clear the "handled" state of this thread, because
+ * we'll soon get a new event for it. Other events
+ * stay as they were.
+ */
+ clear_handled( tid );
+ clear_stepping_mode( tid );
+ new_process_state = FAKE_STEPPING;
+ }
+ }
+
+ else {
+ /* TT_LWP_CONTINUE can pass signals to threads,
+ * TT_PROC_CONTINUE can't. So if there are any
+ * signals to pass, we have to use the (slower)
+ * loop over the stopped threads.
+ *
+ * Equally, if we have to not continue some threads,
+ * due to saved events, we have to use the loop.
+ */
+ if( (signal != 0) || saved_signals_exist()) {
+ if( resume_all_threads ) {
+
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Doing a continue by loop of all threads\n" );
+#endif
+
+ threads_continue_all_with_signals( tid, signal );
+
+ clear_all_handled();
+ clear_all_stepping_mode();
+ }
+
+ else {
+#ifdef THREAD_DEBUG
+ printf( "Doing a continue w/signal of just thread %d\n", tid );
+#endif
+
+ threads_continue_one_with_signal( tid, signal );
+
+ /* Clear the "handled" state of this thread, because
+ * we'll soon get a new event for it. Other events
+ * can stay as they were.
+ */
+ clear_handled( tid );
+ clear_stepping_mode( tid );
+ }
+ }
+
+ else {
+ /* No signals to send.
+ */
+ if( resume_all_threads ) {
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Doing a continue by process of process %d\n", tid );
+#endif
+
+ if( more_events_left > 0 ) {
+ warning( "Losing buffered events on continue." );
+ more_events_left = 0;
+ }
+
+ call_ttrace( TT_PROC_CONTINUE,
+ tid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL );
+
+ clear_all_handled();
+ clear_all_stepping_mode();
+ }
+
+ else {
+#ifdef THREAD_DEBUG
+ if( debug_on ) {
+ printf( "Doing a continue of just thread %d\n", tid );
+ if( is_terminated( tid ))
+ printf( "Why are we continuing a dead thread? (5)\n" );
+ }
+#endif
+
+ call_ttrace( TT_LWP_CONTINUE,
+ tid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL );
+
+ /* Clear the "handled" state of this thread, because
+ * we'll soon get a new event for it. Other events
+ * can stay as they were.
+ */
+ clear_handled( tid );
+ clear_stepping_mode( tid );
+ }
+ }
+ }
+
+ process_state = new_process_state;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if( debug_on )
+ printf( "Process set to %s\n",
+ get_printable_name_of_process_state (process_state) );
+#endif
+
+}
+#endif /* CHILD_RESUME */
+
+
+#ifdef ATTACH_DETACH
+/*
+ * Like it says.
+ *
+ * One worry is that we may not be attaching to "inferior_pid"
+ * and thus may not want to clear out our data. FIXME?
+ *
+ */
+static void
+update_thread_state_after_attach( pid, kind_of_go )
+ int pid;
+ attach_continue_t kind_of_go;
+{
+ int tt_status;
+ ttstate_t thread_state;
+ lwpid_t a_thread;
+ lwpid_t tid;
+
+ /* The process better be stopped.
+ */
+ if( process_state != STOPPED
+ && process_state != VFORKING )
+ warning( "Internal error attaching." );
+
+ /* Clear out old tthread info and start over. This has the
+ * side effect of ensuring that the TRAP is reported as being
+ * in the right thread (re-mapped from tid to pid).
+ *
+ * It's because we need to add the tthread _now_ that we
+ * need to call "clear_thread_info" _now_, and that's why
+ * "require_notification_of_events" doesn't clear the thread
+ * info (it's called later than this routine).
+ */
+ clear_thread_info();
+ a_thread = 0;
+
+ for (tid = get_process_first_stopped_thread_id (pid, &thread_state);
+ tid != 0;
+ tid = get_process_next_stopped_thread_id (pid, &thread_state))
+ {
+ thread_info *p;
+
+ if (a_thread == 0)
+ {
+ a_thread = tid;
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "Attaching to process %d, thread %d\n",
+ pid, a_thread );
+#endif
+ }
+
+ /* Tell ourselves and the "rest of gdb" that this thread
+ * exists.
+ *
+ * This isn't really a hack. Other thread-based versions
+ * of gdb (e.g. gnu-nat.c) seem to do the same thing.
+ *
+ * We don't need to do mapping here, as we know this
+ * is the first thread and thus gets the real pid
+ * (and is "inferior_pid").
+ *
+ * NOTE: it probably isn't the originating thread,
+ * but that doesn't matter (we hope!).
+ */
+ add_tthread( pid, tid );
+ p = find_thread_info( tid );
+ if( NULL == p ) /* ?We just added it! */
+ error( "Internal error adding a thread on attach." );
+
+ copy_ttstate_t( &p->last_stop_state, thread_state );
+ p->have_state = 1;
+
+ if( DO_ATTACH_CONTINUE == kind_of_go ) {
+ /*
+ * If we are going to CONTINUE afterwards,
+ * raising a SIGTRAP, don't bother trying to
+ * handle this event. But check first!
+ */
+ switch( p->last_stop_state.tts_event ) {
+
+ case TTEVT_NONE:
+ /* Ok to set this handled.
+ */
+ break;
+
+ default:
+ warning( "Internal error; skipping event %s on process %d, thread %d.",
+ get_printable_name_of_ttrace_event(
+ p->last_stop_state.tts_event ),
+ p->pid, p->tid);
+ }
+
+ set_handled( pid, tid );
+
+ }
+ else {
+ /* There will be no "continue" opertion, so the
+ * process remains stopped. Don't set any events
+ * handled except the "gimmies".
+ */
+ switch( p->last_stop_state.tts_event ) {
+
+ case TTEVT_NONE:
+ /* Ok to ignore this.
+ */
+ set_handled( pid, tid );
+ break;
+
+ case TTEVT_EXEC:
+ case TTEVT_FORK:
+ /* Expected "other" FORK or EXEC event from a
+ * fork or vfork.
+ */
+ break;
+
+ default:
+ printf( "Internal error: failed to handle event %s on process %d, thread %d.",
+ get_printable_name_of_ttrace_event(
+ p->last_stop_state.tts_event ),
+ p->pid, p->tid);
+ }
+ }
+
+ add_thread( tid ); /* in thread.c */
+ }
+
+#ifdef PARANOIA
+ if( debug_on )
+ print_tthreads();
+#endif
+
+ /* One mustn't call ttrace_wait() after attaching via ttrace,
+ 'cause the process is stopped already.
+
+ However, the upper layers of gdb's execution control will
+ want to wait after attaching (but not after forks, in
+ which case they will be doing a "target_resume", anticipating
+ a later TTEVT_EXEC or TTEVT_FORK event).
+
+ To make this attach() implementation more compatible with
+ others, we'll make the attached-to process raise a SIGTRAP.
+
+ Issue: this continues only one thread. That could be
+ dangerous if the thread is blocked--the process won't run
+ and no trap will be raised. FIX! (check state.tts_flags?
+ need one that's either TTS_WASRUNNING--but we've stopped
+ it and made it TTS_WASSUSPENDED. Hum...FIXME!)
+ */
+ if( DO_ATTACH_CONTINUE == kind_of_go ) {
+ tt_status = call_real_ttrace(
+ TT_LWP_CONTINUE,
+ pid,
+ a_thread,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ clear_handled( a_thread ); /* So TRAP will be reported. */
+
+ /* Now running.
+ */
+ process_state = RUNNING;
+ }
+
+ attach_flag = 1;
+}
+#endif /* ATTACH_DETACH */
+
+
+#ifdef ATTACH_DETACH
+/* Start debugging the process whose number is PID.
+ * (A _real_ pid).
+ */
+int
+attach( pid )
+ int pid;
+{
+ int tt_status;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_ATTACH,
+ pid,
+ (lwpid_t) TT_NIL,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) TT_VERSION,
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace attach");
+
+ /* If successful, the process is now stopped.
+ */
+ process_state = STOPPED;
+
+ /* Our caller ("attach_command" in "infcmd.c")
+ * expects to do a "wait_for_inferior" after
+ * the attach, so make sure the inferior is
+ * running when we're done.
+ */
+ update_thread_state_after_attach( pid, DO_ATTACH_CONTINUE );
+
+ return pid;
+}
+
+
+#if defined(CHILD_POST_ATTACH)
+void
+child_post_attach (pid)
+ int pid;
+{
+#ifdef THREAD_DEBUG
+ if( debug_on )
+ printf( "child-post-attach call\n" );
+#endif
+
+ require_notification_of_events (pid);
+}
+#endif
+
+
+/* Stop debugging the process whose number is PID
+ and continue it with signal number SIGNAL.
+ SIGNAL = 0 means just continue it.
+ */
+void
+detach( signal )
+ int signal;
+{
+ errno = 0;
+ call_ttrace (TT_PROC_DETACH,
+ inferior_pid,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) signal,
+ TT_NIL);
+ attach_flag = 0;
+
+ clear_thread_info();
+
+ /* Process-state? */
+}
+#endif /* ATTACH_DETACH */
+
+
+/* Default the type of the ttrace transfer to int. */
+#ifndef TTRACE_XFER_TYPE
+#define TTRACE_XFER_TYPE int
+#endif
+
+void
+_initialize_kernel_u_addr ()
+{
+}
+
+#if !defined (CHILD_XFER_MEMORY)
+/* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_TTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. Copy to inferior if
+ WRITE is nonzero.
+
+ Returns the length copied, which is either the LEN argument or zero.
+ This xfer function does not do partial moves, since child_ops
+ doesn't allow memory operations to cross below us in the target stack
+ anyway. */
+
+int
+child_xfer_memory (memaddr, myaddr, len, write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int write;
+ struct target_ops *target; /* ignored */
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & - sizeof (TTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
+ / sizeof (TTRACE_XFER_TYPE);
+ /* Allocate buffer of that many longwords. */
+ register TTRACE_XFER_TYPE *buffer
+ = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE)) {
+ /* Need part of initial word -- fetch it. */
+ buffer[0] = call_ttrace (TT_LWP_RDTEXT,
+ inferior_pid,
+ (TTRACE_ARG_TYPE) addr,
+ TT_NIL,
+ TT_NIL);
+ }
+
+ if (count > 1) /* FIXME, avoid if even boundary */
+ {
+ buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT,
+ inferior_pid,
+ ((TTRACE_ARG_TYPE)
+ (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))),
+ TT_NIL,
+ TT_NIL);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
+ myaddr,
+ len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ call_ttrace (TT_LWP_WRDATA,
+ inferior_pid,
+ (TTRACE_ARG_TYPE) addr,
+ (TTRACE_ARG_TYPE) buffer[i],
+ TT_NIL);
+ if (errno)
+ {
+ /* Using the appropriate one (I or D) is necessary for
+ Gould NP1, at least. */
+ errno = 0;
+ call_ttrace (TT_LWP_WRTEXT,
+ inferior_pid,
+ (TTRACE_ARG_TYPE) addr,
+ (TTRACE_ARG_TYPE) buffer[i],
+ TT_NIL);
+ }
+ if (errno)
+ return 0;
+ }
+ }
+ else
+ {
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ buffer[i] = call_ttrace (TT_LWP_RDTEXT,
+ inferior_pid,
+ (TTRACE_ARG_TYPE) addr,
+ TT_NIL,
+ TT_NIL);
+ if (errno)
+ return 0;
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr,
+ (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
+ len);
+ }
+ return len;
+}
+
+
+static void
+udot_info ()
+{
+ int udot_off; /* Offset into user struct */
+ int udot_val; /* Value from user struct at udot_off */
+ char mess[128]; /* For messages */
+
+ if (!target_has_execution)
+ {
+ error ("The program is not being run.");
+ }
+
+#if !defined (KERNEL_U_SIZE)
+
+ /* Adding support for this command is easy. Typically you just add a
+ routine, called "kernel_u_size" that returns the size of the user
+ struct, to the appropriate *-nat.c file and then add to the native
+ config file "#define KERNEL_U_SIZE kernel_u_size()" */
+ error ("Don't know how large ``struct user'' is in this version of gdb.");
+
+#else
+
+ for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
+ {
+ if ((udot_off % 24) == 0)
+ {
+ if (udot_off > 0)
+ {
+ printf_filtered ("\n");
+ }
+ printf_filtered ("%04x:", udot_off);
+ }
+ udot_val = call_ttrace (TT_LWP_RUREGS,
+ inferior_pid,
+ (TTRACE_ARG_TYPE) udot_off,
+ TT_NIL,
+ TT_NIL);
+ if (errno != 0)
+ {
+ sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
+ perror_with_name (mess);
+ }
+ /* Avoid using nonportable (?) "*" in print specs */
+ printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
+ }
+ printf_filtered ("\n");
+
+#endif
+}
+#endif /* !defined (CHILD_XFER_MEMORY). */
+
+/* TTrace version of "target_pid_to_exec_file"
+ */
+char *
+child_pid_to_exec_file (tid)
+ int tid;
+{
+ static char exec_file_buffer[1024];
+ int tt_status;
+ CORE_ADDR top_of_stack;
+ char four_chars[4];
+ int name_index;
+ int i;
+ int done;
+ int saved_inferior_pid;
+
+ /* As of 10.x HP-UX, there's an explicit request to get the
+ *pathname.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_PATHNAME,
+ tid,
+ (TTRACE_ARG_TYPE) exec_file_buffer,
+ (TTRACE_ARG_TYPE) sizeof (exec_file_buffer) - 1,
+ TT_NIL);
+ if (tt_status >= 0)
+ return exec_file_buffer;
+
+ /* ??rehrauer: The above request may or may not be broken. It
+ doesn't seem to work when I use it. But, it may be designed
+ to only work immediately after an exec event occurs. (I'm
+ waiting for COSL to explain.)
+
+ In any case, if it fails, try a really, truly amazingly gross
+ hack that DDE uses, of pawing through the process' data
+ segment to find the pathname.
+ */
+ top_of_stack = 0x7b03a000;
+ name_index = 0;
+ done = 0;
+
+ /* On the chance that pid != inferior_pid, set inferior_pid
+ to pid, so that (grrrr!) implicit uses of inferior_pid get
+ the right id.
+ */
+ saved_inferior_pid = inferior_pid;
+ inferior_pid = tid;
+
+ /* Try to grab a null-terminated string. */
+ while (! done) {
+ if (target_read_memory (top_of_stack, four_chars, 4) != 0)
+ {
+ inferior_pid = saved_inferior_pid;
+ return NULL;
+ }
+ for (i = 0; i < 4; i++) {
+ exec_file_buffer[name_index++] = four_chars[i];
+ done = (four_chars[i] == '\0');
+ if (done)
+ break;
+ }
+ top_of_stack += 4;
+ }
+
+ if (exec_file_buffer[0] == '\0')
+ {
+ inferior_pid = saved_inferior_pid;
+ return NULL;
+ }
+
+ inferior_pid = saved_inferior_pid;
+ return exec_file_buffer;
+}
+
+
+void
+pre_fork_inferior ()
+{
+ int status;
+
+ status = pipe (startup_semaphore.parent_channel);
+ if (status < 0) {
+ warning ("error getting parent pipe for startup semaphore");
+ return;
+ }
+
+ status = pipe (startup_semaphore.child_channel);
+ if (status < 0) {
+ warning ("error getting child pipe for startup semaphore");
+ return;
+ }
+}
+
+/* Called via #define REQUIRE_ATTACH from inftarg.c,
+ * ultimately from "follow_inferior_fork" in infrun.c,
+ * itself called from "resume".
+ *
+ * This seems to be intended to attach after a fork or
+ * vfork, while "attach" is used to attach to a pid
+ * given by the user. The check for an existing attach
+ * seems odd--it always fails in our test system.
+ */
+int
+hppa_require_attach (pid)
+ int pid;
+{
+ int tt_status;
+ CORE_ADDR pc;
+ CORE_ADDR pc_addr;
+ unsigned int regs_offset;
+ process_state_t old_process_state = process_state;
+
+ /* Are we already attached? There appears to be no explicit
+ * way to answer this via ttrace, so we try something which
+ * should be innocuous if we are attached. If that fails,
+ * then we assume we're not attached, and so attempt to make
+ * it so.
+ */
+ errno = 0;
+ tt_status = call_real_ttrace (TT_PROC_STOP,
+ pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ TT_NIL);
+
+ if (errno)
+ {
+ /* No change to process-state!
+ */
+ errno = 0;
+ pid = attach (pid);
+ }
+ else
+ {
+ /* If successful, the process is now stopped. But if
+ * we're VFORKING, the parent is still running, so don't
+ * change the process state.
+ */
+ if( process_state != VFORKING )
+ process_state = STOPPED;
+
+ /* If we were already attached, you'd think that we
+ * would need to start going again--but you'd be wrong,
+ * as the fork-following code is actually in the middle
+ * of the "resume" routine in in "infrun.c" and so
+ * will (almost) immediately do a resume.
+ *
+ * On the other hand, if we are VFORKING, which means
+ * that the child and the parent share a process for a
+ * while, we know that "resume" won't be resuming
+ * until the child EXEC event is seen. But we still
+ * don't want to continue, as the event is already
+ * there waiting.
+ */
+ update_thread_state_after_attach( pid, DONT_ATTACH_CONTINUE );
+ } /* STOP succeeded */
+
+ return pid;
+}
+
+int
+hppa_require_detach (pid, signal)
+ int pid;
+ int signal;
+{
+ int tt_status;
+
+ /* If signal is non-zero, we must pass the signal on to the active
+ thread prior to detaching. We do this by continuing the threads
+ with the signal.
+ */
+ if (signal != 0)
+ {
+ errno = 0;
+ threads_continue_all_with_signals( pid, signal );
+ }
+
+ errno = 0;
+ tt_status = call_ttrace (TT_PROC_DETACH,
+ pid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+
+ errno = 0; /* Ignore any errors. */
+
+ /* process_state? */
+
+ return pid;
+}
+
+/* Given the starting address of a memory page, hash it to a bucket in
+ the memory page dictionary.
+ */
+static int
+get_dictionary_bucket_of_page (page_start)
+ CORE_ADDR page_start;
+{
+ int hash;
+
+ hash = (page_start / memory_page_dictionary.page_size);
+ hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT;
+
+ return hash;
+}
+
+
+/* Given a memory page's starting address, get (i.e., find an existing
+ or create a new) dictionary entry for the page. The page will be
+ write-protected when this function returns, but may have a reference
+ count of 0 (if the page was newly-added to the dictionary).
+ */
+static memory_page_t *
+get_dictionary_entry_of_page (pid, page_start)
+ int pid;
+ CORE_ADDR page_start;
+{
+ int bucket;
+ memory_page_t * page = NULL;
+ memory_page_t * previous_page = NULL;
+
+ /* We're going to be using the dictionary now, than-kew. */
+ require_memory_page_dictionary (pid);
+
+ /* Try to find an existing dictionary entry for this page. Hash
+ on the page's starting address.
+ */
+ bucket = get_dictionary_bucket_of_page (page_start);
+ page = &memory_page_dictionary.buckets[bucket];
+ while (page != NULL)
+ {
+ if (page->page_start == page_start)
+ break;
+ previous_page = page;
+ page = page->next;
+ }
+
+ /* Did we find a dictionary entry for this page? If not, then
+ add it to the dictionary now.
+ */
+ if (page == NULL)
+ {
+ /* Create a new entry. */
+ page = (memory_page_t *) xmalloc (sizeof (memory_page_t));
+ page->page_start = page_start;
+ page->reference_count = 0;
+ page->next = NULL;
+ page->previous = NULL;
+
+ /* We'll write-protect the page now, if that's allowed. */
+ page->original_permissions = write_protect_page (pid, page_start);
+
+ /* Add the new entry to the dictionary. */
+ page->previous = previous_page;
+ previous_page->next = page;
+
+ memory_page_dictionary.page_count++;
+ }
+
+ return page;
+}
+
+
+static void
+remove_dictionary_entry_of_page (pid, page)
+ int pid;
+ memory_page_t * page;
+{
+ /* Restore the page's original permissions. */
+ unwrite_protect_page (pid, page->page_start, page->original_permissions);
+
+ /* Kick the page out of the dictionary. */
+ if (page->previous != NULL)
+ page->previous->next = page->next;
+ if (page->next != NULL)
+ page->next->previous = page->previous;
+
+ /* Just in case someone retains a handle to this after it's freed. */
+ page->page_start = (CORE_ADDR) 0;
+
+ memory_page_dictionary.page_count--;
+
+ free (page);
+}
+
+
+static void
+hppa_enable_syscall_events (pid)
+ int pid;
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled. */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Add syscall events to that set. */
+ ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY;
+ ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN;
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+static void
+hppa_disable_syscall_events (pid)
+ int pid;
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled. */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Remove syscall events from that set. */
+ ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY;
+ ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN;
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) &ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+/* The address range beginning with START and ending with START+LEN-1
+ (inclusive) is to be watched via page-protection by a new watchpoint.
+ Set protection for all pages that overlap that range.
+
+ Note that our caller sets TYPE to:
+ 0 for a bp_hardware_watchpoint,
+ 1 for a bp_read_watchpoint,
+ 2 for a bp_access_watchpoint
+
+ (Yes, this is intentionally (though lord only knows why) different
+ from the TYPE that is passed to hppa_remove_hw_watchpoint.)
+ */
+int
+hppa_insert_hw_watchpoint (pid, start, len, type)
+ int pid;
+ CORE_ADDR start;
+ LONGEST len;
+ int type;
+{
+ CORE_ADDR page_start;
+ int dictionary_was_empty;
+ int page_size;
+ int page_id;
+ LONGEST range_size_in_pages;
+
+ if (type != 0)
+ error ("read or access hardware watchpoints not supported on HP-UX");
+
+ /* Examine all pages in the address range. */
+ require_memory_page_dictionary ();
+
+ dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
+
+ page_size = memory_page_dictionary.page_size;
+ page_start = (start / page_size) * page_size;
+ range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
+
+ for (page_id=0; page_id < range_size_in_pages; page_id++, page_start+=page_size)
+ {
+ memory_page_t * page;
+
+ /* This gets the page entered into the dictionary if it was
+ not already entered.
+ */
+ page = get_dictionary_entry_of_page (pid, page_start);
+ page->reference_count++;
+ }
+
+ /* Our implementation depends on seeing calls to kernel code, for the
+ following reason. Here we ask to be notified of syscalls.
+
+ When a protected page is accessed by user code, HP-UX raises a SIGBUS.
+ Fine.
+
+ But when kernel code accesses the page, it doesn't give a SIGBUS.
+ Rather, the system call that touched the page fails, with errno=EFAULT.
+ Not good for us.
+
+ We could accomodate this "feature" by asking to be notified of syscall
+ entries & exits; upon getting an entry event, disabling page-protections;
+ upon getting an exit event, reenabling page-protections and then checking
+ if any watchpoints triggered.
+
+ However, this turns out to be a real performance loser. syscalls are
+ usually a frequent occurrence. Having to unprotect-reprotect all watched
+ pages, and also to then read all watched memory locations and compare for
+ triggers, can be quite expensive.
+
+ Instead, we'll only ask to be notified of syscall exits. When we get
+ one, we'll check whether errno is set. If not, or if it's not EFAULT,
+ we can just continue the inferior.
+
+ If errno is set upon syscall exit to EFAULT, we must perform some fairly
+ hackish stuff to determine whether the failure really was due to a
+ page-protect trap on a watched location.
+ */
+ if (dictionary_was_empty)
+ hppa_enable_syscall_events (pid);
+
+ return 1;
+}
+
+
+/* The address range beginning with START and ending with START+LEN-1
+ (inclusive) was being watched via page-protection by a watchpoint
+ which has been removed. Remove protection for all pages that
+ overlap that range, which are not also being watched by other
+ watchpoints.
+ */
+int
+hppa_remove_hw_watchpoint (pid, start, len, type)
+ int pid;
+ CORE_ADDR start;
+ LONGEST len;
+ enum bptype type;
+{
+ CORE_ADDR page_start;
+ int dictionary_is_empty;
+ int page_size;
+ int page_id;
+ LONGEST range_size_in_pages;
+
+ if (type != 0)
+ error ("read or access hardware watchpoints not supported on HP-UX");
+
+ /* Examine all pages in the address range. */
+ require_memory_page_dictionary ();
+
+ page_size = memory_page_dictionary.page_size;
+ page_start = (start / page_size) * page_size;
+ range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
+
+ for (page_id=0; page_id < range_size_in_pages; page_id++, page_start+=page_size)
+ {
+ memory_page_t * page;
+
+ page = get_dictionary_entry_of_page (pid, page_start);
+ page->reference_count--;
+
+ /* Was this the last reference of this page? If so, then we
+ must scrub the entry from the dictionary, and also restore
+ the page's original permissions.
+ */
+ if (page->reference_count == 0)
+ remove_dictionary_entry_of_page (pid, page);
+ }
+
+ dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
+
+ /* If write protections are currently disallowed, then that implies that
+ wait_for_inferior believes that the inferior is within a system call.
+ Since we want to see both syscall entry and return, it's clearly not
+ good to disable syscall events in this state!
+
+ ??rehrauer: Yeah, it'd be better if we had a specific flag that said,
+ "inferior is between syscall events now". Oh well.
+ */
+ if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed)
+ hppa_disable_syscall_events (pid);
+
+ return 1;
+}
+
+
+/* Could we implement a watchpoint of this type via our available
+ hardware support?
+
+ This query does not consider whether a particular address range
+ could be so watched, but just whether support is generally available
+ for such things. See hppa_range_profitable_for_hw_watchpoint for a
+ query that answers whether a particular range should be watched via
+ hardware support.
+ */
+int
+hppa_can_use_hw_watchpoint (type, cnt, ot)
+ enum bptype type;
+ int cnt;
+ enum bptype ot;
+{
+ return (type == bp_hardware_watchpoint);
+}
+
+
+/* Assuming we could set a hardware watchpoint on this address, do
+ we think it would be profitable ("a good idea") to do so? If not,
+ we can always set a regular (aka single-step & test) watchpoint
+ on the address...
+ */
+int
+hppa_range_profitable_for_hw_watchpoint (pid, start, len)
+ int pid;
+ CORE_ADDR start;
+ LONGEST len;
+{
+ int range_is_stack_based;
+ int range_is_accessible;
+ CORE_ADDR page_start;
+ int page_size;
+ int page;
+ LONGEST range_size_in_pages;
+
+ /* ??rehrauer: For now, say that all addresses are potentially
+ profitable. Possibly later we'll want to test the address
+ for "stackness"?
+ */
+ range_is_stack_based = 0;
+
+ /* If any page in the range is inaccessible, then we cannot
+ really use hardware watchpointing, even though our client
+ thinks we can. In that case, it's actually an error to
+ attempt to use hw watchpoints, so we'll tell our client
+ that the range is "unprofitable", and hope that they listen...
+ */
+ range_is_accessible = 1; /* Until proven otherwise. */
+
+ /* Examine all pages in the address range. */
+ errno = 0;
+ page_size = sysconf (_SC_PAGE_SIZE);
+
+ /* If we can't determine page size, we're hosed. Tell our
+ client it's unprofitable to use hw watchpoints for this
+ range.
+ */
+ if (errno || (page_size <= 0))
+ {
+ errno = 0;
+ return 0;
+ }
+
+ page_start = (start / page_size) * page_size;
+ range_size_in_pages = len / (LONGEST)page_size;
+
+ for (page=0; page < range_size_in_pages; page++, page_start+=page_size)
+ {
+ int tt_status;
+ int page_permissions;
+
+ /* Is this page accessible? */
+ errno = 0;
+ tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) &page_permissions);
+ if (errno || (tt_status < 0))
+ {
+ errno = 0;
+ range_is_accessible = 0;
+ break;
+ }
+
+ /* Yes, go for another... */
+ }
+
+ return (! range_is_stack_based && range_is_accessible);
+}
+
+
+char *
+hppa_pid_or_tid_to_str (id)
+ pid_t id;
+{
+ static char buf[100]; /* Static because address returned. */
+
+ /* Does this appear to be a process? If so, print it that way. */
+ if (is_process_id (id))
+ return hppa_pid_to_str (id);
+
+ /* Else, print both the GDB thread number and the system thread id. */
+ sprintf (buf, "thread %d (", pid_to_thread_id (id));
+ strcat (buf, hppa_tid_to_str (id));
+ strcat (buf, ")\0");
+
+ return buf;
+}
+
+
+/* If the current pid is not the pid this module reported
+ * from "ptrace_wait" with the most recent event, then the
+ * user has switched threads.
+ *
+ * If the last reported event was a breakpoint, then return
+ * the old thread id, else return 0.
+ */
+pid_t
+hppa_switched_threads( gdb_pid )
+ pid_t gdb_pid;
+{
+ if( gdb_pid == old_gdb_pid ) {
+ /*
+ * Core gdb is working with the same pid that it
+ * was before we reported the last event. This
+ * is ok: e.g. we reported hitting a thread-specific
+ * breakpoint, but we were reporting the wrong
+ * thread, so the core just ignored the event.
+ *
+ * No thread switch has happened.
+ */
+ return (pid_t) 0;
+ }
+ else if( gdb_pid == reported_pid ) {
+ /*
+ * Core gdb is working with the pid we reported, so
+ * any continue or step will be able to figure out
+ * that it needs to step over any hit breakpoints
+ * without our (i.e. PREPARE_TO_PROCEED's) help.
+ */
+ return (pid_t) 0;
+ }
+ else if( !reported_bpt ) {
+ /*
+ * The core switched, but we didn't just report a
+ * breakpoint, so there's no just-hit breakpoint
+ * instruction at "reported_pid"'s PC, and thus there
+ * is no need to step over it.
+ */
+ return (pid_t) 0;
+ }
+ else {
+ /* There's been a real switch, and we reported
+ * a hit breakpoint. Let "hppa_prepare_to_proceed"
+ * know, so it can see whether the breakpoint is
+ * still active.
+ */
+ return reported_pid;
+ }
+
+ /* Keep compiler happy with an obvious return at the end.
+ */
+ return (pid_t) 0;
+}
+
+void
+hppa_ensure_vforking_parent_remains_stopped (pid)
+ int pid;
+{
+ /* Nothing to do when using ttrace. Only the ptrace-based implementation
+ must do real work.
+ */
+}
+
+
+int
+hppa_resume_execd_vforking_child_to_get_parent_vfork ()
+{
+ return 0; /* No, the parent vfork is available now. */
+}
+
+
+
+void
+_initialize_infttrace ()
+{
+ /* Initialize the ttrace-based hardware watchpoint implementation. */
+ memory_page_dictionary.page_count = (LONGEST) -1;
+ memory_page_dictionary.page_protections_allowed = 1;
+
+ errno = 0;
+ memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE);
+
+ if (errno || (memory_page_dictionary.page_size <= 0))
+ perror_with_name ("sysconf");
+}
+
diff --git a/contrib/gdb/gdb/irix4-nat.c b/contrib/gdb/gdb/irix4-nat.c
index 8cd9b4c..5a6e111 100644
--- a/contrib/gdb/gdb/irix4-nat.c
+++ b/contrib/gdb/gdb/irix4-nat.c
@@ -35,6 +35,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
typedef unsigned int greg_t; /* why isn't this defined? */
+static void
+fetch_core_registers PARAMS ((char *, unsigned int, int, CORE_ADDR));
+
/*
* See the comment in m68k-tdep.c regarding the utility of these functions.
*/
@@ -163,7 +166,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which; /* Unused */
- unsigned int reg_addr; /* Unused */
+ CORE_ADDR reg_addr; /* Unused */
{
if (core_reg_size != REGISTER_BYTES)
{
diff --git a/contrib/gdb/gdb/irix5-nat.c b/contrib/gdb/gdb/irix5-nat.c
index fc4c8cb..b3373a9 100644
--- a/contrib/gdb/gdb/irix5-nat.c
+++ b/contrib/gdb/gdb/irix5-nat.c
@@ -1,5 +1,5 @@
/* Native support for the SGI Iris running IRIX version 5, for GDB.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 98, 1999
Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
@@ -32,6 +32,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/procfs.h>
#include <setjmp.h> /* For JB_XXX. */
+static void
+fetch_core_registers PARAMS ((char *, unsigned int, int, CORE_ADDR));
+
/* Size of elements in jmpbuf */
#define JB_ELEMENT_SIZE 4
@@ -49,15 +52,16 @@ supply_gregset (gregsetp)
{
register int regi;
register greg_t *regp = &(*gregsetp)[0];
+ int gregoff = sizeof (greg_t) - MIPS_REGSIZE;
static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
for(regi = 0; regi <= CTX_RA; regi++)
- supply_register (regi, (char *)(regp + regi));
+ supply_register (regi, (char *)(regp + regi) + gregoff);
- supply_register (PC_REGNUM, (char *)(regp + CTX_EPC));
- supply_register (HI_REGNUM, (char *)(regp + CTX_MDHI));
- supply_register (LO_REGNUM, (char *)(regp + CTX_MDLO));
- supply_register (CAUSE_REGNUM, (char *)(regp + CTX_CAUSE));
+ supply_register (PC_REGNUM, (char *)(regp + CTX_EPC) + gregoff);
+ supply_register (HI_REGNUM, (char *)(regp + CTX_MDHI) + gregoff);
+ supply_register (LO_REGNUM, (char *)(regp + CTX_MDLO) + gregoff);
+ supply_register (CAUSE_REGNUM, (char *)(regp + CTX_CAUSE) + gregoff);
/* Fill inaccessible registers with zero. */
supply_register (BADVADDR_REGNUM, zerobuf);
@@ -71,21 +75,35 @@ fill_gregset (gregsetp, regno)
int regi;
register greg_t *regp = &(*gregsetp)[0];
+ /* Under Irix6, if GDB is built with N32 ABI and is debugging an O32
+ executable, we have to sign extend the registers to 64 bits before
+ filling in the gregset structure. */
+
for (regi = 0; regi <= CTX_RA; regi++)
if ((regno == -1) || (regno == regi))
- *(regp + regi) = *(greg_t *) &registers[REGISTER_BYTE (regi)];
+ *(regp + regi) =
+ extract_signed_integer (&registers[REGISTER_BYTE (regi)],
+ REGISTER_RAW_SIZE (regi));
if ((regno == -1) || (regno == PC_REGNUM))
- *(regp + CTX_EPC) = *(greg_t *) &registers[REGISTER_BYTE (PC_REGNUM)];
+ *(regp + CTX_EPC) =
+ extract_signed_integer (&registers[REGISTER_BYTE (PC_REGNUM)],
+ REGISTER_RAW_SIZE (PC_REGNUM));
if ((regno == -1) || (regno == CAUSE_REGNUM))
- *(regp + CTX_CAUSE) = *(greg_t *) &registers[REGISTER_BYTE (CAUSE_REGNUM)];
+ *(regp + CTX_CAUSE) =
+ extract_signed_integer (&registers[REGISTER_BYTE (CAUSE_REGNUM)],
+ REGISTER_RAW_SIZE (CAUSE_REGNUM));
if ((regno == -1) || (regno == HI_REGNUM))
- *(regp + CTX_MDHI) = *(greg_t *) &registers[REGISTER_BYTE (HI_REGNUM)];
+ *(regp + CTX_MDHI) =
+ extract_signed_integer (&registers[REGISTER_BYTE (HI_REGNUM)],
+ REGISTER_RAW_SIZE (HI_REGNUM));
if ((regno == -1) || (regno == LO_REGNUM))
- *(regp + CTX_MDLO) = *(greg_t *) &registers[REGISTER_BYTE (LO_REGNUM)];
+ *(regp + CTX_MDLO) =
+ extract_signed_integer (&registers[REGISTER_BYTE (LO_REGNUM)],
+ REGISTER_RAW_SIZE (LO_REGNUM));
}
/*
@@ -103,6 +121,8 @@ supply_fpregset (fpregsetp)
register int regi;
static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
+ /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
+
for (regi = 0; regi < 32; regi++)
supply_register (FP0_REGNUM + regi,
(char *)&fpregsetp->fp_r.fp_regs[regi]);
@@ -121,6 +141,8 @@ fill_fpregset (fpregsetp, regno)
int regi;
char *from, *to;
+ /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
+
for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
{
if ((regno == -1) || (regno == regi))
@@ -164,19 +186,69 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which; /* Unused */
- unsigned int reg_addr; /* Unused */
+ CORE_ADDR reg_addr; /* Unused */
{
- if (core_reg_size != REGISTER_BYTES)
+ if (core_reg_size == REGISTER_BYTES)
+ {
+ memcpy ((char *)registers, core_reg_sect, core_reg_size);
+ }
+ else if (MIPS_REGSIZE == 4 &&
+ core_reg_size == (2 * MIPS_REGSIZE) * NUM_REGS)
+ {
+ /* This is a core file from a N32 executable, 64 bits are saved
+ for all registers. */
+ char *srcp = core_reg_sect;
+ char *dstp = registers;
+ int regno;
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ if (regno >= FP0_REGNUM && regno < (FP0_REGNUM + 32))
+ {
+ /* FIXME, this is wrong, N32 has 64 bit FP regs, but GDB
+ currently assumes that they are 32 bit. */
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ if (REGISTER_RAW_SIZE(regno) == 4)
+ {
+ /* copying 4 bytes from eight bytes?
+ I don't see how this can be right... */
+ srcp += 4;
+ }
+ else
+ {
+ /* copy all 8 bytes (sizeof(double)) */
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ }
+ }
+ else
+ {
+ srcp += 4;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ }
+ }
+ }
+ else
{
warning ("wrong size gregset struct in core file");
return;
}
- memcpy ((char *)registers, core_reg_sect, core_reg_size);
+ registers_fetched ();
}
/* Irix 5 uses what appears to be a unique form of shared library
support. This is a copy of solib.c modified for Irix 5. */
+/* FIXME: Most of this code could be merged with osfsolib.c and solib.c
+ by using next_link_map_member and xfer_link_map_member in solib.c. */
#include <sys/types.h>
#include <signal.h>
@@ -189,6 +261,13 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
#define __SYM_H__
#define __SYMCONST_H__
#include <obj.h>
+#ifdef HAVE_OBJLIST_H
+#include <objlist.h>
+#endif
+
+#ifdef NEW_OBJ_INFO_MAGIC
+#define HANDLE_NEW_OBJ_LIST
+#endif
#include "symtab.h"
#include "bfd.h"
@@ -204,16 +283,43 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
/* The symbol which starts off the list of shared libraries. */
#define DEBUG_BASE "__rld_obj_head"
-/* How to get the loaded address of a shared library. */
-#define LM_ADDR(so) ((so)->lm.o_praw)
+/* Irix 6.x introduces a new variant of object lists.
+ To be able to debug O32 executables under Irix 6, we have to handle both
+ variants. */
+
+typedef enum
+{
+ OBJ_LIST_OLD, /* Pre Irix 6.x object list. */
+ OBJ_LIST_32, /* 32 Bit Elf32_Obj_Info. */
+ OBJ_LIST_64 /* 64 Bit Elf64_Obj_Info, FIXME not yet implemented. */
+} obj_list_variant;
+
+/* Define our own link_map structure.
+ This will help to share code with osfsolib.c and solib.c. */
+
+struct link_map {
+ obj_list_variant l_variant; /* which variant of object list */
+ CORE_ADDR l_lladdr; /* addr in inferior list was read from */
+ CORE_ADDR l_next; /* address of next object list entry */
+};
+
+/* Irix 5 shared objects are pre-linked to particular addresses
+ although the dynamic linker may have to relocate them if the
+ address ranges of the libraries used by the main program clash.
+ The offset is the difference between the address where the object
+ is mapped and the binding address of the shared library. */
+#define LM_OFFSET(so) ((so) -> offset)
+/* Loaded address of shared library. */
+#define LM_ADDR(so) ((so) -> lmstart)
char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
struct so_list {
struct so_list *next; /* next structure in linked list */
- struct obj_list ll;
- struct obj lm; /* copy of link map from inferior */
- struct obj_list *lladdr; /* addr in inferior lm was read from */
+ struct link_map lm;
+ CORE_ADDR offset; /* prelink to load address offset */
+ char *so_name; /* shared object lib name */
+ CORE_ADDR lmstart; /* lower addr bound of mapped object */
CORE_ADDR lmend; /* upper addr bound of mapped object */
char symbols_loaded; /* flag: symbols read in yet? */
char from_tty; /* flag: print msgs? */
@@ -248,14 +354,20 @@ symbol_add_stub PARAMS ((char *));
static struct so_list *
find_solib PARAMS ((struct so_list *));
-static struct obj_list *
+static struct link_map *
first_link_map_member PARAMS ((void));
+static struct link_map *
+next_link_map_member PARAMS ((struct so_list *));
+
+static void
+xfer_link_map_member PARAMS ((struct so_list *, struct link_map *));
+
static CORE_ADDR
locate_base PARAMS ((void));
-static void
-solib_map_sections PARAMS ((struct so_list *));
+static int
+solib_map_sections PARAMS ((char *));
/*
@@ -265,7 +377,7 @@ LOCAL FUNCTION
SYNOPSIS
- static void solib_map_sections (struct so_list *so)
+ static int solib_map_sections (struct so_list *so)
DESCRIPTION
@@ -284,19 +396,19 @@ FIXMES
expansion stuff?).
*/
-static void
-solib_map_sections (so)
- struct so_list *so;
+static int
+solib_map_sections (arg)
+ char *arg;
{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
char *scratch_pathname;
int scratch_chan;
struct section_table *p;
struct cleanup *old_chain;
bfd *abfd;
- CORE_ADDR offset;
- filename = tilde_expand (so -> lm.o_path);
+ filename = tilde_expand (so -> so_name);
old_chain = make_cleanup (free, filename);
scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
@@ -334,20 +446,13 @@ solib_map_sections (so)
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
}
- /* Irix 5 shared objects are pre-linked to particular addresses
- although the dynamic linker may have to relocate them if the
- address ranges of the libraries used by the main program clash.
- The offset is the difference between the address where the object
- is mapped and the binding address of the shared library. */
- offset = (CORE_ADDR) LM_ADDR (so) - so -> lm.o_base_address;
-
for (p = so -> sections; p < so -> sections_end; p++)
{
/* Relocate the section binding addresses as recorded in the shared
object's file by the offset to get the address to which the
object was actually mapped. */
- p -> addr += offset;
- p -> endaddr += offset;
+ p -> addr += LM_OFFSET (so);
+ p -> endaddr += LM_OFFSET (so);
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
if (STREQ (p -> the_bfd_section -> name, ".text"))
{
@@ -357,6 +462,8 @@ solib_map_sections (so)
/* Free the file names, close the file now. */
do_cleanups (old_chain);
+
+ return (1);
}
/*
@@ -434,31 +541,223 @@ DESCRIPTION
Read in a copy of the first member in the inferior's dynamic
link map from the inferior's dynamic linker structures, and return
- a pointer to the copy in our address space.
+ a pointer to the link map descriptor.
*/
-static struct obj_list *
+static struct link_map *
first_link_map_member ()
{
- struct obj_list *lm;
- struct obj_list s;
+ struct obj_list *listp;
+ struct obj_list list_old;
+ struct link_map *lm;
+ static struct link_map first_lm;
+ CORE_ADDR lladdr;
+ CORE_ADDR next_lladdr;
+
+ /* We have not already read in the dynamic linking structures
+ from the inferior, lookup the address of the base structure. */
+ debug_base = locate_base ();
+ if (debug_base == 0)
+ return NULL;
- read_memory (debug_base, (char *) &lm, sizeof (struct obj_list *));
+ /* Get address of first list entry. */
+ read_memory (debug_base, (char *) &listp, sizeof (struct obj_list *));
- if (lm == NULL)
+ if (listp == NULL)
return NULL;
+ /* Get first list entry. */
+ lladdr = (CORE_ADDR) listp;
+ read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list));
+
/* The first entry in the list is the object file we are debugging,
so skip it. */
- read_memory ((CORE_ADDR) lm, (char *) &s, sizeof (struct obj_list));
+ next_lladdr = (CORE_ADDR) list_old.next;
+
+#ifdef HANDLE_NEW_OBJ_LIST
+ if (list_old.data == NEW_OBJ_INFO_MAGIC)
+ {
+ Elf32_Obj_Info list_32;
- return s.next;
+ read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info));
+ if (list_32.oi_size != sizeof (Elf32_Obj_Info))
+ return NULL;
+ next_lladdr = (CORE_ADDR) list_32.oi_next;
+ }
+#endif
+
+ if (next_lladdr == 0)
+ return NULL;
+
+ first_lm.l_lladdr = next_lladdr;
+ lm = &first_lm;
+ return lm;
}
/*
LOCAL FUNCTION
+ next_link_map_member -- locate next member in dynamic linker's map
+
+SYNOPSIS
+
+ static struct link_map *next_link_map_member (so_list_ptr)
+
+DESCRIPTION
+
+ Read in a copy of the next member in the inferior's dynamic
+ link map from the inferior's dynamic linker structures, and return
+ a pointer to the link map descriptor.
+*/
+
+static struct link_map *
+next_link_map_member (so_list_ptr)
+ struct so_list *so_list_ptr;
+{
+ struct link_map *lm = &so_list_ptr -> lm;
+ CORE_ADDR next_lladdr = lm -> l_next;
+ static struct link_map next_lm;
+
+ if (next_lladdr == 0)
+ {
+ /* We have hit the end of the list, so check to see if any were
+ added, but be quiet if we can't read from the target any more. */
+ int status = 0;
+
+ if (lm -> l_variant == OBJ_LIST_OLD)
+ {
+ struct obj_list list_old;
+
+ status = target_read_memory (lm -> l_lladdr,
+ (char *) &list_old,
+ sizeof (struct obj_list));
+ next_lladdr = (CORE_ADDR) list_old.next;
+ }
+#ifdef HANDLE_NEW_OBJ_LIST
+ else if (lm -> l_variant == OBJ_LIST_32)
+ {
+ Elf32_Obj_Info list_32;
+ status = target_read_memory (lm -> l_lladdr,
+ (char *) &list_32,
+ sizeof (Elf32_Obj_Info));
+ next_lladdr = (CORE_ADDR) list_32.oi_next;
+ }
+#endif
+
+ if (status != 0 || next_lladdr == 0)
+ return NULL;
+ }
+
+ next_lm.l_lladdr = next_lladdr;
+ lm = &next_lm;
+ return lm;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ xfer_link_map_member -- set local variables from dynamic linker's map
+
+SYNOPSIS
+
+ static void xfer_link_map_member (so_list_ptr, lm)
+
+DESCRIPTION
+
+ Read in a copy of the requested member in the inferior's dynamic
+ link map from the inferior's dynamic linker structures, and fill
+ in the necessary so_list_ptr elements.
+*/
+
+static void
+xfer_link_map_member (so_list_ptr, lm)
+ struct so_list *so_list_ptr;
+ struct link_map *lm;
+{
+ struct obj_list list_old;
+ CORE_ADDR lladdr = lm -> l_lladdr;
+ struct link_map *new_lm = &so_list_ptr -> lm;
+ int errcode;
+
+ read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list));
+
+ new_lm -> l_variant = OBJ_LIST_OLD;
+ new_lm -> l_lladdr = lladdr;
+ new_lm -> l_next = (CORE_ADDR) list_old.next;
+
+#ifdef HANDLE_NEW_OBJ_LIST
+ if (list_old.data == NEW_OBJ_INFO_MAGIC)
+ {
+ Elf32_Obj_Info list_32;
+
+ read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info));
+ if (list_32.oi_size != sizeof (Elf32_Obj_Info))
+ return;
+ new_lm -> l_variant = OBJ_LIST_32;
+ new_lm -> l_next = (CORE_ADDR) list_32.oi_next;
+
+ target_read_string ((CORE_ADDR) list_32.oi_pathname,
+ &so_list_ptr -> so_name,
+ list_32.oi_pathname_len + 1, &errcode);
+ if (errcode != 0)
+ memory_error (errcode, (CORE_ADDR) list_32.oi_pathname);
+
+ LM_ADDR (so_list_ptr) = (CORE_ADDR) list_32.oi_ehdr;
+ LM_OFFSET (so_list_ptr) =
+ (CORE_ADDR) list_32.oi_ehdr - (CORE_ADDR) list_32.oi_orig_ehdr;
+ }
+ else
+#endif
+ {
+#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32
+ /* If we are compiling GDB under N32 ABI, the alignments in
+ the obj struct are different from the O32 ABI and we will get
+ wrong values when accessing the struct.
+ As a workaround we use fixed values which are good for
+ Irix 6.2. */
+ char buf[432];
+
+ read_memory ((CORE_ADDR) list_old.data, buf, sizeof (buf));
+
+ target_read_string (extract_address (&buf[236], 4),
+ &so_list_ptr -> so_name,
+ INT_MAX, &errcode);
+ if (errcode != 0)
+ memory_error (errcode, extract_address (&buf[236], 4));
+
+ LM_ADDR (so_list_ptr) = extract_address (&buf[196], 4);
+ LM_OFFSET (so_list_ptr) =
+ extract_address (&buf[196], 4) - extract_address (&buf[248], 4);
+#else
+ struct obj obj_old;
+
+ read_memory ((CORE_ADDR) list_old.data, (char *) &obj_old,
+ sizeof (struct obj));
+
+ target_read_string ((CORE_ADDR) obj_old.o_path,
+ &so_list_ptr -> so_name,
+ INT_MAX, &errcode);
+ if (errcode != 0)
+ memory_error (errcode, (CORE_ADDR) obj_old.o_path);
+
+ LM_ADDR (so_list_ptr) = (CORE_ADDR) obj_old.o_praw;
+ LM_OFFSET (so_list_ptr) =
+ (CORE_ADDR) obj_old.o_praw - obj_old.o_base_address;
+#endif
+ }
+
+ catch_errors (solib_map_sections, (char *) so_list_ptr,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
+}
+
+
+/*
+
+LOCAL FUNCTION
+
find_solib -- step through list of shared objects
SYNOPSIS
@@ -480,7 +779,7 @@ find_solib (so_list_ptr)
struct so_list *so_list_ptr; /* Last lm or NULL for first one */
{
struct so_list *so_list_next = NULL;
- struct obj_list *lm = NULL;
+ struct link_map *lm = NULL;
struct so_list *new;
if (so_list_ptr == NULL)
@@ -488,49 +787,21 @@ find_solib (so_list_ptr)
/* We are setting up for a new scan through the loaded images. */
if ((so_list_next = so_list_head) == NULL)
{
- /* We have not already read in the dynamic linking structures
- from the inferior, lookup the address of the base structure. */
- debug_base = locate_base ();
- if (debug_base != 0)
- {
- /* Read the base structure in and find the address of the first
- link map list member. */
- lm = first_link_map_member ();
- }
+ /* Find the first link map list member. */
+ lm = first_link_map_member ();
}
}
else
{
/* We have been called before, and are in the process of walking
the shared library list. Advance to the next shared object. */
- if ((lm = so_list_ptr->ll.next) == NULL)
- {
- /* We have hit the end of the list, so check to see if any were
- added, but be quiet if we can't read from the target any more. */
- int status = target_read_memory ((CORE_ADDR) so_list_ptr -> lladdr,
- (char *) &(so_list_ptr -> ll),
- sizeof (struct obj_list));
- if (status == 0)
- {
- lm = so_list_ptr->ll.next;
- }
- else
- {
- lm = NULL;
- }
- }
+ lm = next_link_map_member (so_list_ptr);
so_list_next = so_list_ptr -> next;
}
if ((so_list_next == NULL) && (lm != NULL))
{
- int errcode;
- char *buffer;
-
- /* Get next link map structure from inferior image and build a local
- abbreviated load_map structure */
new = (struct so_list *) xmalloc (sizeof (struct so_list));
memset ((char *) new, 0, sizeof (struct so_list));
- new -> lladdr = lm;
/* Add the new node as the next node in the list, or as the root
node if this is the first one. */
if (so_list_ptr != NULL)
@@ -542,16 +813,7 @@ find_solib (so_list_ptr)
so_list_head = new;
}
so_list_next = new;
- read_memory ((CORE_ADDR) lm, (char *) &(new -> ll),
- sizeof (struct obj_list));
- read_memory ((CORE_ADDR) new->ll.data, (char *) &(new -> lm),
- sizeof (struct obj));
- target_read_string ((CORE_ADDR)new->lm.o_path, &buffer,
- INT_MAX, &errcode);
- if (errcode != 0)
- memory_error (errcode, (CORE_ADDR)new->lm.o_path);
- new->lm.o_path = buffer;
- solib_map_sections (new);
+ xfer_link_map_member (new, lm);
}
return (so_list_next);
}
@@ -563,10 +825,28 @@ symbol_add_stub (arg)
char *arg;
{
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+
+ if (so -> textsection)
+ text_addr = so -> textsection -> addr;
+ else if (so -> abfd != NULL)
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ lowest_sect = bfd_get_section_by_name (so -> abfd, ".text");
+ if (lowest_sect == NULL)
+ bfd_map_over_sections (so -> abfd, find_lowest_section,
+ (PTR) &lowest_sect);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so -> abfd, lowest_sect) + LM_OFFSET (so);
+ }
- so -> objfile = symbol_file_add (so -> lm.o_path, so -> from_tty,
- (unsigned int) so -> textsection -> addr,
- 0, 0, 0);
+ so -> objfile = symbol_file_add (so -> so_name, so -> from_tty,
+ text_addr,
+ 0, 0, 0, 0, 0);
return (1);
}
@@ -614,7 +894,7 @@ solib_add (arg_string, from_tty, target)
count = 0;
while ((so = find_solib (so)) != NULL)
{
- if (so -> lm.o_path[0])
+ if (so -> so_name[0])
{
count += so -> sections_end - so -> sections;
}
@@ -656,7 +936,7 @@ solib_add (arg_string, from_tty, target)
/* Add these section table entries to the target's table. */
while ((so = find_solib (so)) != NULL)
{
- if (so -> lm.o_path[0])
+ if (so -> so_name[0])
{
count = so -> sections_end - so -> sections;
memcpy ((char *) (target -> to_sections + old),
@@ -671,14 +951,14 @@ solib_add (arg_string, from_tty, target)
/* Now add the symbol files. */
while ((so = find_solib (so)) != NULL)
{
- if (so -> lm.o_path[0] && re_exec (so -> lm.o_path))
+ if (so -> so_name[0] && re_exec (so -> so_name))
{
so -> from_tty = from_tty;
if (so -> symbols_loaded)
{
if (from_tty)
{
- printf_unfiltered ("Symbols already loaded for %s\n", so -> lm.o_path);
+ printf_unfiltered ("Symbols already loaded for %s\n", so -> so_name);
}
}
else if (catch_errors
@@ -729,7 +1009,7 @@ info_sharedlibrary_command (ignore, from_tty)
}
while ((so = find_solib (so)) != NULL)
{
- if (so -> lm.o_path[0])
+ if (so -> so_name[0])
{
if (!header_done)
{
@@ -744,7 +1024,7 @@ info_sharedlibrary_command (ignore, from_tty)
local_hex_string_custom ((unsigned long) so -> lmend,
"08l"));
printf_unfiltered ("%-12s", so -> symbols_loaded ? "Yes" : "No");
- printf_unfiltered ("%s\n", so -> lm.o_path);
+ printf_unfiltered ("%s\n", so -> so_name);
}
}
if (so_list_head == NULL)
@@ -785,11 +1065,11 @@ solib_address (address)
while ((so = find_solib (so)) != NULL)
{
- if (so -> lm.o_path[0])
+ if (so -> so_name[0])
{
if ((address >= (CORE_ADDR) LM_ADDR (so)) &&
(address < (CORE_ADDR) so -> lmend))
- return (so->lm.o_path);
+ return (so->so_name);
}
}
return (0);
@@ -803,6 +1083,8 @@ clear_solib()
struct so_list *next;
char *bfd_filename;
+ disable_breakpoints_in_shlibs (1);
+
while (so_list_head)
{
if (so_list_head -> sections)
@@ -823,7 +1105,7 @@ clear_solib()
next = so_list_head -> next;
if (bfd_filename)
free ((PTR)bfd_filename);
- free (so_list_head->lm.o_path);
+ free (so_list_head->so_name);
free ((PTR)so_list_head);
so_list_head = next;
}
@@ -971,13 +1253,13 @@ solib_create_inferior_hook()
clear_proceed_status ();
stop_soon_quietly = 1;
- stop_signal = 0;
+ stop_signal = TARGET_SIGNAL_0;
do
{
target_resume (-1, 0, stop_signal);
wait_for_inferior ();
}
- while (stop_signal != SIGTRAP);
+ while (stop_signal != TARGET_SIGNAL_TRAP);
/* We are now either at the "mapping complete" breakpoint (or somewhere
else, a condition we aren't prepared to deal with anyway), so adjust
diff --git a/contrib/gdb/gdb/jv-exp.tab.c b/contrib/gdb/gdb/jv-exp.tab.c
new file mode 100644
index 0000000..39920ca
--- /dev/null
+++ b/contrib/gdb/gdb/jv-exp.tab.c
@@ -0,0 +1,2351 @@
+
+/* A Bison parser, made from jv-exp.y
+ by GNU Bison version 1.25
+ */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define INTEGER_LITERAL 258
+#define FLOATING_POINT_LITERAL 259
+#define IDENTIFIER 260
+#define STRING_LITERAL 261
+#define BOOLEAN_LITERAL 262
+#define TYPENAME 263
+#define NAME_OR_INT 264
+#define ERROR 265
+#define LONG 266
+#define SHORT 267
+#define BYTE 268
+#define INT 269
+#define CHAR 270
+#define BOOLEAN 271
+#define DOUBLE 272
+#define FLOAT 273
+#define VARIABLE 274
+#define ASSIGN_MODIFY 275
+#define THIS 276
+#define SUPER 277
+#define NEW 278
+#define OROR 279
+#define ANDAND 280
+#define EQUAL 281
+#define NOTEQUAL 282
+#define LEQ 283
+#define GEQ 284
+#define LSH 285
+#define RSH 286
+#define INCREMENT 287
+#define DECREMENT 288
+
+#line 38 "jv-exp.y"
+
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth java_maxdepth
+#define yyparse java_parse
+#define yylex java_lex
+#define yyerror java_error
+#define yylval java_lval
+#define yychar java_char
+#define yydebug java_debug
+#define yypact java_pact
+#define yyr1 java_r1
+#define yyr2 java_r2
+#define yydef java_def
+#define yychk java_chk
+#define yypgo java_pgo
+#define yyact java_act
+#define yyexca java_exca
+#define yyerrflag java_errflag
+#define yynerrs java_nerrs
+#define yyps java_ps
+#define yypv java_pv
+#define yys java_s
+#define yy_yys java_yys
+#define yystate java_state
+#define yytmp java_tmp
+#define yyv java_v
+#define yy_yyv java_yyv
+#define yyval java_val
+#define yylloc java_lloc
+#define yyreds java_reds /* With YYDEBUG defined */
+#define yytoks java_toks /* With YYDEBUG defined */
+#define yylhs java_yylhs
+#define yylen java_yylen
+#define yydefred java_yydefred
+#define yydgoto java_yydgoto
+#define yysindex java_yysindex
+#define yyrindex java_yyrindex
+#define yygindex java_yygindex
+#define yytable java_yytable
+#define yycheck java_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+int
+yyparse PARAMS ((void));
+
+static int
+yylex PARAMS ((void));
+
+void
+yyerror PARAMS ((char *));
+
+static struct type * java_type_from_name PARAMS ((struct stoken));
+static void push_expression_name PARAMS ((struct stoken));
+static void push_fieldnames PARAMS ((struct stoken));
+
+static struct expression *copy_exp PARAMS ((struct expression *, int));
+static void insert_exp PARAMS ((int, struct expression *));
+
+
+#line 124 "jv-exp.y"
+typedef union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val_int;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+ int *ivec;
+ } YYSTYPE;
+#line 146 "jv-exp.y"
+
+/* YYSTYPE gets defined by %union */
+static int
+parse_number PARAMS ((char *, int, int, YYSTYPE *));
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 208
+#define YYFLAG -32768
+#define YYNTBASE 57
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 288 ? yytranslate[x] : 112)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 55, 2, 2, 2, 44, 31, 2, 49,
+ 50, 42, 40, 24, 41, 47, 43, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 56, 2, 34,
+ 25, 35, 26, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 48, 2, 53, 30, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 51, 29, 52, 54, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 27, 28,
+ 32, 33, 36, 37, 38, 39, 45, 46
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
+ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
+ 40, 42, 44, 46, 48, 51, 54, 56, 58, 60,
+ 62, 64, 66, 70, 72, 76, 78, 80, 82, 84,
+ 88, 90, 92, 94, 96, 100, 102, 104, 110, 112,
+ 116, 117, 119, 124, 129, 131, 134, 138, 141, 145,
+ 147, 148, 152, 156, 161, 168, 175, 180, 185, 190,
+ 192, 194, 196, 198, 200, 203, 206, 208, 210, 213,
+ 216, 219, 221, 224, 227, 229, 232, 235, 237, 243,
+ 248, 254, 256, 260, 264, 268, 270, 274, 278, 280,
+ 284, 288, 290, 294, 298, 302, 306, 308, 312, 316,
+ 318, 322, 324, 328, 330, 334, 336, 340, 342, 346,
+ 348, 354, 356, 358, 362, 366, 368, 370, 372, 374
+};
+
+static const short yyrhs[] = { 73,
+ 0, 58, 0, 59, 0, 62, 0, 68, 0, 6,
+ 0, 3, 0, 9, 0, 4, 0, 7, 0, 60,
+ 0, 63, 0, 16, 0, 64, 0, 65, 0, 13,
+ 0, 12, 0, 14, 0, 11, 0, 15, 0, 18,
+ 0, 17, 0, 69, 0, 66, 0, 62, 84, 0,
+ 69, 84, 0, 5, 0, 72, 0, 71, 0, 72,
+ 0, 5, 0, 9, 0, 69, 47, 71, 0, 111,
+ 0, 73, 24, 111, 0, 75, 0, 81, 0, 61,
+ 0, 21, 0, 49, 111, 50, 0, 78, 0, 86,
+ 0, 87, 0, 88, 0, 76, 79, 77, 0, 51,
+ 0, 52, 0, 23, 67, 49, 80, 50, 0, 111,
+ 0, 79, 24, 111, 0, 0, 79, 0, 23, 62,
+ 82, 85, 0, 23, 66, 82, 85, 0, 83, 0,
+ 82, 83, 0, 48, 111, 53, 0, 48, 53, 0,
+ 84, 48, 53, 0, 84, 0, 0, 74, 47, 71,
+ 0, 19, 47, 71, 0, 69, 49, 80, 50, 0,
+ 74, 47, 71, 49, 80, 50, 0, 22, 47, 71,
+ 49, 80, 50, 0, 69, 48, 111, 53, 0, 19,
+ 48, 111, 53, 0, 75, 48, 111, 53, 0, 74,
+ 0, 69, 0, 19, 0, 90, 0, 91, 0, 89,
+ 45, 0, 89, 46, 0, 93, 0, 94, 0, 40,
+ 92, 0, 41, 92, 0, 42, 92, 0, 95, 0,
+ 45, 92, 0, 46, 92, 0, 89, 0, 54, 92,
+ 0, 55, 92, 0, 96, 0, 49, 62, 85, 50,
+ 92, 0, 49, 111, 50, 95, 0, 49, 69, 84,
+ 50, 95, 0, 92, 0, 97, 42, 92, 0, 97,
+ 43, 92, 0, 97, 44, 92, 0, 97, 0, 98,
+ 40, 97, 0, 98, 41, 97, 0, 98, 0, 99,
+ 38, 98, 0, 99, 39, 98, 0, 99, 0, 100,
+ 34, 99, 0, 100, 35, 99, 0, 100, 36, 99,
+ 0, 100, 37, 99, 0, 100, 0, 101, 32, 100,
+ 0, 101, 33, 100, 0, 101, 0, 102, 31, 101,
+ 0, 102, 0, 103, 30, 102, 0, 103, 0, 104,
+ 29, 103, 0, 104, 0, 105, 28, 104, 0, 105,
+ 0, 106, 27, 105, 0, 106, 0, 106, 26, 111,
+ 56, 107, 0, 107, 0, 109, 0, 110, 25, 107,
+ 0, 110, 20, 107, 0, 70, 0, 19, 0, 86,
+ 0, 88, 0, 108, 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 203, 204, 207, 215, 217, 220, 229, 235, 243, 248,
+ 253, 263, 265, 269, 271, 274, 277, 279, 281, 283,
+ 287, 290, 301, 306, 310, 313, 317, 319, 322, 324,
+ 327, 329, 332, 356, 357, 361, 363, 366, 368, 371,
+ 372, 373, 374, 375, 376, 383, 388, 393, 398, 401,
+ 405, 408, 411, 414, 418, 420, 423, 427, 430, 434,
+ 436, 440, 443, 448, 451, 453, 457, 475, 477, 481,
+ 483, 485, 487, 488, 491, 496, 501, 503, 504, 505,
+ 507, 509, 512, 517, 522, 524, 526, 528, 531, 536,
+ 557, 564, 566, 568, 570, 574, 576, 578, 582, 584,
+ 586, 591, 593, 595, 597, 599, 604, 606, 608, 612,
+ 614, 618, 620, 623, 625, 629, 631, 635, 637, 641,
+ 643, 647, 649, 652, 655, 661, 664, 666, 667, 671
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = { "$","error","$undefined.","INTEGER_LITERAL",
+"FLOATING_POINT_LITERAL","IDENTIFIER","STRING_LITERAL","BOOLEAN_LITERAL","TYPENAME",
+"NAME_OR_INT","ERROR","LONG","SHORT","BYTE","INT","CHAR","BOOLEAN","DOUBLE",
+"FLOAT","VARIABLE","ASSIGN_MODIFY","THIS","SUPER","NEW","','","'='","'?'","OROR",
+"ANDAND","'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'","'>'","LEQ","GEQ","LSH",
+"RSH","'+'","'-'","'*'","'/'","'%'","INCREMENT","DECREMENT","'.'","'['","'('",
+"')'","'{'","'}'","']'","'~'","'!'","':'","start","type_exp","PrimitiveOrArrayType",
+"StringLiteral","Literal","PrimitiveType","NumericType","IntegralType","FloatingPointType",
+"ClassOrInterfaceType","ClassType","ArrayType","Name","ForcedName","SimpleName",
+"QualifiedName","exp1","Primary","PrimaryNoNewArray","lcurly","rcurly","ClassInstanceCreationExpression",
+"ArgumentList","ArgumentList_opt","ArrayCreationExpression","DimExprs","DimExpr",
+"Dims","Dims_opt","FieldAccess","MethodInvocation","ArrayAccess","PostfixExpression",
+"PostIncrementExpression","PostDecrementExpression","UnaryExpression","PreIncrementExpression",
+"PreDecrementExpression","UnaryExpressionNotPlusMinus","CastExpression","MultiplicativeExpression",
+"AdditiveExpression","ShiftExpression","RelationalExpression","EqualityExpression",
+"AndExpression","ExclusiveOrExpression","InclusiveOrExpression","ConditionalAndExpression",
+"ConditionalOrExpression","ConditionalExpression","AssignmentExpression","Assignment",
+"LeftHandSide","Expression", NULL
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 57, 57, 58, 59, 59, 60, 61, 61, 61, 61,
+ 61, 62, 62, 63, 63, 64, 64, 64, 64, 64,
+ 65, 65, 66, 67, 68, 68, 69, 69, 70, 70,
+ 71, 71, 72, 73, 73, 74, 74, 75, 75, 75,
+ 75, 75, 75, 75, 75, 76, 77, 78, 79, 79,
+ 80, 80, 81, 81, 82, 82, 83, 84, 84, 85,
+ 85, 86, 86, 87, 87, 87, 88, 88, 88, 89,
+ 89, 89, 89, 89, 90, 91, 92, 92, 92, 92,
+ 92, 92, 93, 94, 95, 95, 95, 95, 96, 96,
+ 96, 97, 97, 97, 97, 98, 98, 98, 99, 99,
+ 99, 100, 100, 100, 100, 100, 101, 101, 101, 102,
+ 102, 103, 103, 104, 104, 105, 105, 106, 106, 107,
+ 107, 108, 108, 109, 109, 110, 110, 110, 110, 111
+};
+
+static const short yyr2[] = { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 1, 1, 1, 1,
+ 1, 1, 3, 1, 3, 1, 1, 1, 1, 3,
+ 1, 1, 1, 1, 3, 1, 1, 5, 1, 3,
+ 0, 1, 4, 4, 1, 2, 3, 2, 3, 1,
+ 0, 3, 3, 4, 6, 6, 4, 4, 4, 1,
+ 1, 1, 1, 1, 2, 2, 1, 1, 2, 2,
+ 2, 1, 2, 2, 1, 2, 2, 1, 5, 4,
+ 5, 1, 3, 3, 3, 1, 3, 3, 1, 3,
+ 3, 1, 3, 3, 3, 3, 1, 3, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 5, 1, 1, 3, 3, 1, 1, 1, 1, 1
+};
+
+static const short yydefact[] = { 0,
+ 7, 9, 27, 6, 10, 8, 19, 17, 16, 18,
+ 20, 13, 22, 21, 72, 39, 0, 0, 0, 0,
+ 0, 0, 0, 0, 46, 0, 0, 2, 3, 11,
+ 38, 4, 12, 14, 15, 5, 71, 126, 29, 28,
+ 1, 70, 36, 0, 41, 37, 42, 43, 44, 85,
+ 73, 74, 92, 77, 78, 82, 88, 96, 99, 102,
+ 107, 110, 112, 114, 116, 118, 120, 122, 130, 123,
+ 0, 34, 0, 0, 0, 27, 0, 24, 0, 23,
+ 28, 8, 72, 71, 42, 44, 79, 80, 81, 83,
+ 84, 61, 71, 0, 86, 87, 0, 25, 0, 0,
+ 51, 26, 0, 0, 0, 0, 49, 75, 76, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 31, 32, 63, 0, 0, 0, 61, 55, 61, 51,
+ 0, 60, 0, 0, 40, 58, 0, 33, 0, 52,
+ 0, 35, 62, 0, 0, 47, 45, 93, 94, 95,
+ 97, 98, 100, 101, 103, 104, 105, 106, 108, 109,
+ 111, 113, 115, 117, 0, 119, 125, 124, 68, 51,
+ 0, 0, 56, 53, 54, 0, 0, 0, 90, 59,
+ 67, 64, 51, 69, 50, 0, 0, 57, 48, 89,
+ 91, 0, 121, 66, 65, 0, 0, 0
+};
+
+static const short yydefgoto[] = { 206,
+ 28, 29, 30, 31, 32, 33, 34, 35, 78, 79,
+ 36, 84, 38, 39, 81, 41, 42, 43, 44, 157,
+ 45, 150, 151, 46, 137, 138, 142, 143, 85, 48,
+ 86, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 107
+};
+
+static const short yypact[] = { 206,
+-32768,-32768, -5,-32768,-32768, -3,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 1,-32768, -34, 225, 312, 312,
+ 312, 312, 312, 206,-32768, 312, 312,-32768,-32768,-32768,
+-32768, -23,-32768,-32768,-32768,-32768, 34,-32768,-32768, 7,
+ 4, -28, -17, 365,-32768,-32768, 15,-32768, 21, 74,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 45, 44, 86,
+ 35, 96, 3, 23, 8, 51, 104,-32768,-32768,-32768,
+ 32,-32768, 46, 365, 46,-32768, 25, 25, 14, 55,
+-32768,-32768, 87, 47,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, -23, 34, 40,-32768,-32768, 57, 50, 46, 259,
+ 365, 50, 365, 46, 365, -13,-32768,-32768,-32768, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 365, 312, 312, 312,
+-32768,-32768,-32768, 61, 59, 365, 56,-32768, 56, 365,
+ 365, 50, 66, 43, 372,-32768, 69,-32768, 73, 108,
+ 106,-32768, 111, 109, 365,-32768,-32768,-32768,-32768,-32768,
+ 45, 45, 44, 44, 86, 86, 86, 86, 35, 35,
+ 96, 3, 23, 8, 107, 51,-32768,-32768,-32768, 365,
+ 112, 259,-32768,-32768,-32768, 114, 312, 372,-32768,-32768,
+-32768,-32768, 365,-32768,-32768, 312, 116,-32768,-32768,-32768,
+-32768, 118,-32768,-32768,-32768, 169, 170,-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768,-32768,-32768, -8,-32768,-32768,-32768,-32768,-32768,
+-32768, 5,-32768, -66, 0,-32768,-32768,-32768,-32768,-32768,
+-32768, 127, -126,-32768, 94, -94, -29, -40, 6,-32768,
+ 12,-32768,-32768,-32768, 39,-32768,-32768, -141,-32768, 24,
+ 28, -42, 36, 52, 53, 49, 58, 48,-32768, -128,
+-32768,-32768,-32768, 18
+};
+
+
+#define YYLAST 427
+
+
+static const short yytable[] = { 40,
+ 177, 178, 98, 189, 37, 47, 133, 102, 135, 77,
+ 155, 49, 75, 186, -31, 92, -32, 72, 104, -31,
+ -127, -32, 80, 40, 97, -127, -30, 103, 93, 47,
+ 105, -30, 148, 123, -128, 49, 125, 153, 156, -128,
+ -129, 94, 183, 40, 183, -129, 201, 73, 74, 47,
+ 131, 129, 124, 197, 132, 49, 130, 87, 88, 89,
+ 90, 91, 140, 144, 95, 96, 202, 203, 117, 118,
+ 119, 120, 136, 40, 165, 166, 167, 168, 126, 47,
+ 99, 100, 101, 113, 114, 49, 110, 111, 112, 145,
+ 147, 134, 188, 99, 141, 101, 184, 147, 185, 40,
+ 40, 99, 40, 182, 40, 47, 47, 180, 47, 146,
+ 47, 49, 49, 179, 49, 187, 49, 149, 108, 109,
+ 152, 190, 154, 115, 116, 191, 40, 121, 122, 127,
+ 128, 155, 47, 73, 74, 40, 161, 162, 49, 40,
+ 40, 47, 163, 164, 175, 47, 47, 49, 158, 159,
+ 160, 49, 49, 181, 40, 192, 169, 170, 149, 193,
+ 47, 194, 196, 199, 198, 204, 49, 205, 207, 208,
+ 106, 139, 195, 173, 171, 176, 172, 0, 0, 40,
+ 0, 40, 0, 174, 0, 47, 0, 47, 0, 0,
+ 0, 49, 40, 49, 0, 0, 0, 0, 47, 181,
+ 0, 0, 0, 0, 49, 0, 0, 0, 1, 2,
+ 3, 4, 5, 0, 6, 0, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 200, 16, 17, 18, 76,
+ 0, 0, 0, 0, 0, 7, 8, 9, 10, 11,
+ 12, 13, 14, 0, 0, 19, 20, 21, 0, 0,
+ 22, 23, 0, 0, 24, 0, 25, 0, 0, 26,
+ 27, 1, 2, 3, 4, 5, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 15, 0, 16,
+ 17, 18, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 19, 20,
+ 21, 0, 0, 22, 23, 0, 0, 24, 0, 25,
+ 0, 146, 26, 27, 1, 2, 76, 4, 5, 0,
+ 82, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83, 0, 16, 17, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 19, 20, 21, 0, 0, 22, 23, 0, 0,
+ 24, 0, 25, 0, 0, 26, 27, 1, 2, 3,
+ 4, 5, 0, 6, 1, 2, 76, 4, 5, 0,
+ 82, 0, 0, 15, 0, 16, 17, 18, 0, 0,
+ 83, 0, 16, 17, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 19, 20, 21, 0, 0, 22,
+ 23, 0, 0, 24, 0, 25, 0, 0, 26, 27,
+ 24, 0, 25, 0, 0, 26, 27
+};
+
+static const short yycheck[] = { 0,
+ 129, 130, 32, 145, 0, 0, 73, 37, 75, 18,
+ 24, 0, 47, 140, 20, 24, 20, 0, 47, 25,
+ 20, 25, 18, 24, 48, 25, 20, 24, 24, 24,
+ 48, 25, 99, 31, 20, 24, 29, 104, 52, 25,
+ 20, 24, 137, 44, 139, 25, 188, 47, 48, 44,
+ 5, 20, 30, 180, 9, 44, 25, 19, 20, 21,
+ 22, 23, 49, 93, 26, 27, 193, 196, 34, 35,
+ 36, 37, 48, 74, 117, 118, 119, 120, 28, 74,
+ 47, 48, 49, 40, 41, 74, 42, 43, 44, 50,
+ 48, 74, 50, 47, 48, 49, 137, 48, 139, 100,
+ 101, 47, 103, 48, 105, 100, 101, 49, 103, 53,
+ 105, 100, 101, 53, 103, 50, 105, 100, 45, 46,
+ 103, 53, 105, 38, 39, 53, 127, 32, 33, 26,
+ 27, 24, 127, 47, 48, 136, 113, 114, 127, 140,
+ 141, 136, 115, 116, 127, 140, 141, 136, 110, 111,
+ 112, 140, 141, 136, 155, 50, 121, 122, 141, 49,
+ 155, 53, 56, 50, 53, 50, 155, 50, 0, 0,
+ 44, 78, 155, 125, 123, 128, 124, -1, -1, 180,
+ -1, 182, -1, 126, -1, 180, -1, 182, -1, -1,
+ -1, 180, 193, 182, -1, -1, -1, -1, 193, 182,
+ -1, -1, -1, -1, 193, -1, -1, -1, 3, 4,
+ 5, 6, 7, -1, 9, -1, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 187, 21, 22, 23, 5,
+ -1, -1, -1, -1, -1, 11, 12, 13, 14, 15,
+ 16, 17, 18, -1, -1, 40, 41, 42, -1, -1,
+ 45, 46, -1, -1, 49, -1, 51, -1, -1, 54,
+ 55, 3, 4, 5, 6, 7, -1, 9, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 19, -1, 21,
+ 22, 23, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 40, 41,
+ 42, -1, -1, 45, 46, -1, -1, 49, -1, 51,
+ -1, 53, 54, 55, 3, 4, 5, 6, 7, -1,
+ 9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 19, -1, 21, 22, 23, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 40, 41, 42, -1, -1, 45, 46, -1, -1,
+ 49, -1, 51, -1, -1, 54, 55, 3, 4, 5,
+ 6, 7, -1, 9, 3, 4, 5, 6, 7, -1,
+ 9, -1, -1, 19, -1, 21, 22, 23, -1, -1,
+ 19, -1, 21, 22, 23, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 40, 41, 42, -1, -1, 45,
+ 46, -1, -1, 49, -1, 51, -1, -1, 54, 55,
+ 49, -1, 51, -1, -1, 54, 55
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/stone/jimb/main-98r2/share/bison.simple"
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (to, from, count)
+ char *to;
+ char *from;
+ int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (char *to, char *from, int count)
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 196 "/stone/jimb/main-98r2/share/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to xreallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to xreallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 3:
+#line 208 "jv-exp.y"
+{
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(yyvsp[0].tval);
+ write_exp_elt_opcode(OP_TYPE);
+ ;
+ break;}
+case 6:
+#line 222 "jv-exp.y"
+{
+ write_exp_elt_opcode (OP_STRING);
+ write_exp_string (yyvsp[0].sval);
+ write_exp_elt_opcode (OP_STRING);
+ ;
+ break;}
+case 7:
+#line 231 "jv-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (yyvsp[0].typed_val_int.type);
+ write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val_int.val));
+ write_exp_elt_opcode (OP_LONG); ;
+ break;}
+case 8:
+#line 236 "jv-exp.y"
+{ YYSTYPE val;
+ parse_number (yyvsp[0].sval.ptr, yyvsp[0].sval.length, 0, &val);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (val.typed_val_int.type);
+ write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+ write_exp_elt_opcode (OP_LONG);
+ ;
+ break;}
+case 9:
+#line 244 "jv-exp.y"
+{ write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type (yyvsp[0].typed_val_float.type);
+ write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval);
+ write_exp_elt_opcode (OP_DOUBLE); ;
+ break;}
+case 10:
+#line 249 "jv-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (java_boolean_type);
+ write_exp_elt_longcst ((LONGEST)yyvsp[0].lval);
+ write_exp_elt_opcode (OP_LONG); ;
+ break;}
+case 13:
+#line 266 "jv-exp.y"
+{ yyval.tval = java_boolean_type; ;
+ break;}
+case 16:
+#line 276 "jv-exp.y"
+{ yyval.tval = java_byte_type; ;
+ break;}
+case 17:
+#line 278 "jv-exp.y"
+{ yyval.tval = java_short_type; ;
+ break;}
+case 18:
+#line 280 "jv-exp.y"
+{ yyval.tval = java_int_type; ;
+ break;}
+case 19:
+#line 282 "jv-exp.y"
+{ yyval.tval = java_long_type; ;
+ break;}
+case 20:
+#line 284 "jv-exp.y"
+{ yyval.tval = java_char_type; ;
+ break;}
+case 21:
+#line 289 "jv-exp.y"
+{ yyval.tval = java_float_type; ;
+ break;}
+case 22:
+#line 291 "jv-exp.y"
+{ yyval.tval = java_double_type; ;
+ break;}
+case 23:
+#line 303 "jv-exp.y"
+{ yyval.tval = java_type_from_name (yyvsp[0].sval); ;
+ break;}
+case 25:
+#line 312 "jv-exp.y"
+{ yyval.tval = java_array_type (yyvsp[-1].tval, yyvsp[0].lval); ;
+ break;}
+case 26:
+#line 314 "jv-exp.y"
+{ yyval.tval = java_array_type (java_type_from_name (yyvsp[-1].sval), yyvsp[0].lval); ;
+ break;}
+case 33:
+#line 334 "jv-exp.y"
+{ yyval.sval.length = yyvsp[-2].sval.length + yyvsp[0].sval.length + 1;
+ if (yyvsp[-2].sval.ptr + yyvsp[-2].sval.length + 1 == yyvsp[0].sval.ptr
+ && yyvsp[-2].sval.ptr[yyvsp[-2].sval.length] == '.')
+ yyval.sval.ptr = yyvsp[-2].sval.ptr; /* Optimization. */
+ else
+ {
+ yyval.sval.ptr = (char *) xmalloc (yyval.sval.length + 1);
+ make_cleanup (free, yyval.sval.ptr);
+ sprintf (yyval.sval.ptr, "%.*s.%.*s",
+ yyvsp[-2].sval.length, yyvsp[-2].sval.ptr, yyvsp[0].sval.length, yyvsp[0].sval.ptr);
+ } ;
+ break;}
+case 35:
+#line 358 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_COMMA); ;
+ break;}
+case 39:
+#line 369 "jv-exp.y"
+{ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS); ;
+ break;}
+case 45:
+#line 377 "jv-exp.y"
+{ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+ write_exp_elt_opcode (OP_ARRAY); ;
+ break;}
+case 46:
+#line 385 "jv-exp.y"
+{ start_arglist (); ;
+ break;}
+case 47:
+#line 390 "jv-exp.y"
+{ yyval.lval = end_arglist () - 1; ;
+ break;}
+case 48:
+#line 395 "jv-exp.y"
+{ error ("FIXME - ClassInstanceCreationExpression"); ;
+ break;}
+case 49:
+#line 400 "jv-exp.y"
+{ arglist_len = 1; ;
+ break;}
+case 50:
+#line 402 "jv-exp.y"
+{ arglist_len++; ;
+ break;}
+case 51:
+#line 407 "jv-exp.y"
+{ arglist_len = 0; ;
+ break;}
+case 53:
+#line 413 "jv-exp.y"
+{ error ("FIXME - ArrayCreatiionExpression"); ;
+ break;}
+case 54:
+#line 415 "jv-exp.y"
+{ error ("FIXME - ArrayCreatiionExpression"); ;
+ break;}
+case 58:
+#line 429 "jv-exp.y"
+{ yyval.lval = 1; ;
+ break;}
+case 59:
+#line 431 "jv-exp.y"
+{ yyval.lval = yyvsp[-2].lval + 1; ;
+ break;}
+case 61:
+#line 437 "jv-exp.y"
+{ yyval.lval = 0; ;
+ break;}
+case 62:
+#line 442 "jv-exp.y"
+{ push_fieldnames (yyvsp[0].sval); ;
+ break;}
+case 63:
+#line 444 "jv-exp.y"
+{ push_fieldnames (yyvsp[0].sval); ;
+ break;}
+case 64:
+#line 450 "jv-exp.y"
+{ error ("method invocation not implemented"); ;
+ break;}
+case 65:
+#line 452 "jv-exp.y"
+{ error ("method invocation not implemented"); ;
+ break;}
+case 66:
+#line 454 "jv-exp.y"
+{ error ("method invocation not implemented"); ;
+ break;}
+case 67:
+#line 459 "jv-exp.y"
+{
+ /* Emit code for the Name now, then exchange it in the
+ expout array with the Expression's code. We could
+ introduce a OP_SWAP code or a reversed version of
+ BINOP_SUBSCRIPT, but that makes the rest of GDB pay
+ for our parsing kludges. */
+ struct expression *name_expr;
+
+ push_expression_name (yyvsp[-3].sval);
+ name_expr = copy_exp (expout, expout_ptr);
+ expout_ptr -= name_expr->nelts;
+ insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr),
+ name_expr);
+ free (name_expr);
+ write_exp_elt_opcode (BINOP_SUBSCRIPT);
+ ;
+ break;}
+case 68:
+#line 476 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ;
+ break;}
+case 69:
+#line 478 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ;
+ break;}
+case 71:
+#line 484 "jv-exp.y"
+{ push_expression_name (yyvsp[0].sval); ;
+ break;}
+case 75:
+#line 493 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_POSTINCREMENT); ;
+ break;}
+case 76:
+#line 498 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_POSTDECREMENT); ;
+ break;}
+case 80:
+#line 506 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_NEG); ;
+ break;}
+case 81:
+#line 508 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_IND); ;
+ break;}
+case 83:
+#line 514 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_PREINCREMENT); ;
+ break;}
+case 84:
+#line 519 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_PREDECREMENT); ;
+ break;}
+case 86:
+#line 525 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_COMPLEMENT); ;
+ break;}
+case 87:
+#line 527 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ;
+ break;}
+case 89:
+#line 533 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (java_array_type (yyvsp[-3].tval, yyvsp[-2].lval));
+ write_exp_elt_opcode (UNOP_CAST); ;
+ break;}
+case 90:
+#line 537 "jv-exp.y"
+{
+ int exp_size = expout_ptr;
+ int last_exp_size = length_of_subexp(expout, expout_ptr);
+ struct type *type;
+ int i;
+ int base = expout_ptr - last_exp_size - 3;
+ if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
+ error ("invalid cast expression");
+ type = expout->elts[base+1].type;
+ /* Remove the 'Expression' and slide the
+ UnaryExpressionNotPlusMinus down to replace it. */
+ for (i = 0; i < last_exp_size; i++)
+ expout->elts[base + i] = expout->elts[base + i + 3];
+ expout_ptr -= 3;
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ type = lookup_pointer_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ ;
+ break;}
+case 91:
+#line 558 "jv-exp.y"
+{ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (java_array_type (java_type_from_name (yyvsp[-3].sval), yyvsp[-2].lval));
+ write_exp_elt_opcode (UNOP_CAST); ;
+ break;}
+case 93:
+#line 567 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_MUL); ;
+ break;}
+case 94:
+#line 569 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_DIV); ;
+ break;}
+case 95:
+#line 571 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_REM); ;
+ break;}
+case 97:
+#line 577 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_ADD); ;
+ break;}
+case 98:
+#line 579 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_SUB); ;
+ break;}
+case 100:
+#line 585 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_LSH); ;
+ break;}
+case 101:
+#line 587 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_RSH); ;
+ break;}
+case 103:
+#line 594 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_LESS); ;
+ break;}
+case 104:
+#line 596 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_GTR); ;
+ break;}
+case 105:
+#line 598 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_LEQ); ;
+ break;}
+case 106:
+#line 600 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_GEQ); ;
+ break;}
+case 108:
+#line 607 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_EQUAL); ;
+ break;}
+case 109:
+#line 609 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_NOTEQUAL); ;
+ break;}
+case 111:
+#line 615 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_BITWISE_AND); ;
+ break;}
+case 113:
+#line 621 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_BITWISE_XOR); ;
+ break;}
+case 115:
+#line 626 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_BITWISE_IOR); ;
+ break;}
+case 117:
+#line 632 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ;
+ break;}
+case 119:
+#line 638 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ;
+ break;}
+case 121:
+#line 644 "jv-exp.y"
+{ write_exp_elt_opcode (TERNOP_COND); ;
+ break;}
+case 124:
+#line 654 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_ASSIGN); ;
+ break;}
+case 125:
+#line 656 "jv-exp.y"
+{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode (yyvsp[-1].opcode);
+ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ;
+ break;}
+case 126:
+#line 663 "jv-exp.y"
+{ push_expression_name (yyvsp[0].sval); ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 498 "/stone/jimb/main-98r2/share/bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) xmalloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+ goto yyerrlab1;
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
+#line 675 "jv-exp.y"
+
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+ register char *p;
+ register int len;
+ int parsed_float;
+ YYSTYPE *putithere;
+{
+ register ULONGEST n = 0;
+ ULONGEST limit, limit_div_base;
+
+ register int c;
+ register int base = input_radix;
+
+ struct type *type;
+
+ if (parsed_float)
+ {
+ /* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+
+ p[len] = 0; /* null-terminate the token */
+ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
+ else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
+ else
+ {
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
+#else
+ /* Scan it into a double, then assign it to the long double.
+ This at least wins with values representable in the range
+ of doubles. */
+ double temp;
+ num = sscanf (p, "%lg%c", &temp, &c);
+ putithere->typed_val_float.dval = temp;
+#endif
+ }
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
+ /* See if it has `f' or `d' suffix (float or double). */
+
+ c = tolower (p[len - 1]);
+
+ if (c == 'f' || c == 'F')
+ putithere->typed_val_float.type = builtin_type_float;
+ else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
+ putithere->typed_val_float.type = builtin_type_double;
+ else
+ return ERROR;
+
+ return FLOATING_POINT_LITERAL;
+ }
+
+ /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+ if (p[0] == '0')
+ switch (p[1])
+ {
+ case 'x':
+ case 'X':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 16;
+ len -= 2;
+ }
+ break;
+
+ case 't':
+ case 'T':
+ case 'd':
+ case 'D':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 10;
+ len -= 2;
+ }
+ break;
+
+ default:
+ base = 8;
+ break;
+ }
+
+ c = p[len-1];
+ limit = (ULONGEST)0xffffffff;
+ if (c == 'l' || c == 'L')
+ {
+ type = java_long_type;
+ len--;
+ /* A paranoid calculation of (1<<64)-1. */
+ limit = ((limit << 16) << 16) | limit;
+ }
+ else
+ {
+ type = java_int_type;
+ }
+ limit_div_base = limit / (ULONGEST) base;
+
+ while (--len >= 0)
+ {
+ c = *p++;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ return ERROR; /* Char not a digit */
+ if (c >= base)
+ return ERROR;
+ if (n > limit_div_base
+ || (n *= base) > limit - c)
+ error ("Numeric constant too large.");
+ n += c;
+ }
+
+ putithere->typed_val_int.val = n;
+ putithere->typed_val_int.type = type;
+ return INTEGER_LITERAL;
+}
+
+struct token
+{
+ char *operator;
+ int token;
+ enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+ {
+ {">>=", ASSIGN_MODIFY, BINOP_RSH},
+ {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+ };
+
+static const struct token tokentab2[] =
+ {
+ {"+=", ASSIGN_MODIFY, BINOP_ADD},
+ {"-=", ASSIGN_MODIFY, BINOP_SUB},
+ {"*=", ASSIGN_MODIFY, BINOP_MUL},
+ {"/=", ASSIGN_MODIFY, BINOP_DIV},
+ {"%=", ASSIGN_MODIFY, BINOP_REM},
+ {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
+ {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
+ {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
+ {"++", INCREMENT, BINOP_END},
+ {"--", DECREMENT, BINOP_END},
+ {"&&", ANDAND, BINOP_END},
+ {"||", OROR, BINOP_END},
+ {"<<", LSH, BINOP_END},
+ {">>", RSH, BINOP_END},
+ {"==", EQUAL, BINOP_END},
+ {"!=", NOTEQUAL, BINOP_END},
+ {"<=", LEQ, BINOP_END},
+ {">=", GEQ, BINOP_END}
+ };
+
+/* Read one token, getting characters through lexptr. */
+
+static int
+yylex ()
+{
+ int c;
+ int namelen;
+ unsigned int i;
+ char *tokstart;
+ char *tokptr;
+ int tempbufindex;
+ static char *tempbuf;
+ static int tempbufsize;
+
+ retry:
+
+ tokstart = lexptr;
+ /* See if it is a special token of length 3. */
+ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+ if (STREQN (tokstart, tokentab3[i].operator, 3))
+ {
+ lexptr += 3;
+ yylval.opcode = tokentab3[i].opcode;
+ return tokentab3[i].token;
+ }
+
+ /* See if it is a special token of length 2. */
+ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+ if (STREQN (tokstart, tokentab2[i].operator, 2))
+ {
+ lexptr += 2;
+ yylval.opcode = tokentab2[i].opcode;
+ return tokentab2[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '\'':
+ /* We either have a character constant ('0' or '\177' for example)
+ or we have a quoted symbol reference ('foo(int,int)' in C++
+ for example). */
+ lexptr++;
+ c = *lexptr++;
+ if (c == '\\')
+ c = parse_escape (&lexptr);
+ else if (c == '\'')
+ error ("Empty character constant.");
+
+ yylval.typed_val_int.val = c;
+ yylval.typed_val_int.type = builtin_type_char;
+
+ c = *lexptr++;
+ if (c != '\'')
+ {
+ namelen = skip_quoted (tokstart) - tokstart;
+ if (namelen > 2)
+ {
+ lexptr = tokstart + namelen;
+ if (lexptr[-1] != '\'')
+ error ("Unmatched single quote.");
+ namelen -= 2;
+ tokstart++;
+ goto tryname;
+ }
+ error ("Invalid character constant.");
+ }
+ return INTEGER_LITERAL;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates && paren_depth == 0)
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] < '0' || lexptr[1] > '9')
+ goto symbol; /* Nope, must be a symbol. */
+ /* FALL THRU into number case. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0, toktype;
+ register char *p = tokstart;
+ int hex = input_radix > 10;
+
+ if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ hex = 1;
+ }
+ else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ {
+ p += 2;
+ hex = 0;
+ }
+
+ for (;; ++p)
+ {
+ /* This test includes !hex because 'e' is a valid hex digit
+ and thus does not indicate a floating point number when
+ the radix is hex. */
+ if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ /* This test does not include !hex, because a '.' always indicates
+ a decimal floating point number regardless of the radix. */
+ else if (!got_dot && *p == '.')
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ /* We will take any letters or digits. parse_number will
+ complain if past the radix, or if L or U are not final. */
+ else if ((*p < '0' || *p > '9')
+ && ((*p < 'a' || *p > 'z')
+ && (*p < 'A' || *p > 'Z')))
+ break;
+ }
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case '|':
+ case '&':
+ case '^':
+ case '~':
+ case '!':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '?':
+ case ':':
+ case '=':
+ case '{':
+ case '}':
+ symbol:
+ lexptr++;
+ return c;
+
+ case '"':
+
+ /* Build the gdb internal form of the input string in tempbuf,
+ translating any standard C escape forms seen. Note that the
+ buffer is null byte terminated *only* for the convenience of
+ debugging gdb itself and printing the buffer contents when
+ the buffer contains no embedded nulls. Gdb does not depend
+ upon the buffer being null byte terminated, it uses the length
+ string instead. This allows gdb to handle C strings (as well
+ as strings in other languages) with embedded null bytes */
+
+ tokptr = ++tokstart;
+ tempbufindex = 0;
+
+ do {
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex + 1 >= tempbufsize)
+ {
+ tempbuf = (char *) xrealloc (tempbuf, tempbufsize += 64);
+ }
+ switch (*tokptr)
+ {
+ case '\0':
+ case '"':
+ /* Do nothing, loop will terminate. */
+ break;
+ case '\\':
+ tokptr++;
+ c = parse_escape (&tokptr);
+ if (c == -1)
+ {
+ continue;
+ }
+ tempbuf[tempbufindex++] = c;
+ break;
+ default:
+ tempbuf[tempbufindex++] = *tokptr++;
+ break;
+ }
+ } while ((*tokptr != '"') && (*tokptr != '\0'));
+ if (*tokptr++ != '"')
+ {
+ error ("Unterminated string in expression.");
+ }
+ tempbuf[tempbufindex] = '\0'; /* See note above */
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = tokptr;
+ return (STRING_LITERAL);
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ /* It's a name. See how long it is. */
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_'
+ || c == '$'
+ || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '<');
+ )
+ {
+ if (c == '<')
+ {
+ int i = namelen;
+ while (tokstart[++i] && tokstart[i] != '>');
+ if (tokstart[i] == '>')
+ namelen = i;
+ }
+ c = tokstart[++namelen];
+ }
+
+ /* The token "if" terminates the expression and is NOT
+ removed from the input stream. */
+ if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+ {
+ return 0;
+ }
+
+ lexptr += namelen;
+
+ tryname:
+
+ /* Catch specific keywords. Should be done with a data structure. */
+ switch (namelen)
+ {
+ case 7:
+ if (STREQN (tokstart, "boolean", 7))
+ return BOOLEAN;
+ break;
+ case 6:
+ if (STREQN (tokstart, "double", 6))
+ return DOUBLE;
+ break;
+ case 5:
+ if (STREQN (tokstart, "short", 5))
+ return SHORT;
+ if (STREQN (tokstart, "false", 5))
+ {
+ yylval.lval = 0;
+ return BOOLEAN_LITERAL;
+ }
+ if (STREQN (tokstart, "super", 5))
+ return SUPER;
+ if (STREQN (tokstart, "float", 5))
+ return FLOAT;
+ break;
+ case 4:
+ if (STREQN (tokstart, "long", 4))
+ return LONG;
+ if (STREQN (tokstart, "byte", 4))
+ return BYTE;
+ if (STREQN (tokstart, "char", 4))
+ return CHAR;
+ if (STREQN (tokstart, "true", 4))
+ {
+ yylval.lval = 1;
+ return BOOLEAN_LITERAL;
+ }
+ if (current_language->la_language == language_cplus
+ && STREQN (tokstart, "this", 4))
+ {
+ static const char this_name[] =
+ { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ break;
+ case 3:
+ if (STREQN (tokstart, "int", 3))
+ return INT;
+ if (STREQN (tokstart, "new", 3))
+ return NEW;
+ break;
+ default:
+ break;
+ }
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ write_dollar_variable (yylval.sval);
+ return VARIABLE;
+ }
+
+ /* Input names that aren't symbols but ARE valid hex numbers,
+ when the input radix permits them, can be names or numbers
+ depending on the parse. Note we support radixes > 16 here. */
+ if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+ (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+ {
+ YYSTYPE newlval; /* Its value is ignored. */
+ int hextype = parse_number (tokstart, namelen, 0, &newlval);
+ if (hextype == INTEGER_LITERAL)
+ return NAME_OR_INT;
+ }
+ return IDENTIFIER;
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
+
+static struct type *
+java_type_from_name (name)
+ struct stoken name;
+
+{
+ char *tmp = copy_name (name);
+ struct type *typ = java_lookup_class (tmp);
+ if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
+ error ("No class named %s.", tmp);
+ return typ;
+}
+
+/* If NAME is a valid variable name in this scope, push it and return 1.
+ Otherwise, return 0. */
+
+static int
+push_variable (name)
+ struct stoken name;
+
+{
+ char *tmp = copy_name (name);
+ int is_a_field_of_this = 0;
+ struct symbol *sym;
+ sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
+ &is_a_field_of_this, (struct symtab **) NULL);
+ if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not another more inner frame
+ which happens to be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return 1;
+ }
+ if (is_a_field_of_this)
+ {
+ /* it hangs off of `this'. Must not inadvertently convert from a
+ method call to data ref. */
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ write_exp_string (name);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ return 1;
+ }
+ return 0;
+}
+
+/* Assuming a reference expression has been pushed, emit the
+ STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a
+ qualified name (has '.'), generate a field access for each part. */
+
+static void
+push_fieldnames (name)
+ struct stoken name;
+{
+ int i;
+ struct stoken token;
+ token.ptr = name.ptr;
+ for (i = 0; ; i++)
+ {
+ if (i == name.length || name.ptr[i] == '.')
+ {
+ /* token.ptr is start of current field name. */
+ token.length = &name.ptr[i] - token.ptr;
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (token);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ token.ptr += token.length + 1;
+ }
+ if (i >= name.length)
+ break;
+ }
+}
+
+/* Helper routine for push_expression_name.
+ Handle a qualified name, where DOT_INDEX is the index of the first '.' */
+
+static void
+push_qualified_expression_name (name, dot_index)
+ struct stoken name;
+ int dot_index;
+{
+ struct stoken token;
+ char *tmp;
+ struct type *typ;
+
+ token.ptr = name.ptr;
+ token.length = dot_index;
+
+ if (push_variable (token))
+ {
+ token.ptr = name.ptr + dot_index + 1;
+ token.length = name.length - dot_index - 1;
+ push_fieldnames (token);
+ return;
+ }
+
+ token.ptr = name.ptr;
+ for (;;)
+ {
+ token.length = dot_index;
+ tmp = copy_name (token);
+ typ = java_lookup_class (tmp);
+ if (typ != NULL)
+ {
+ if (dot_index == name.length)
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(typ);
+ write_exp_elt_opcode(OP_TYPE);
+ return;
+ }
+ dot_index++; /* Skip '.' */
+ name.ptr += dot_index;
+ name.length -= dot_index;
+ dot_index = 0;
+ while (dot_index < name.length && name.ptr[dot_index] != '.')
+ dot_index++;
+ token.ptr = name.ptr;
+ token.length = dot_index;
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (typ);
+ write_exp_string (token);
+ write_exp_elt_opcode (OP_SCOPE);
+ if (dot_index < name.length)
+ {
+ dot_index++;
+ name.ptr += dot_index;
+ name.length -= dot_index;
+ push_fieldnames (name);
+ }
+ return;
+ }
+ else if (dot_index >= name.length)
+ break;
+ dot_index++; /* Skip '.' */
+ while (dot_index < name.length && name.ptr[dot_index] != '.')
+ dot_index++;
+ }
+ error ("unknown type `%.*s'", name.length, name.ptr);
+}
+
+/* Handle Name in an expression (or LHS).
+ Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
+
+static void
+push_expression_name (name)
+ struct stoken name;
+{
+ char *tmp;
+ struct type *typ;
+ char *ptr;
+ int i;
+
+ for (i = 0; i < name.length; i++)
+ {
+ if (name.ptr[i] == '.')
+ {
+ /* It's a Qualified Expression Name. */
+ push_qualified_expression_name (name, i);
+ return;
+ }
+ }
+
+ /* It's a Simple Expression Name. */
+
+ if (push_variable (name))
+ return;
+ tmp = copy_name (name);
+ typ = java_lookup_class (tmp);
+ if (typ != NULL)
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(typ);
+ write_exp_elt_opcode(OP_TYPE);
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+
+ msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.", tmp);
+ }
+
+}
+
+
+/* The following two routines, copy_exp and insert_exp, aren't specific to
+ Java, so they could go in parse.c, but their only purpose is to support
+ the parsing kludges we use in this file, so maybe it's best to isolate
+ them here. */
+
+/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
+ into a freshly xmalloc'ed struct expression. Its language_defn is set
+ to null. */
+static struct expression *
+copy_exp (expr, endpos)
+ struct expression *expr;
+ int endpos;
+{
+ int len = length_of_subexp (expr, endpos);
+ struct expression *new
+ = (struct expression *) xmalloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
+ new->nelts = len;
+ memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len));
+ new->language_defn = 0;
+
+ return new;
+}
+
+/* Insert the expression NEW into the current expression (expout) at POS. */
+static void
+insert_exp (pos, new)
+ int pos;
+ struct expression *new;
+{
+ int newlen = new->nelts;
+
+ /* Grow expout if necessary. In this function's only use at present,
+ this should never be necessary. */
+ if (expout_ptr + newlen > expout_size)
+ {
+ expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
+ expout = (struct expression *)
+ xrealloc ((char *) expout, (sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size)));
+ }
+
+ {
+ int i;
+
+ for (i = expout_ptr - 1; i >= pos; i--)
+ expout->elts[i + newlen] = expout->elts[i];
+ }
+
+ memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen));
+ expout_ptr += newlen;
+}
diff --git a/contrib/gdb/gdb/jv-exp.y b/contrib/gdb/gdb/jv-exp.y
new file mode 100644
index 0000000..d17c4f3
--- /dev/null
+++ b/contrib/gdb/gdb/jv-exp.y
@@ -0,0 +1,1466 @@
+/* YACC parser for Java expressions, for GDB.
+ Copyright (C) 1997, 1998, 1999.
+ Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Parse a Java expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result. Well, almost always; see ArrayAccess.
+
+ Note that malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth java_maxdepth
+#define yyparse java_parse
+#define yylex java_lex
+#define yyerror java_error
+#define yylval java_lval
+#define yychar java_char
+#define yydebug java_debug
+#define yypact java_pact
+#define yyr1 java_r1
+#define yyr2 java_r2
+#define yydef java_def
+#define yychk java_chk
+#define yypgo java_pgo
+#define yyact java_act
+#define yyexca java_exca
+#define yyerrflag java_errflag
+#define yynerrs java_nerrs
+#define yyps java_ps
+#define yypv java_pv
+#define yys java_s
+#define yy_yys java_yys
+#define yystate java_state
+#define yytmp java_tmp
+#define yyv java_v
+#define yy_yyv java_yyv
+#define yyval java_val
+#define yylloc java_lloc
+#define yyreds java_reds /* With YYDEBUG defined */
+#define yytoks java_toks /* With YYDEBUG defined */
+#define yylhs java_yylhs
+#define yylen java_yylen
+#define yydefred java_yydefred
+#define yydgoto java_yydgoto
+#define yysindex java_yysindex
+#define yyrindex java_yyrindex
+#define yygindex java_yygindex
+#define yytable java_yytable
+#define yycheck java_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+int
+yyparse PARAMS ((void));
+
+static int
+yylex PARAMS ((void));
+
+void
+yyerror PARAMS ((char *));
+
+static struct type * java_type_from_name PARAMS ((struct stoken));
+static void push_expression_name PARAMS ((struct stoken));
+static void push_fieldnames PARAMS ((struct stoken));
+
+static struct expression *copy_exp PARAMS ((struct expression *, int));
+static void insert_exp PARAMS ((int, struct expression *));
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+ since the result is stored in the structure being created,
+ other node types do have values. */
+
+%union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val_int;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+ int *ivec;
+ }
+
+%{
+/* YYSTYPE gets defined by %union */
+static int
+parse_number PARAMS ((char *, int, int, YYSTYPE *));
+%}
+
+%type <lval> rcurly Dims Dims_opt
+%type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
+%type <tval> IntegralType FloatingPointType NumericType PrimitiveType ArrayType PrimitiveOrArrayType
+
+%token <typed_val_int> INTEGER_LITERAL
+%token <typed_val_float> FLOATING_POINT_LITERAL
+
+%token <sval> IDENTIFIER
+%token <sval> STRING_LITERAL
+%token <lval> BOOLEAN_LITERAL
+%token <tsym> TYPENAME
+%type <sval> Name SimpleName QualifiedName ForcedName
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+ but which would parse as a valid number in the current input radix.
+ E.g. "c" when input_radix==16. Depending on the parse, it will be
+ turned into a name or into a number. */
+
+%token <sval> NAME_OR_INT
+
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+ legal basetypes. */
+%token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
+
+%token VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+%token THIS SUPER NEW
+
+%left ','
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left OROR
+%left ANDAND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH
+%left '+' '-'
+%left '*' '/' '%'
+%right INCREMENT DECREMENT
+%right '.' '[' '('
+
+
+%%
+
+start : exp1
+ | type_exp
+ ;
+
+type_exp: PrimitiveOrArrayType
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);
+ }
+ ;
+
+PrimitiveOrArrayType:
+ PrimitiveType
+ | ArrayType
+ ;
+
+StringLiteral:
+ STRING_LITERAL
+ {
+ write_exp_elt_opcode (OP_STRING);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_STRING);
+ }
+;
+
+Literal:
+ INTEGER_LITERAL
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_longcst ((LONGEST)($1.val));
+ write_exp_elt_opcode (OP_LONG); }
+| NAME_OR_INT
+ { YYSTYPE val;
+ parse_number ($1.ptr, $1.length, 0, &val);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (val.typed_val_int.type);
+ write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+| FLOATING_POINT_LITERAL
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_dblcst ($1.dval);
+ write_exp_elt_opcode (OP_DOUBLE); }
+| BOOLEAN_LITERAL
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (java_boolean_type);
+ write_exp_elt_longcst ((LONGEST)$1);
+ write_exp_elt_opcode (OP_LONG); }
+| StringLiteral
+ ;
+
+/* UNUSED:
+Type:
+ PrimitiveType
+| ReferenceType
+;
+*/
+
+PrimitiveType:
+ NumericType
+| BOOLEAN
+ { $$ = java_boolean_type; }
+;
+
+NumericType:
+ IntegralType
+| FloatingPointType
+;
+
+IntegralType:
+ BYTE
+ { $$ = java_byte_type; }
+| SHORT
+ { $$ = java_short_type; }
+| INT
+ { $$ = java_int_type; }
+| LONG
+ { $$ = java_long_type; }
+| CHAR
+ { $$ = java_char_type; }
+;
+
+FloatingPointType:
+ FLOAT
+ { $$ = java_float_type; }
+| DOUBLE
+ { $$ = java_double_type; }
+;
+
+/* UNUSED:
+ReferenceType:
+ ClassOrInterfaceType
+| ArrayType
+;
+*/
+
+ClassOrInterfaceType:
+ Name
+ { $$ = java_type_from_name ($1); }
+;
+
+ClassType:
+ ClassOrInterfaceType
+;
+
+ArrayType:
+ PrimitiveType Dims
+ { $$ = java_array_type ($1, $2); }
+| Name Dims
+ { $$ = java_array_type (java_type_from_name ($1), $2); }
+;
+
+Name:
+ IDENTIFIER
+| QualifiedName
+;
+
+ForcedName:
+ SimpleName
+| QualifiedName
+;
+
+SimpleName:
+ IDENTIFIER
+| NAME_OR_INT
+;
+
+QualifiedName:
+ Name '.' SimpleName
+ { $$.length = $1.length + $3.length + 1;
+ if ($1.ptr + $1.length + 1 == $3.ptr
+ && $1.ptr[$1.length] == '.')
+ $$.ptr = $1.ptr; /* Optimization. */
+ else
+ {
+ $$.ptr = (char *) malloc ($$.length + 1);
+ make_cleanup (free, $$.ptr);
+ sprintf ($$.ptr, "%.*s.%.*s",
+ $1.length, $1.ptr, $3.length, $3.ptr);
+ } }
+;
+
+/*
+type_exp: type
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);}
+ ;
+ */
+
+/* Expressions, including the comma operator. */
+exp1 : Expression
+ | exp1 ',' Expression
+ { write_exp_elt_opcode (BINOP_COMMA); }
+ ;
+
+Primary:
+ PrimaryNoNewArray
+| ArrayCreationExpression
+;
+
+PrimaryNoNewArray:
+ Literal
+| THIS
+ { write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS); }
+| '(' Expression ')'
+| ClassInstanceCreationExpression
+| FieldAccess
+| MethodInvocation
+| ArrayAccess
+| lcurly ArgumentList rcurly
+ { write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) $3);
+ write_exp_elt_opcode (OP_ARRAY); }
+;
+
+lcurly:
+ '{'
+ { start_arglist (); }
+;
+
+rcurly:
+ '}'
+ { $$ = end_arglist () - 1; }
+;
+
+ClassInstanceCreationExpression:
+ NEW ClassType '(' ArgumentList_opt ')'
+ { error ("FIXME - ClassInstanceCreationExpression"); }
+;
+
+ArgumentList:
+ Expression
+ { arglist_len = 1; }
+| ArgumentList ',' Expression
+ { arglist_len++; }
+;
+
+ArgumentList_opt:
+ /* EMPTY */
+ { arglist_len = 0; }
+| ArgumentList
+;
+
+ArrayCreationExpression:
+ NEW PrimitiveType DimExprs Dims_opt
+ { error ("FIXME - ArrayCreatiionExpression"); }
+| NEW ClassOrInterfaceType DimExprs Dims_opt
+ { error ("FIXME - ArrayCreatiionExpression"); }
+;
+
+DimExprs:
+ DimExpr
+| DimExprs DimExpr
+;
+
+DimExpr:
+ '[' Expression ']'
+;
+
+Dims:
+ '[' ']'
+ { $$ = 1; }
+| Dims '[' ']'
+ { $$ = $1 + 1; }
+;
+
+Dims_opt:
+ Dims
+| /* EMPTY */
+ { $$ = 0; }
+;
+
+FieldAccess:
+ Primary '.' SimpleName
+ { push_fieldnames ($3); }
+| VARIABLE '.' SimpleName
+ { push_fieldnames ($3); }
+/*| SUPER '.' SimpleName { FIXME } */
+;
+
+MethodInvocation:
+ Name '(' ArgumentList_opt ')'
+ { error ("method invocation not implemented"); }
+| Primary '.' SimpleName '(' ArgumentList_opt ')'
+ { error ("method invocation not implemented"); }
+| SUPER '.' SimpleName '(' ArgumentList_opt ')'
+ { error ("method invocation not implemented"); }
+;
+
+ArrayAccess:
+ Name '[' Expression ']'
+ {
+ /* Emit code for the Name now, then exchange it in the
+ expout array with the Expression's code. We could
+ introduce a OP_SWAP code or a reversed version of
+ BINOP_SUBSCRIPT, but that makes the rest of GDB pay
+ for our parsing kludges. */
+ struct expression *name_expr;
+
+ push_expression_name ($1);
+ name_expr = copy_exp (expout, expout_ptr);
+ expout_ptr -= name_expr->nelts;
+ insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr),
+ name_expr);
+ free (name_expr);
+ write_exp_elt_opcode (BINOP_SUBSCRIPT);
+ }
+| VARIABLE '[' Expression ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+| PrimaryNoNewArray '[' Expression ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+;
+
+PostfixExpression:
+ Primary
+| Name
+ { push_expression_name ($1); }
+| VARIABLE
+ /* Already written by write_dollar_variable. */
+| PostIncrementExpression
+| PostDecrementExpression
+;
+
+PostIncrementExpression:
+ PostfixExpression INCREMENT
+ { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+;
+
+PostDecrementExpression:
+ PostfixExpression DECREMENT
+ { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+;
+
+UnaryExpression:
+ PreIncrementExpression
+| PreDecrementExpression
+| '+' UnaryExpression
+| '-' UnaryExpression
+ { write_exp_elt_opcode (UNOP_NEG); }
+| '*' UnaryExpression
+ { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java */
+| UnaryExpressionNotPlusMinus
+;
+
+PreIncrementExpression:
+ INCREMENT UnaryExpression
+ { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+;
+
+PreDecrementExpression:
+ DECREMENT UnaryExpression
+ { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+;
+
+UnaryExpressionNotPlusMinus:
+ PostfixExpression
+| '~' UnaryExpression
+ { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+| '!' UnaryExpression
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+| CastExpression
+ ;
+
+CastExpression:
+ '(' PrimitiveType Dims_opt ')' UnaryExpression
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (java_array_type ($2, $3));
+ write_exp_elt_opcode (UNOP_CAST); }
+| '(' Expression ')' UnaryExpressionNotPlusMinus
+ {
+ int exp_size = expout_ptr;
+ int last_exp_size = length_of_subexp(expout, expout_ptr);
+ struct type *type;
+ int i;
+ int base = expout_ptr - last_exp_size - 3;
+ if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
+ error ("invalid cast expression");
+ type = expout->elts[base+1].type;
+ /* Remove the 'Expression' and slide the
+ UnaryExpressionNotPlusMinus down to replace it. */
+ for (i = 0; i < last_exp_size; i++)
+ expout->elts[base + i] = expout->elts[base + i + 3];
+ expout_ptr -= 3;
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ type = lookup_pointer_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+| '(' Name Dims ')' UnaryExpressionNotPlusMinus
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
+ write_exp_elt_opcode (UNOP_CAST); }
+;
+
+
+MultiplicativeExpression:
+ UnaryExpression
+| MultiplicativeExpression '*' UnaryExpression
+ { write_exp_elt_opcode (BINOP_MUL); }
+| MultiplicativeExpression '/' UnaryExpression
+ { write_exp_elt_opcode (BINOP_DIV); }
+| MultiplicativeExpression '%' UnaryExpression
+ { write_exp_elt_opcode (BINOP_REM); }
+;
+
+AdditiveExpression:
+ MultiplicativeExpression
+| AdditiveExpression '+' MultiplicativeExpression
+ { write_exp_elt_opcode (BINOP_ADD); }
+| AdditiveExpression '-' MultiplicativeExpression
+ { write_exp_elt_opcode (BINOP_SUB); }
+;
+
+ShiftExpression:
+ AdditiveExpression
+| ShiftExpression LSH AdditiveExpression
+ { write_exp_elt_opcode (BINOP_LSH); }
+| ShiftExpression RSH AdditiveExpression
+ { write_exp_elt_opcode (BINOP_RSH); }
+/* | ShiftExpression >>> AdditiveExpression { FIXME } */
+;
+
+RelationalExpression:
+ ShiftExpression
+| RelationalExpression '<' ShiftExpression
+ { write_exp_elt_opcode (BINOP_LESS); }
+| RelationalExpression '>' ShiftExpression
+ { write_exp_elt_opcode (BINOP_GTR); }
+| RelationalExpression LEQ ShiftExpression
+ { write_exp_elt_opcode (BINOP_LEQ); }
+| RelationalExpression GEQ ShiftExpression
+ { write_exp_elt_opcode (BINOP_GEQ); }
+/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
+;
+
+EqualityExpression:
+ RelationalExpression
+| EqualityExpression EQUAL RelationalExpression
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+| EqualityExpression NOTEQUAL RelationalExpression
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+;
+
+AndExpression:
+ EqualityExpression
+| AndExpression '&' EqualityExpression
+ { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+;
+
+ExclusiveOrExpression:
+ AndExpression
+| ExclusiveOrExpression '^' AndExpression
+ { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+;
+InclusiveOrExpression:
+ ExclusiveOrExpression
+| InclusiveOrExpression '|' ExclusiveOrExpression
+ { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+;
+
+ConditionalAndExpression:
+ InclusiveOrExpression
+| ConditionalAndExpression ANDAND InclusiveOrExpression
+ { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+;
+
+ConditionalOrExpression:
+ ConditionalAndExpression
+| ConditionalOrExpression OROR ConditionalAndExpression
+ { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+;
+
+ConditionalExpression:
+ ConditionalOrExpression
+| ConditionalOrExpression '?' Expression ':' ConditionalExpression
+ { write_exp_elt_opcode (TERNOP_COND); }
+;
+
+AssignmentExpression:
+ ConditionalExpression
+| Assignment
+;
+
+Assignment:
+ LeftHandSide '=' ConditionalExpression
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+| LeftHandSide ASSIGN_MODIFY ConditionalExpression
+ { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode ($2);
+ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+;
+
+LeftHandSide:
+ ForcedName
+ { push_expression_name ($1); }
+| VARIABLE
+ /* Already written by write_dollar_variable. */
+| FieldAccess
+| ArrayAccess
+;
+
+
+Expression:
+ AssignmentExpression
+;
+
+%%
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+ register char *p;
+ register int len;
+ int parsed_float;
+ YYSTYPE *putithere;
+{
+ register ULONGEST n = 0;
+ ULONGEST limit, limit_div_base;
+
+ register int c;
+ register int base = input_radix;
+
+ struct type *type;
+
+ if (parsed_float)
+ {
+ /* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+
+ p[len] = 0; /* null-terminate the token */
+ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
+ else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
+ else
+ {
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
+#else
+ /* Scan it into a double, then assign it to the long double.
+ This at least wins with values representable in the range
+ of doubles. */
+ double temp;
+ num = sscanf (p, "%lg%c", &temp, &c);
+ putithere->typed_val_float.dval = temp;
+#endif
+ }
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
+ /* See if it has `f' or `d' suffix (float or double). */
+
+ c = tolower (p[len - 1]);
+
+ if (c == 'f' || c == 'F')
+ putithere->typed_val_float.type = builtin_type_float;
+ else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
+ putithere->typed_val_float.type = builtin_type_double;
+ else
+ return ERROR;
+
+ return FLOATING_POINT_LITERAL;
+ }
+
+ /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+ if (p[0] == '0')
+ switch (p[1])
+ {
+ case 'x':
+ case 'X':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 16;
+ len -= 2;
+ }
+ break;
+
+ case 't':
+ case 'T':
+ case 'd':
+ case 'D':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 10;
+ len -= 2;
+ }
+ break;
+
+ default:
+ base = 8;
+ break;
+ }
+
+ c = p[len-1];
+ limit = (ULONGEST)0xffffffff;
+ if (c == 'l' || c == 'L')
+ {
+ type = java_long_type;
+ len--;
+ /* A paranoid calculation of (1<<64)-1. */
+ limit = ((limit << 16) << 16) | limit;
+ }
+ else
+ {
+ type = java_int_type;
+ }
+ limit_div_base = limit / (ULONGEST) base;
+
+ while (--len >= 0)
+ {
+ c = *p++;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ return ERROR; /* Char not a digit */
+ if (c >= base)
+ return ERROR;
+ if (n > limit_div_base
+ || (n *= base) > limit - c)
+ error ("Numeric constant too large.");
+ n += c;
+ }
+
+ putithere->typed_val_int.val = n;
+ putithere->typed_val_int.type = type;
+ return INTEGER_LITERAL;
+}
+
+struct token
+{
+ char *operator;
+ int token;
+ enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+ {
+ {">>=", ASSIGN_MODIFY, BINOP_RSH},
+ {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+ };
+
+static const struct token tokentab2[] =
+ {
+ {"+=", ASSIGN_MODIFY, BINOP_ADD},
+ {"-=", ASSIGN_MODIFY, BINOP_SUB},
+ {"*=", ASSIGN_MODIFY, BINOP_MUL},
+ {"/=", ASSIGN_MODIFY, BINOP_DIV},
+ {"%=", ASSIGN_MODIFY, BINOP_REM},
+ {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
+ {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
+ {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
+ {"++", INCREMENT, BINOP_END},
+ {"--", DECREMENT, BINOP_END},
+ {"&&", ANDAND, BINOP_END},
+ {"||", OROR, BINOP_END},
+ {"<<", LSH, BINOP_END},
+ {">>", RSH, BINOP_END},
+ {"==", EQUAL, BINOP_END},
+ {"!=", NOTEQUAL, BINOP_END},
+ {"<=", LEQ, BINOP_END},
+ {">=", GEQ, BINOP_END}
+ };
+
+/* Read one token, getting characters through lexptr. */
+
+static int
+yylex ()
+{
+ int c;
+ int namelen;
+ unsigned int i;
+ char *tokstart;
+ char *tokptr;
+ int tempbufindex;
+ static char *tempbuf;
+ static int tempbufsize;
+
+ retry:
+
+ tokstart = lexptr;
+ /* See if it is a special token of length 3. */
+ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+ if (STREQN (tokstart, tokentab3[i].operator, 3))
+ {
+ lexptr += 3;
+ yylval.opcode = tokentab3[i].opcode;
+ return tokentab3[i].token;
+ }
+
+ /* See if it is a special token of length 2. */
+ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+ if (STREQN (tokstart, tokentab2[i].operator, 2))
+ {
+ lexptr += 2;
+ yylval.opcode = tokentab2[i].opcode;
+ return tokentab2[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '\'':
+ /* We either have a character constant ('0' or '\177' for example)
+ or we have a quoted symbol reference ('foo(int,int)' in C++
+ for example). */
+ lexptr++;
+ c = *lexptr++;
+ if (c == '\\')
+ c = parse_escape (&lexptr);
+ else if (c == '\'')
+ error ("Empty character constant.");
+
+ yylval.typed_val_int.val = c;
+ yylval.typed_val_int.type = builtin_type_char;
+
+ c = *lexptr++;
+ if (c != '\'')
+ {
+ namelen = skip_quoted (tokstart) - tokstart;
+ if (namelen > 2)
+ {
+ lexptr = tokstart + namelen;
+ if (lexptr[-1] != '\'')
+ error ("Unmatched single quote.");
+ namelen -= 2;
+ tokstart++;
+ goto tryname;
+ }
+ error ("Invalid character constant.");
+ }
+ return INTEGER_LITERAL;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates && paren_depth == 0)
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] < '0' || lexptr[1] > '9')
+ goto symbol; /* Nope, must be a symbol. */
+ /* FALL THRU into number case. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0, toktype;
+ register char *p = tokstart;
+ int hex = input_radix > 10;
+
+ if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ hex = 1;
+ }
+ else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ {
+ p += 2;
+ hex = 0;
+ }
+
+ for (;; ++p)
+ {
+ /* This test includes !hex because 'e' is a valid hex digit
+ and thus does not indicate a floating point number when
+ the radix is hex. */
+ if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ /* This test does not include !hex, because a '.' always indicates
+ a decimal floating point number regardless of the radix. */
+ else if (!got_dot && *p == '.')
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ /* We will take any letters or digits. parse_number will
+ complain if past the radix, or if L or U are not final. */
+ else if ((*p < '0' || *p > '9')
+ && ((*p < 'a' || *p > 'z')
+ && (*p < 'A' || *p > 'Z')))
+ break;
+ }
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case '|':
+ case '&':
+ case '^':
+ case '~':
+ case '!':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '?':
+ case ':':
+ case '=':
+ case '{':
+ case '}':
+ symbol:
+ lexptr++;
+ return c;
+
+ case '"':
+
+ /* Build the gdb internal form of the input string in tempbuf,
+ translating any standard C escape forms seen. Note that the
+ buffer is null byte terminated *only* for the convenience of
+ debugging gdb itself and printing the buffer contents when
+ the buffer contains no embedded nulls. Gdb does not depend
+ upon the buffer being null byte terminated, it uses the length
+ string instead. This allows gdb to handle C strings (as well
+ as strings in other languages) with embedded null bytes */
+
+ tokptr = ++tokstart;
+ tempbufindex = 0;
+
+ do {
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex + 1 >= tempbufsize)
+ {
+ tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+ }
+ switch (*tokptr)
+ {
+ case '\0':
+ case '"':
+ /* Do nothing, loop will terminate. */
+ break;
+ case '\\':
+ tokptr++;
+ c = parse_escape (&tokptr);
+ if (c == -1)
+ {
+ continue;
+ }
+ tempbuf[tempbufindex++] = c;
+ break;
+ default:
+ tempbuf[tempbufindex++] = *tokptr++;
+ break;
+ }
+ } while ((*tokptr != '"') && (*tokptr != '\0'));
+ if (*tokptr++ != '"')
+ {
+ error ("Unterminated string in expression.");
+ }
+ tempbuf[tempbufindex] = '\0'; /* See note above */
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = tokptr;
+ return (STRING_LITERAL);
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ /* It's a name. See how long it is. */
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_'
+ || c == '$'
+ || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '<');
+ )
+ {
+ if (c == '<')
+ {
+ int i = namelen;
+ while (tokstart[++i] && tokstart[i] != '>');
+ if (tokstart[i] == '>')
+ namelen = i;
+ }
+ c = tokstart[++namelen];
+ }
+
+ /* The token "if" terminates the expression and is NOT
+ removed from the input stream. */
+ if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+ {
+ return 0;
+ }
+
+ lexptr += namelen;
+
+ tryname:
+
+ /* Catch specific keywords. Should be done with a data structure. */
+ switch (namelen)
+ {
+ case 7:
+ if (STREQN (tokstart, "boolean", 7))
+ return BOOLEAN;
+ break;
+ case 6:
+ if (STREQN (tokstart, "double", 6))
+ return DOUBLE;
+ break;
+ case 5:
+ if (STREQN (tokstart, "short", 5))
+ return SHORT;
+ if (STREQN (tokstart, "false", 5))
+ {
+ yylval.lval = 0;
+ return BOOLEAN_LITERAL;
+ }
+ if (STREQN (tokstart, "super", 5))
+ return SUPER;
+ if (STREQN (tokstart, "float", 5))
+ return FLOAT;
+ break;
+ case 4:
+ if (STREQN (tokstart, "long", 4))
+ return LONG;
+ if (STREQN (tokstart, "byte", 4))
+ return BYTE;
+ if (STREQN (tokstart, "char", 4))
+ return CHAR;
+ if (STREQN (tokstart, "true", 4))
+ {
+ yylval.lval = 1;
+ return BOOLEAN_LITERAL;
+ }
+ if (current_language->la_language == language_cplus
+ && STREQN (tokstart, "this", 4))
+ {
+ static const char this_name[] =
+ { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ break;
+ case 3:
+ if (STREQN (tokstart, "int", 3))
+ return INT;
+ if (STREQN (tokstart, "new", 3))
+ return NEW;
+ break;
+ default:
+ break;
+ }
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ write_dollar_variable (yylval.sval);
+ return VARIABLE;
+ }
+
+ /* Input names that aren't symbols but ARE valid hex numbers,
+ when the input radix permits them, can be names or numbers
+ depending on the parse. Note we support radixes > 16 here. */
+ if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+ (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+ {
+ YYSTYPE newlval; /* Its value is ignored. */
+ int hextype = parse_number (tokstart, namelen, 0, &newlval);
+ if (hextype == INTEGER_LITERAL)
+ return NAME_OR_INT;
+ }
+ return IDENTIFIER;
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
+
+static struct type *
+java_type_from_name (name)
+ struct stoken name;
+
+{
+ char *tmp = copy_name (name);
+ struct type *typ = java_lookup_class (tmp);
+ if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
+ error ("No class named %s.", tmp);
+ return typ;
+}
+
+/* If NAME is a valid variable name in this scope, push it and return 1.
+ Otherwise, return 0. */
+
+static int
+push_variable (name)
+ struct stoken name;
+
+{
+ char *tmp = copy_name (name);
+ int is_a_field_of_this = 0;
+ struct symbol *sym;
+ sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
+ &is_a_field_of_this, (struct symtab **) NULL);
+ if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not another more inner frame
+ which happens to be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return 1;
+ }
+ if (is_a_field_of_this)
+ {
+ /* it hangs off of `this'. Must not inadvertently convert from a
+ method call to data ref. */
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ write_exp_string (name);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ return 1;
+ }
+ return 0;
+}
+
+/* Assuming a reference expression has been pushed, emit the
+ STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a
+ qualified name (has '.'), generate a field access for each part. */
+
+static void
+push_fieldnames (name)
+ struct stoken name;
+{
+ int i;
+ struct stoken token;
+ token.ptr = name.ptr;
+ for (i = 0; ; i++)
+ {
+ if (i == name.length || name.ptr[i] == '.')
+ {
+ /* token.ptr is start of current field name. */
+ token.length = &name.ptr[i] - token.ptr;
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (token);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ token.ptr += token.length + 1;
+ }
+ if (i >= name.length)
+ break;
+ }
+}
+
+/* Helper routine for push_expression_name.
+ Handle a qualified name, where DOT_INDEX is the index of the first '.' */
+
+static void
+push_qualified_expression_name (name, dot_index)
+ struct stoken name;
+ int dot_index;
+{
+ struct stoken token;
+ char *tmp;
+ struct type *typ;
+
+ token.ptr = name.ptr;
+ token.length = dot_index;
+
+ if (push_variable (token))
+ {
+ token.ptr = name.ptr + dot_index + 1;
+ token.length = name.length - dot_index - 1;
+ push_fieldnames (token);
+ return;
+ }
+
+ token.ptr = name.ptr;
+ for (;;)
+ {
+ token.length = dot_index;
+ tmp = copy_name (token);
+ typ = java_lookup_class (tmp);
+ if (typ != NULL)
+ {
+ if (dot_index == name.length)
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(typ);
+ write_exp_elt_opcode(OP_TYPE);
+ return;
+ }
+ dot_index++; /* Skip '.' */
+ name.ptr += dot_index;
+ name.length -= dot_index;
+ dot_index = 0;
+ while (dot_index < name.length && name.ptr[dot_index] != '.')
+ dot_index++;
+ token.ptr = name.ptr;
+ token.length = dot_index;
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (typ);
+ write_exp_string (token);
+ write_exp_elt_opcode (OP_SCOPE);
+ if (dot_index < name.length)
+ {
+ dot_index++;
+ name.ptr += dot_index;
+ name.length -= dot_index;
+ push_fieldnames (name);
+ }
+ return;
+ }
+ else if (dot_index >= name.length)
+ break;
+ dot_index++; /* Skip '.' */
+ while (dot_index < name.length && name.ptr[dot_index] != '.')
+ dot_index++;
+ }
+ error ("unknown type `%.*s'", name.length, name.ptr);
+}
+
+/* Handle Name in an expression (or LHS).
+ Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
+
+static void
+push_expression_name (name)
+ struct stoken name;
+{
+ char *tmp;
+ struct type *typ;
+ char *ptr;
+ int i;
+
+ for (i = 0; i < name.length; i++)
+ {
+ if (name.ptr[i] == '.')
+ {
+ /* It's a Qualified Expression Name. */
+ push_qualified_expression_name (name, i);
+ return;
+ }
+ }
+
+ /* It's a Simple Expression Name. */
+
+ if (push_variable (name))
+ return;
+ tmp = copy_name (name);
+ typ = java_lookup_class (tmp);
+ if (typ != NULL)
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(typ);
+ write_exp_elt_opcode(OP_TYPE);
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+
+ msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.", tmp);
+ }
+
+}
+
+
+/* The following two routines, copy_exp and insert_exp, aren't specific to
+ Java, so they could go in parse.c, but their only purpose is to support
+ the parsing kludges we use in this file, so maybe it's best to isolate
+ them here. */
+
+/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
+ into a freshly malloc'ed struct expression. Its language_defn is set
+ to null. */
+static struct expression *
+copy_exp (expr, endpos)
+ struct expression *expr;
+ int endpos;
+{
+ int len = length_of_subexp (expr, endpos);
+ struct expression *new
+ = (struct expression *) malloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
+ new->nelts = len;
+ memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len));
+ new->language_defn = 0;
+
+ return new;
+}
+
+/* Insert the expression NEW into the current expression (expout) at POS. */
+static void
+insert_exp (pos, new)
+ int pos;
+ struct expression *new;
+{
+ int newlen = new->nelts;
+
+ /* Grow expout if necessary. In this function's only use at present,
+ this should never be necessary. */
+ if (expout_ptr + newlen > expout_size)
+ {
+ expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
+ expout = (struct expression *)
+ realloc ((char *) expout, (sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size)));
+ }
+
+ {
+ int i;
+
+ for (i = expout_ptr - 1; i >= pos; i--)
+ expout->elts[i + newlen] = expout->elts[i];
+ }
+
+ memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen));
+ expout_ptr += newlen;
+}
diff --git a/contrib/gdb/gdb/jv-lang.c b/contrib/gdb/gdb/jv-lang.c
new file mode 100644
index 0000000..a98147a
--- /dev/null
+++ b/contrib/gdb/gdb/jv-lang.c
@@ -0,0 +1,1088 @@
+/* Java language support routines for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "gdbtypes.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "c-lang.h"
+#include "jv-lang.h"
+#include "gdbcore.h"
+#include <ctype.h>
+
+struct type *java_int_type;
+struct type *java_byte_type;
+struct type *java_short_type;
+struct type *java_long_type;
+struct type *java_boolean_type;
+struct type *java_char_type;
+struct type *java_float_type;
+struct type *java_double_type;
+struct type *java_void_type;
+
+static int java_demangled_signature_length PARAMS ((char*));
+static void java_demangled_signature_copy PARAMS ((char*, char*));
+
+static void java_emit_char PARAMS ((int c, GDB_FILE *stream, int quoter));
+
+/* This objfile contains symtabs that have been dynamically created
+ to record dynamically loaded Java classes and dynamically
+ compiled java methods. */
+
+static struct objfile *dynamics_objfile = NULL;
+
+static struct type *java_link_class_type PARAMS ((struct type *, value_ptr));
+
+static struct objfile *
+get_dynamics_objfile ()
+{
+ if (dynamics_objfile == NULL)
+ {
+ dynamics_objfile = allocate_objfile (NULL, 0, 0, 0);
+ }
+ return dynamics_objfile;
+}
+
+#if 1
+/* symtab contains classes read from the inferior. */
+
+static struct symtab *class_symtab = NULL;
+
+/* Maximum number of class in class_symtab before relocation is needed. */
+
+static int class_symtab_space;
+
+struct symtab *
+get_java_class_symtab ()
+{
+ if (class_symtab == NULL)
+ {
+ struct objfile *objfile = get_dynamics_objfile();
+ struct blockvector *bv;
+ struct block *bl;
+ class_symtab = allocate_symtab ("<java-classes>", objfile);
+ class_symtab->language = language_java;
+ bv = (struct blockvector *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector));
+ BLOCKVECTOR_NBLOCKS (bv) = 1;
+ BLOCKVECTOR (class_symtab) = bv;
+
+ /* Allocate dummy STATIC_BLOCK. */
+ bl = (struct block *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+ BLOCK_NSYMS (bl) = 0;
+ BLOCK_START (bl) = 0;
+ BLOCK_END (bl) = 0;
+ BLOCK_FUNCTION (bl) = NULL;
+ BLOCK_SUPERBLOCK (bl) = NULL;
+ BLOCK_GCC_COMPILED (bl) = 0;
+ BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
+
+ /* Allocate GLOBAL_BLOCK. This has to be relocatable. */
+ class_symtab_space = 128;
+ bl = (struct block *)
+ mmalloc (objfile->md,
+ sizeof (struct block)
+ + ((class_symtab_space - 1) * sizeof (struct symbol *)));
+ *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+ class_symtab->free_ptr = (char *) bl;
+ }
+ return class_symtab;
+}
+
+static void
+add_class_symtab_symbol (sym)
+ struct symbol *sym;
+{
+ struct symtab *symtab = get_java_class_symtab ();
+ struct blockvector *bv = BLOCKVECTOR (symtab);
+ struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ if (BLOCK_NSYMS (bl) >= class_symtab_space)
+ {
+ /* Need to re-allocate. */
+ class_symtab_space *= 2;
+ bl = (struct block *)
+ mrealloc (symtab->objfile->md, bl,
+ sizeof (struct block)
+ + ((class_symtab_space - 1) * sizeof (struct symbol *)));
+ class_symtab->free_ptr = (char *) bl;
+ BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+ }
+
+ BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym;
+ BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1;
+}
+
+static struct symbol * add_class_symbol PARAMS ((struct type *type, CORE_ADDR addr));
+
+static struct symbol *
+add_class_symbol (type, addr)
+ struct type *type;
+ CORE_ADDR addr;
+{
+ struct symbol *sym;
+ sym = (struct symbol *)
+ obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_LANGUAGE (sym) = language_java;
+ SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ /* SYMBOL_VALUE (sym) = valu;*/
+ SYMBOL_TYPE (sym) = type;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ SYMBOL_VALUE_ADDRESS (sym) = addr;
+ return sym;
+}
+#endif
+
+struct type *
+java_lookup_class (name)
+ char *name;
+{
+ struct symbol *sym;
+ sym = lookup_symbol (name, expression_context_block, STRUCT_NAMESPACE,
+ (int *) 0, (struct symtab **) NULL);
+ if (sym != NULL)
+ return SYMBOL_TYPE (sym);
+#if 0
+ CORE_ADDR addr;
+ if (called from parser)
+ {
+ call lookup_class (or similar) in inferior;
+ if not found:
+ return NULL;
+ addr = found in inferior;
+ }
+ else
+ addr = 0;
+ struct type *type;
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack);
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+ TYPE ? = addr;
+ return type;
+#else
+ /* FIXME - should search inferior's symbol table. */
+ return NULL;
+#endif
+}
+
+/* Return a nul-terminated string (allocated on OBSTACK) for
+ a name given by NAME (which has type Utf8Const*). */
+
+char *
+get_java_utf8_name (obstack, name)
+ struct obstack *obstack;
+ value_ptr name;
+{
+ char *chrs;
+ value_ptr temp = name;
+ int name_length;
+ CORE_ADDR data_addr;
+ temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
+ name_length = (int) value_as_long (temp);
+ data_addr = VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)
+ + TYPE_LENGTH (VALUE_TYPE (temp));
+ chrs = obstack_alloc (obstack, name_length+1);
+ chrs [name_length] = '\0';
+ read_memory_section (data_addr, chrs, name_length, NULL);
+ return chrs;
+}
+
+value_ptr
+java_class_from_object (obj_val)
+ value_ptr obj_val;
+{
+ /* This is all rather inefficient, since the offsets of vtable and
+ class are fixed. FIXME */
+ value_ptr vtable_val;
+
+ if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0)
+ obj_val = value_at (get_java_object_type (),
+ value_as_pointer (obj_val), NULL);
+
+ vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
+ return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
+}
+
+/* Check if CLASS_IS_PRIMITIVE(value of clas): */
+int
+java_class_is_primitive (clas)
+ value_ptr clas;
+{
+ value_ptr vtable = value_struct_elt (&clas, NULL, "vtable", NULL, "struct");
+ CORE_ADDR i = value_as_pointer (vtable);
+ return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
+}
+
+/* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
+
+struct type *
+type_from_class (clas)
+ value_ptr clas;
+{
+ struct type *type;
+ char *name;
+ value_ptr temp;
+ struct objfile *objfile;
+ value_ptr utf8_name;
+ char *nptr;
+ CORE_ADDR addr;
+ struct block *bl;
+ int i;
+ int is_array = 0;
+
+ type = check_typedef (VALUE_TYPE (clas));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ if (value_logical_not (clas))
+ return NULL;
+ clas = value_ind (clas);
+ }
+ addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
+
+#if 0
+ get_java_class_symtab ();
+ bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
+ for (i = BLOCK_NSYMS (bl); --i >= 0; )
+ {
+ struct symbol *sym = BLOCK_SYM (bl, i);
+ if (SYMBOL_VALUE_ADDRESS (sym) == addr)
+ return SYMBOL_TYPE (sym);
+ }
+#endif
+
+ objfile = get_dynamics_objfile();
+ if (java_class_is_primitive (clas))
+ {
+ value_ptr sig;
+ temp = clas;
+ sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure");
+ return java_primitive_type (value_as_long (sig));
+ }
+
+ /* Get Class name. */
+ /* if clasloader non-null, prepend loader address. FIXME */
+ temp = clas;
+ utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+ name = get_java_utf8_name (&objfile->type_obstack, utf8_name);
+ for (nptr = name; *nptr != 0; nptr++)
+ {
+ if (*nptr == '/')
+ *nptr = '.';
+ }
+
+ type = java_lookup_class (name);
+ if (type != NULL)
+ return type;
+
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ INIT_CPLUS_SPECIFIC (type);
+
+ if (name[0] == '[')
+ {
+ char *signature = name;
+ int namelen = java_demangled_signature_length (signature);
+ if (namelen > strlen (name))
+ name = obstack_alloc (&objfile->type_obstack, namelen+1);
+ java_demangled_signature_copy (name, signature);
+ name[namelen] = '\0';
+ is_array = 1;
+ temp = clas;
+ /* Set array element type. */
+ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
+ VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
+ TYPE_TARGET_TYPE (type) = type_from_class (temp);
+ }
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_TAG_NAME (type) = name;
+
+ add_class_symtab_symbol (add_class_symbol (type, addr));
+ return java_link_class_type (type, clas);
+}
+
+/* Fill in class TYPE with data from the CLAS value. */
+
+struct type *
+java_link_class_type (type, clas)
+ struct type *type;
+ value_ptr clas;
+{
+ value_ptr temp;
+ char *unqualified_name;
+ char *name = TYPE_TAG_NAME (type);
+ int ninterfaces, nfields, nmethods;
+ int type_is_object = 0;
+ struct fn_field *fn_fields;
+ struct fn_fieldlist *fn_fieldlists;
+ value_ptr fields, field, method, methods;
+ int i, j;
+ struct objfile *objfile = get_dynamics_objfile();
+ struct type *tsuper;
+
+ unqualified_name = strrchr (name, '.');
+ if (unqualified_name == NULL)
+ unqualified_name = name;
+
+ temp = clas;
+ temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
+ if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+ {
+ tsuper = get_java_object_type ();
+ if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
+ tsuper = TYPE_TARGET_TYPE (tsuper);
+ type_is_object = 1;
+ }
+ else
+ tsuper = type_from_class (temp);
+
+#if 1
+ ninterfaces = 0;
+#else
+ temp = clas;
+ ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure"));
+#endif
+ TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
+ temp = clas;
+ nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure"));
+ nfields += TYPE_N_BASECLASSES (type);
+ nfields++; /* Add one for dummy "class" field. */
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+
+ memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
+ TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+ if (tsuper != NULL)
+ {
+ TYPE_BASECLASS (type, 0) = tsuper;
+ if (type_is_object)
+ SET_TYPE_FIELD_PRIVATE (type, 0);
+ }
+
+ i = strlen (name);
+ if (i > 2 && name[i-1] == ']' && tsuper != NULL)
+ {
+ /* FIXME */
+ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */
+ }
+ else
+ {
+ temp = clas;
+ temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure");
+ TYPE_LENGTH (type) = value_as_long (temp);
+ }
+
+ fields = NULL;
+ nfields--; /* First set up dummy "class" field. */
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
+ VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
+ TYPE_FIELD_NAME (type, nfields) = "class";
+ TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+
+ for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
+ {
+ int accflags;
+ int boffset;
+ if (fields == NULL)
+ {
+ temp = clas;
+ fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
+ field = value_ind (fields);
+ }
+ else
+ { /* Re-use field value for next field. */
+ VALUE_ADDRESS (field) += TYPE_LENGTH (VALUE_TYPE (field));
+ VALUE_LAZY (field) = 1;
+ }
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+ TYPE_FIELD_NAME (type, i) =
+ get_java_utf8_name (&objfile->type_obstack, temp);
+ temp = field;
+ accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
+ NULL, "structure"));
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "info", NULL, "structure");
+ boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
+ NULL, "structure"));
+ if (accflags & 0x0001) /* public access */
+ {
+ /* ??? */
+ }
+ if (accflags & 0x0002) /* private access */
+ {
+ SET_TYPE_FIELD_PRIVATE (type, i);
+ }
+ if (accflags & 0x0004) /* protected access */
+ {
+ SET_TYPE_FIELD_PROTECTED (type, i);
+ }
+ if (accflags & 0x0008) /* ACC_STATIC */
+ SET_FIELD_PHYSADDR(TYPE_FIELD(type, i), boffset);
+ else
+ TYPE_FIELD_BITPOS (type, i) = 8 * boffset;
+ if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */
+ {
+ TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */
+ }
+ else
+ {
+ struct type *ftype;
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
+ ftype = type_from_class (temp);
+ if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
+ ftype = lookup_pointer_type (ftype);
+ TYPE_FIELD_TYPE (type, i) = ftype;
+ }
+ }
+
+ temp = clas;
+ nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count",
+ NULL, "structure"));
+ TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
+ j = nmethods * sizeof (struct fn_field);
+ fn_fields = (struct fn_field*)
+ obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+ memset (fn_fields, 0, j);
+ fn_fieldlists = (struct fn_fieldlist*)
+ alloca (nmethods * sizeof (struct fn_fieldlist));
+
+ methods = NULL;
+ for (i = 0; i < nmethods; i++)
+ {
+ char *mname;
+ int k;
+ if (methods == NULL)
+ {
+ temp = clas;
+ methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
+ method = value_ind (methods);
+ }
+ else
+ { /* Re-use method value for next method. */
+ VALUE_ADDRESS (method) += TYPE_LENGTH (VALUE_TYPE (method));
+ VALUE_LAZY (method) = 1;
+ }
+
+ /* Get method name. */
+ temp = method;
+ temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+ mname = get_java_utf8_name (&objfile->type_obstack, temp);
+ if (strcmp (mname, "<init>") == 0)
+ mname = unqualified_name;
+
+ /* Check for an existing method with the same name.
+ * This makes building the fn_fieldslists an O(nmethods**2)
+ * operation. That could be using hashing, but I doubt it
+ * is worth it. Note that we do maintain the order of methods
+ * in the inferior's Method table (as long as that is grouped
+ * by method name), which I think is desirable. --PB */
+ for (k = 0, j = TYPE_NFN_FIELDS (type); ; )
+ {
+ if (--j < 0)
+ { /* No match - new method name. */
+ j = TYPE_NFN_FIELDS(type)++;
+ fn_fieldlists[j].name = mname;
+ fn_fieldlists[j].length = 1;
+ fn_fieldlists[j].fn_fields = &fn_fields[i];
+ k = i;
+ break;
+ }
+ if (strcmp (mname, fn_fieldlists[j].name) == 0)
+ { /* Found an existing method with the same name. */
+ int l;
+ if (mname != unqualified_name)
+ obstack_free (&objfile->type_obstack, mname);
+ mname = fn_fieldlists[j].name;
+ fn_fieldlists[j].length++;
+ k = i - k; /* Index of new slot. */
+ /* Shift intervening fn_fields (between k and i) down. */
+ for (l = i; l > k; l--) fn_fields[l] = fn_fields[l-1];
+ for (l = TYPE_NFN_FIELDS (type); --l > j; )
+ fn_fieldlists[l].fn_fields++;
+ break;
+ }
+ k += fn_fieldlists[j].length;
+ }
+ fn_fields[k].physname = "";
+ fn_fields[k].is_stub = 1;
+ fn_fields[k].type = make_function_type (java_void_type, NULL); /* FIXME*/
+ TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
+ }
+
+ j = TYPE_NFN_FIELDS(type) * sizeof (struct fn_fieldlist);
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist*)
+ obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+ memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
+
+ return type;
+}
+
+static struct type *java_object_type;
+
+struct type *
+get_java_object_type ()
+{
+ if (java_object_type == NULL)
+ {
+ struct symbol *sym;
+ sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_NAMESPACE,
+ (int *) 0, (struct symtab **) NULL);
+ if (sym == NULL)
+ error ("cannot find java.lang.Object");
+ java_object_type = SYMBOL_TYPE (sym);
+ }
+ return java_object_type;
+}
+
+int
+get_java_object_header_size ()
+{
+ struct type *objtype = get_java_object_type ();
+ if (objtype == NULL)
+ return (2 * TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ else
+ return TYPE_LENGTH (objtype);
+}
+
+int
+is_object_type (type)
+ struct type *type;
+{
+ CHECK_TYPEDEF (type);
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
+ char *name;
+ if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
+ return 0;
+ while (TYPE_N_BASECLASSES (ttype) > 0)
+ ttype = TYPE_BASECLASS (ttype, 0);
+ name = TYPE_TAG_NAME (ttype);
+ if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+ return 1;
+ name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0;
+ if (name != NULL && strcmp (name, "vtable") == 0)
+ {
+ if (java_object_type == NULL)
+ java_object_type = type;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+struct type *
+java_primitive_type (signature)
+ int signature;
+{
+ switch (signature)
+ {
+ case 'B': return java_byte_type;
+ case 'S': return java_short_type;
+ case 'I': return java_int_type;
+ case 'J': return java_long_type;
+ case 'Z': return java_boolean_type;
+ case 'C': return java_char_type;
+ case 'F': return java_float_type;
+ case 'D': return java_double_type;
+ case 'V': return java_void_type;
+ }
+ error ("unknown signature '%c' for primitive type", (char) signature);
+}
+
+/* If name[0 .. namelen-1] is the name of a primitive Java type,
+ return that type. Otherwise, return NULL. */
+
+struct type *
+java_primitive_type_from_name (name, namelen)
+ char* name;
+ int namelen;
+{
+ switch (name[0])
+ {
+ case 'b':
+ if (namelen == 4 && memcmp (name, "byte", 4) == 0)
+ return java_byte_type;
+ if (namelen == 7 && memcmp (name, "boolean", 7) == 0)
+ return java_boolean_type;
+ break;
+ case 'c':
+ if (namelen == 4 && memcmp (name, "char", 4) == 0)
+ return java_char_type;
+ case 'd':
+ if (namelen == 6 && memcmp (name, "double", 6) == 0)
+ return java_double_type;
+ break;
+ case 'f':
+ if (namelen == 5 && memcmp (name, "float", 5) == 0)
+ return java_float_type;
+ break;
+ case 'i':
+ if (namelen == 3 && memcmp (name, "int", 3) == 0)
+ return java_int_type;
+ break;
+ case 'l':
+ if (namelen == 4 && memcmp (name, "long", 4) == 0)
+ return java_long_type;
+ break;
+ case 's':
+ if (namelen == 5 && memcmp (name, "short", 5) == 0)
+ return java_short_type;
+ break;
+ case 'v':
+ if (namelen == 4 && memcmp (name, "void", 4) == 0)
+ return java_void_type;
+ break;
+ }
+ return NULL;
+}
+
+/* Return the length (in bytes) of demangled name of the Java type
+ signature string SIGNATURE. */
+
+static int
+java_demangled_signature_length (signature)
+ char *signature;
+{
+ int array = 0;
+ for (; *signature == '['; signature++)
+ array += 2; /* Two chars for "[]". */
+ switch (signature[0])
+ {
+ case 'L':
+ /* Subtract 2 for 'L' and ';'. */
+ return strlen (signature) - 2 + array;
+ default:
+ return strlen (TYPE_NAME (java_primitive_type (signature[0]))) + array;
+ }
+}
+
+/* Demangle the Java type signature SIGNATURE, leaving the result in RESULT. */
+
+static void
+java_demangled_signature_copy (result, signature)
+ char *result;
+ char *signature;
+{
+ int array = 0;
+ char *ptr;
+ int i;
+ while (*signature == '[')
+ {
+ array++;
+ signature++;
+ }
+ switch (signature[0])
+ {
+ case 'L':
+ /* Subtract 2 for 'L' and ';', but add 1 for final nul. */
+ signature++;
+ ptr = result;
+ for ( ; *signature != ';' && *signature != '\0'; signature++)
+ {
+ if (*signature == '/')
+ *ptr++ = '.';
+ else
+ *ptr++ = *signature;
+ }
+ break;
+ default:
+ ptr = TYPE_NAME (java_primitive_type (signature[0]));
+ i = strlen (ptr);
+ strcpy (result, ptr);
+ ptr = result + i;
+ break;
+ }
+ while (--array >= 0)
+ {
+ *ptr++ = '[';
+ *ptr++ = ']';
+ }
+}
+
+/* Return the demangled name of the Java type signature string SIGNATURE,
+ as a freshly allocated copy. */
+
+char *
+java_demangle_type_signature (signature)
+ char *signature;
+{
+ int length = java_demangled_signature_length (signature);
+ char *result = xmalloc (length + 1);
+ java_demangled_signature_copy (result, signature);
+ result[length] = '\0';
+ return result;
+}
+
+struct type *
+java_lookup_type (signature)
+ char *signature;
+{
+ switch (signature[0])
+ {
+ case 'L':
+ case '[':
+ error ("java_lookup_type not fully implemented");
+ default:
+ return java_primitive_type (signature[0]);
+ }
+}
+
+/* Return the type of TYPE followed by DIMS pairs of [ ].
+ If DIMS == 0, TYPE is returned. */
+
+struct type *
+java_array_type (type, dims)
+ struct type *type;
+ int dims;
+{
+ struct type *range_type;
+
+ while (dims-- > 0)
+ {
+ range_type = create_range_type (NULL, builtin_type_int, 0, 0);
+ /* FIXME This is bogus! Java arrays are not gdb arrays! */
+ type = create_array_type (NULL, type, range_type);
+ }
+
+ return type;
+}
+
+/* Create a Java string in the inferior from a (Utf8) literal. */
+
+value_ptr
+java_value_string (ptr, len)
+ char *ptr;
+ int len;
+{
+ error ("not implemented - java_value_string"); /* FIXME */
+}
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific. */
+
+static void
+java_emit_char (c, stream, quoter)
+ int c;
+ GDB_FILE *stream;
+ int quoter;
+{
+ switch (c)
+ {
+ case '\\':
+ case '\'':
+ fprintf_filtered (stream, "\\%c", c);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ default:
+ if (isprint (c))
+ fputc_filtered (c, stream);
+ else
+ fprintf_filtered (stream, "\\u%.4x", (unsigned int) c);
+ break;
+ }
+}
+
+static value_ptr
+evaluate_subexp_java (expect_type, exp, pos, noside)
+ struct type *expect_type;
+ register struct expression *exp;
+ register int *pos;
+ enum noside noside;
+{
+ int pc = *pos;
+ int i;
+ char *name;
+ enum exp_opcode op = exp->elts[*pos].opcode;
+ value_ptr arg1, arg2;
+ struct type *type;
+ switch (op)
+ {
+ case UNOP_IND:
+ if (noside == EVAL_SKIP)
+ goto standard;
+ (*pos)++;
+ arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
+ if (is_object_type (VALUE_TYPE (arg1)))
+ {
+ struct type *type;
+
+ type = type_from_class (java_class_from_object (arg1));
+ arg1 = value_cast (lookup_pointer_type (type), arg1);
+ }
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_ind (arg1);
+
+ case BINOP_SUBSCRIPT:
+ (*pos)++;
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
+
+ COERCE_REF (arg1);
+ type = check_typedef (VALUE_TYPE (arg1));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ name = TYPE_NAME (type);
+ if (name == NULL)
+ name = TYPE_TAG_NAME (type);
+ i = name == NULL ? 0 : strlen (name);
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && i > 2 && name [i - 1] == ']')
+ {
+ CORE_ADDR address;
+ long length, index;
+ struct type *el_type;
+ char buf4[4];
+
+ value_ptr clas = java_class_from_object(arg1);
+ value_ptr temp = clas;
+ /* Get CLASS_ELEMENT_TYPE of the array type. */
+ temp = value_struct_elt (&temp, NULL, "methods",
+ NULL, "structure");
+ VALUE_TYPE (temp) = VALUE_TYPE (clas);
+ el_type = type_from_class (temp);
+ if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
+ el_type = lookup_pointer_type (el_type);
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (el_type, VALUE_LVAL (arg1));
+ address = value_as_pointer (arg1);
+ address += JAVA_OBJECT_SIZE;
+ read_memory (address, buf4, 4);
+ length = (long) extract_signed_integer (buf4, 4);
+ index = (long) value_as_long (arg2);
+ if (index >= length || index < 0)
+ error ("array index (%ld) out of bounds (length: %ld)",
+ index, length);
+ address = (address + 4) + index * TYPE_LENGTH (el_type);
+ return value_at (el_type, address, NULL);
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
+ else
+ return value_subscript (arg1, arg2);
+ }
+ if (name)
+ error ("cannot subscript something of type `%s'", name);
+ else
+ error ("cannot subscript requested type");
+
+ case OP_STRING:
+ (*pos)++;
+ i = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return java_value_string (&exp->elts[pc + 2].string, i);
+
+ case STRUCTOP_STRUCT:
+ arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
+ /* Convert object field (such as TYPE.class) to reference. */
+ if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
+ arg1 = value_addr (arg1);
+ return arg1;
+ default:
+ break;
+ }
+standard:
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+ nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
+static struct type *
+java_create_fundamental_type (objfile, typeid)
+ struct objfile *objfile;
+ int typeid;
+{
+ switch (typeid)
+ {
+ case FT_VOID: return java_void_type;
+ case FT_BOOLEAN: return java_boolean_type;
+ case FT_CHAR: return java_char_type;
+ case FT_FLOAT: return java_float_type;
+ case FT_DBL_PREC_FLOAT: return java_double_type;
+ case FT_BYTE: case FT_SIGNED_CHAR: return java_byte_type;
+ case FT_SHORT: case FT_SIGNED_SHORT: return java_short_type;
+ case FT_INTEGER: case FT_SIGNED_INTEGER: return java_int_type;
+ case FT_LONG: case FT_SIGNED_LONG: return java_long_type;
+ }
+ return c_create_fundamental_type (objfile, typeid);
+}
+
+/* Table mapping opcodes into strings for printing operators
+ and precedences of the operators. */
+
+const struct op_print java_op_print_tab[] =
+ {
+ {",", BINOP_COMMA, PREC_COMMA, 0},
+ {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+ {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+ {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+ {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+ {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+ {"==", BINOP_EQUAL, PREC_EQUAL, 0},
+ {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {"<=", BINOP_LEQ, PREC_ORDER, 0},
+ {">=", BINOP_GEQ, PREC_ORDER, 0},
+ {">", BINOP_GTR, PREC_ORDER, 0},
+ {"<", BINOP_LESS, PREC_ORDER, 0},
+ {">>", BINOP_RSH, PREC_SHIFT, 0},
+ {"<<", BINOP_LSH, PREC_SHIFT, 0},
+#if 0
+ {">>>", BINOP_???, PREC_SHIFT, 0},
+#endif
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"%", BINOP_REM, PREC_MUL, 0},
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
+ {"*", UNOP_IND, PREC_PREFIX, 0},
+#if 0
+ {"instanceof", ???, ???, 0},
+#endif
+ {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
+ {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
+ {NULL, 0, 0, 0}
+};
+
+const struct language_defn java_language_defn = {
+ "java", /* Language name */
+ language_java,
+ c_builtin_types,
+ range_check_off,
+ type_check_off,
+ java_parse,
+ java_error,
+ evaluate_subexp_java,
+ c_printchar, /* Print a character constant */
+ c_printstr, /* Function to print string constant */
+ java_emit_char, /* Function to print a single character */
+ java_create_fundamental_type, /* Create fundamental type in this language */
+ java_print_type, /* Print a type using appropriate syntax */
+ java_val_print, /* Print a value using appropriate syntax */
+ java_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ java_op_print_tab, /* expression operators for printing */
+ 0, /* not c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+void
+_initialize_java_language ()
+{
+
+ java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
+ java_short_type = init_type (TYPE_CODE_INT, 2, 0, "short", NULL);
+ java_long_type = init_type (TYPE_CODE_INT, 8, 0, "long", NULL);
+ java_byte_type = init_type (TYPE_CODE_INT, 1, 0, "byte", NULL);
+ java_boolean_type= init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL);
+ java_char_type = init_type (TYPE_CODE_CHAR, 2, TYPE_FLAG_UNSIGNED, "char", NULL);
+ java_float_type = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL);
+ java_double_type = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL);
+ java_void_type = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
+
+ add_language (&java_language_defn);
+}
+
+/* Cleanup code that should be run on every "run".
+ We should use make_run_cleanup to have this be called.
+ But will that mess up values in value histry? FIXME */
+
+void java_rerun_cleanup ()
+{
+ if (class_symtab != NULL)
+ {
+ free_symtab (class_symtab); /* ??? */
+ class_symtab = NULL;
+ }
+ if (dynamics_objfile != NULL)
+ {
+ free_objfile (dynamics_objfile);
+ dynamics_objfile = NULL;
+ }
+
+ java_object_type = NULL;
+}
diff --git a/contrib/gdb/gdb/jv-lang.h b/contrib/gdb/gdb/jv-lang.h
new file mode 100644
index 0000000..44c4437
--- /dev/null
+++ b/contrib/gdb/gdb/jv-lang.h
@@ -0,0 +1,67 @@
+/* Java language support definitions for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern int
+java_parse PARAMS ((void)); /* Defined in jv-exp.y */
+
+extern void
+java_error PARAMS ((char *)); /* Defined in jv-exp.y */
+
+/* sizeof (struct Object) */
+#define JAVA_OBJECT_SIZE (get_java_object_header_size ())
+
+extern struct type *java_int_type;
+extern struct type *java_byte_type;
+extern struct type *java_short_type;
+extern struct type *java_long_type;
+extern struct type *java_boolean_type;
+extern struct type *java_char_type;
+extern struct type *java_float_type;
+extern struct type *java_double_type;
+extern struct type *java_void_type;
+
+extern int
+java_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *, int, int,
+ int, enum val_prettyprint));
+
+extern int
+java_value_print PARAMS ((struct value *, GDB_FILE *, int,
+ enum val_prettyprint));
+
+extern value_ptr java_class_from_object PARAMS ((value_ptr));
+
+extern struct type *type_from_class PARAMS ((struct value *));
+
+extern struct type *java_primitive_type PARAMS ((int signature));
+
+extern struct type *java_primitive_type_from_name PARAMS ((char*, int));
+
+extern struct type *java_array_type PARAMS ((struct type *, int));
+
+extern struct type *get_java_object_type PARAMS ((void));
+extern int get_java_object_header_size PARAMS ((void));
+
+extern struct type *java_lookup_class PARAMS((char *));
+
+extern int is_object_type PARAMS ((struct type*));
+
+extern void /* Defined in jv-typeprint.c */
+java_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
+
+extern char *java_demangle_type_signature PARAMS ((char *));
diff --git a/contrib/gdb/gdb/jv-typeprint.c b/contrib/gdb/gdb/jv-typeprint.c
new file mode 100644
index 0000000..59539a0
--- /dev/null
+++ b/contrib/gdb/gdb/jv-typeprint.c
@@ -0,0 +1,339 @@
+/* Support for printing Java types for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "demangle.h"
+#include "jv-lang.h"
+#include "gdb_string.h"
+#include "typeprint.h"
+
+static void
+java_type_print_derivation_info (stream, type)
+ GDB_FILE *stream;
+ struct type *type;
+{
+ char *name;
+ int i;
+ int n_bases;
+ int prev;
+
+ n_bases = TYPE_N_BASECLASSES (type);
+
+ for (i = 0, prev = 0; i < n_bases; i++)
+ {
+ int kind;
+
+ kind = BASETYPE_VIA_VIRTUAL(type, i) ? 'I' : 'E';
+
+ fputs_filtered (kind == prev ? ", "
+ : kind == 'I' ? " implements "
+ : " extends ",
+ stream);
+ prev = kind;
+ name = type_name_no_tag (TYPE_BASECLASS (type, i));
+
+ fprintf_filtered (stream, "%s", name ? name : "(null)");
+ }
+
+ if (i > 0)
+ fputs_filtered (" ", stream);
+}
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element), or the description of a
+ structure or union.
+
+ SHOW positive means print details about the type (e.g. enum values),
+ and print structure elements passing SHOW - 1 for show.
+ SHOW negative means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but concise like
+ "struct {...}".
+ SHOW zero means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but not as concise like
+ "struct {int x; int y;}".
+
+ LEVEL is the number of spaces to indent by.
+ We increase it for some recursive calls. */
+
+void
+java_type_print_base (type, stream, show, level)
+ struct type *type;
+ GDB_FILE *stream;
+ int show;
+ int level;
+{
+ register int i;
+ register int len;
+ char *mangled_name;
+ char *demangled_name;
+ QUIT;
+
+ wrap_here (" ");
+
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+
+ if (show <= 0
+ && TYPE_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
+ { /* array type */
+ char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
+ fputs_filtered (name, stream);
+ free (name);
+ break;
+ }
+
+ if (show >= 0)
+ fprintf_filtered (stream, "class ");
+
+ if (TYPE_TAG_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
+
+ wrap_here (" ");
+
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ java_type_print_derivation_info (stream, type);
+
+ fprintf_filtered (stream, "{\n");
+ if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+ if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
+ fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
+ else
+ fprintfi_filtered (level + 4, stream, "<no data fields>\n");
+
+ /* If there is a base class for this type,
+ do not print the field that it occupies. */
+
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ {
+ QUIT;
+ /* Don't print out virtual function table. */
+ if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
+ && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
+ continue;
+
+ /* Don't print the dummy field "class". */
+ if (STREQN (TYPE_FIELD_NAME (type, i), "class", 5))
+ continue;
+
+ print_spaces_filtered (level + 4, stream);
+
+ if (HAVE_CPLUS_STRUCT (type))
+ if (TYPE_FIELD_PROTECTED (type, i))
+ fprintf_filtered (stream, "protected ");
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ fprintf_filtered (stream, "private ");
+ else
+ fprintf_filtered (stream, "public ");
+
+ if (TYPE_FIELD_STATIC (type, i))
+ fprintf_filtered (stream, "static ");
+
+ java_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4);
+
+ fprintf_filtered (stream, ";\n");
+ }
+
+ /* If there are both fields and methods, put a space between. */
+ len = TYPE_NFN_FIELDS (type);
+ if (len)
+ fprintf_filtered (stream, "\n");
+
+ /* Print out the methods */
+
+ for (i = 0; i < len; i++)
+ {
+ struct fn_field *f;
+ int j;
+ char *method_name;
+ char *name;
+ int is_constructor;
+ int n_overloads;
+
+ f = TYPE_FN_FIELDLIST1 (type, i);
+ n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ name = type_name_no_tag (type);
+ is_constructor = name && STREQ (method_name, name);
+
+ for (j = 0; j < n_overloads; j++)
+ {
+ char *physname;
+ int is_full_physname_constructor;
+
+ physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ is_full_physname_constructor =
+ ((physname[0] == '_' && physname[1] == '_'
+ && strchr ("0123456789Qt", physname[2]))
+ || STREQN (physname, "__ct__", 6)
+ || DESTRUCTOR_PREFIX_P (physname)
+ || STREQN (physname, "__dt__", 6));
+
+ QUIT;
+
+ print_spaces_filtered (level + 4, stream);
+
+ if (TYPE_FN_FIELD_PROTECTED (f, j))
+ fprintf_filtered (stream, "protected ");
+ else if (TYPE_FN_FIELD_PRIVATE (f, j))
+ fprintf_filtered (stream, "private ");
+ else if (TYPE_FN_FIELD_PUBLIC (f, j))
+ fprintf_filtered (stream, "public ");
+
+ if (TYPE_FN_FIELD_ABSTRACT (f, j))
+ fprintf_filtered (stream, "abstract ");
+ if (TYPE_FN_FIELD_STATIC (f, j))
+ fprintf_filtered (stream, "static ");
+ if (TYPE_FN_FIELD_FINAL (f, j))
+ fprintf_filtered (stream, "final ");
+ if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
+ fprintf_filtered (stream, "synchronized ");
+ if (TYPE_FN_FIELD_NATIVE (f, j))
+ fprintf_filtered (stream, "native ");
+
+ if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
+ {
+ /* Keep GDB from crashing here. */
+ fprintf_filtered (stream, "<undefined type> %s;\n",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
+ break;
+ }
+ else if (!is_constructor && !is_full_physname_constructor)
+ {
+ type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
+ "", stream, -1);
+ fputs_filtered (" ", stream);
+ }
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ /* Build something we can demangle. */
+ mangled_name = gdb_mangle_name (type, i, j);
+ else
+ mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ demangled_name =
+ cplus_demangle (mangled_name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+
+ if (demangled_name == NULL)
+ demangled_name = strdup (mangled_name);
+
+ {
+ char *demangled_no_class;
+ char *ptr;
+
+ ptr = demangled_no_class = demangled_name;
+
+ while (1)
+ {
+ char c;
+
+ c = *ptr++;
+
+ if (c == 0 || c == '(')
+ break;
+ if (c == '.')
+ demangled_no_class = ptr;
+ }
+
+ fputs_filtered (demangled_no_class, stream);
+ free (demangled_name);
+ }
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ free (mangled_name);
+
+ fprintf_filtered (stream, ";\n");
+ }
+ }
+
+ fprintfi_filtered (level, stream, "}");
+ }
+ break;
+
+ default:
+ c_type_print_base (type, stream, show, level);
+ }
+}
+
+/* LEVEL is the depth to indent lines by. */
+
+void
+java_print_type (type, varstring, stream, show, level)
+ struct type *type;
+ char *varstring;
+ GDB_FILE *stream;
+ int show;
+ int level;
+{
+ int demangled_args;
+
+ java_type_print_base (type, stream, show, level);
+
+ if (varstring != NULL && *varstring != '\0')
+ {
+ fputs_filtered (" ", stream);
+ fputs_filtered (varstring, stream);
+ }
+
+ /* For demangled function names, we have the arglist as part of the name,
+ so don't print an additional pair of ()'s */
+
+ demangled_args = strchr(varstring, '(') != NULL;
+ c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
+}
diff --git a/contrib/gdb/gdb/jv-valprint.c b/contrib/gdb/gdb/jv-valprint.c
new file mode 100644
index 0000000..6bfae7e
--- /dev/null
+++ b/contrib/gdb/gdb/jv-valprint.c
@@ -0,0 +1,526 @@
+/* Support for printing Java values for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "c-lang.h"
+
+int
+java_value_print (val, stream, format, pretty)
+ value_ptr val;
+ GDB_FILE *stream;
+ int format;
+ enum val_prettyprint pretty;
+{
+ struct type *type;
+ CORE_ADDR address;
+ int i;
+ char *name;
+
+ type = VALUE_TYPE (val);
+ address = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
+
+ if (is_object_type (type))
+ {
+ CORE_ADDR obj_addr;
+
+ /* Get the run-time type, and cast the object into that */
+
+ obj_addr = unpack_pointer (type, VALUE_CONTENTS (val));
+
+ if (obj_addr != 0)
+ {
+ type = type_from_class (java_class_from_object (val));
+ type = lookup_pointer_type (type);
+
+ val = value_at (type, address, NULL);
+ }
+ }
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR && ! value_logical_not (val))
+ type_print (TYPE_TARGET_TYPE (type), "", stream, -1);
+
+ name = TYPE_TAG_NAME (type);
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL
+ && (i = strlen (name), name[i-1] == ']'))
+ {
+ char buf4[4];
+ long length;
+ unsigned int things_printed = 0;
+ int reps;
+ struct type *el_type = java_primitive_type_from_name (name, i - 2);
+
+ i = 0;
+ read_memory (address + JAVA_OBJECT_SIZE, buf4, 4);
+
+ length = (long) extract_signed_integer (buf4, 4);
+ fprintf_filtered (stream, "{length: %ld", length);
+
+ if (el_type == NULL)
+ {
+ CORE_ADDR element, next_element;
+
+ address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */
+
+ while (i < length && things_printed < print_max)
+ {
+ char buf[TARGET_PTR_BIT / HOST_CHAR_BIT];
+
+ fputs_filtered (", ", stream);
+ wrap_here (n_spaces (2));
+
+ if (i > 0)
+ element = next_element;
+ else
+ {
+ read_memory (address, buf, sizeof(buf));
+ address += TARGET_PTR_BIT / HOST_CHAR_BIT;
+ element = extract_address (buf, sizeof(buf));
+ }
+
+ for (reps = 1; i + reps < length; reps++)
+ {
+ read_memory (address, buf, sizeof(buf));
+ address += TARGET_PTR_BIT / HOST_CHAR_BIT;
+ next_element = extract_address (buf, sizeof(buf));
+ if (next_element != element)
+ break;
+ }
+
+ if (reps == 1)
+ fprintf_filtered (stream, "%d: ", i);
+ else
+ fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
+
+ if (element == 0)
+ fprintf_filtered (stream, "null");
+ else
+ fprintf_filtered (stream, "@%x", element);
+
+ things_printed++;
+ i += reps;
+ }
+ }
+ else
+ {
+ value_ptr v = allocate_value (el_type);
+ value_ptr next_v = allocate_value (el_type);
+
+ VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4;
+ VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v);
+
+ while (i < length && things_printed < print_max)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (n_spaces (2));
+
+ if (i > 0)
+ {
+ value_ptr tmp;
+
+ tmp = next_v;
+ next_v = v;
+ v = tmp;
+ }
+ else
+ {
+ VALUE_LAZY (v) = 1;
+ VALUE_OFFSET (v) = 0;
+ }
+
+ VALUE_OFFSET (next_v) = VALUE_OFFSET (v);
+
+ for (reps = 1; i + reps < length; reps++)
+ {
+ VALUE_LAZY (next_v) = 1;
+ VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type);
+ if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v),
+ TYPE_LENGTH (el_type)) != 0)
+ break;
+ }
+
+ if (reps == 1)
+ fprintf_filtered (stream, "%d: ", i);
+ else
+ fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
+
+ val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 2, 1, pretty);
+
+ things_printed++;
+ i += reps;
+ }
+ }
+
+ if (i < length)
+ fprintf_filtered (stream, "...");
+
+ fprintf_filtered (stream, "}");
+
+ return 0;
+ }
+
+ /* If it's type String, print it */
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ && TYPE_TARGET_TYPE (type)
+ && TYPE_NAME (TYPE_TARGET_TYPE (type))
+ && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0
+ && (format == 0 || format == 's')
+ && address != 0)
+ {
+ value_ptr data_val;
+ CORE_ADDR data;
+ value_ptr boffset_val;
+ unsigned long boffset;
+ value_ptr count_val;
+ unsigned long count;
+ value_ptr mark;
+
+ mark = value_mark (); /* Remember start of new values */
+
+ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL);
+ data = value_as_pointer (data_val);
+
+ boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL);
+ boffset = value_as_pointer (boffset_val);
+
+ count_val = value_struct_elt (&val, NULL, "count", NULL, NULL);
+ count = value_as_pointer (count_val);
+
+ value_free_to_mark (mark); /* Release unnecessary values */
+
+ val_print_string (data + boffset, count, 2, stream);
+
+ return 0;
+ }
+
+ return (val_print (type, VALUE_CONTENTS (val), 0, address,
+ stream, format, 1, 0, pretty));
+}
+
+/* TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
+ same meanings as in cp_print_value and c_val_print.
+
+ DONT_PRINT is an array of baseclass types that we
+ should not print, or zero if called from top level. */
+
+void
+java_print_value_fields (type, valaddr, address, stream,
+ format, recurse, pretty)
+ struct type *type;
+ char *valaddr;
+ CORE_ADDR address;
+ GDB_FILE *stream;
+ int format;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ int i, len, n_baseclasses;
+
+ CHECK_TYPEDEF (type);
+
+ fprintf_filtered (stream, "{");
+ len = TYPE_NFIELDS (type);
+ n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ if (n_baseclasses > 0)
+ {
+ int i, n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ for (i = 0; i < n_baseclasses; i++)
+ {
+ int boffset;
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *basename = TYPE_NAME (baseclass);
+ char *base_valaddr;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ continue;
+
+ if (basename != NULL && strcmp (basename, "java.lang.Object") == 0)
+ continue;
+
+ boffset = 0;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * (recurse+1), stream);
+ }
+ fputs_filtered ("<", stream);
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+ fputs_filtered (basename ? basename : "", stream);
+ fputs_filtered ("> = ", stream);
+
+ base_valaddr = valaddr;
+
+ java_print_value_fields (baseclass, base_valaddr, address + boffset,
+ stream, format, recurse+1, pretty);
+ fputs_filtered (", ", stream);
+
+ flush_it:
+ ;
+ }
+
+ }
+
+ if (!len && n_baseclasses == 1)
+ fprintf_filtered (stream, "<No data fields>");
+ else
+ {
+ extern int inspect_it;
+ int fields_seen = 0;
+
+ for (i = n_baseclasses; i < len; i++)
+ {
+ /* If requested, skip printing of static fields. */
+ if (TYPE_FIELD_STATIC (type, i))
+ {
+ char *name = TYPE_FIELD_NAME (type, i);
+ if (!static_field_print)
+ continue;
+ if (name != NULL && strcmp (name, "class") == 0)
+ continue;
+ }
+ if (fields_seen)
+ fprintf_filtered (stream, ", ");
+ else if (n_baseclasses > 0)
+ {
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ fputs_filtered ("members of ", stream);
+ fputs_filtered (type_name_no_tag (type), stream);
+ fputs_filtered (": ", stream);
+ }
+ }
+ fields_seen = 1;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ if (inspect_it)
+ {
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
+ fputs_filtered ("\"( ptr \"", stream);
+ else
+ fputs_filtered ("\"( nodef \"", stream);
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\" \"", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\") \"", stream);
+ }
+ else
+ {
+ annotate_field_begin (TYPE_FIELD_TYPE (type, i));
+
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ annotate_field_name_end ();
+ fputs_filtered (": ", stream);
+ annotate_field_value ();
+ }
+
+ if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
+ {
+ value_ptr v;
+
+ /* Bitfields require special handling, especially due to byte
+ order problems. */
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+ unpack_field_as_long (type, valaddr, i));
+
+ val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
+ 0, stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ else
+ {
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else if (TYPE_FIELD_STATIC (type, i))
+ {
+ value_ptr v = value_static_field (type, i);
+ if (v == NULL)
+ fputs_filtered ("<optimized out>", stream);
+ else
+ {
+ struct type *t = check_typedef (VALUE_TYPE (v));
+ if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
+ v = value_addr (v);
+ val_print (VALUE_TYPE (v),
+ VALUE_CONTENTS (v), 0, VALUE_ADDRESS (v),
+ stream, format, 0, recurse+1, pretty);
+ }
+ }
+ else
+ {
+ val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
+ address + TYPE_FIELD_BITPOS (type, i) / 8,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ annotate_field_end ();
+ }
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ }
+ fprintf_filtered (stream, "}");
+}
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+int
+java_val_print (type, valaddr, embedded_offset, address, stream, format,
+ deref_ref, recurse, pretty)
+ struct type *type;
+ char *valaddr;
+ CORE_ADDR address;
+ GDB_FILE *stream;
+ int format;
+ int deref_ref;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ register unsigned int i = 0; /* Number of characters printed */
+ struct type *target_type;
+ CORE_ADDR addr;
+
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+#if 0
+ if (vtblprint && cp_is_vtbl_ptr_type(type))
+ {
+ /* Print the unmangled name if desired. */
+ /* Print vtable entry - we only get here if we ARE using
+ -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
+ print_address_demangle(extract_address (valaddr, TYPE_LENGTH (type)),
+ stream, demangle);
+ break;
+ }
+#endif
+ addr = unpack_pointer (type, valaddr);
+ if (addr == 0)
+ {
+ fputs_filtered ("null", stream);
+ return i;
+ }
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_CODE (target_type) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (addr, stream, demangle);
+ /* Return value is irrelevant except for string pointers. */
+ return (0);
+ }
+
+ if (addressprint && format != 's')
+ {
+ fputs_filtered ("@", stream);
+ print_longest (stream, 'x', 0, (ULONGEST) addr);
+ }
+
+ return i;
+
+ case TYPE_CODE_CHAR:
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ else
+ LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream);
+ break;
+
+ case TYPE_CODE_INT:
+ /* Can't just call c_val_print because that print bytes as C chars. */
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ else
+ val_print_type_code_int (type, valaddr, stream);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ java_print_value_fields (type, valaddr, address, stream, format,
+ recurse, pretty);
+ break;
+
+ default:
+ return c_val_print (type, valaddr, embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty);
+ }
+
+ return 0;
+}
diff --git a/contrib/gdb/gdb/language.c b/contrib/gdb/gdb/language.c
index 51ce181..225d423 100644
--- a/contrib/gdb/gdb/language.c
+++ b/contrib/gdb/gdb/language.c
@@ -30,11 +30,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <ctype.h>
#include "gdb_string.h"
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include "symtab.h"
#include "gdbtypes.h"
@@ -88,6 +83,28 @@ set_check PARAMS ((char *, int));
static void
set_type_range PARAMS ((void));
+static void
+unk_lang_emit_char PARAMS ((int c, GDB_FILE *stream, int quoter));
+
+static void
+unk_lang_printchar PARAMS ((int c, GDB_FILE *stream));
+
+static void
+unk_lang_printstr PARAMS ((GDB_FILE *stream, char *string, unsigned int length, int width, int force_ellipses));
+
+static struct type *
+unk_lang_create_fundamental_type PARAMS ((struct objfile *, int));
+
+static void
+unk_lang_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
+
+static int
+unk_lang_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *,
+ int, int, int, enum val_prettyprint));
+
+static int
+unk_lang_value_print PARAMS ((value_ptr, GDB_FILE *, int, enum val_prettyprint));
+
/* Forward declaration */
extern const struct language_defn unknown_language_defn;
extern char *warning_pre_print;
@@ -149,9 +166,9 @@ show_language_command (ignore, from_tty)
flang = get_frame_language();
if (flang != language_unknown &&
- language_mode == language_mode_manual &&
- current_language->la_language != flang)
- printf_filtered("%s\n",lang_frame_mismatch_warn);
+ language_mode == language_mode_manual &&
+ current_language->la_language != flang)
+ printf_filtered("%s\n",lang_frame_mismatch_warn);
}
/* Set command. Change the current working language. */
@@ -331,13 +348,16 @@ set_type_range()
set_range_str();
}
-/* Set current language to (enum language) LANG. */
+/* Set current language to (enum language) LANG. Returns previous language. */
-void
+enum language
set_language(lang)
enum language lang;
{
int i;
+ enum language prev_language;
+
+ prev_language = current_language->la_language;
for (i = 0; i < languages_size; i++) {
if (languages[i]->la_language == lang) {
@@ -347,6 +367,8 @@ set_language(lang)
break;
}
}
+
+ return prev_language;
}
/* This page contains functions that update the global vars
@@ -812,7 +834,7 @@ lang_bool_type ()
if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
return type;
}
- /* ... else fall through ... */
+ return builtin_type_bool;
default:
return builtin_type_int;
}
@@ -1101,6 +1123,21 @@ range_error (va_alist)
/* This page contains miscellaneous functions */
+/* Return the language enum for a given language string. */
+
+enum language
+language_enum (str)
+ char *str;
+{
+ int i;
+
+ for (i = 0; i < languages_size; i++)
+ if (STREQ (languages[i]->la_name, str))
+ return languages[i]->la_language;
+
+ return language_unknown;
+}
+
/* Return the language struct for a given language enum. */
const struct language_defn *
@@ -1194,6 +1231,15 @@ unk_lang_error (msg)
}
static void
+unk_lang_emit_char (c, stream, quoter)
+ register int c;
+ GDB_FILE *stream;
+ int quoter;
+{
+ error ("internal error - unimplemented function unk_lang_emit_char called.");
+}
+
+static void
unk_lang_printchar (c, stream)
register int c;
GDB_FILE *stream;
@@ -1202,10 +1248,11 @@ unk_lang_printchar (c, stream)
}
static void
-unk_lang_printstr (stream, string, length, force_ellipses)
+unk_lang_printstr (stream, string, length, width, force_ellipses)
GDB_FILE *stream;
char *string;
unsigned int length;
+ int width;
int force_ellipses;
{
error ("internal error - unimplemented function unk_lang_printstr called.");
@@ -1219,7 +1266,7 @@ unk_lang_create_fundamental_type (objfile, typeid)
error ("internal error - unimplemented function unk_lang_create_fundamental_type called.");
}
-void
+static void
unk_lang_print_type (type, varstring, stream, show, level)
struct type *type;
char *varstring;
@@ -1230,11 +1277,12 @@ unk_lang_print_type (type, varstring, stream, show, level)
error ("internal error - unimplemented function unk_lang_print_type called.");
}
-int
-unk_lang_val_print (type, valaddr, address, stream, format, deref_ref,
+static int
+unk_lang_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
recurse, pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -1245,7 +1293,7 @@ unk_lang_val_print (type, valaddr, address, stream, format, deref_ref,
error ("internal error - unimplemented function unk_lang_val_print called.");
}
-int
+static int
unk_lang_value_print (val, stream, format, pretty)
value_ptr val;
GDB_FILE *stream;
@@ -1255,7 +1303,7 @@ unk_lang_value_print (val, stream, format, pretty)
error ("internal error - unimplemented function unk_lang_value_print called.");
}
-static struct type ** const (unknown_builtin_types[]) = { 0 };
+static struct type ** CONST_PTR (unknown_builtin_types[]) = { 0 };
static const struct op_print unk_op_print_tab[] = {
{NULL, OP_NULL, PREC_NULL, 0}
};
@@ -1271,6 +1319,7 @@ const struct language_defn unknown_language_defn = {
evaluate_subexp_standard,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
+ unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type, /* Print a type using appropriate syntax */
unk_lang_val_print, /* Print a value using appropriate syntax */
@@ -1298,6 +1347,7 @@ const struct language_defn auto_language_defn = {
evaluate_subexp_standard,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
+ unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type, /* Print a type using appropriate syntax */
unk_lang_val_print, /* Print a value using appropriate syntax */
@@ -1324,6 +1374,7 @@ const struct language_defn local_language_defn = {
evaluate_subexp_standard,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
+ unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type, /* Print a type using appropriate syntax */
unk_lang_val_print, /* Print a value using appropriate syntax */
diff --git a/contrib/gdb/gdb/language.h b/contrib/gdb/gdb/language.h
index 941943b..e336869 100644
--- a/contrib/gdb/gdb/language.h
+++ b/contrib/gdb/gdb/language.h
@@ -134,12 +134,16 @@ struct language_defn
void (*la_error) PARAMS ((char *));
/* Evaluate an expression. */
- struct value * (*evaluate_exp) PARAMS ((struct type*, struct expression *,
+ struct value * (*evaluate_exp) PARAMS ((struct type *, struct expression *,
int *, enum noside));
- void (*la_printchar) PARAMS ((int, GDB_FILE *));
+ void (*la_printchar) PARAMS ((int ch, GDB_FILE *stream));
- void (*la_printstr) PARAMS ((GDB_FILE *, char *, unsigned int, int));
+ void (*la_printstr) PARAMS ((GDB_FILE *stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses));
+
+ void (*la_emitchar) PARAMS ((int ch, GDB_FILE *stream, int quoter));
struct type *(*la_fund_type) PARAMS ((struct objfile *, int));
@@ -149,7 +153,7 @@ struct language_defn
/* Print a value using syntax appropriate for this language. */
- int (*la_val_print) PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *,
+ int (*la_val_print) PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *,
int, int, int, enum val_prettyprint));
/* Print a top-level value using syntax appropriate for this language. */
@@ -245,7 +249,7 @@ extern enum language_mode
extern void
language_info PARAMS ((int));
-extern void
+extern enum language
set_language PARAMS ((enum language));
@@ -260,8 +264,8 @@ set_language PARAMS ((enum language));
#define LA_PRINT_TYPE(type,varstring,stream,show,level) \
(current_language->la_print_type(type,varstring,stream,show,level))
-#define LA_VAL_PRINT(type,valaddr,addr,stream,fmt,deref,recurse,pretty) \
- (current_language->la_val_print(type,valaddr,addr,stream,fmt,deref, \
+#define LA_VAL_PRINT(type,valaddr,offset,addr,stream,fmt,deref,recurse,pretty) \
+ (current_language->la_val_print(type,valaddr,offset,addr,stream,fmt,deref, \
recurse,pretty))
#define LA_VALUE_PRINT(val,stream,fmt,pretty) \
(current_language->la_value_print(val,stream,fmt,pretty))
@@ -309,8 +313,10 @@ set_language PARAMS ((enum language));
#define LA_PRINT_CHAR(ch, stream) \
(current_language->la_printchar(ch, stream))
-#define LA_PRINT_STRING(stream, string, length, force_ellipses) \
- (current_language->la_printstr(stream, string, length, force_ellipses))
+#define LA_PRINT_STRING(stream, string, length, width, force_ellipses) \
+ (current_language->la_printstr(stream, string, length, width, force_ellipses))
+#define LA_EMIT_CHAR(ch, stream, quoter) \
+ (current_language->la_emitchar(ch, stream, quoter))
/* Test a character to decide whether it can be printed in literal form
or needs to be printed in another representation. For example,
@@ -318,8 +324,10 @@ set_language PARAMS ((enum language));
and the "other representation" is '\141'. The "other representation"
is program language dependent. */
-#define PRINT_LITERAL_FORM(c) \
- ((c)>=0x20 && ((c)<0x7F || (c)>=0xA0) && (!sevenbit_strings || (c)<0x80))
+#define PRINT_LITERAL_FORM(c) \
+ ((c) >= 0x20 \
+ && ((c) < 0x7F || (c) >= 0xA0) \
+ && (!sevenbit_strings || (c) < 0x80))
/* Return a format string for printf that will print a number in one of
the local (language-specific) formats. Result is static and is
diff --git a/contrib/gdb/gdb/lynx-nat.c b/contrib/gdb/gdb/lynx-nat.c
index 78716e0..f006aa4 100644
--- a/contrib/gdb/gdb/lynx-nat.c
+++ b/contrib/gdb/gdb/lynx-nat.c
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/fpp.h>
static unsigned long registers_addr PARAMS ((int pid));
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR);
#define X(ENTRY)(offsetof(struct econtext, ENTRY))
@@ -655,13 +656,11 @@ child_wait (pid, ourstatus)
if (realsig == SIGNEWTHREAD)
{
- /* It's a new thread notification. Nothing to do here since
- the machine independent code in wait_for_inferior will
- add the thread to the thread list and restart the thread
- when pid != inferior_pid and pid is not in the thread
- list. We don't even want to much with realsig -- the
- code in wait_for_inferior expects SIGTRAP. */
- ;
+ /* It's a new thread notification. We don't want to much with
+ realsig -- the code in wait_for_inferior expects SIGTRAP. */
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ ourstatus->value.sig = TARGET_SIGNAL_0;
+ return pid;
}
else
error ("Signal for unknown thread was not SIGNEWTHREAD");
@@ -802,7 +801,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned reg_addr;
+ CORE_ADDR reg_addr;
{
struct st_entry s;
unsigned int regno;
diff --git a/contrib/gdb/gdb/m2-exp.tab.c b/contrib/gdb/gdb/m2-exp.tab.c
index 0ad36c3..2bfc681 100644
--- a/contrib/gdb/gdb/m2-exp.tab.c
+++ b/contrib/gdb/gdb/m2-exp.tab.c
@@ -1,5 +1,6 @@
-/* A Bison parser, made from ./m2-exp.y with Bison version GNU Bison version 1.24
+/* A Bison parser, made from m2-exp.y
+ by GNU Bison version 1.25
*/
#define YYBISON 1 /* Identify Bison output. */
@@ -51,7 +52,7 @@
#define NOT 302
#define QID 303
-#line 40 "./m2-exp.y"
+#line 40 "m2-exp.y"
#include "defs.h"
@@ -142,11 +143,11 @@ static struct block *modblock=0;
#endif
-#line 135 "./m2-exp.y"
+#line 135 "m2-exp.y"
typedef union
{
LONGEST lval;
- unsigned LONGEST ulval;
+ ULONGEST ulval;
DOUBLEST dval;
struct symbol *sym;
struct type *tval;
@@ -159,23 +160,6 @@ typedef union
struct type **tvec;
int *ivec;
} YYSTYPE;
-
-#ifndef YYLTYPE
-typedef
- struct yyltype
- {
- int timestamp;
- int first_line;
- int first_column;
- int last_line;
- int last_column;
- char *text;
- }
- yyltype;
-
-#define YYLTYPE yyltype
-#endif
-
#include <stdio.h>
#ifndef __cplusplus
@@ -283,6 +267,10 @@ static const short yyrline[] = { 0,
463, 467, 474, 480, 486, 493, 502, 510, 517, 520,
527, 534, 538, 547, 559, 567, 571, 587, 638
};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
static const char * const yytname[] = { "$","error","$undefined.","INT","HEX",
"ERROR","UINT","M2_TRUE","M2_FALSE","CHAR","FLOAT","STRING","NAME","BLOCKNAME",
@@ -292,7 +280,7 @@ static const char * const yytname[] = { "$","error","$undefined.","INT","HEX",
"'#'","IN","OROR","LOGICAL_AND","'&'","'@'","'+'","'-'","'*'","'/'","DIV","MOD",
"UNARY","'^'","DOT","'['","'('","NOT","'~'","QID","')'","'{'","'}'","']'","start",
"type_exp","exp","@1","not_exp","set","@2","@3","arglist","non_empty_arglist",
-"block","fblock","variable","type",""
+"block","fblock","variable","type", NULL
};
#endif
@@ -552,7 +540,7 @@ static const short yycheck[] = { 0,
55, -1, 57, 58, 59, 60
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/unsupported/share/bison.simple"
+#line 3 "/stone/jimb/main-98r2/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -705,16 +693,16 @@ int yyparse (void);
#endif
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
-#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
#ifndef __cplusplus
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (from, to, count)
- char *from;
+__yy_memcpy (to, from, count)
char *to;
+ char *from;
int count;
{
register char *f = from;
@@ -730,7 +718,7 @@ __yy_memcpy (from, to, count)
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (char *from, char *to, int count)
+__yy_memcpy (char *to, char *from, int count)
{
register char *f = from;
register char *t = to;
@@ -743,7 +731,7 @@ __yy_memcpy (char *from, char *to, int count)
#endif
#endif
-#line 192 "/usr/unsupported/share/bison.simple"
+#line 196 "/stone/jimb/main-98r2/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -752,14 +740,20 @@ __yy_memcpy (char *from, char *to, int count)
to the proper pointer type. */
#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#else
-#define YYPARSE_PARAM
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
#define YYPARSE_PARAM_DECL
-#endif
+#endif /* not YYPARSE_PARAM */
int
-yyparse(YYPARSE_PARAM)
+yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
register int yystate;
@@ -876,12 +870,12 @@ yynewstate:
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
@@ -1042,274 +1036,274 @@ yyreduce:
switch (yyn) {
case 3:
-#line 209 "./m2-exp.y"
+#line 209 "m2-exp.y"
{ write_exp_elt_opcode(OP_TYPE);
write_exp_elt_type(yyvsp[0].tval);
write_exp_elt_opcode(OP_TYPE);
;
break;}
case 4:
-#line 218 "./m2-exp.y"
+#line 218 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_IND); ;
break;}
case 5:
-#line 221 "./m2-exp.y"
+#line 221 "m2-exp.y"
{ number_sign = -1; ;
break;}
case 6:
-#line 223 "./m2-exp.y"
+#line 223 "m2-exp.y"
{ number_sign = 1;
write_exp_elt_opcode (UNOP_NEG); ;
break;}
case 7:
-#line 228 "./m2-exp.y"
+#line 228 "m2-exp.y"
{ write_exp_elt_opcode(UNOP_PLUS); ;
break;}
case 8:
-#line 232 "./m2-exp.y"
+#line 232 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); ;
break;}
case 11:
-#line 240 "./m2-exp.y"
+#line 240 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_CAP); ;
break;}
case 12:
-#line 244 "./m2-exp.y"
+#line 244 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_ORD); ;
break;}
case 13:
-#line 248 "./m2-exp.y"
+#line 248 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_ABS); ;
break;}
case 14:
-#line 252 "./m2-exp.y"
+#line 252 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_HIGH); ;
break;}
case 15:
-#line 256 "./m2-exp.y"
+#line 256 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_MIN);
write_exp_elt_type (yyvsp[-1].tval);
write_exp_elt_opcode (UNOP_MIN); ;
break;}
case 16:
-#line 262 "./m2-exp.y"
+#line 262 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_MAX);
write_exp_elt_type (yyvsp[-1].tval);
write_exp_elt_opcode (UNOP_MIN); ;
break;}
case 17:
-#line 268 "./m2-exp.y"
+#line 268 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_FLOAT); ;
break;}
case 18:
-#line 272 "./m2-exp.y"
+#line 272 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_VAL);
write_exp_elt_type (yyvsp[-3].tval);
write_exp_elt_opcode (BINOP_VAL); ;
break;}
case 19:
-#line 278 "./m2-exp.y"
+#line 278 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_CHR); ;
break;}
case 20:
-#line 282 "./m2-exp.y"
+#line 282 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_ODD); ;
break;}
case 21:
-#line 286 "./m2-exp.y"
+#line 286 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_TRUNC); ;
break;}
case 22:
-#line 290 "./m2-exp.y"
+#line 290 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_SIZEOF); ;
break;}
case 23:
-#line 295 "./m2-exp.y"
+#line 295 "m2-exp.y"
{ write_exp_elt_opcode(UNOP_PREINCREMENT); ;
break;}
case 24:
-#line 299 "./m2-exp.y"
+#line 299 "m2-exp.y"
{ write_exp_elt_opcode(BINOP_ASSIGN_MODIFY);
write_exp_elt_opcode(BINOP_ADD);
write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); ;
break;}
case 25:
-#line 305 "./m2-exp.y"
+#line 305 "m2-exp.y"
{ write_exp_elt_opcode(UNOP_PREDECREMENT);;
break;}
case 26:
-#line 309 "./m2-exp.y"
+#line 309 "m2-exp.y"
{ write_exp_elt_opcode(BINOP_ASSIGN_MODIFY);
write_exp_elt_opcode(BINOP_SUB);
write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); ;
break;}
case 27:
-#line 315 "./m2-exp.y"
+#line 315 "m2-exp.y"
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
write_exp_string (yyvsp[0].sval);
write_exp_elt_opcode (STRUCTOP_STRUCT); ;
break;}
case 29:
-#line 324 "./m2-exp.y"
+#line 324 "m2-exp.y"
{ error("Sets are not implemented.");;
break;}
case 30:
-#line 328 "./m2-exp.y"
+#line 328 "m2-exp.y"
{ error("Sets are not implemented.");;
break;}
case 31:
-#line 332 "./m2-exp.y"
+#line 332 "m2-exp.y"
{ error("Sets are not implemented.");;
break;}
case 32:
-#line 335 "./m2-exp.y"
+#line 335 "m2-exp.y"
{ error("Sets are not implemented.");;
break;}
case 33:
-#line 337 "./m2-exp.y"
+#line 337 "m2-exp.y"
{ error("Sets are not implemented.");;
break;}
case 34:
-#line 346 "./m2-exp.y"
+#line 346 "m2-exp.y"
{ start_arglist(); ;
break;}
case 35:
-#line 348 "./m2-exp.y"
+#line 348 "m2-exp.y"
{ write_exp_elt_opcode (MULTI_SUBSCRIPT);
write_exp_elt_longcst ((LONGEST) end_arglist());
write_exp_elt_opcode (MULTI_SUBSCRIPT); ;
break;}
case 36:
-#line 356 "./m2-exp.y"
+#line 356 "m2-exp.y"
{ start_arglist (); ;
break;}
case 37:
-#line 358 "./m2-exp.y"
+#line 358 "m2-exp.y"
{ write_exp_elt_opcode (OP_FUNCALL);
write_exp_elt_longcst ((LONGEST) end_arglist ());
write_exp_elt_opcode (OP_FUNCALL); ;
break;}
case 39:
-#line 367 "./m2-exp.y"
+#line 367 "m2-exp.y"
{ arglist_len = 1; ;
break;}
case 40:
-#line 371 "./m2-exp.y"
+#line 371 "m2-exp.y"
{ arglist_len++; ;
break;}
case 41:
-#line 376 "./m2-exp.y"
+#line 376 "m2-exp.y"
{ arglist_len = 1; ;
break;}
case 42:
-#line 381 "./m2-exp.y"
+#line 381 "m2-exp.y"
{ arglist_len++; ;
break;}
case 43:
-#line 386 "./m2-exp.y"
+#line 386 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_MEMVAL);
write_exp_elt_type (yyvsp[-2].tval);
write_exp_elt_opcode (UNOP_MEMVAL); ;
break;}
case 44:
-#line 392 "./m2-exp.y"
+#line 392 "m2-exp.y"
{ write_exp_elt_opcode (UNOP_CAST);
write_exp_elt_type (yyvsp[-3].tval);
write_exp_elt_opcode (UNOP_CAST); ;
break;}
case 45:
-#line 398 "./m2-exp.y"
+#line 398 "m2-exp.y"
{ ;
break;}
case 46:
-#line 406 "./m2-exp.y"
+#line 406 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_REPEAT); ;
break;}
case 47:
-#line 410 "./m2-exp.y"
+#line 410 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_MUL); ;
break;}
case 48:
-#line 414 "./m2-exp.y"
+#line 414 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_DIV); ;
break;}
case 49:
-#line 418 "./m2-exp.y"
+#line 418 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_INTDIV); ;
break;}
case 50:
-#line 422 "./m2-exp.y"
+#line 422 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_REM); ;
break;}
case 51:
-#line 426 "./m2-exp.y"
+#line 426 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_ADD); ;
break;}
case 52:
-#line 430 "./m2-exp.y"
+#line 430 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_SUB); ;
break;}
case 53:
-#line 434 "./m2-exp.y"
+#line 434 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_EQUAL); ;
break;}
case 54:
-#line 438 "./m2-exp.y"
+#line 438 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_NOTEQUAL); ;
break;}
case 55:
-#line 440 "./m2-exp.y"
+#line 440 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_NOTEQUAL); ;
break;}
case 56:
-#line 444 "./m2-exp.y"
+#line 444 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_LEQ); ;
break;}
case 57:
-#line 448 "./m2-exp.y"
+#line 448 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_GEQ); ;
break;}
case 58:
-#line 452 "./m2-exp.y"
+#line 452 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_LESS); ;
break;}
case 59:
-#line 456 "./m2-exp.y"
+#line 456 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_GTR); ;
break;}
case 60:
-#line 460 "./m2-exp.y"
+#line 460 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_LOGICAL_AND); ;
break;}
case 61:
-#line 464 "./m2-exp.y"
+#line 464 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_LOGICAL_OR); ;
break;}
case 62:
-#line 468 "./m2-exp.y"
+#line 468 "m2-exp.y"
{ write_exp_elt_opcode (BINOP_ASSIGN); ;
break;}
case 63:
-#line 475 "./m2-exp.y"
+#line 475 "m2-exp.y"
{ write_exp_elt_opcode (OP_BOOL);
write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval);
write_exp_elt_opcode (OP_BOOL); ;
break;}
case 64:
-#line 481 "./m2-exp.y"
+#line 481 "m2-exp.y"
{ write_exp_elt_opcode (OP_BOOL);
write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval);
write_exp_elt_opcode (OP_BOOL); ;
break;}
case 65:
-#line 487 "./m2-exp.y"
+#line 487 "m2-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_m2_int);
write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
write_exp_elt_opcode (OP_LONG); ;
break;}
case 66:
-#line 494 "./m2-exp.y"
+#line 494 "m2-exp.y"
{
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_m2_card);
@@ -1318,45 +1312,45 @@ case 66:
;
break;}
case 67:
-#line 503 "./m2-exp.y"
+#line 503 "m2-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_m2_char);
write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval);
write_exp_elt_opcode (OP_LONG); ;
break;}
case 68:
-#line 511 "./m2-exp.y"
+#line 511 "m2-exp.y"
{ write_exp_elt_opcode (OP_DOUBLE);
write_exp_elt_type (builtin_type_m2_real);
write_exp_elt_dblcst (yyvsp[0].dval);
write_exp_elt_opcode (OP_DOUBLE); ;
break;}
case 70:
-#line 521 "./m2-exp.y"
+#line 521 "m2-exp.y"
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval));
write_exp_elt_opcode (OP_LONG); ;
break;}
case 71:
-#line 528 "./m2-exp.y"
+#line 528 "m2-exp.y"
{ write_exp_elt_opcode (OP_M2_STRING);
write_exp_string (yyvsp[0].sval);
write_exp_elt_opcode (OP_M2_STRING); ;
break;}
case 72:
-#line 535 "./m2-exp.y"
+#line 535 "m2-exp.y"
{ yyval.bval = SYMBOL_BLOCK_VALUE(yyvsp[0].sym); ;
break;}
case 73:
-#line 539 "./m2-exp.y"
+#line 539 "m2-exp.y"
{ struct symbol *sym
= lookup_symbol (copy_name (yyvsp[0].sval), expression_context_block,
VAR_NAMESPACE, 0, NULL);
yyval.sym = sym;;
break;}
case 74:
-#line 548 "./m2-exp.y"
+#line 548 "m2-exp.y"
{ struct symbol *tem
= lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval,
VAR_NAMESPACE, 0, NULL);
@@ -1367,14 +1361,14 @@ case 74:
;
break;}
case 75:
-#line 560 "./m2-exp.y"
+#line 560 "m2-exp.y"
{ write_exp_elt_opcode(OP_VAR_VALUE);
write_exp_elt_block (NULL);
write_exp_elt_sym (yyvsp[0].sym);
write_exp_elt_opcode (OP_VAR_VALUE); ;
break;}
case 77:
-#line 572 "./m2-exp.y"
+#line 572 "m2-exp.y"
{ struct symbol *sym;
sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval,
VAR_NAMESPACE, 0, NULL);
@@ -1389,7 +1383,7 @@ case 77:
write_exp_elt_opcode (OP_VAR_VALUE); ;
break;}
case 78:
-#line 588 "./m2-exp.y"
+#line 588 "m2-exp.y"
{ struct symbol *sym;
int is_a_field_of_this;
@@ -1439,13 +1433,13 @@ case 78:
;
break;}
case 79:
-#line 639 "./m2-exp.y"
+#line 639 "m2-exp.y"
{ yyval.tval = lookup_typename (copy_name (yyvsp[0].sval),
expression_context_block, 0); ;
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 487 "/usr/unsupported/share/bison.simple"
+#line 498 "/stone/jimb/main-98r2/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1641,7 +1635,7 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 644 "./m2-exp.y"
+#line 644 "m2-exp.y"
#if 0 /* FIXME! */
diff --git a/contrib/gdb/gdb/m2-exp.y b/contrib/gdb/gdb/m2-exp.y
index 08a11ce..507e5bc 100644
--- a/contrib/gdb/gdb/m2-exp.y
+++ b/contrib/gdb/gdb/m2-exp.y
@@ -135,7 +135,7 @@ static struct block *modblock=0;
%union
{
LONGEST lval;
- unsigned LONGEST ulval;
+ ULONGEST ulval;
DOUBLEST dval;
struct symbol *sym;
struct type *tval;
diff --git a/contrib/gdb/gdb/m2-lang.c b/contrib/gdb/gdb/m2-lang.c
index 7502033..f5f38a9 100644
--- a/contrib/gdb/gdb/m2-lang.c
+++ b/contrib/gdb/gdb/m2-lang.c
@@ -26,6 +26,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "m2-lang.h"
#include "c-lang.h"
+static struct type *m2_create_fundamental_type PARAMS ((struct objfile *, int));
+static void m2_printstr PARAMS ((GDB_FILE *stream, char *string, unsigned int length, int width, int force_ellipses));
+static void m2_printchar PARAMS ((int, GDB_FILE *));
+static void m2_emit_char PARAMS ((int, GDB_FILE *, int));
+
/* Print the character C on STREAM as part of the contents of a literal
string whose delimiter is QUOTER. Note that that format for printing
characters and strings is language specific.
@@ -34,7 +39,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
*/
static void
-emit_char (c, stream, quoter)
+m2_emit_char (c, stream, quoter)
register int c;
GDB_FILE *stream;
int quoter;
@@ -91,7 +96,7 @@ m2_printchar (c, stream)
GDB_FILE *stream;
{
fputs_filtered ("'", stream);
- emit_char (c, stream, '\'');
+ LA_EMIT_CHAR (c, stream, '\'');
fputs_filtered ("'", stream);
}
@@ -103,10 +108,11 @@ m2_printchar (c, stream)
be replaced with a true Modula version. */
static void
-m2_printstr (stream, string, length, force_ellipses)
+m2_printstr (stream, string, length, width, force_ellipses)
GDB_FILE *stream;
char *string;
unsigned int length;
+ int width;
int force_ellipses;
{
register unsigned int i;
@@ -173,7 +179,7 @@ m2_printstr (stream, string, length, force_ellipses)
fputs_filtered ("\"", stream);
in_quotes = 1;
}
- emit_char (string[i], stream, '"');
+ LA_EMIT_CHAR (string[i], stream, '"');
++things_printed;
}
}
@@ -398,7 +404,7 @@ struct type *builtin_type_m2_card;
struct type *builtin_type_m2_real;
struct type *builtin_type_m2_bool;
-struct type ** const (m2_builtin_types[]) =
+struct type ** CONST_PTR (m2_builtin_types[]) =
{
&builtin_type_m2_char,
&builtin_type_m2_int,
@@ -419,6 +425,7 @@ const struct language_defn m2_language_defn = {
evaluate_subexp_standard,
m2_printchar, /* Print character constant */
m2_printstr, /* function to print string constant */
+ m2_emit_char, /* Function to print a single character */
m2_create_fundamental_type, /* Create fundamental type in this language */
m2_print_type, /* Print a type using appropriate syntax */
m2_val_print, /* Print a value using appropriate syntax */
diff --git a/contrib/gdb/gdb/m2-lang.h b/contrib/gdb/gdb/m2-lang.h
index 36bcfc3..dc627b7 100644
--- a/contrib/gdb/gdb/m2-lang.h
+++ b/contrib/gdb/gdb/m2-lang.h
@@ -27,5 +27,5 @@ extern void /* Defined in m2-typeprint.c */
m2_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
extern int
-m2_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
+m2_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *, int, int,
int, enum val_prettyprint));
diff --git a/contrib/gdb/gdb/m2-valprint.c b/contrib/gdb/gdb/m2-valprint.c
index 28ea3b1..12a2f27 100644
--- a/contrib/gdb/gdb/m2-valprint.c
+++ b/contrib/gdb/gdb/m2-valprint.c
@@ -22,14 +22,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "symtab.h"
#include "gdbtypes.h"
#include "valprint.h"
+#include "m2-lang.h"
/* FIXME: For now, just explicitly declare c_val_print and use it instead */
int
-m2_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
- pretty)
+m2_val_print (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -38,8 +40,8 @@ m2_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
enum val_prettyprint pretty;
{
extern int
- c_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
- int, enum val_prettyprint));
- return (c_val_print (type, valaddr, address, stream, format, deref_ref,
+ c_val_print PARAMS ((struct type *, char *, int, CORE_ADDR,
+ GDB_FILE *, int, int, int, enum val_prettyprint));
+ return (c_val_print (type, valaddr, 0, address, stream, format, deref_ref,
recurse, pretty));
}
diff --git a/contrib/gdb/gdb/m3-nat.c b/contrib/gdb/gdb/m3-nat.c
index 1ea1769..4614f65 100644
--- a/contrib/gdb/gdb/m3-nat.c
+++ b/contrib/gdb/gdb/m3-nat.c
@@ -1,7 +1,7 @@
/* Interface GDB to Mach 3.0 operating systems.
(Most) Mach 3.0 related routines live in this file.
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1996, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -260,7 +260,8 @@ int must_suspend_thread = 0;
struct cleanup *cleanup_step = NULL_CLEANUP;
-extern struct target_ops m3_ops;
+static struct target_ops m3_ops;
+
static void m3_kill_inferior ();
#if 0
@@ -1138,7 +1139,7 @@ switch_to_thread (new_thread)
/* Do this in gdb after doing FORK but before STARTUP_INFERIOR.
* Note that the registers are not yet valid in the inferior task.
*/
-static void
+static int
m3_trace_him (pid)
int pid;
{
@@ -1173,6 +1174,8 @@ m3_trace_him (pid)
/* One trap to exec the shell, one to exec the program being debugged. */
intercept_exec_calls (2);
+
+ return pid;
}
setup_exception_port ()
@@ -3923,7 +3926,7 @@ m3_create_inferior (exec_file, allargs, env)
char *allargs;
char **env;
{
- fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL);
+ fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, NULL);
/* We are at the first instruction we care about. */
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, 0, 0);
@@ -4524,55 +4527,58 @@ m3_stop ()
error ("to_stop target function not implemented");
}
-struct target_ops m3_ops = {
- "mach", /* to_shortname */
- "Mach child process", /* to_longname */
- "Mach child process (started by the \"run\" command).", /* to_doc */
- m3_open, /* to_open */
- 0, /* to_close */
- m3_attach, /* to_attach */
- m3_detach, /* to_detach */
- m3_resume, /* to_resume */
- mach_really_wait, /* to_wait */
- fetch_inferior_registers, /* to_fetch_registers */
- store_inferior_registers, /* to_store_registers */
- m3_prepare_to_store, /* to_prepare_to_store */
- m3_xfer_memory, /* to_xfer_memory */
- m3_files_info, /* to_files_info */
- memory_insert_breakpoint, /* to_insert_breakpoint */
- memory_remove_breakpoint, /* to_remove_breakpoint */
- terminal_init_inferior, /* to_terminal_init */
- terminal_inferior, /* to_terminal_inferior */
- terminal_ours_for_output, /* to_terminal_ours_for_output */
- terminal_ours, /* to_terminal_ours */
- child_terminal_info, /* to_terminal_info */
- m3_kill_inferior, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
-
- m3_create_inferior, /* to_create_inferior */
- m3_mourn_inferior, /* to_mourn_inferior */
- m3_can_run, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- m3_stop, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+static char *
+m3_pid_to_exec_file (pid)
+int pid;
+{
+ error ("to_pid_to_exec_file target function not implemented");
+ return NULL; /* To keep all compilers happy. */
+}
+
+static void
+init_m3_ops ()
+{
+ m3_ops.to_shortname = "mach";
+ m3_ops.to_longname = "Mach child process";
+ m3_ops.to_doc = "Mach child process (started by the \"run\" command).";
+ m3_ops.to_open = m3_open;
+ m3_ops.to_attach = m3_attach;
+ m3_ops.to_detach = m3_detach;
+ m3_ops.to_resume = m3_resume;
+ m3_ops.to_wait = mach_really__wait;
+ m3_ops.to_fetch_registers = fetch_inferior_registers;
+ m3_ops.to_store_registers = store_inferior_registers;
+ m3_ops.to_prepare_to_store = m3_prepare_to_store;
+ m3_ops.to_xfer_memory = m3_xfer_memory;
+ m3_ops.to_files_info = m3_files_info;
+ m3_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ m3_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ m3_ops.to_terminal_init = terminal_init_inferior;
+ m3_ops.to_terminal_inferior = terminal_inferior;
+ m3_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ m3_ops.to_terminal_ours = terminal_ours;
+ m3_ops.to_terminal_info = child_terminal_info;
+ m3_ops.to_kill = m3_kill_inferior;
+ m3_ops.to_create_inferior = m3_create_inferior;
+ m3_ops.to_mourn_inferior = m3_mourn_inferior;
+ m3_ops.to_can_run = m3_can_run;
+ m3_ops.to_stop = m3_stop;
+ m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file;
+ m3_ops.to_stratum = process_stratum;
+ m3_ops.to_has_all_memory = 1;
+ m3_ops.to_has_memory = 1;
+ m3_ops.to_has_stack = 1;
+ m3_ops.to_has_registers = 1;
+ m3_ops.to_has_execution = 1;
+ m3_ops.to_magic = OPS_MAGIC;
+}
void
_initialize_m3_nat ()
{
kern_return_t ret;
+ init_m3_ops ();
add_target (&m3_ops);
ret = mach_port_allocate(mach_task_self(),
diff --git a/contrib/gdb/gdb/m32r-rom.c b/contrib/gdb/gdb/m32r-rom.c
new file mode 100644
index 0000000..2be833e
--- /dev/null
+++ b/contrib/gdb/gdb/m32r-rom.c
@@ -0,0 +1,650 @@
+/* Remote debugging interface to m32r and mon2000 ROM monitors for GDB,
+ the GNU debugger.
+ Copyright 1996 Free Software Foundation, Inc.
+
+ Adapted by Michael Snyder of Cygnus Support.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This module defines communication with the Mitsubishi m32r monitor */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "symtab.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "symfile.h" /* for generic load */
+#include <time.h> /* for time_t */
+#include "gdb_string.h"
+#include "objfiles.h" /* for ALL_OBJFILES etc. */
+
+
+extern void report_transfer_performance PARAMS ((unsigned long, time_t, time_t));
+
+#ifndef _MSC_VER
+/*
+ * All this stuff just to get my host computer's IP address!
+ */
+#include <sys/types.h>
+#include <netdb.h> /* for hostent */
+#include <netinet/in.h> /* for struct in_addr */
+#if 1
+#include <arpa/inet.h> /* for inet_ntoa */
+#endif
+#endif
+
+static char *board_addr; /* user-settable IP address for M32R-EVA */
+static char *server_addr; /* user-settable IP address for gdb host */
+static char *download_path; /* user-settable path for SREC files */
+
+
+/*
+ * Function: m32r_load_1 (helper function)
+ */
+
+static void
+m32r_load_section (abfd, s, data_count)
+ bfd *abfd;
+ asection *s;
+ unsigned int *data_count;
+{
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_lma (abfd, s);
+ unsigned int buffer, i;
+
+ *data_count += section_size;
+
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_section_name (abfd, s), section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ monitor_printf ("%x mw\r" , section_base);
+ for (i = 0; i < section_size; i += 4)
+ {
+ QUIT;
+ monitor_expect (" -> ", NULL, 0);
+ bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
+ monitor_printf ("%x\n", buffer);
+ }
+ monitor_expect (" -> ", NULL, 0);
+ monitor_printf ("q\n");
+ monitor_expect_prompt (NULL, 0);
+ }
+}
+
+static int
+m32r_load_1 (dummy)
+ void *dummy;
+{
+ int data_count = 0;
+
+ bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count);
+ return data_count;
+}
+
+/*
+ * Function: m32r_load (an alternate way to load)
+ */
+
+static void
+m32r_load (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ extern int inferior_pid;
+ bfd *abfd;
+ asection *s;
+ unsigned int i, data_count = 0;
+ time_t start_time, end_time; /* for timing of download */
+
+ if (filename == NULL || filename[0] == 0)
+ filename = get_exec_file (1);
+
+ abfd = bfd_openr (filename, 0);
+ if (!abfd)
+ error ("Unable to open file %s\n", filename);
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ error ("File is not an object file\n");
+ start_time = time (NULL);
+#if 0
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_vma (abfd, s);
+ unsigned int buffer;
+
+ data_count += section_size;
+
+ printf_filtered ("Loading section %s, size 0x%lx vma ",
+ bfd_section_name (abfd, s), section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ monitor_printf ("%x mw\r" , section_base);
+ for (i = 0; i < section_size; i += 4)
+ {
+ monitor_expect (" -> ", NULL, 0);
+ bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
+ monitor_printf ("%x\n", buffer);
+ }
+ monitor_expect (" -> ", NULL, 0);
+ monitor_printf ("q\n");
+ monitor_expect_prompt (NULL, 0);
+ }
+#else
+ if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL)))
+ {
+ monitor_printf ("q\n");
+ return;
+ }
+#endif
+ end_time = time (NULL);
+ printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
+ report_transfer_performance (data_count, start_time, end_time);
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_pid = 0; /* No process now */
+
+ /* This is necessary because many things were based on the PC at the
+ time that we attached to the monitor, which is no longer valid
+ now that we have loaded new code (and just changed the PC).
+ Another way to do this might be to call normal_stop, except that
+ the stack may not be valid, and things would get horribly
+ confused... */
+
+ clear_symtab_users ();
+}
+
+static void
+m32r_load_gen (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ generic_load (filename, from_tty);
+}
+
+static void m32r_open PARAMS ((char *args, int from_tty));
+static void mon2000_open PARAMS ((char *args, int from_tty));
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. So, typing "info reg sp" becomes an "A7". */
+
+static char *m32r_regnames[] =
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",
+};
+
+static void
+m32r_supply_register (regname, regnamelen, val, vallen)
+ char *regname;
+ int regnamelen;
+ char *val;
+ int vallen;
+{
+ int regno;
+ int num_regs = sizeof(m32r_regnames) / sizeof(m32r_regnames[0]);
+
+ for (regno = 0; regno < num_regs; regno++)
+ if (strncmp(regname, m32r_regnames[regno], regnamelen) == 0)
+ break;
+
+ if (regno >= num_regs)
+ return; /* no match */
+
+ if (regno == ACCL_REGNUM)
+ { /* special handling for 64-bit acc reg */
+ monitor_supply_register (ACCH_REGNUM, val);
+ if (val = (char *) strchr(val, ':')) /* skip past ':' to get 2nd word */
+ monitor_supply_register (ACCL_REGNUM, val + 1);
+ }
+ else
+ {
+ monitor_supply_register (regno, val);
+ if (regno == PSW_REGNUM)
+ {
+ unsigned long psw = strtoul (val, NULL, 16);
+ char *zero = "00000000", *one = "00000001";
+
+#ifdef SM_REGNUM
+ /* Stack mode bit */
+ monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero);
+#endif
+#ifdef BSM_REGNUM
+ /* Backup stack mode bit */
+ monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero);
+#endif
+#ifdef IE_REGNUM
+ /* Interrupt enable bit */
+ monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero);
+#endif
+#ifdef BIE_REGNUM
+ /* Backup interrupt enable bit */
+ monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero);
+#endif
+#ifdef COND_REGNUM
+ /* Condition bit (carry etc.) */
+ monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero);
+#endif
+#ifdef CBR_REGNUM
+ monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero);
+#endif
+#ifdef BPC_REGNUM
+ monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */
+#endif
+#ifdef BCARRY_REGNUM
+ monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */
+#endif
+ }
+
+ if (regno == SPI_REGNUM || regno == SPU_REGNUM)
+ { /* special handling for stack pointer (spu or spi) */
+ unsigned long stackmode = read_register (PSW_REGNUM) & 0x80;
+
+ if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */
+ monitor_supply_register (SP_REGNUM, val);
+ else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */
+ monitor_supply_register (SP_REGNUM, val);
+ }
+ }
+}
+
+/* m32r RevC board monitor */
+
+static struct target_ops m32r_ops;
+
+static char *m32r_inits[] = {"\r", NULL};
+
+static struct monitor_ops m32r_cmds ;
+
+static void
+init_m32r_cmds(void)
+{
+ m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
+ m32r_cmds.init = m32r_inits; /* Init strings */
+ m32r_cmds.cont = "go\r"; /* continue command */
+ m32r_cmds.step = "step\r"; /* single step */
+ m32r_cmds.stop = NULL; /* interrupt command */
+ m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */
+ m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */
+ m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */
+ m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */
+ m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */
+ m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r";/* setmem.cmdw (addr, value) */
+ m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r";/* setmem.cmdl (addr, value) */
+ m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ m32r_cmds.setmem.term = NULL; /* setmem.term */
+ m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */
+ m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
+ m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
+ m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ m32r_cmds.getmem.term = NULL; /* getmem.term */
+ m32r_cmds.getmem.term_cmd = NULL ; /* getmem.term_cmd */
+ m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */
+ m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ m32r_cmds.setreg.term = NULL; /* setreg.term */
+ m32r_cmds.setreg.term_cmd = NULL ; /* setreg.term_cmd */
+ m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
+ m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */
+ m32r_cmds.getreg.term = NULL; /* getreg.term */
+ m32r_cmds.getreg.term_cmd = NULL ; /* getreg.term_cmd */
+ m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */
+ m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ m32r_cmds.supply_register = m32r_supply_register; /* supply_register */
+ m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ m32r_cmds.load = NULL; /* download command */
+ m32r_cmds.loadresp = NULL; /* load response */
+ m32r_cmds.prompt = "ok "; /* monitor command prompt */
+ m32r_cmds.line_term = "\r"; /* end-of-line terminator */
+ m32r_cmds.cmd_end = NULL; /* optional command terminator */
+ m32r_cmds.target = &m32r_ops; /* target operations */
+ m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ m32r_cmds.regnames = m32r_regnames; /* registers names */
+ m32r_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */
+} /* init_m32r_cmds */
+
+static void
+m32r_open(args, from_tty)
+ char *args;
+ int from_tty;
+{
+ monitor_open (args, &m32r_cmds, from_tty);
+}
+
+/* Mon2000 monitor (MSA2000 board) */
+
+static struct target_ops mon2000_ops;
+static struct monitor_ops mon2000_cmds;
+
+static void
+init_mon2000_cmds(void)
+{
+ mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
+ mon2000_cmds.init = m32r_inits; /* Init strings */
+ mon2000_cmds.cont = "go\r"; /* continue command */
+ mon2000_cmds.step = "step\r"; /* single step */
+ mon2000_cmds.stop = NULL; /* interrupt command */
+ mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */
+ mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */
+ mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */
+ mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */
+ mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */
+ mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r";/* setmem.cmdw (addr, value) */
+ mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r";/* setmem.cmdl (addr, value) */
+ mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ mon2000_cmds.setmem.term = NULL; /* setmem.term */
+ mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */
+ mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
+ mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
+ mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ mon2000_cmds.getmem.term = NULL; /* getmem.term */
+ mon2000_cmds.getmem.term_cmd = NULL ; /* getmem.term_cmd */
+ mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */
+ mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ mon2000_cmds.setreg.term = NULL; /* setreg.term */
+ mon2000_cmds.setreg.term_cmd = NULL ; /* setreg.term_cmd */
+ mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
+ mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */
+ mon2000_cmds.getreg.term = NULL; /* getreg.term */
+ mon2000_cmds.getreg.term_cmd = NULL ; /* getreg.term_cmd */
+ mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */
+ mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */
+ mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ mon2000_cmds.load = NULL; /* download command */
+ mon2000_cmds.loadresp = NULL; /* load response */
+ mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */
+ mon2000_cmds.line_term = "\r"; /* end-of-line terminator */
+ mon2000_cmds.cmd_end = NULL; /* optional command terminator */
+ mon2000_cmds.target = &mon2000_ops; /* target operations */
+ mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ mon2000_cmds.regnames = m32r_regnames; /* registers names */
+ mon2000_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */
+} /* init_mon2000_cmds */
+
+static void
+mon2000_open(args, from_tty)
+ char *args;
+ int from_tty;
+{
+ monitor_open (args, &mon2000_cmds, from_tty);
+}
+
+#ifndef _MSC_VER
+
+/* Function: set_board_address
+ Tell the BootOne monitor what it's ethernet IP address is. */
+
+static void
+m32r_set_board_address (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int resp_len;
+ char buf[1024];
+
+ if (args && *args)
+ {
+ monitor_printf ("ulip %s\n", args);
+ resp_len = monitor_expect_prompt (buf, sizeof(buf));
+ /* now parse the result for success */
+ }
+ else
+ error ("Requires argument (IP address for M32R-EVA board)");
+}
+
+/* Function: set_server_address
+ Tell the BootOne monitor what gdb's ethernet IP address is. */
+
+static void
+m32r_set_server_address (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int resp_len;
+ char buf[1024];
+
+ if (args && *args)
+ {
+ monitor_printf ("uhip %s\n", args);
+ resp_len = monitor_expect_prompt (buf, sizeof(buf));
+ /* now parse the result for success */
+ }
+ else
+ error ("Requires argument (IP address of GDB's host computer)");
+}
+
+/* Function: set_download_path
+ Tell the BootOne monitor the default path for downloadable SREC files. */
+
+static void
+m32r_set_download_path (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int resp_len;
+ char buf[1024];
+
+ if (args && *args)
+ {
+ monitor_printf ("up %s\n", args);
+ resp_len = monitor_expect_prompt (buf, sizeof(buf));
+ /* now parse the result for success */
+ }
+ else
+ error ("Requires argument (default path for downloadable SREC files)");
+}
+
+static void
+m32r_upload_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ bfd *abfd;
+ asection *s;
+ time_t start_time, end_time; /* for timing of download */
+ extern int inferior_pid;
+ int resp_len, data_count = 0;
+ char buf[1024];
+ struct hostent *hostent;
+ struct in_addr inet_addr;
+
+ /* first check to see if there's an ethernet port! */
+ monitor_printf ("ust\r");
+ resp_len = monitor_expect_prompt (buf, sizeof(buf));
+ if (!strchr (buf, ':'))
+ error ("No ethernet connection!");
+
+ if (board_addr == 0)
+ {
+ /* scan second colon in the output from the "ust" command */
+ char * myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1;
+
+ while (isspace(*myIPaddress))
+ myIPaddress++;
+
+ if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */
+ error ("Please use 'set board-address' to set the M32R-EVA board's IP address.");
+ if (strchr (myIPaddress, '('))
+ *(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */
+ board_addr = strsave (myIPaddress);
+ }
+ if (server_addr == 0)
+ {
+ buf[0] = 0;
+ gethostname (buf, sizeof(buf));
+ if (buf[0] != 0)
+ hostent = gethostbyname (buf);
+ if (hostent != 0)
+ {
+#if 1
+ memcpy (&inet_addr.s_addr, hostent->h_addr,
+ sizeof(inet_addr.s_addr));
+ server_addr = (char *) inet_ntoa (inet_addr);
+#else
+ server_addr = (char *) inet_ntoa (hostent->h_addr);
+#endif
+ }
+ if (server_addr == 0) /* failed? */
+ error ("Need to know gdb host computer's IP address (use 'set server-address')");
+ }
+
+ if (args == 0 || args[0] == 0) /* no args: upload the current file */
+ args = get_exec_file (1);
+
+ if (args[0] != '/' && download_path == 0)
+ if (current_directory)
+ download_path = strsave (current_directory);
+ else
+ error ("Need to know default download path (use 'set download-path')");
+
+ start_time = time (NULL);
+ monitor_printf ("uhip %s\r", server_addr);
+ resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */
+ monitor_printf ("ulip %s\r", board_addr);
+ resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */
+ if (args[0] != '/')
+ monitor_printf ("up %s\r", download_path); /* use default path */
+ else
+ monitor_printf ("up\r"); /* rooted filename/path */
+ resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */
+
+ if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec"))
+ monitor_printf ("ul %s\r", args);
+ else /* add ".srec" suffix */
+ monitor_printf ("ul %s.srec\r", args);
+ resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */
+
+ if (buf[0] == 0 || strstr(buf, "complete") == 0)
+ error("Upload file not found: %s.srec\nCheck IP addresses and download path.", args);
+ else
+ printf_filtered (" -- Ethernet load complete.\n");
+
+ end_time = time (NULL);
+ if (abfd = bfd_openr (args, 0))
+ { /* Download is done -- print section statistics */
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ }
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_lma (abfd, s);
+ unsigned int buffer;
+
+ data_count += section_size;
+
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_section_name (abfd, s), section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ }
+ /* Finally, make the PC point at the start address */
+ write_pc (bfd_get_start_address (abfd));
+ report_transfer_performance (data_count, start_time, end_time);
+ printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
+ }
+ inferior_pid = 0; /* No process now */
+
+ /* This is necessary because many things were based on the PC at the
+ time that we attached to the monitor, which is no longer valid
+ now that we have loaded new code (and just changed the PC).
+ Another way to do this might be to call normal_stop, except that
+ the stack may not be valid, and things would get horribly
+ confused... */
+
+ clear_symtab_users ();
+}
+
+#endif /* ! _MSC_VER */
+
+void
+_initialize_m32r_rom ()
+{
+ /* Initialize m32r RevC monitor target */
+ init_m32r_cmds () ;
+ init_monitor_ops (&m32r_ops);
+
+ m32r_ops.to_shortname = "m32r";
+ m32r_ops.to_longname = "m32r monitor";
+ m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */
+ m32r_ops.to_doc = "Debug via the m32r monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ m32r_ops.to_open = m32r_open;
+ add_target (&m32r_ops);
+
+ /* Initialize mon2000 monitor target */
+ init_mon2000_cmds ();
+ init_monitor_ops (&mon2000_ops);
+
+ mon2000_ops.to_shortname = "mon2000";
+ mon2000_ops.to_longname = "Mon2000 monitor";
+ mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */
+ mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ mon2000_ops.to_open = mon2000_open;
+ add_target (&mon2000_ops);
+
+#ifndef _MSC_VER
+ add_show_from_set
+ (add_set_cmd ("download-path", class_obscure, var_string,
+ (char *) &download_path,
+ "Set the default path for downloadable SREC files.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("board-address", class_obscure, var_string,
+ (char *) &board_addr,
+ "Set IP address for M32R-EVA target board.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("server-address", class_obscure, var_string,
+ (char *) &server_addr,
+ "Set IP address for download server (GDB's host computer).",
+ &setlist),
+ &showlist);
+
+ add_com ("upload", class_obscure, m32r_upload_command,
+ "Upload the srec file via the monitor's Ethernet upload capability.");
+
+ add_com ("tload", class_obscure, m32r_load, "test upload command.");
+#endif
+}
diff --git a/contrib/gdb/gdb/m32r-stub.c b/contrib/gdb/gdb/m32r-stub.c
new file mode 100644
index 0000000..60c828f
--- /dev/null
+++ b/contrib/gdb/gdb/m32r-stub.c
@@ -0,0 +1,1685 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for M32R by Michael Snyder, Cygnus Support.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ * The external function exceptionHandler() is
+ * used to attach a specific handler to a specific M32R vector number.
+ * It should use the same privilege level it runs at. It should
+ * install it as an interrupt gate so that interrupts are masked
+ * while the handler runs.
+ *
+ * Because gdb will sometimes write to the stack area to execute function
+ * calls, this program cannot rely on using the supervisor stack so it
+ * uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN
+ * AA..AA
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
+extern void exceptionHandler(); /* assign an exception handler */
+
+/*****************************************************************************
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets
+ */
+#define BUFMAX 400
+
+static char initialized; /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+
+static const unsigned char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 24
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames { R0, R1, R2, R3, R4, R5, R6, R7,
+ R8, R9, R10, R11, R12, R13, R14, R15,
+ PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH };
+
+enum SYS_calls {
+ SYS_null,
+ SYS_exit,
+ SYS_open,
+ SYS_close,
+ SYS_read,
+ SYS_write,
+ SYS_lseek,
+ SYS_unlink,
+ SYS_getpid,
+ SYS_kill,
+ SYS_fstat,
+ SYS_sbrk,
+ SYS_fork,
+ SYS_execve,
+ SYS_wait4,
+ SYS_link,
+ SYS_chdir,
+ SYS_stat,
+ SYS_utime,
+ SYS_chown,
+ SYS_chmod,
+ SYS_time,
+ SYS_pipe };
+
+static int registers[NUMREGS];
+
+#define STACKSIZE 8096
+static unsigned char remcomInBuffer[BUFMAX];
+static unsigned char remcomOutBuffer[BUFMAX];
+static int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+static unsigned int save_vectors[18]; /* previous exception vectors */
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an error. */
+static volatile int mem_err = 0;
+
+/* Store the vector number here (since GDB only gets the signal
+ number through the usual means, and that's not very specific). */
+int gdb_m32r_vector = -1;
+
+#if 0
+#include "syscall.h" /* for SYS_exit, SYS_write etc. */
+#endif
+
+/* Global entry points:
+ */
+
+extern void handle_exception(int);
+extern void set_debug_traps(void);
+extern void breakpoint(void);
+
+/* Local functions:
+ */
+
+static int computeSignal(int);
+static void putpacket(unsigned char *);
+static void getpacket(unsigned char *);
+
+static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int);
+static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int);
+static int hexToInt(unsigned char **, int *);
+static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int);
+static void stash_registers(void);
+static void restore_registers(void);
+static int prepare_to_step(int);
+static int finish_from_step(void);
+
+static void gdb_error(char *, char *);
+static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int);
+
+static unsigned char *strcpy (unsigned char *, const unsigned char *);
+static int strlen (const unsigned char *);
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+
+void
+handle_exception(int exceptionVector)
+{
+ int sigval;
+ int addr, length, i;
+ unsigned char * ptr;
+ unsigned char buf[16];
+ int binary;
+
+ if (!finish_from_step())
+ return; /* "false step": let the target continue */
+
+ gdb_m32r_vector = exceptionVector;
+
+ if (remote_debug)
+ {
+ mem2hex((unsigned char *) &exceptionVector, buf, 4, 0);
+ gdb_error("Handle exception %s, ", buf);
+ mem2hex((unsigned char *) &registers[PC], buf, 4, 0);
+ gdb_error("PC == 0x%s\n", buf);
+ }
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal( exceptionVector );
+
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[PC], ptr, 4, 0); /* PC */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R13 >> 4];
+ *ptr++ = hexchars[R13 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R13], ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R15 >> 4];
+ *ptr++ = hexchars[R15 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R15], ptr, 4, 0); /* SP */
+ *ptr++ = ';';
+ *ptr++ = 0;
+
+ if (exceptionVector == 0) /* simulated SYS call stuff */
+ {
+ mem2hex((unsigned char *) &registers[PC], buf, 4, 0);
+ switch (registers[R0]) {
+ case SYS_exit:
+ gdb_error("Target program has exited at %s\n", buf);
+ ptr = remcomOutBuffer;
+ *ptr++ = 'W';
+ sigval = registers[R1] & 0xff;
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+ *ptr++ = 0;
+ break;
+ case SYS_open:
+ gdb_error("Target attempts SYS_open call at %s\n", buf);
+ break;
+ case SYS_close:
+ gdb_error("Target attempts SYS_close call at %s\n", buf);
+ break;
+ case SYS_read:
+ gdb_error("Target attempts SYS_read call at %s\n", buf);
+ break;
+ case SYS_write:
+ if (registers[R1] == 1 || /* write to stdout */
+ registers[R1] == 2) /* write to stderr */
+ { /* (we can do that) */
+ registers[R0] = gdb_write((void *) registers[R2], registers[R3]);
+ return;
+ }
+ else
+ gdb_error("Target attempts SYS_write call at %s\n", buf);
+ break;
+ case SYS_lseek:
+ gdb_error("Target attempts SYS_lseek call at %s\n", buf);
+ break;
+ case SYS_unlink:
+ gdb_error("Target attempts SYS_unlink call at %s\n", buf);
+ break;
+ case SYS_getpid:
+ gdb_error("Target attempts SYS_getpid call at %s\n", buf);
+ break;
+ case SYS_kill:
+ gdb_error("Target attempts SYS_kill call at %s\n", buf);
+ break;
+ case SYS_fstat:
+ gdb_error("Target attempts SYS_fstat call at %s\n", buf);
+ break;
+ default:
+ gdb_error("Target attempts unknown SYS call at %s\n", buf);
+ break;
+ }
+ }
+
+ putpacket(remcomOutBuffer);
+
+ while (1==1) {
+ remcomOutBuffer[0] = 0;
+ getpacket(remcomInBuffer);
+ binary = 0;
+ switch (remcomInBuffer[0]) {
+ default: /* Unknown code. Return an empty reply message. */
+ break;
+ case 'R':
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &addr))
+ registers[PC] = addr;
+ strcpy(remcomOutBuffer, "OK");
+ break;
+ case '!':
+ strcpy(remcomOutBuffer, "OK");
+ break;
+ case 'X': /* XAA..AA,LLLL:<binary data>#cs */
+ binary = 1;
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ {
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ if (*(ptr++) == ':')
+ {
+ mem_err = 0;
+ if (binary)
+ bin2mem (ptr, (unsigned char *) addr, length, 1);
+ else
+ hex2mem(ptr, (unsigned char*) addr, length, 1);
+ if (mem_err) {
+ strcpy (remcomOutBuffer, "E03");
+ gdb_error ("memory fault", "");
+ } else {
+ strcpy(remcomOutBuffer,"OK");
+ }
+ ptr = 0;
+ }
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E02");
+ gdb_error("malformed write memory command: %s",
+ remcomInBuffer);
+ }
+ }
+ break;
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ {
+ ptr = 0;
+ mem_err = 0;
+ mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1);
+ if (mem_err) {
+ strcpy (remcomOutBuffer, "E03");
+ gdb_error ("memory fault", "");
+ }
+ }
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E01");
+ gdb_error("malformed read memory command: %s",
+ remcomInBuffer);
+ }
+ break;
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU registers */
+ mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0);
+ break;
+ case 'P': /* set the value of a single CPU register - return OK */
+ {
+ int regno;
+
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &regno) && *ptr++ == '=')
+ if (regno >= 0 && regno < NUMREGS)
+ {
+ int stackmode;
+
+ hex2mem (ptr, (unsigned char *) &registers[regno], 4, 0);
+ /*
+ * Since we just changed a single CPU register, let's
+ * make sure to keep the several stack pointers consistant.
+ */
+ stackmode = registers[PSW] & 0x80;
+ if (regno == R15) /* stack pointer changed */
+ { /* need to change SPI or SPU */
+ if (stackmode == 0)
+ registers[SPI] = registers[R15];
+ else
+ registers[SPU] = registers[R15];
+ }
+ else if (regno == SPU) /* "user" stack pointer changed */
+ {
+ if (stackmode != 0) /* stack in user mode: copy SP */
+ registers[R15] = registers[SPU];
+ }
+ else if (regno == SPI) /* "interrupt" stack pointer changed */
+ {
+ if (stackmode == 0) /* stack in interrupt mode: copy SP */
+ registers[R15] = registers[SPI];
+ }
+ else if (regno == PSW) /* stack mode may have changed! */
+ { /* force SP to either SPU or SPI */
+ if (stackmode == 0) /* stack in user mode */
+ registers[R15] = registers[SPI];
+ else /* stack in interrupt mode */
+ registers[R15] = registers[SPU];
+ }
+ strcpy (remcomOutBuffer, "OK");
+ break;
+ }
+ strcpy (remcomOutBuffer, "P01");
+ break;
+ }
+ case 'G': /* set the value of the CPU registers - return OK */
+ hex2mem(&remcomInBuffer[1], (unsigned char*) registers, NUMREGBYTES, 0);
+ strcpy(remcomOutBuffer,"OK");
+ break;
+ case 's': /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 'c': /* cAA..AA Continue from address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ registers[ PC ] = addr;
+
+ if (remcomInBuffer[0] == 's') /* single-stepping */
+ {
+ if (!prepare_to_step(0)) /* set up for single-step */
+ {
+ /* prepare_to_step has already emulated the target insn:
+ Send SIGTRAP to gdb, don't resume the target at all. */
+ ptr = remcomOutBuffer;
+ *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */
+ *ptr++ = '0';
+ *ptr++ = '5';
+
+ *ptr++ = hexchars[PC >> 4]; /* send PC */
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R13 >> 4]; /* send FP */
+ *ptr++ = hexchars[R13 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R13], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R15 >> 4]; /* send SP */
+ *ptr++ = hexchars[R15 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R15], ptr, 4, 0);
+ *ptr++ = ';';
+ *ptr++ = 0;
+
+ break;
+ }
+ }
+ else /* continuing, not single-stepping */
+ {
+ /* OK, about to do a "continue". First check to see if the
+ target pc is on an odd boundary (second instruction in the
+ word). If so, we must do a single-step first, because
+ ya can't jump or return back to an odd boundary! */
+ if ((registers[PC] & 2) != 0)
+ prepare_to_step(1);
+ }
+ return;
+
+ case 'D': /* Detach */
+ /* I am interpreting this to mean, release the board from control
+ by the remote stub. To do this, I am restoring the original
+ (or at least previous) exception vectors.
+ */
+ for (i = 0; i < 18; i++)
+ exceptionHandler (i, save_vectors[i]);
+ putpacket ("OK");
+ return; /* continue the inferior */
+
+ case 'k': /* kill the program */
+ continue;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+static int
+hex(ch)
+ unsigned char ch;
+{
+ if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
+ if ((ch >= '0') && (ch <= '9')) return (ch-'0');
+ if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
+ return (-1);
+}
+
+/* scan for the sequence $<data>#<checksum> */
+
+static void
+getpacket(buffer)
+ unsigned char * buffer;
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ unsigned char ch;
+
+ do {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar()) != '$');
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX) {
+ ch = getDebugChar();
+
+ if (ch == '#' && (count == 0 || buffer[count-1] != 0x7d))
+ break;
+
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#') {
+ xmitcsum = hex(getDebugChar()) << 4;
+ xmitcsum += hex(getDebugChar());
+ if (checksum != xmitcsum) {
+ if (remote_debug) {
+ unsigned char buf[16];
+
+ mem2hex((unsigned char *) &checksum, buf, 4, 0);
+ gdb_error("Bad checksum: my count = %s, ", buf);
+ mem2hex((unsigned char *) &xmitcsum, buf, 4, 0);
+ gdb_error("sent count = %s\n", buf);
+ gdb_error(" -- Bad buffer: \"%s\"\n", buffer);
+ }
+
+ putDebugChar('-'); /* failed checksum */
+ } else {
+ putDebugChar('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':') {
+ putDebugChar( buffer[0] );
+ putDebugChar( buffer[1] );
+ /* remove sequence chars from buffer */
+ count = strlen(buffer);
+ for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
+ }
+ }
+ }
+ } while (checksum != xmitcsum);
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket(buffer)
+ unsigned char *buffer;
+{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ /* $<packet info>#<checksum>. */
+ do {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch=buffer[count]) {
+ putDebugChar(ch);
+ checksum += ch;
+ count += 1;
+ }
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum % 16]);
+ } while (getDebugChar() != '+');
+}
+
+/* Address of a routine to RTE to if we get a memory fault. */
+
+static void (*volatile mem_fault_routine)() = 0;
+
+static void
+set_mem_err ()
+{
+ mem_err = 1;
+}
+
+/* Check the address for safe access ranges. As currently defined,
+ this routine will reject the "expansion bus" address range(s).
+ To make those ranges useable, someone must implement code to detect
+ whether there's anything connected to the expansion bus. */
+
+static int
+mem_safe (addr)
+ unsigned char *addr;
+{
+#define BAD_RANGE_ONE_START ((unsigned char *) 0x600000)
+#define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000)
+#define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000)
+#define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000)
+
+ if (addr < BAD_RANGE_ONE_START) return 1; /* safe */
+ if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */
+ if (addr < BAD_RANGE_TWO_START) return 1; /* safe */
+ if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */
+}
+
+/* These are separate functions so that they are so short and sweet
+ that the compiler won't save any registers (if there is a fault
+ to mem_fault, they won't get restored, so there better not be any
+ saved). */
+static int
+get_char (addr)
+ unsigned char *addr;
+{
+#if 1
+ if (mem_fault_routine && !mem_safe(addr))
+ {
+ mem_fault_routine ();
+ return 0;
+ }
+#endif
+ return *addr;
+}
+
+static void
+set_char (addr, val)
+ unsigned char *addr;
+ unsigned char val;
+{
+#if 1
+ if (mem_fault_routine && !mem_safe (addr))
+ {
+ mem_fault_routine ();
+ return;
+ }
+#endif
+ *addr = val;
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ Return a pointer to the last char put in buf (null).
+ If MAY_FAULT is non-zero, then we should set mem_err in response to
+ a fault; if zero treat a fault like any other fault in the stub. */
+
+static unsigned char *
+mem2hex(mem, buf, count, may_fault)
+ unsigned char* mem;
+ unsigned char* buf;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i=0;i<count;i++) {
+ ch = get_char (mem++);
+ if (may_fault && mem_err)
+ return (buf);
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ if (may_fault)
+ mem_fault_routine = 0;
+ return(buf);
+}
+
+/* Convert the hex array pointed to by buf into binary to be placed in mem.
+ Return a pointer to the character AFTER the last byte written. */
+
+static unsigned char*
+hex2mem(buf, mem, count, may_fault)
+ unsigned char* buf;
+ unsigned char* mem;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i=0;i<count;i++) {
+ ch = hex(*buf++) << 4;
+ ch = ch + hex(*buf++);
+ set_char (mem++, ch);
+ if (may_fault && mem_err)
+ return (mem);
+ }
+ if (may_fault)
+ mem_fault_routine = 0;
+ return(mem);
+}
+
+/* Convert the binary stream in BUF to memory.
+
+ Gdb will escape $, #, and the escape char (0x7d).
+ COUNT is the total number of bytes to write into
+ memory. */
+static unsigned char *
+bin2mem (buf, mem, count, may_fault)
+ unsigned char *buf;
+ unsigned char *mem;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i = 0; i < count; i++)
+ {
+ /* Check for any escaped characters. Be paranoid and
+ only unescape chars that should be escaped. */
+ if (*buf == 0x7d)
+ {
+ switch (*(buf+1))
+ {
+ case 0x3: /* # */
+ case 0x4: /* $ */
+ case 0x5d: /* escape char */
+ buf++;
+ *buf += 0x20;
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+ }
+
+ set_char (mem++, *buf++);
+
+ if (may_fault && mem_err)
+ return mem;
+ }
+
+ if (may_fault)
+ mem_fault_routine = 0;
+ return mem;
+}
+
+/* this function takes the m32r exception vector and attempts to
+ translate this number into a unix compatible signal value */
+
+static int
+computeSignal(exceptionVector)
+ int exceptionVector;
+{
+ int sigval;
+ switch (exceptionVector) {
+ case 0 : sigval = 23; break; /* I/O trap */
+ case 1 : sigval = 5; break; /* breakpoint */
+ case 2 : sigval = 5; break; /* breakpoint */
+ case 3 : sigval = 5; break; /* breakpoint */
+ case 4 : sigval = 5; break; /* breakpoint */
+ case 5 : sigval = 5; break; /* breakpoint */
+ case 6 : sigval = 5; break; /* breakpoint */
+ case 7 : sigval = 5; break; /* breakpoint */
+ case 8 : sigval = 5; break; /* breakpoint */
+ case 9 : sigval = 5; break; /* breakpoint */
+ case 10 : sigval = 5; break; /* breakpoint */
+ case 11 : sigval = 5; break; /* breakpoint */
+ case 12 : sigval = 5; break; /* breakpoint */
+ case 13 : sigval = 5; break; /* breakpoint */
+ case 14 : sigval = 5; break; /* breakpoint */
+ case 15 : sigval = 5; break; /* breakpoint */
+ case 16 : sigval = 10; break; /* BUS ERROR (alignment) */
+ case 17 : sigval = 2; break; /* INTerrupt */
+ default : sigval = 7; break; /* "software generated" */
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+static int
+hexToInt(ptr, intValue)
+ unsigned char **ptr;
+ int *intValue;
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue >=0)
+ {
+ *intValue = (*intValue <<4) | hexValue;
+ numChars ++;
+ }
+ else
+ break;
+ (*ptr)++;
+ }
+ return (numChars);
+}
+
+/*
+ Table of branch instructions:
+
+ 10B6 RTE return from trap or exception
+ 1FCr JMP jump
+ 1ECr JL jump and link
+ 7Fxx BRA branch
+ FFxxxxxx BRA branch (long)
+ B09rxxxx BNEZ branch not-equal-zero
+ Br1rxxxx BNE branch not-equal
+ 7Dxx BNC branch not-condition
+ FDxxxxxx BNC branch not-condition (long)
+ B0Arxxxx BLTZ branch less-than-zero
+ B0Crxxxx BLEZ branch less-equal-zero
+ 7Exx BL branch and link
+ FExxxxxx BL branch and link (long)
+ B0Drxxxx BGTZ branch greater-than-zero
+ B0Brxxxx BGEZ branch greater-equal-zero
+ B08rxxxx BEQZ branch equal-zero
+ Br0rxxxx BEQ branch equal
+ 7Cxx BC branch condition
+ FCxxxxxx BC branch condition (long)
+ */
+
+static int
+isShortBranch(instr)
+ unsigned char *instr;
+{
+ unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */
+
+ if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */
+ return 1; /* return from trap or exception */
+
+ if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */
+ if ((instr[1] & 0xF0) == 0xC0)
+ return 2; /* jump thru a register */
+
+ if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */
+ instr0 == 0x7E || instr0 == 0x7F)
+ return 3; /* eight bit PC offset */
+
+ return 0;
+}
+
+static int
+isLongBranch(instr)
+ unsigned char *instr;
+{
+ if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */
+ instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */
+ return 4;
+ if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */
+ {
+ if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */
+ (instr[1] & 0xF0) == 0x10)
+ return 5;
+ if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
+ if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
+ (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
+ (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
+ return 6;
+ }
+ return 0;
+}
+
+/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero,
+ then it's a 2-byte instruction, else it's a 4-byte instruction. */
+
+#define INSTRUCTION_SIZE(addr) \
+ ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
+
+static int
+isBranch(instr)
+ unsigned char *instr;
+{
+ if (INSTRUCTION_SIZE(instr) == 2)
+ return isShortBranch(instr);
+ else
+ return isLongBranch(instr);
+}
+
+static int
+willBranch(instr, branchCode)
+ unsigned char *instr;
+{
+ switch (branchCode)
+ {
+ case 0: return 0; /* not a branch */
+ case 1: return 1; /* RTE */
+ case 2: return 1; /* JL or JMP */
+ case 3: /* BC, BNC, BL, BRA (short) */
+ case 4: /* BC, BNC, BL, BRA (long) */
+ switch (instr[0] & 0x0F)
+ {
+ case 0xC: /* Branch if Condition Register */
+ return (registers[CBR] != 0);
+ case 0xD: /* Branch if NOT Condition Register */
+ return (registers[CBR] == 0);
+ case 0xE: /* Branch and Link */
+ case 0xF: /* Branch (unconditional) */
+ return 1;
+ default: /* oops? */
+ return 0;
+ }
+ case 5: /* BNE, BEQ */
+ switch (instr[1] & 0xF0)
+ {
+ case 0x00: /* Branch if r1 equal to r2 */
+ return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
+ case 0x10: /* Branch if r1 NOT equal to r2 */
+ return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
+ default: /* oops? */
+ return 0;
+ }
+ case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
+ switch (instr[1] & 0xF0)
+ {
+ case 0x80: /* Branch if reg equal to zero */
+ return (registers[instr[1] & 0x0F] == 0);
+ case 0x90: /* Branch if reg NOT equal to zero */
+ return (registers[instr[1] & 0x0F] != 0);
+ case 0xA0: /* Branch if reg less than zero */
+ return (registers[instr[1] & 0x0F] < 0);
+ case 0xB0: /* Branch if reg greater or equal to zero */
+ return (registers[instr[1] & 0x0F] >= 0);
+ case 0xC0: /* Branch if reg less than or equal to zero */
+ return (registers[instr[1] & 0x0F] <= 0);
+ case 0xD0: /* Branch if reg greater than zero */
+ return (registers[instr[1] & 0x0F] > 0);
+ default: /* oops? */
+ return 0;
+ }
+ default: /* oops? */
+ return 0;
+ }
+}
+
+static int
+branchDestination(instr, branchCode)
+ unsigned char *instr;
+{
+ switch (branchCode) {
+ default:
+ case 0: /* not a branch */
+ return 0;
+ case 1: /* RTE */
+ return registers[BPC] & ~3; /* pop BPC into PC */
+ case 2: /* JL or JMP */
+ return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */
+ case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
+ return (((int) instr) & ~3) + ((unsigned char) instr[1] << 2);
+ case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
+ return ((int) instr +
+ ((((unsigned char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2));
+ case 5: /* BNE, BEQ (16-bit relative offset) */
+ case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
+ return ((int) instr + ((((unsigned char) instr[2] << 8) | (instr[3])) << 2));
+ }
+
+ /* An explanatory note: in the last three return expressions, I have
+ cast the most-significant byte of the return offset to char.
+ What this accomplishes is sign extension. If the other
+ less-significant bytes were signed as well, they would get sign
+ extended too and, if negative, their leading bits would clobber
+ the bits of the more-significant bytes ahead of them. There are
+ other ways I could have done this, but sign extension from
+ odd-sized integers is always a pain. */
+}
+
+static void
+branchSideEffects(instr, branchCode)
+ unsigned char *instr;
+ int branchCode;
+{
+ switch (branchCode)
+ {
+ case 1: /* RTE */
+ return; /* I <THINK> this is already handled... */
+ case 2: /* JL (or JMP) */
+ case 3: /* BL (or BC, BNC, BRA) */
+ case 4:
+ if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */
+ registers[R14] = (registers[PC] & ~3) + 4;
+ return;
+ default: /* any other branch has no side effects */
+ return;
+ }
+}
+
+static struct STEPPING_CONTEXT {
+ int stepping; /* true when we've started a single-step */
+ unsigned long target_addr; /* the instr we're trying to execute */
+ unsigned long target_size; /* the size of the target instr */
+ unsigned long noop_addr; /* where we've inserted a no-op, if any */
+ unsigned long trap1_addr; /* the trap following the target instr */
+ unsigned long trap2_addr; /* the trap at a branch destination, if any */
+ unsigned short noop_save; /* instruction overwritten by our no-op */
+ unsigned short trap1_save; /* instruction overwritten by trap1 */
+ unsigned short trap2_save; /* instruction overwritten by trap2 */
+ unsigned short continue_p; /* true if NOT returning to gdb after step */
+} stepping;
+
+/* Function: prepare_to_step
+ Called from handle_exception to prepare the user program to single-step.
+ Places a trap instruction after the target instruction, with special
+ extra handling for branch instructions and for instructions in the
+ second half-word of a word.
+
+ Returns: True if we should actually execute the instruction;
+ False if we are going to emulate executing the instruction,
+ in which case we simply report to GDB that the instruction
+ has already been executed. */
+
+#define TRAP1 0x10f1; /* trap #1 instruction */
+#define NOOP 0x7000; /* noop instruction */
+
+static unsigned short trap1 = TRAP1;
+static unsigned short noop = NOOP;
+
+static int
+prepare_to_step(continue_p)
+ int continue_p; /* if this isn't REALLY a single-step (see below) */
+{
+ unsigned long pc = registers[PC];
+ int branchCode = isBranch((unsigned char *) pc);
+ unsigned char *p;
+
+ /* zero out the stepping context
+ (paranoia -- it should already be zeroed) */
+ for (p = (unsigned char *) &stepping;
+ p < ((unsigned char *) &stepping) + sizeof(stepping);
+ p++)
+ *p = 0;
+
+ if (branchCode != 0) /* next instruction is a branch */
+ {
+ branchSideEffects((unsigned char *) pc, branchCode);
+ if (willBranch((unsigned char *)pc, branchCode))
+ registers[PC] = branchDestination((unsigned char *) pc, branchCode);
+ else
+ registers[PC] = pc + INSTRUCTION_SIZE(pc);
+ return 0; /* branch "executed" -- just notify GDB */
+ }
+ else if (((int) pc & 2) != 0) /* "second-slot" instruction */
+ {
+ /* insert no-op before pc */
+ stepping.noop_addr = pc - 2;
+ stepping.noop_save = *(unsigned short *) stepping.noop_addr;
+ *(unsigned short *) stepping.noop_addr = noop;
+ /* insert trap after pc */
+ stepping.trap1_addr = pc + 2;
+ stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
+ *(unsigned short *) stepping.trap1_addr = trap1;
+ }
+ else /* "first-slot" instruction */
+ {
+ /* insert trap after pc */
+ stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc);
+ stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
+ *(unsigned short *) stepping.trap1_addr = trap1;
+ }
+ /* "continue_p" means that we are actually doing a continue, and not
+ being requested to single-step by GDB. Sometimes we have to do
+ one single-step before continuing, because the PC is on a half-word
+ boundary. There's no way to simply resume at such an address. */
+ stepping.continue_p = continue_p;
+ stepping.stepping = 1; /* starting a single-step */
+ return 1;
+}
+
+/* Function: finish_from_step
+ Called from handle_exception to finish up when the user program
+ returns from a single-step. Replaces the instructions that had
+ been overwritten by traps or no-ops,
+
+ Returns: True if we should notify GDB that the target stopped.
+ False if we only single-stepped because we had to before we
+ could continue (ie. we were trying to continue at a
+ half-word boundary). In that case don't notify GDB:
+ just "continue continuing". */
+
+static int
+finish_from_step()
+{
+ if (stepping.stepping) /* anything to do? */
+ {
+ int continue_p = stepping.continue_p;
+ unsigned char *p;
+
+ if (stepping.noop_addr) /* replace instr "under" our no-op */
+ *(unsigned short *) stepping.noop_addr = stepping.noop_save;
+ if (stepping.trap1_addr) /* replace instr "under" our trap */
+ *(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
+ if (stepping.trap2_addr) /* ditto our other trap, if any */
+ *(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
+
+ for (p = (unsigned char *) &stepping; /* zero out the stepping context */
+ p < ((unsigned char *) &stepping) + sizeof(stepping);
+ p++)
+ *p = 0;
+
+ return !(continue_p);
+ }
+ else /* we didn't single-step, therefore this must be a legitimate stop */
+ return 1;
+}
+
+struct PSWreg { /* separate out the bit flags in the PSW register */
+ int pad1 : 16;
+ int bsm : 1;
+ int bie : 1;
+ int pad2 : 5;
+ int bc : 1;
+ int sm : 1;
+ int ie : 1;
+ int pad3 : 5;
+ int c : 1;
+} *psw;
+
+/* Upon entry the value for LR to save has been pushed.
+ We unpush that so that the value for the stack pointer saved is correct.
+ Upon entry, all other registers are assumed to have not been modified
+ since the interrupt/trap occured. */
+
+asm ("
+stash_registers:
+ push r0
+ push r1
+ seth r1, #shigh(registers)
+ add3 r1, r1, #low(registers)
+ pop r0 ; r1
+ st r0, @(4,r1)
+ pop r0 ; r0
+ st r0, @r1
+ addi r1, #4 ; only add 4 as subsequent saves are `pre inc'
+ st r2, @+r1
+ st r3, @+r1
+ st r4, @+r1
+ st r5, @+r1
+ st r6, @+r1
+ st r7, @+r1
+ st r8, @+r1
+ st r9, @+r1
+ st r10, @+r1
+ st r11, @+r1
+ st r12, @+r1
+ st r13, @+r1 ; fp
+ pop r0 ; lr (r14)
+ st r0, @+r1
+ st sp, @+r1 ; sp contains right value at this point
+ mvfc r0, cr0
+ st r0, @+r1 ; cr0 == PSW
+ mvfc r0, cr1
+ st r0, @+r1 ; cr1 == CBR
+ mvfc r0, cr2
+ st r0, @+r1 ; cr2 == SPI
+ mvfc r0, cr3
+ st r0, @+r1 ; cr3 == SPU
+ mvfc r0, cr6
+ st r0, @+r1 ; cr6 == BPC
+ st r0, @+r1 ; PC == BPC
+ mvfaclo r0
+ st r0, @+r1 ; ACCL
+ mvfachi r0
+ st r0, @+r1 ; ACCH
+ jmp lr");
+
+/* C routine to clean up what stash_registers did.
+ It is called after calling stash_registers.
+ This is separate from stash_registers as we want to do this in C
+ but doing stash_registers in C isn't straightforward. */
+
+static void
+cleanup_stash ()
+{
+ psw = (struct PSWreg *) &registers[PSW]; /* fields of PSW register */
+ psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */
+ psw->ie = psw->bie;
+ psw->c = psw->bc;
+ registers[CBR] = psw->bc; /* fix up pre-trap "C" register */
+
+#if 0 /* FIXME: Was in previous version. Necessary?
+ (Remember that we use the "rte" insn to return from the
+ trap/interrupt so the values of bsm, bie, bc are important. */
+ psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */
+#endif
+
+ /* FIXME: Copied from previous version. This can probably be deleted
+ since methinks stash_registers has already done this. */
+ registers[PC] = registers[BPC]; /* pre-trap PC */
+
+ /* FIXME: Copied from previous version. Necessary? */
+ if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */
+ registers[SPU] = registers[R15];
+ else
+ registers[SPI] = registers[R15];
+}
+
+asm ("
+restore_and_return:
+ seth r0, #shigh(registers+8)
+ add3 r0, r0, #low(registers+8)
+ ld r2, @r0+ ; restore r2
+ ld r3, @r0+ ; restore r3
+ ld r4, @r0+ ; restore r4
+ ld r5, @r0+ ; restore r5
+ ld r6, @r0+ ; restore r6
+ ld r7, @r0+ ; restore r7
+ ld r8, @r0+ ; restore r8
+ ld r9, @r0+ ; restore r9
+ ld r10, @r0+ ; restore r10
+ ld r11, @r0+ ; restore r11
+ ld r12, @r0+ ; restore r12
+ ld r13, @r0+ ; restore r13
+ ld r14, @r0+ ; restore r14
+ ld r15, @r0+ ; restore r15
+ ld r1, @r0+ ; restore cr0 == PSW
+ mvtc r1, cr0
+ ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only)
+ mvtc r1, cr1
+ ld r1, @r0+ ; restore cr2 == SPI
+ mvtc r1, cr2
+ ld r1, @r0+ ; restore cr3 == SPU
+ mvtc r1, cr3
+ addi r0, #4 ; skip BPC
+ ld r1, @r0+ ; restore cr6 (BPC) == PC
+ mvtc r1, cr6
+ ld r1, @r0+ ; restore ACCL
+ mvtaclo r1
+ ld r1, @r0+ ; restore ACCH
+ mvtachi r1
+ seth r0, #shigh(registers)
+ add3 r0, r0, #low(registers)
+ ld r1, @(4,r0) ; restore r1
+ ld r0, @r0 ; restore r0
+ rte");
+
+/* General trap handler, called after the registers have been stashed.
+ NUM is the trap/exception number. */
+
+static void
+process_exception (num)
+ int num;
+{
+ cleanup_stash ();
+ asm volatile ("
+ seth r1, #shigh(stackPtr)
+ add3 r1, r1, #low(stackPtr)
+ ld r15, @r1 ; setup local stack (protect user stack)
+ mv r0, %0
+ bl handle_exception
+ bl restore_and_return"
+ : : "r" (num) : "r0", "r1");
+}
+
+void _catchException0 ();
+
+asm ("
+_catchException0:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #0
+ bl process_exception");
+
+void _catchException1 ();
+
+asm ("
+_catchException1:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ bl cleanup_stash
+ seth r1, #shigh(stackPtr)
+ add3 r1, r1, #low(stackPtr)
+ ld r15, @r1 ; setup local stack (protect user stack)
+ seth r1, #shigh(registers + 21*4) ; PC
+ add3 r1, r1, #low(registers + 21*4)
+ ld r0, @r1
+ addi r0, #-4 ; back up PC for breakpoint trap.
+ st r0, @r1 ; FIXME: what about bp in right slot?
+ ldi r0, #1
+ bl handle_exception
+ bl restore_and_return");
+
+void _catchException2 ();
+
+asm ("
+_catchException2:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #2
+ bl process_exception");
+
+void _catchException3 ();
+
+asm ("
+_catchException3:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #3
+ bl process_exception");
+
+void _catchException4 ();
+
+asm ("
+_catchException4:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #4
+ bl process_exception");
+
+void _catchException5 ();
+
+asm ("
+_catchException5:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #5
+ bl process_exception");
+
+void _catchException6 ();
+
+asm ("
+_catchException6:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #6
+ bl process_exception");
+
+void _catchException7 ();
+
+asm ("
+_catchException7:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #7
+ bl process_exception");
+
+void _catchException8 ();
+
+asm ("
+_catchException8:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #8
+ bl process_exception");
+
+void _catchException9 ();
+
+asm ("
+_catchException9:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #9
+ bl process_exception");
+
+void _catchException10 ();
+
+asm ("
+_catchException10:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #10
+ bl process_exception");
+
+void _catchException11 ();
+
+asm ("
+_catchException11:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #11
+ bl process_exception");
+
+void _catchException12 ();
+
+asm ("
+_catchException12:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #12
+ bl process_exception");
+
+void _catchException13 ();
+
+asm ("
+_catchException13:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #13
+ bl process_exception");
+
+void _catchException14 ();
+
+asm ("
+_catchException14:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #14
+ bl process_exception");
+
+void _catchException15 ();
+
+asm ("
+_catchException15:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #15
+ bl process_exception");
+
+void _catchException16 ();
+
+asm ("
+_catchException16:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #16
+ bl process_exception");
+
+void _catchException17 ();
+
+asm ("
+_catchException17:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #17
+ bl process_exception");
+
+
+/* this function is used to set up exception handlers for tracing and
+ breakpoints */
+void
+set_debug_traps()
+{
+ /* extern void remcomHandler(); */
+ int i;
+
+ for (i = 0; i < 18; i++) /* keep a copy of old vectors */
+ if (save_vectors[i] == 0) /* only copy them the first time */
+ save_vectors[i] = getExceptionHandler (i);
+
+ stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+ exceptionHandler (0, _catchException0);
+ exceptionHandler (1, _catchException1);
+ exceptionHandler (2, _catchException2);
+ exceptionHandler (3, _catchException3);
+ exceptionHandler (4, _catchException4);
+ exceptionHandler (5, _catchException5);
+ exceptionHandler (6, _catchException6);
+ exceptionHandler (7, _catchException7);
+ exceptionHandler (8, _catchException8);
+ exceptionHandler (9, _catchException9);
+ exceptionHandler (10, _catchException10);
+ exceptionHandler (11, _catchException11);
+ exceptionHandler (12, _catchException12);
+ exceptionHandler (13, _catchException13);
+ exceptionHandler (14, _catchException14);
+ exceptionHandler (15, _catchException15);
+ exceptionHandler (16, _catchException16);
+ /* exceptionHandler (17, _catchException17); */
+
+ /* In case GDB is started before us, ack any packets (presumably
+ "$?#xx") sitting there. */
+ putDebugChar ('+');
+
+ initialized = 1;
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+#define BREAKPOINT() asm volatile (" trap #2");
+
+void
+breakpoint()
+{
+ if (initialized)
+ BREAKPOINT();
+}
+
+/* STDOUT section:
+ Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
+ Functions: gdb_putchar(char ch)
+ gdb_puts(char *str)
+ gdb_write(char *str, int len)
+ gdb_error(char *format, char *parm)
+ */
+
+/* Function: gdb_putchar(int)
+ Make gdb write a char to stdout.
+ Returns: the char */
+
+static int
+gdb_putchar(ch)
+ int ch;
+{
+ char buf[4];
+
+ buf[0] = 'O';
+ buf[1] = hexchars[ch >> 4];
+ buf[2] = hexchars[ch & 0x0F];
+ buf[3] = 0;
+ putpacket(buf);
+ return ch;
+}
+
+/* Function: gdb_write(char *, int)
+ Make gdb write n bytes to stdout (not assumed to be null-terminated).
+ Returns: number of bytes written */
+
+static int
+gdb_write(data, len)
+ char *data;
+ int len;
+{
+ char *buf, *cpy;
+ int i;
+
+ buf = remcomOutBuffer;
+ buf[0] = 'O';
+ i = 0;
+ while (i < len)
+ {
+ for (cpy = buf+1;
+ i < len && cpy < buf + sizeof(remcomOutBuffer) - 3;
+ i++)
+ {
+ *cpy++ = hexchars[data[i] >> 4];
+ *cpy++ = hexchars[data[i] & 0x0F];
+ }
+ *cpy = 0;
+ putpacket(buf);
+ }
+ return len;
+}
+
+/* Function: gdb_puts(char *)
+ Make gdb write a null-terminated string to stdout.
+ Returns: the length of the string */
+
+static int
+gdb_puts(str)
+ char *str;
+{
+ return gdb_write(str, strlen(str));
+}
+
+/* Function: gdb_error(char *, char *)
+ Send an error message to gdb's stdout.
+ First string may have 1 (one) optional "%s" in it, which
+ will cause the optional second string to be inserted. */
+
+static void
+gdb_error(format, parm)
+ char * format;
+ char * parm;
+{
+ char buf[400], *cpy;
+ int len;
+
+ if (remote_debug)
+ {
+ if (format && *format)
+ len = strlen(format);
+ else
+ return; /* empty input */
+
+ if (parm && *parm)
+ len += strlen(parm);
+
+ for (cpy = buf; *format; )
+ {
+ if (format[0] == '%' && format[1] == 's') /* include second string */
+ {
+ format += 2; /* advance two chars instead of just one */
+ while (parm && *parm)
+ *cpy++ = *parm++;
+ }
+ else
+ *cpy++ = *format++;
+ }
+ *cpy = '\0';
+ gdb_puts(buf);
+ }
+}
+
+static unsigned char *
+strcpy (unsigned char *dest, const unsigned char *src)
+{
+ unsigned char *ret = dest;
+
+ if (dest && src)
+ {
+ while (*src)
+ *dest++ = *src++;
+ *dest = 0;
+ }
+ return ret;
+}
+
+static int
+strlen (const unsigned char *src)
+{
+ int ret;
+
+ for (ret = 0; *src; src++)
+ ret++;
+
+ return ret;
+}
+
+#if 0
+void exit (code)
+ int code;
+{
+ _exit (code);
+}
+
+int atexit (void *p)
+{
+ return 0;
+}
+
+void abort (void)
+{
+ _exit (1);
+}
+#endif
diff --git a/contrib/gdb/gdb/m32r-tdep.c b/contrib/gdb/gdb/m32r-tdep.c
new file mode 100644
index 0000000..acd34fa
--- /dev/null
+++ b/contrib/gdb/gdb/m32r-tdep.c
@@ -0,0 +1,745 @@
+/* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger.
+ Copyright 1996, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+
+/* Function: m32r_use_struct_convention
+ Return nonzero if call_function should allocate stack space for a
+ struct return? */
+int
+m32r_use_struct_convention (gcc_p, type)
+ int gcc_p;
+ struct type *type;
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+/* Function: frame_find_saved_regs
+ Return the frame_saved_regs structure for the frame.
+ Doesn't really work for dummy frames, but it does pass back
+ an empty frame_saved_regs, so I guess that's better than total failure */
+
+void
+m32r_frame_find_saved_regs (fi, regaddr)
+ struct frame_info *fi;
+ struct frame_saved_regs *regaddr;
+{
+ memcpy(regaddr, &fi->fsr, sizeof(struct frame_saved_regs));
+}
+
+/* Turn this on if you want to see just how much instruction decoding
+ if being done, its quite a lot
+ */
+#if 0
+static void dump_insn(char * commnt,CORE_ADDR pc, int insn)
+{
+ printf_filtered(" %s %08x %08x ",
+ commnt,(unsigned int)pc,(unsigned int) insn);
+ (*tm_print_insn)(pc,&tm_print_insn_info);
+ printf_filtered("\n");
+}
+#define insn_debug(args) { printf_filtered args; }
+#else
+#define dump_insn(a,b,c) {}
+#define insn_debug(args) {}
+#endif
+
+#define DEFAULT_SEARCH_LIMIT 44
+
+/* Function: scan_prologue
+ This function decodes the target function prologue to determine
+ 1) the size of the stack frame, and 2) which registers are saved on it.
+ It saves the offsets of saved regs in the frame_saved_regs argument,
+ and returns the frame size. */
+
+/*
+ The sequence it currently generates is:
+
+ if (varargs function) { ddi sp,#n }
+ push registers
+ if (additional stack <= 256) { addi sp,#-stack }
+ else if (additional stack < 65k) { add3 sp,sp,#-stack
+
+ } else if (additional stack) {
+ seth sp,#(stack & 0xffff0000)
+ or3 sp,sp,#(stack & 0x0000ffff)
+ sub sp,r4
+ }
+ if (frame pointer) {
+ mv sp,fp
+ }
+
+These instructions are scheduled like everything else, so you should stop at
+the first branch instruction.
+
+*/
+
+/* This is required by skip prologue and by m32r_init_extra_frame_info.
+ The results of decoding a prologue should be cached because this
+ thrashing is getting nuts.
+ I am thinking of making a container class with two indexes, name and
+ address. It may be better to extend the symbol table.
+ */
+
+static void decode_prologue (start_pc, scan_limit,
+ pl_endptr, framelength,
+ fi, fsr)
+ CORE_ADDR start_pc;
+ CORE_ADDR scan_limit;
+ CORE_ADDR * pl_endptr; /* var parameter */
+ unsigned long * framelength;
+ struct frame_info * fi;
+ struct frame_saved_regs * fsr;
+{
+ unsigned long framesize;
+ int insn;
+ int op1;
+ int maybe_one_more = 0;
+ CORE_ADDR after_prologue = 0;
+ CORE_ADDR after_stack_adjust = 0;
+ CORE_ADDR current_pc;
+
+
+ framesize = 0;
+ after_prologue = 0;
+ insn_debug(("rd prolog l(%d)\n",scan_limit - current_pc));
+
+ for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2)
+ {
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+ dump_insn("insn-1",current_pc,insn); /* MTZ */
+
+ /* If this is a 32 bit instruction, we dont want to examine its
+ immediate data as though it were an instruction */
+ if (current_pc & 0x02)
+ { /* Clear the parallel execution bit from 16 bit instruction */
+ if (maybe_one_more)
+ { /* The last instruction was a branch, usually terminates
+ the series, but if this is a parallel instruction,
+ it may be a stack framing instruction */
+ if (! (insn & 0x8000))
+ { insn_debug(("Really done"));
+ break; /* nope, we are really done */
+ }
+ }
+ insn &= 0x7fff; /* decode this instruction further */
+ }
+ else
+ {
+ if (maybe_one_more)
+ break; /* This isnt the one more */
+ if (insn & 0x8000)
+ {
+ insn_debug(("32 bit insn\n"));
+ if (current_pc == scan_limit)
+ scan_limit += 2; /* extend the search */
+ current_pc += 2; /* skip the immediate data */
+ if (insn == 0x8faf) /* add3 sp, sp, xxxx */
+ /* add 16 bit sign-extended offset */
+ { insn_debug(("stack increment\n"));
+ framesize += -((short) read_memory_unsigned_integer (current_pc, 2));
+ }
+ else
+ {
+ if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */
+ read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24)
+ { /* subtract 24 bit sign-extended negative-offset */
+ dump_insn("insn-2",current_pc+2,insn);
+ insn = read_memory_unsigned_integer (current_pc - 2, 4);
+ dump_insn("insn-3(l4)",current_pc -2,insn);
+ if (insn & 0x00800000) /* sign extend */
+ insn |= 0xff000000; /* negative */
+ else
+ insn &= 0x00ffffff; /* positive */
+ framesize += insn;
+ }
+ }
+ after_prologue = current_pc;
+ continue;
+ }
+ }
+ op1 = insn & 0xf000; /* isolate just the first nibble */
+
+ if ((insn & 0xf0ff) == 0x207f)
+ { /* st reg, @-sp */
+ int regno;
+ insn_debug(("push\n"));
+#if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */
+ if (((insn & 0xffff) == 0x2d7f) && fi)
+ fi->using_frame_pointer = 1;
+#endif
+ framesize += 4;
+#if 0
+/* Why should we increase the scan limit, just because we did a push?
+ And if there is a reason, surely we would only want to do it if we
+ had already reached the scan limit... */
+ if (current_pc == scan_limit)
+ scan_limit += 2;
+#endif
+ regno = ((insn >> 8) & 0xf);
+ if (fsr) /* save_regs offset */
+ fsr->regs[regno] = framesize;
+ after_prologue = 0;
+ continue;
+ }
+ if ((insn >> 8) == 0x4f) /* addi sp, xx */
+ /* add 8 bit sign-extended offset */
+ {
+ int stack_adjust = (char) (insn & 0xff);
+
+ /* there are probably two of these stack adjustments:
+ 1) A negative one in the prologue, and
+ 2) A positive one in the epilogue.
+ We are only interested in the first one. */
+
+ if (stack_adjust < 0)
+ {
+ framesize -= stack_adjust;
+ after_prologue = 0;
+ /* A frameless function may have no "mv fp, sp".
+ In that case, this is the end of the prologue. */
+ after_stack_adjust = current_pc + 2;
+ }
+ continue;
+ }
+ if (insn == 0x1d8f) { /* mv fp, sp */
+ if (fi)
+ fi->using_frame_pointer = 1; /* fp is now valid */
+ insn_debug(("done fp found\n"));
+ after_prologue = current_pc + 2;
+ break; /* end of stack adjustments */
+ }
+ if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */
+ { insn_debug(("nop\n"));
+ after_prologue = current_pc + 2;
+ continue; /* nop occurs between pushes */
+ }
+ /* End of prolog if any of these are branch instructions */
+ if ((op1 == 0x7000)
+ || ( op1 == 0xb000)
+ || (op1 == 0x7000))
+ {
+ after_prologue = current_pc;
+ insn_debug(("Done: branch\n"));
+ maybe_one_more = 1;
+ continue;
+ }
+ /* Some of the branch instructions are mixed with other types */
+ if (op1 == 0x1000)
+ {int subop = insn & 0x0ff0;
+ if ((subop == 0x0ec0) || (subop == 0x0fc0))
+ { insn_debug(("done: jmp\n"));
+ after_prologue = current_pc;
+ maybe_one_more = 1;
+ continue; /* jmp , jl */
+ }
+ }
+ }
+
+ if (current_pc >= scan_limit)
+ {
+ if (pl_endptr)
+#if 1
+ if (after_stack_adjust != 0)
+ /* We did not find a "mv fp,sp", but we DID find
+ a stack_adjust. Is it safe to use that as the
+ end of the prologue? I just don't know. */
+ {
+ *pl_endptr = after_stack_adjust;
+ if (framelength)
+ *framelength = framesize;
+ }
+ else
+#endif
+ /* We reached the end of the loop without finding the end
+ of the prologue. No way to win -- we should report failure.
+ The way we do that is to return the original start_pc.
+ GDB will set a breakpoint at the start of the function (etc.) */
+
+ *pl_endptr = start_pc;
+
+ return;
+ }
+ if (after_prologue == 0)
+ after_prologue = current_pc;
+
+ insn_debug((" framesize %d, firstline %08x\n",framesize,after_prologue));
+ if (framelength)
+ *framelength = framesize;
+ if (pl_endptr)
+ *pl_endptr = after_prologue;
+} /* decode_prologue */
+
+/* Function: skip_prologue
+ Find end of function prologue */
+
+CORE_ADDR
+m32r_skip_prologue (pc)
+ CORE_ADDR pc;
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end <= func_end)
+ {
+
+ insn_debug(("BP after prologue %08x\n",sal.end));
+ func_end = sal.end;
+ }
+ else
+ /* Either there's no line info, or the line after the prologue is after
+ the end of the function. In this case, there probably isn't a
+ prologue. */
+ {
+ insn_debug(("No line info, line(%x) sal_end(%x) funcend(%x)\n",
+ sal.line,sal.end,func_end));
+ func_end = min(func_end,func_addr + DEFAULT_SEARCH_LIMIT);
+ }
+ }
+ else
+ func_end = pc + DEFAULT_SEARCH_LIMIT;
+ decode_prologue (pc, func_end, &sal.end, 0, 0, 0);
+ return sal.end;
+}
+
+static unsigned long
+m32r_scan_prologue (fi, fsr)
+ struct frame_info *fi;
+ struct frame_saved_regs *fsr;
+{
+ struct symtab_and_line sal;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+ unsigned long framesize;
+
+ /* this code essentially duplicates skip_prologue,
+ but we need the start address below. */
+
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ if (prologue_start == entry_point_address ())
+ return 0;
+ }
+ else
+ {
+ prologue_start = fi->pc;
+ prologue_end = prologue_start + 48; /* We're in the boondocks:
+ allow for 16 pushes, an add,
+ and "mv fp,sp" */
+ }
+#if 0
+ prologue_end = min (prologue_end, fi->pc);
+#endif
+ insn_debug(("fipc(%08x) start(%08x) end(%08x)\n",
+ fi->pc,prologue_start,prologue_end));
+ prologue_end = min(prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT);
+ decode_prologue (prologue_start,prologue_end,&prologue_end,&framesize,
+ fi,fsr);
+ return framesize;
+}
+
+/* Function: init_extra_frame_info
+ This function actually figures out the frame address for a given pc and
+ sp. This is tricky on the m32r because we sometimes don't use an explicit
+ frame pointer, and the previous stack pointer isn't necessarily recorded
+ on the stack. The only reliable way to get this info is to
+ examine the prologue. */
+
+void
+m32r_init_extra_frame_info (fi)
+ struct frame_info *fi;
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->framesize = 0;
+ return;
+ }
+ else
+ {
+ fi->using_frame_pointer = 0;
+ fi->framesize = m32r_scan_prologue (fi, &fi->fsr);
+
+ if (!fi->next)
+ if (fi->using_frame_pointer)
+ {
+ fi->frame = read_register (FP_REGNUM);
+ }
+ else
+ fi->frame = read_register (SP_REGNUM);
+ else /* fi->next means this is not the innermost frame */
+ if (fi->using_frame_pointer) /* we have an FP */
+ if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */
+ fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->fsr.regs[reg] != 0)
+ fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg];
+ }
+}
+
+/* Function: mn10300_virtual_frame_pointer
+ Return the register that the function uses for a frame pointer,
+ plus any necessary offset to be applied to the register before
+ any frame pointer offsets. */
+
+void
+m32r_virtual_frame_pointer (pc, reg, offset)
+ CORE_ADDR pc;
+ long *reg;
+ long *offset;
+{
+ struct frame_info fi;
+
+ /* Set up a dummy frame_info. */
+ fi.next = NULL;
+ fi.prev = NULL;
+ fi.frame = 0;
+ fi.pc = pc;
+
+ /* Analyze the prolog and fill in the extra info. */
+ m32r_init_extra_frame_info (&fi);
+
+
+ /* Results will tell us which type of frame it uses. */
+ if (fi.using_frame_pointer)
+ {
+ *reg = FP_REGNUM;
+ *offset = 0;
+ }
+ else
+ {
+ *reg = SP_REGNUM;
+ *offset = 0;
+ }
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register. One thing
+ we might want to do here is to check REGNUM against the clobber mask, and
+ somehow flag it as invalid if it isn't saved on the stack somewhere. This
+ would provide a graceful failure mode when trying to get the value of
+ caller-saves registers for an inner frame. */
+
+CORE_ADDR
+m32r_find_callers_reg (fi, regnum)
+ struct frame_info *fi;
+ int regnum;
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->fsr.regs[regnum] != 0)
+ return read_memory_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum));
+ return read_register (regnum);
+}
+
+/* Function: frame_chain
+ Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+ For m32r, we save the frame size when we initialize the frame_info. */
+
+CORE_ADDR
+m32r_frame_chain (fi)
+ struct frame_info *fi;
+{
+ CORE_ADDR fn_start, callers_pc, fp;
+
+ /* is this a dummy frame? */
+ if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
+ return fi->frame; /* dummy frame same as caller's frame */
+
+ /* is caller-of-this a dummy frame? */
+ callers_pc = FRAME_SAVED_PC(fi); /* find out who called us: */
+ fp = m32r_find_callers_reg (fi, FP_REGNUM);
+ if (PC_IN_CALL_DUMMY(callers_pc, fp, fp))
+ return fp; /* dummy frame's frame may bear no relation to ours */
+
+ if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0; /* in _start fn, don't chain further */
+ if (fi->framesize == 0)
+ {
+ printf_filtered("cannot determine frame size @ %08x , pc(%08x)\n",
+ (unsigned long) fi->frame,
+ (unsigned long) fi->pc );
+ return 0;
+ }
+ insn_debug(("m32rx frame %08x\n",fi->frame+fi->framesize));
+ return fi->frame + fi->framesize;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Necessary for targets that don't actually execute a JSR/BSR instruction
+ (ie. when using an empty CALL_DUMMY) */
+
+CORE_ADDR
+m32r_push_return_address (pc, sp)
+ CORE_ADDR pc;
+ CORE_ADDR sp;
+{
+ write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+
+/* Function: pop_frame
+ Discard from the stack the innermost frame,
+ restoring all saved registers. */
+
+struct frame_info *
+m32r_pop_frame (frame)
+ struct frame_info *frame;
+{
+ int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_integer (frame->fsr.regs[regnum], 4));
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (SP_REGNUM, read_register (FP_REGNUM));
+ if (read_register (PSW_REGNUM) & 0x80)
+ write_register (SPU_REGNUM, read_register (SP_REGNUM));
+ else
+ write_register (SPI_REGNUM, read_register (SP_REGNUM));
+ }
+ flush_cached_frames ();
+ return NULL;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM is saved
+ in the stack anywhere, otherwise we get it from the registers. */
+
+CORE_ADDR
+m32r_frame_saved_pc (fi)
+ struct frame_info *fi;
+{
+ if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM);
+ else
+ return m32r_find_callers_reg (fi, RP_REGNUM);
+}
+
+/* Function: push_arguments
+ Setup the function arguments for calling a function in the inferior.
+
+ On the Mitsubishi M32R architecture, there are four registers (R0 to R3)
+ which are dedicated for passing function arguments. Up to the first
+ four arguments (depending on size) may go into these registers.
+ The rest go on the stack.
+
+ Arguments that are smaller than 4 bytes will still take up a whole
+ register or a whole 32-bit word on the stack, and will be
+ right-justified in the register or the stack word. This includes
+ chars, shorts, and small aggregate types.
+
+ Arguments of 8 bytes size are split between two registers, if
+ available. If only one register is available, the argument will
+ be split between the register and the stack. Otherwise it is
+ passed entirely on the stack. Aggregate types with sizes between
+ 4 and 8 bytes are passed entirely on the stack, and are left-justified
+ within the double-word (as opposed to aggregates smaller than 4 bytes
+ which are right-justified).
+
+ Aggregates of greater than 8 bytes are first copied onto the stack,
+ and then a pointer to the copy is passed in the place of the normal
+ argument (either in a register if available, or on the stack).
+
+ Functions that must return an aggregate type can return it in the
+ normal return value registers (R0 and R1) if its size is 8 bytes or
+ less. For larger return values, the caller must allocate space for
+ the callee to copy the return value to. A pointer to this space is
+ passed as an implicit first argument, always in R0. */
+
+CORE_ADDR
+m32r_push_arguments (nargs, args, sp, struct_return, struct_addr)
+ int nargs;
+ value_ptr *args;
+ CORE_ADDR sp;
+ unsigned char struct_return;
+ CORE_ADDR struct_addr;
+{
+ int stack_offset, stack_alloc;
+ int argreg;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[4];
+ int len;
+ int odd_sized_struct;
+
+ /* first force sp to a 4-byte alignment */
+ sp = sp & ~3;
+
+ argreg = ARG0_REGNUM;
+ /* The "struct return pointer" pseudo-argument goes in R0 */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0;
+ argnum < nargs; argnum++)
+ stack_alloc += ((TYPE_LENGTH(VALUE_TYPE(args[argnum])) + 3) & ~3);
+ sp -= stack_alloc; /* make room on stack for args */
+
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 16 bytes
+ in four registers available. Loop thru args from first to last. */
+
+ argreg = ARG0_REGNUM;
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ memset(valbuf, 0, sizeof(valbuf));
+ if (len < 4)
+ { /* value gets right-justified in the register or stack word */
+ memcpy(valbuf + (4 - len),
+ (char *) VALUE_CONTENTS (args[argnum]), len);
+ val = valbuf;
+ }
+ else
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ if (len > 4 && (len & 3) != 0)
+ odd_sized_struct = 1; /* such structs go entirely on stack */
+ else
+ odd_sized_struct = 0;
+ while (len > 0)
+ {
+ if (argreg > ARGLAST_REGNUM || odd_sized_struct)
+ { /* must go on the stack */
+ write_memory (sp + stack_offset, val, 4);
+ stack_offset += 4;
+ }
+ /* NOTE WELL!!!!! This is not an "else if" clause!!!
+ That's because some *&^%$ things get passed on the stack
+ AND in the registers! */
+ if (argreg <= ARGLAST_REGNUM)
+ { /* there's room in a register */
+ regval = extract_address (val, REGISTER_RAW_SIZE(argreg));
+ write_register (argreg++, regval);
+ }
+ /* Store the value 4 bytes at a time. This means that things
+ larger than 4 bytes may go partly in registers and partly
+ on the stack. */
+ len -= REGISTER_RAW_SIZE(argreg);
+ val += REGISTER_RAW_SIZE(argreg);
+ }
+ }
+ return sp;
+}
+
+/* Function: fix_call_dummy
+ If there is real CALL_DUMMY code (eg. on the stack), this function
+ has the responsability to insert the address of the actual code that
+ is the target of the target function call. */
+
+void
+m32r_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
+ char *dummy;
+ CORE_ADDR pc;
+ CORE_ADDR fun;
+ int nargs;
+ value_ptr *args;
+ struct type *type;
+ int gcc_p;
+{
+ /* ld24 r8, <(imm24) fun> */
+ *(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000;
+}
+
+/* Function: get_saved_register
+ Just call the generic_get_saved_register function. */
+
+void
+get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+ char *raw_buffer;
+ int *optimized;
+ CORE_ADDR *addrp;
+ struct frame_info *frame;
+ int regnum;
+ enum lval_type *lval;
+{
+ generic_get_saved_register (raw_buffer, optimized, addrp,
+ frame, regnum, lval);
+}
+
+
+/* Function: m32r_write_sp
+ Because SP is really a read-only register that mirrors either SPU or SPI,
+ we must actually write one of those two as well, depending on PSW. */
+
+void
+m32r_write_sp (val)
+ CORE_ADDR val;
+{
+ unsigned long psw = read_register (PSW_REGNUM);
+
+ if (psw & 0x80) /* stack mode: user or interrupt */
+ write_register (SPU_REGNUM, val);
+ else
+ write_register (SPI_REGNUM, val);
+ write_register (SP_REGNUM, val);
+}
+
+void
+_initialize_m32r_tdep ()
+{
+ tm_print_insn = print_insn_m32r;
+}
+
diff --git a/contrib/gdb/gdb/m68k-stub.c b/contrib/gdb/gdb/m68k-stub.c
index 009cba3..c2f1d3f 100644
--- a/contrib/gdb/gdb/m68k-stub.c
+++ b/contrib/gdb/gdb/m68k-stub.c
@@ -116,8 +116,8 @@
typedef void (*ExceptionHook)(int); /* pointer to function with int parm */
typedef void (*Function)(); /* pointer to a function */
-extern putDebugChar(); /* write a single character */
-extern getDebugChar(); /* read and return a single char */
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
extern Function exceptionHandler(); /* assign an exception handler */
extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */
@@ -594,7 +594,7 @@ char * buffer;
count = 0;
while (ch=buffer[count]) {
- if (! putDebugChar(ch)) return;
+ putDebugChar(ch);
checksum += ch;
count += 1;
}
diff --git a/contrib/gdb/gdb/m68k-tdep.c b/contrib/gdb/gdb/m68k-tdep.c
index f5cc3b0..d597efa 100644
--- a/contrib/gdb/gdb/m68k-tdep.c
+++ b/contrib/gdb/gdb/m68k-tdep.c
@@ -20,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "symtab.h"
+#include "gdbcore.h"
+#include "value.h"
+#include "gdb_string.h"
/* Push an empty stack frame, to record the current PC, etc. */
@@ -61,7 +64,6 @@ m68k_pop_frame ()
register CORE_ADDR fp;
register int regnum;
struct frame_saved_regs fsr;
- struct frame_info *fi;
char raw_buffer[12];
fp = FRAME_FP (frame);
diff --git a/contrib/gdb/gdb/m68klinux-nat.c b/contrib/gdb/gdb/m68klinux-nat.c
new file mode 100644
index 0000000..8367b24
--- /dev/null
+++ b/contrib/gdb/gdb/m68klinux-nat.c
@@ -0,0 +1,155 @@
+/* Motorola m68k native support for Linux
+ Copyright (C) 1996,1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcore.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/procfs.h>
+
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#include "floatformat.h"
+
+#include "target.h"
+
+
+/* This table must line up with REGISTER_NAMES in tm-m68k.h */
+static const int regmap[] =
+{
+ PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+ PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+ PT_SR, PT_PC,
+ /* PT_FP0, ..., PT_FP7 */
+ 21, 24, 27, 30, 33, 36, 39, 42,
+ /* PT_FPCR, PT_FPSR, PT_FPIAR */
+ 45, 46, 47
+};
+
+/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
+ is stored. */
+
+int
+m68k_linux_register_u_addr (blockend, regnum)
+ int blockend;
+ int regnum;
+{
+ return (blockend + 4 * regmap[regnum]);
+}
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+
+/* Note both m68k-tdep.c and m68klinux-nat.c contain definitions
+ for supply_gregset and supply_fpregset. The definitions
+ in m68k-tdep.c are valid if USE_PROC_FS is defined. Otherwise,
+ the definitions in m68klinux-nat.c will be used. This is a
+ bit of a hack. The supply_* routines do not belong in
+ *_tdep.c files. But, there are several lynx ports that currently
+ depend on these definitions. */
+
+#ifndef USE_PROC_FS
+
+void
+supply_gregset (gregsetp)
+ gregset_t *gregsetp;
+{
+ int regi;
+
+ for (regi = D0_REGNUM ; regi <= SP_REGNUM ; regi++)
+ supply_register (regi, (char *) (*gregsetp + regmap[regi]));
+ supply_register (PS_REGNUM, (char *) (*gregsetp + PT_SR));
+ supply_register (PC_REGNUM, (char *) (*gregsetp + PT_PC));
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (fpregsetp)
+ fpregset_t *fpregsetp;
+{
+ int regi;
+
+ for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
+ supply_register (regi, (char *) &fpregsetp->fpregs[(regi - FP0_REGNUM) * 3]);
+ supply_register (FPC_REGNUM, (char *) &fpregsetp->fpcntl[0]);
+ supply_register (FPS_REGNUM, (char *) &fpregsetp->fpcntl[1]);
+ supply_register (FPI_REGNUM, (char *) &fpregsetp->fpcntl[2]);
+}
+
+#endif
+
+
+int
+kernel_u_size ()
+{
+ return (sizeof (struct user));
+}
+
+/* Return non-zero if PC points into the signal trampoline. */
+
+int
+in_sigtramp (pc)
+ CORE_ADDR pc;
+{
+ CORE_ADDR sp;
+ char buf[TARGET_SHORT_BIT / TARGET_CHAR_BIT];
+ int insn;
+
+ sp = read_register (SP_REGNUM);
+ if (pc - 2 < sp)
+ return 0;
+
+ if (read_memory_nobpt (pc, buf, sizeof (buf)))
+ return 0;
+ insn = extract_unsigned_integer (buf, sizeof (buf));
+ if (insn == 0xdefc /* addaw #,sp */
+ || insn == 0x7077 /* moveq #119,d0 */
+ || insn == 0x4e40 /* trap #0 */
+ || insn == 0x203c /* movel #,d0 */)
+ return 1;
+
+ if (read_memory_nobpt (pc - 2, buf, sizeof (buf)))
+ return 0;
+ insn = extract_unsigned_integer (buf, sizeof (buf));
+ if (insn == 0xdefc /* addaw #,sp */
+ || insn == 0x7077 /* moveq #119,d0 */
+ || insn == 0x4e40 /* trap #0 */
+ || insn == 0x203c /* movel #,d0 */)
+ return 1;
+
+ return 0;
+}
diff --git a/contrib/gdb/gdb/m68knbsd-nat.c b/contrib/gdb/gdb/m68knbsd-nat.c
index 7f98147..c2e71df 100644
--- a/contrib/gdb/gdb/m68knbsd-nat.c
+++ b/contrib/gdb/gdb/m68knbsd-nat.c
@@ -73,7 +73,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int ignore;
+ CORE_ADDR ignore;
{
struct md_core *core_reg = (struct md_core *)core_reg_sect;
diff --git a/contrib/gdb/gdb/m88k-tdep.c b/contrib/gdb/gdb/m88k-tdep.c
index a21bd96..f82cb76 100644
--- a/contrib/gdb/gdb/m88k-tdep.c
+++ b/contrib/gdb/gdb/m88k-tdep.c
@@ -36,6 +36,21 @@ void frame_find_saved_regs ();
int target_is_m88110 = 0;
+/* The m88k kernel aligns all instructions on 4-byte boundaries. The
+ kernel also uses the least significant two bits for its own hocus
+ pocus. When gdb receives an address from the kernel, it needs to
+ preserve those right-most two bits, but gdb also needs to be careful
+ to realize that those two bits are not really a part of the address
+ of an instruction. Shrug. */
+
+CORE_ADDR
+m88k_addr_bits_remove (addr)
+ CORE_ADDR addr;
+{
+ return ((addr) & ~3);
+}
+
+
/* Given a GDB frame, determine the address of the calling function's frame.
This will be used to create a new GDB frame struct, and then
INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
@@ -406,8 +421,8 @@ skip_prologue (ip)
ways in the stack frame. sp is even more special:
the address we return for it IS the sp for the next frame.
- We cache the result of doing this in the frame_cache_obstack, since
- it is fairly expensive. */
+ We cache the result of doing this in the frame_obstack, since it is
+ fairly expensive. */
void
frame_find_saved_regs (fi, fsr)
@@ -415,7 +430,6 @@ frame_find_saved_regs (fi, fsr)
struct frame_saved_regs *fsr;
{
register struct frame_saved_regs *cache_fsr;
- extern struct obstack frame_cache_obstack;
CORE_ADDR ip;
struct symtab_and_line sal;
CORE_ADDR limit;
@@ -423,8 +437,7 @@ frame_find_saved_regs (fi, fsr)
if (!fi->fsr)
{
cache_fsr = (struct frame_saved_regs *)
- obstack_alloc (&frame_cache_obstack,
- sizeof (struct frame_saved_regs));
+ frame_obstack_alloc (sizeof (struct frame_saved_regs));
memset (cache_fsr, '\0', sizeof (struct frame_saved_regs));
fi->fsr = cache_fsr;
@@ -514,7 +527,7 @@ frame_saved_pc (frame)
static void
write_word (sp, word)
CORE_ADDR sp;
- unsigned LONGEST word;
+ ULONGEST word;
{
register int len = REGISTER_SIZE;
char buffer[MAX_REGISTER_RAW_SIZE];
diff --git a/contrib/gdb/gdb/main.c b/contrib/gdb/gdb/main.c
index c440217..18c2445 100644
--- a/contrib/gdb/gdb/main.c
+++ b/contrib/gdb/gdb/main.c
@@ -32,12 +32,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include "gdb_string.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
/* Temporary variable for SET_TOP_LEVEL. */
@@ -48,8 +42,8 @@ static int top_level_val;
ugly if it had to use catch_errors each time. */
#define SET_TOP_LEVEL() \
- (((top_level_val = setjmp (error_return)) \
- ? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (jmp_buf))) \
+ (((top_level_val = SIGSETJMP (error_return)) \
+ ? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (SIGJMP_BUF))) \
, top_level_val)
/* If nonzero, display time usage both at startup and for each command. */
@@ -60,7 +54,34 @@ int display_time;
int display_space;
-extern void gdb_init PARAMS ((void));
+/* Whether this is the command line version or not */
+int tui_version = 0;
+
+/* Whether xdb commands will be handled */
+int xdb_commands = 0;
+
+/* Whether dbx commands will be handled */
+int dbx_commands = 0;
+
+GDB_FILE *gdb_stdout;
+GDB_FILE *gdb_stderr;
+
+/* Whether to enable writing into executable and core files */
+extern int write_files;
+
+static void print_gdb_help PARAMS ((GDB_FILE *));
+extern void gdb_init PARAMS ((char *));
+
+/* These two are used to set the external editor commands when gdb is farming
+ out files to be edited by another program. */
+
+extern int enable_external_editor;
+extern char * external_editor_command;
+
+#ifdef __CYGWIN__
+#include <windows.h> /* for MAX_PATH */
+#include <sys/cygwin.h> /* for cygwin32_conv_to_posix_path */
+#endif
int
main (argc, argv)
@@ -103,6 +124,8 @@ main (argc, argv)
long time_at_startup = get_run_time ();
+ int gdb_file_size;
+
START_PROGRESS (argv[0], 0);
#ifdef MPW
@@ -139,8 +162,21 @@ main (argc, argv)
getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
current_directory = gdb_dirbuf;
+ gdb_file_size = sizeof(GDB_FILE);
+
+ gdb_stdout = (GDB_FILE *)xmalloc (gdb_file_size);
+ gdb_stdout->ts_streamtype = afile;
+ gdb_stdout->ts_filestream = stdout;
+ gdb_stdout->ts_strbuf = NULL;
+ gdb_stdout->ts_buflen = 0;
+
+ gdb_stderr = (GDB_FILE *)xmalloc (gdb_file_size);
+ gdb_stderr->ts_streamtype = afile;
+ gdb_stderr->ts_filestream = stderr;
+ gdb_stderr->ts_strbuf = NULL;
+ gdb_stderr->ts_buflen = 0;
+
/* Parse arguments and options. */
-#ifndef WINGDB
{
int c;
/* When var field is 0, use flag field to record the equivalent
@@ -148,6 +184,11 @@ main (argc, argv)
with no equivalent). */
static struct option long_options[] =
{
+#if defined(TUI)
+ {"tui", no_argument, &tui_version, 1},
+#endif
+ {"xdb", no_argument, &xdb_commands, 1},
+ {"dbx", no_argument, &dbx_commands, 1},
{"readnow", no_argument, &readnow_symbol_files, 1},
{"r", no_argument, &readnow_symbol_files, 1},
{"mapped", no_argument, &mapped_symbol_files, 1},
@@ -188,6 +229,7 @@ main (argc, argv)
{"w", no_argument, &use_windows, 1},
{"windows", no_argument, &use_windows, 1},
{"statistics", no_argument, 0, 13},
+ {"write", no_argument, &write_files, 1},
/* Allow machine descriptions to add more options... */
#ifdef ADDITIONAL_OPTIONS
ADDITIONAL_OPTIONS
@@ -284,6 +326,23 @@ main (argc, argv)
else
baud_rate = i;
}
+ case 'l':
+ {
+ int i;
+ char *p;
+
+ i = strtol (optarg, &p, 0);
+ if (i == 0 && p == optarg)
+
+ /* Don't use *_filtered or warning() (which relies on
+ current_target) until after initialize_all_files(). */
+
+ fprintf_unfiltered
+ (gdb_stderr,
+ "warning: could not set timeout limit to `%s'.\n", optarg);
+ else
+ remote_timeout = i;
+ }
break;
#ifdef ADDITIONAL_OPTION_CASES
@@ -299,7 +358,20 @@ main (argc, argv)
/* If --help or --version, disable window interface. */
if (print_help || print_version)
+ {
+ use_windows = 0;
+#ifdef TUI
+ /* Disable the TUI as well. */
+ tui_version = 0;
+#endif
+ }
+
+#ifdef TUI
+ /* An explicit --tui flag overrides the default UI, which is the
+ window system. */
+ if (tui_version)
use_windows = 0;
+#endif
/* OK, that's all the options. The other arguments are filenames. */
count = 0;
@@ -323,8 +395,11 @@ main (argc, argv)
quiet = 1;
}
+#if defined(TUI)
+ if (tui_version)
+ init_ui_hook = tuiInit;
#endif
- gdb_init ();
+ gdb_init (argv[0]);
/* Do these (and anything which might call wrap_here or *_filtered)
after initialize_all_files. */
@@ -338,52 +413,8 @@ main (argc, argv)
if (print_help)
{
- /* --version is intentionally not documented here, because we
- are printing the version here, and the help is long enough
- already. */
-
- print_gdb_version (gdb_stdout);
- /* Make sure the output gets printed. */
- wrap_here ("");
- printf_filtered ("\n");
-
- /* But don't use *_filtered here. We don't want to prompt for continue
- no matter how small the screen or how much we're going to print. */
- fputs_unfiltered ("\
-This is the GNU debugger. Usage:\n\
- gdb [options] [executable-file [core-file or process-id]]\n\
-Options:\n\
- --help Print this message.\n\
- --quiet Do not print version number on startup.\n\
- --fullname Output information used by emacs-GDB interface.\n\
- --epoch Output information used by epoch emacs-GDB interface.\n\
-", gdb_stdout);
- fputs_unfiltered ("\
- --batch Exit after processing options.\n\
- --nx Do not read .gdbinit file.\n\
- --tty=TTY Use TTY for input/output by the program being debugged.\n\
- --cd=DIR Change current directory to DIR.\n\
- --directory=DIR Search for source files in DIR.\n\
-", gdb_stdout);
- fputs_unfiltered ("\
- --command=FILE Execute GDB commands from FILE.\n\
- --symbols=SYMFILE Read symbols from SYMFILE.\n\
- --exec=EXECFILE Use EXECFILE as the executable.\n\
- --se=FILE Use FILE as symbol file and executable file.\n\
-", gdb_stdout);
- fputs_unfiltered ("\
- --core=COREFILE Analyze the core dump COREFILE.\n\
- -b BAUDRATE Set serial port baud rate used for remote debugging.\n\
- --mapped Use mapped symbol files if supported on this system.\n\
- --readnow Fully read symbol files on first access.\n\
- --nw Do not use a window interface.\n\
-", gdb_stdout);
-#ifdef ADDITIONAL_OPTION_HELP
- fputs_unfiltered (ADDITIONAL_OPTION_HELP, gdb_stdout);
-#endif
- fputs_unfiltered ("\n\
-For more information, type \"help\" from within GDB, or consult the\n\
-GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
+ print_gdb_help (gdb_stdout);
+ fputs_unfiltered ("\n", gdb_stdout);
exit (0);
}
@@ -391,7 +422,6 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
{
/* Print all the junk at the top, with trailing "..." if we are about
to read a symbol file (possibly slowly). */
- print_gnu_advertisement ();
print_gdb_version (gdb_stdout);
if (symarg)
printf_filtered ("..");
@@ -409,16 +439,30 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
*before* all the command line arguments are processed; it sets
global parameters, which are independent of what file you are
debugging or what directory you are in. */
- homedir = getenv ("HOME");
+#ifdef __CYGWIN32__
+ {
+ char * tmp = getenv ("HOME");
+
+ if (tmp != NULL)
+ {
+ homedir = (char *) alloca (MAX_PATH+1);
+ cygwin32_conv_to_posix_path (tmp, homedir);
+ }
+ else
+ homedir = NULL;
+ }
+#else
+ homedir = getenv ("HOME");
+#endif
if (homedir)
{
- homeinit = (char *) alloca (strlen (getenv ("HOME")) +
+ homeinit = (char *) alloca (strlen (homedir) +
strlen (gdbinit) + 10);
- strcpy (homeinit, getenv ("HOME"));
+ strcpy (homeinit, homedir);
strcat (homeinit, "/");
strcat (homeinit, gdbinit);
- if (!inhibit_gdbinit && access (homeinit, R_OK) == 0)
+ if (!inhibit_gdbinit)
{
if (!SET_TOP_LEVEL ())
source_command (homeinit, 0);
@@ -487,10 +531,12 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
warning_pre_print = "\nwarning: ";
if (corearg != NULL)
- if (!SET_TOP_LEVEL ())
- core_file_command (corearg, !batch);
- else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ())
- attach_command (corearg, !batch);
+ {
+ if (!SET_TOP_LEVEL ())
+ core_file_command (corearg, !batch);
+ else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ())
+ attach_command (corearg, !batch);
+ }
do_cleanups (ALL_CLEANUPS);
if (ttyarg != NULL)
@@ -512,7 +558,7 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
if (!homedir
|| memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
- if (!inhibit_gdbinit && access (gdbinit, R_OK) == 0)
+ if (!inhibit_gdbinit)
{
if (!SET_TOP_LEVEL ())
source_command (gdbinit, 0);
@@ -574,7 +620,7 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
/* The default command loop.
The WIN32 Gui calls this main to set up gdb's state, and
has its own command loop. */
-#if !defined (WINGDB)
+#if !defined _WIN32 || defined __GNUC__
while (1)
{
if (!SET_TOP_LEVEL ())
@@ -595,6 +641,68 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
#endif
}
+
+/* Don't use *_filtered for printing help. We don't want to prompt
+ for continue no matter how small the screen or how much we're going
+ to print. */
+
+static void
+print_gdb_help (stream)
+ GDB_FILE *stream;
+{
+ fputs_unfiltered ("\
+This is the GNU debugger. Usage:\n\n\
+ gdb [options] [executable-file [core-file or process-id]]\n\n\
+Options:\n\n\
+", stream);
+ fputs_unfiltered ("\
+ -b BAUDRATE Set serial port baud rate used for remote debugging.\n\
+ --batch Exit after processing options.\n\
+ --cd=DIR Change current directory to DIR.\n\
+ --command=FILE Execute GDB commands from FILE.\n\
+ --core=COREFILE Analyze the core dump COREFILE.\n\
+", stream);
+ fputs_unfiltered ("\
+ --dbx DBX compatibility mode.\n\
+ --directory=DIR Search for source files in DIR.\n\
+ --epoch Output information used by epoch emacs-GDB interface.\n\
+ --exec=EXECFILE Use EXECFILE as the executable.\n\
+ --fullname Output information used by emacs-GDB interface.\n\
+ --help Print this message.\n\
+", stream);
+ fputs_unfiltered ("\
+ --mapped Use mapped symbol files if supported on this system.\n\
+ --nw Do not use a window interface.\n\
+ --nx Do not read .gdbinit file.\n\
+ --quiet Do not print version number on startup.\n\
+ --readnow Fully read symbol files on first access.\n\
+", stream);
+ fputs_unfiltered ("\
+ --se=FILE Use FILE as symbol file and executable file.\n\
+ --symbols=SYMFILE Read symbols from SYMFILE.\n\
+ --tty=TTY Use TTY for input/output by the program being debugged.\n\
+", stream);
+#if defined(TUI)
+ fputs_unfiltered ("\
+ --tui Use a terminal user interface.\n\
+", stream);
+#endif
+ fputs_unfiltered ("\
+ --version Print version information and then exit.\n\
+ -w Use a window interface.\n\
+ --write Set writing into executable and core files.\n\
+ --xdb XDB compatibility mode.\n\
+", stream);
+#ifdef ADDITIONAL_OPTION_HELP
+ fputs_unfiltered (ADDITIONAL_OPTION_HELP, stream);
+#endif
+ fputs_unfiltered ("\n\
+For more information, type \"help\" from within GDB, or consult the\n\
+GDB manual (available as on-line info or a printed manual).\n\
+Report bugs to \"bug-gdb@prep.ai.mit.edu\".\
+", stream);
+}
+
void
init_proc ()
@@ -607,21 +715,66 @@ proc_remove_foreign (pid)
{
}
+/* All I/O sent to the *_filtered and *_unfiltered functions eventually ends up
+ here. The fputs_unfiltered_hook is primarily used by GUIs to collect all
+ output and send it to the GUI, instead of the controlling terminal. Only
+ output to gdb_stdout and gdb_stderr are sent to the hook. Everything else
+ is sent on to fputs to allow file I/O to be handled appropriately. */
+
void
fputs_unfiltered (linebuffer, stream)
const char *linebuffer;
- FILE *stream;
+ GDB_FILE *stream;
{
- if (fputs_unfiltered_hook)
+#if defined(TUI)
+ extern int tui_owns_terminal;
+#endif
+ /* If anything (GUI, TUI) wants to capture GDB output, this is
+ * the place... the way to do it is to set up
+ * fputs_unfiltered_hook.
+ * Our TUI ("gdb -tui") used to hook output, but in the
+ * new (XDB style) scheme, we do not do that anymore... - RT
+ */
+ if (fputs_unfiltered_hook
+ && (stream == gdb_stdout
+ || stream == gdb_stderr))
+ fputs_unfiltered_hook (linebuffer, stream);
+ else
{
- /* FIXME: I think we should only be doing this for stdout or stderr.
- Either that or we should be passing stream to the hook so it can
- deal with it. If that is cleaned up, this function can go back
- into utils.c and the fputs_unfiltered_hook can replace the current
- ability to avoid this function by not linking with main.c. */
- fputs_unfiltered_hook (linebuffer, stream);
- return;
- }
+#if defined(TUI)
+ if (tui_version && tui_owns_terminal) {
+ /* If we get here somehow while updating the TUI (from
+ * within a tuiDo(), then we need to temporarily
+ * set up the terminal for GDB output. This probably just
+ * happens on error output.
+ */
+
+ if (stream->ts_streamtype == astring) {
+ gdb_file_adjust_strbuf(strlen(linebuffer), stream);
+ strcat(stream->ts_strbuf, linebuffer);
+ } else {
+ tuiTermUnsetup(0, (tui_version) ? cmdWin->detail.commandInfo.curch : 0);
+ fputs (linebuffer, stream->ts_filestream);
+ tuiTermSetup(0);
+ if (linebuffer[strlen(linebuffer) - 1] == '\n')
+ tuiClearCommandCharCount();
+ else
+ tuiIncrCommandCharCountBy(strlen(linebuffer));
+ }
+ } else {
+ /* The normal case - just do a fputs() */
+ if (stream->ts_streamtype == astring) {
+ gdb_file_adjust_strbuf(strlen(linebuffer), stream);
+ strcat(stream->ts_strbuf, linebuffer);
+ } else fputs (linebuffer, stream->ts_filestream);
+ }
+
- fputs (linebuffer, stream);
+#else
+ if (stream->ts_streamtype == astring) {
+ gdb_file_adjust_strbuf(strlen(linebuffer), stream);
+ strcat(stream->ts_strbuf, linebuffer);
+ } else fputs (linebuffer, stream->ts_filestream);
+#endif
+ }
}
diff --git a/contrib/gdb/gdb/maint.c b/contrib/gdb/gdb/maint.c
index 9ce342c..cf4ceb7e 100644
--- a/contrib/gdb/gdb/maint.c
+++ b/contrib/gdb/gdb/maint.c
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if MAINTENANCE_CMDS /* Entire rest of file goes away if not including maint cmds */
+#include <ctype.h>
#include <signal.h>
#include "command.h"
#include "gdbcmd.h"
@@ -34,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h"
#include "symfile.h"
#include "objfiles.h"
+#include "value.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -49,6 +51,14 @@ static void maintenance_time_display PARAMS ((char *, int));
static void maintenance_space_display PARAMS ((char *, int));
+static void maintenance_info_command PARAMS ((char *, int));
+
+static void print_section_table PARAMS ((bfd *, asection *, PTR));
+
+static void maintenance_info_sections PARAMS ((char *, int));
+
+static void maintenance_print_command PARAMS ((char *, int));
+
/* Set this to the maximum number of seconds to wait instead of waiting forever
in target_wait(). If this timer times out, then it generates an error and
the command is aborted. This replaces most of the need for timeouts in the
@@ -80,7 +90,7 @@ maintenance_command (args, from_tty)
help_list (maintenancelist, "maintenance ", -1, gdb_stdout);
}
-
+#ifndef _WIN32
/* ARGSUSED */
static void
maintenance_dump_me (args, from_tty)
@@ -93,6 +103,7 @@ maintenance_dump_me (args, from_tty)
kill (getpid (), SIGQUIT);
}
}
+#endif
/* Someday we should allow demangling for things other than just
explicit strings. For example, we might want to be able to
@@ -269,6 +280,68 @@ maintenance_print_command (arg, from_tty)
help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout);
}
+/* The "maintenance translate-address" command converts a section and address
+ to a symbol. This can be called in two ways:
+ maintenance translate-address <secname> <addr>
+ or maintenance translate-address <addr>
+*/
+
+static void
+maintenance_translate_address (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ CORE_ADDR address;
+ asection *sect;
+ char *p;
+ struct minimal_symbol *sym;
+ struct objfile *objfile;
+
+ if (arg == NULL || *arg == 0)
+ error ("requires argument (address or section + address)");
+
+ sect = NULL;
+ p = arg;
+
+ if (!isdigit (*p))
+ { /* See if we have a valid section name */
+ while (*p && !isspace (*p)) /* Find end of section name */
+ p++;
+ if (*p == '\000') /* End of command? */
+ error ("Need to specify <section-name> and <address>");
+ *p++ = '\000';
+ while (isspace (*p)) p++; /* Skip whitespace */
+
+ ALL_OBJFILES (objfile)
+ {
+ sect = bfd_get_section_by_name (objfile->obfd, arg);
+ if (sect != NULL)
+ break;
+ }
+
+ if (!sect)
+ error ("Unknown section %s.", arg);
+ }
+
+ address = parse_and_eval_address (p);
+
+ if (sect)
+ sym = lookup_minimal_symbol_by_pc_section (address, sect);
+ else
+ sym = lookup_minimal_symbol_by_pc (address);
+
+ if (sym)
+ printf_filtered ("%s+%u\n",
+ SYMBOL_SOURCE_NAME (sym),
+ address - SYMBOL_VALUE_ADDRESS (sym));
+ else if (sect)
+ printf_filtered ("no symbol at %s:0x%08x\n", sect->name, address);
+ else
+ printf_filtered ("no symbol at 0x%08x\n", address);
+
+ return;
+}
+
#endif /* MAINTENANCE_CMDS */
void
@@ -299,11 +372,13 @@ to test internal functions such as the C++ demangler, etc.",
&maintenanceprintlist, "maintenance print ", 0,
&maintenancelist);
+#ifndef _WIN32
add_cmd ("dump-me", class_maintenance, maintenance_dump_me,
"Get fatal error; make debugger dump its core.\n\
GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\
itself a SIGQUIT signal.",
&maintenancelist);
+#endif
add_cmd ("demangle", class_maintenance, maintenance_demangle,
"Demangle a C++ mangled name.\n\
@@ -359,6 +434,10 @@ If a SOURCE file is specified, dump only that file's partial symbols.",
"Check consistency of psymtabs and symtabs.",
&maintenancelist);
+ add_cmd ("translate-address", class_maintenance, maintenance_translate_address,
+ "Translate a section name and address to a symbol.",
+ &maintenancelist);
+
add_show_from_set (
add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *)&watchdog,
"Set watchdog timer.\n\
diff --git a/contrib/gdb/gdb/mdebugread.c b/contrib/gdb/gdb/mdebugread.c
index 3fe4f96..1064490 100644
--- a/contrib/gdb/gdb/mdebugread.c
+++ b/contrib/gdb/gdb/mdebugread.c
@@ -1,5 +1,5 @@
/* Read a symbol table in ECOFF format (Third-Eye).
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
Original version contributed by Alessandro Forin (af@cs.cmu.edu) at
CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor
@@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef MIPS_EFI_SYMBOL_NAME
#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+extern void ecoff_relocate_efi PARAMS ((struct symbol *, CORE_ADDR));
#include "coff/sym.h"
#include "coff/symconst.h"
typedef struct mips_extra_func_info {
@@ -71,8 +72,6 @@ typedef struct mips_extra_func_info {
#include <sys/types.h>
#endif
-#include <sys/param.h>
-#include <sys/file.h>
#include "gdb_stat.h"
#include "gdb_string.h"
@@ -89,10 +88,19 @@ typedef struct mips_extra_func_info {
#include "expression.h"
#include "language.h" /* Needed inside partial-stab.h */
+
/* Provide a default mapping from a ecoff register number to a gdb REGNUM. */
#ifndef ECOFF_REG_TO_REGNUM
#define ECOFF_REG_TO_REGNUM(num) (num)
#endif
+
+/* Provide a way to test if we have both ECOFF and ELF symbol tables.
+ We use this define in order to know whether we should override a
+ symbol's ECOFF section with its ELF section. This is necessary in
+ case the symbol's ELF section could not be represented in ECOFF. */
+#define ECOFF_IN_ELF(bfd) (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && bfd_get_section_by_name (bfd, ".mdebug") != NULL)
+
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab. */
@@ -119,6 +127,20 @@ struct symloc
#define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap)
#define DEBUG_INFO(p) (PST_PRIVATE(p)->debug_info)
#define PENDING_LIST(p) (PST_PRIVATE(p)->pending_list)
+
+#define SC_IS_TEXT(sc) ((sc) == scText \
+ || (sc) == scRConst \
+ || (sc) == scInit \
+ || (sc) == scFini)
+#define SC_IS_DATA(sc) ((sc) == scData \
+ || (sc) == scSData \
+ || (sc) == scRData \
+ || (sc) == scPData \
+ || (sc) == scXData)
+#define SC_IS_COMMON(sc) ((sc) == scCommon || (sc) == scSCommon)
+#define SC_IS_BSS(sc) ((sc) == scBss || (sc) == scSBss)
+#define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined)
+
/* Things we import explicitly from other modules */
@@ -255,8 +277,8 @@ static int cur_sdx;
/* Note how much "debuggable" this image is. We would like
to see at least one FDR with full symbols */
-static max_gdbinfo;
-static max_glevel;
+static int max_gdbinfo;
+static int max_glevel;
/* When examining .o files, report on undefined symbols */
@@ -305,6 +327,24 @@ static int found_ecoff_debugging_info;
/* Forward declarations */
+static void
+add_pending PARAMS ((FDR *, char *, struct type *));
+
+static struct mdebug_pending *
+is_pending_symbol PARAMS ((FDR *, char *));
+
+static void
+pop_parse_stack PARAMS ((void));
+
+static void
+push_parse_stack PARAMS ((void));
+
+static char *
+fdr_name PARAMS ((FDR *));
+
+static void
+mdebug_psymtab_to_symtab PARAMS ((struct partial_symtab *));
+
static int
upgrade_type PARAMS ((int, struct type **, int, union aux_ext *, int, char *));
@@ -704,6 +744,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
switch (sh->sc)
{
case scText:
+ case scRConst:
/* Do not relocate relative values.
The value of a stEnd symbol is the displacement from the
corresponding start symbol value.
@@ -742,7 +783,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
class = LOC_STATIC;
b = top_stack->cur_block;
s = new_symbol (name);
- if (sh->sc == scCommon || sh->sc == scSCommon)
+ if (SC_IS_COMMON(sh->sc))
{
/* It is a FORTRAN common block. At least for SGI Fortran the
address is not in the symbol; we need to fix it later in
@@ -773,7 +814,8 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
add_symbol (s, b);
/* Type could be missing if file is compiled without debugging info. */
- if (sh->sc == scUndefined || sh->sc == scNil || sh->index == indexNil)
+ if (SC_IS_UNDEF(sh->sc)
+ || sh->sc == scNil || sh->index == indexNil)
SYMBOL_TYPE (s) = nodebug_var_symbol_type;
else
SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
@@ -832,10 +874,26 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
SYMBOL_CLASS (s) = LOC_BLOCK;
/* Type of the return value */
- if (sh->sc == scUndefined || sh->sc == scNil)
+ if (SC_IS_UNDEF(sh->sc) || sh->sc == scNil)
t = mdebug_type_int;
else
- t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
+ {
+ t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
+ if (STREQ(name, "malloc") && t->code == TYPE_CODE_VOID)
+ {
+ /* I don't know why, but, at least under Alpha GNU/Linux,
+ when linking against a malloc without debugging
+ symbols, its read as a function returning void---this
+ is bad because it means we cannot call functions with
+ string arguments interactively; i.e., "call
+ printf("howdy\n")" would fail with the error message
+ "program has no memory available". To avoid this, we
+ patch up the type and make it void*
+ instead. (davidm@azstarnet.com)
+ */
+ t = make_pointer_type (t, NULL);
+ }
+ }
b = top_stack->cur_block;
if (sh->st == stProc)
{
@@ -865,7 +923,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
add_block (b, top_stack->cur_st);
/* Not if we only have partial info */
- if (sh->sc == scUndefined || sh->sc == scNil)
+ if (SC_IS_UNDEF(sh->sc) || sh->sc == scNil)
break;
push_parse_stack ();
@@ -899,7 +957,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
goto structured_common;
case stBlock: /* Either a lexical block, or some type */
- if (sh->sc != scInfo && sh->sc != scCommon && sh->sc != scSCommon)
+ if (sh->sc != scInfo && !SC_IS_COMMON(sh->sc))
goto case_stBlock_code; /* Lexical block */
type_code = TYPE_CODE_UNDEF; /* We have a type. */
@@ -934,7 +992,9 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
without qualifiers, assume the tag is an
enumeration.
Alpha cc -migrate enums are recognized by a zero
- index and a zero symbol value. */
+ index and a zero symbol value.
+ DU 4.0 cc enums are recognized by a member type of
+ btEnum without qualifiers and a zero symbol value. */
if (tsym.index == indexNil
|| (tsym.index == 0 && sh->value == 0))
type_code = TYPE_CODE_ENUM;
@@ -943,7 +1003,8 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
(*debug_swap->swap_tir_in) (bigend,
&ax[tsym.index].a_ti,
&tir);
- if ((tir.bt == btNil || tir.bt == btVoid)
+ if ((tir.bt == btNil || tir.bt == btVoid
+ || (tir.bt == btEnum && sh->value == 0))
&& tir.tq0 == tqNil)
type_code = TYPE_CODE_ENUM;
}
@@ -1089,16 +1150,18 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
if (tsym.st != stMember)
break;
- f->bitpos = tsym.value;
- f->type = t;
- f->name = debug_info->ss + cur_fdr->issBase + tsym.iss;
- f->bitsize = 0;
+ FIELD_BITPOS (*f) = tsym.value;
+ FIELD_TYPE (*f) = t;
+ FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss;
+ FIELD_BITSIZE (*f) = 0;
enum_sym = ((struct symbol *)
obstack_alloc (&current_objfile->symbol_obstack,
sizeof (struct symbol)));
memset ((PTR) enum_sym, 0, sizeof (struct symbol));
- SYMBOL_NAME (enum_sym) = f->name;
+ SYMBOL_NAME (enum_sym) =
+ obsavestring (f->name, strlen (f->name),
+ &current_objfile->symbol_obstack);
SYMBOL_CLASS (enum_sym) = LOC_CONST;
SYMBOL_TYPE (enum_sym) = t;
SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
@@ -1167,7 +1230,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
break;
case stEnd: /* end (of anything) */
- if (sh->sc == scInfo || sh->sc == scCommon || sh->sc == scSCommon)
+ if (sh->sc == scInfo || SC_IS_COMMON(sh->sc))
{
/* Finished with type */
top_stack->cur_type = 0;
@@ -1277,11 +1340,11 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
case stMember: /* member of struct or union */
f = &TYPE_FIELDS (top_stack->cur_type)[top_stack->cur_field++];
- f->name = name;
- f->bitpos = sh->value;
+ FIELD_NAME (*f) = name;
+ FIELD_BITPOS (*f) = sh->value;
bitsize = 0;
- f->type = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name);
- f->bitsize = bitsize;
+ FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name);
+ FIELD_BITSIZE (*f) = bitsize;
break;
case stIndirect: /* forward declaration on Irix5 */
@@ -1856,14 +1919,13 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name)
to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol
in question, or NULL to use top_stack->cur_block. */
-static void parse_procedure PARAMS ((PDR *, struct symtab *, CORE_ADDR,
+static void parse_procedure PARAMS ((PDR *, struct symtab *,
struct partial_symtab *));
static void
-parse_procedure (pr, search_symtab, lowest_pdr_addr, pst)
+parse_procedure (pr, search_symtab, pst)
PDR *pr;
struct symtab *search_symtab;
- CORE_ADDR lowest_pdr_addr;
struct partial_symtab *pst;
{
struct symbol *s, *i;
@@ -1969,7 +2031,18 @@ parse_procedure (pr, search_symtab, lowest_pdr_addr, pst)
e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
e->pdr = *pr;
e->pdr.isym = (long) s;
- e->pdr.adr += pst->textlow - lowest_pdr_addr;
+
+ /* GDB expects the absolute function start address for the
+ procedure descriptor in e->pdr.adr.
+ As the address in the procedure descriptor is usually relative,
+ we would have to relocate e->pdr.adr with cur_fdr->adr and
+ ANOFFSET (pst->section_offsets, SECT_OFF_TEXT).
+ Unfortunately cur_fdr->adr and e->pdr.adr are both absolute
+ in shared libraries on some systems, and on other systems
+ e->pdr.adr is sometimes offset by a bogus value.
+ To work around these problems, we replace e->pdr.adr with
+ the start address of the function. */
+ e->pdr.adr = BLOCK_START (b);
/* Correct incorrect setjmp procedure descriptor from the library
to make backtrace through setjmp work. */
@@ -2046,7 +2119,7 @@ parse_external (es, bigend, section_offsets)
}
/* Reading .o files */
- if (es->asym.sc == scUndefined || es->asym.sc == scNil)
+ if (SC_IS_UNDEF(es->asym.sc) || es->asym.sc == scNil)
{
char *what;
switch (es->asym.st)
@@ -2099,7 +2172,7 @@ parse_external (es, bigend, section_offsets)
case stLabel:
/* Global common symbols are resolved by the runtime loader,
ignore them. */
- if (es->asym.sc == scCommon || es->asym.sc == scSCommon)
+ if (SC_IS_COMMON(es->asym.sc))
break;
/* Note that the case of a symbol with indexNil must be handled
@@ -2217,7 +2290,7 @@ parse_partial_symbols (objfile, section_offsets)
EXTR *ext_in_end;
SYMR sh;
struct partial_symtab *pst;
-
+ int textlow_not_set = 1;
int past_first_source_file = 0;
/* List of current psymtab's include files */
@@ -2327,104 +2400,140 @@ parse_partial_symbols (objfile, section_offsets)
fdr_to_pst[f_idx].n_globals = 0;
}
- /* Pass 2 over external syms: fill in external symbols */
- ext_in = ext_block;
- ext_in_end = ext_in + hdr->iextMax;
- for (; ext_in < ext_in_end; ext_in++)
- {
- enum minimal_symbol_type ms_type = mst_text;
- CORE_ADDR svalue = ext_in->asym.value;
+ /* ECOFF in ELF:
+
+ For ECOFF in ELF, we skip the creation of the minimal symbols.
+ The ECOFF symbols should be a subset of the Elf symbols, and the
+ section information of the elf symbols will be more accurate.
+ FIXME! What about Irix 5's native linker?
+
+ By default, Elf sections which don't exist in ECOFF
+ get put in ECOFF's absolute section by the gnu linker.
+ Since absolute sections don't get relocated, we
+ end up calculating an address different from that of
+ the symbol's minimal symbol (created earlier from the
+ Elf symtab).
+
+ To fix this, either :
+ 1) don't create the duplicate symbol
+ (assumes ECOFF symtab is a subset of the ELF symtab;
+ assumes no side-effects result from ignoring ECOFF symbol)
+ 2) create it, only if lookup for existing symbol in ELF's minimal
+ symbols fails
+ (inefficient;
+ assumes no side-effects result from ignoring ECOFF symbol)
+ 3) create it, but lookup ELF's minimal symbol and use it's section
+ during relocation, then modify "uniqify" phase to merge and
+ eliminate the duplicate symbol
+ (highly inefficient)
+
+ I've implemented #1 here...
+ Skip the creation of the minimal symbols based on the ECOFF
+ symbol table. */
+
+ /* Pass 2 over external syms: fill in external symbols */
+ ext_in = ext_block;
+ ext_in_end = ext_in + hdr->iextMax;
+ for (; ext_in < ext_in_end; ext_in++)
+ {
+ enum minimal_symbol_type ms_type = mst_text;
+ CORE_ADDR svalue = ext_in->asym.value;
- /* The Irix 5 native tools seem to sometimes generate bogus
- external symbols. */
- if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax)
- {
- complain (&bad_ext_ifd_complaint, ext_in->ifd, hdr->ifdMax);
- continue;
- }
- if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax)
- {
- complain (&bad_ext_iss_complaint, ext_in->asym.iss,
- hdr->issExtMax);
- continue;
- }
+ /* The Irix 5 native tools seem to sometimes generate bogus
+ external symbols. */
+ if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax)
+ {
+ complain (&bad_ext_ifd_complaint, ext_in->ifd, hdr->ifdMax);
+ continue;
+ }
+ if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax)
+ {
+ complain (&bad_ext_iss_complaint, ext_in->asym.iss,
+ hdr->issExtMax);
+ continue;
+ }
- extern_tab[fdr_to_pst[ext_in->ifd].globals_offset
- + fdr_to_pst[ext_in->ifd].n_globals++] = *ext_in;
+ extern_tab[fdr_to_pst[ext_in->ifd].globals_offset
+ + fdr_to_pst[ext_in->ifd].n_globals++] = *ext_in;
- if (ext_in->asym.sc == scUndefined || ext_in->asym.sc == scNil)
- continue;
- name = debug_info->ssext + ext_in->asym.iss;
- switch (ext_in->asym.st)
- {
- case stProc:
- svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
- break;
- case stStaticProc:
- ms_type = mst_file_text;
- svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
- break;
- case stGlobal:
- if (ext_in->asym.sc == scCommon || ext_in->asym.sc == scSCommon)
- {
- /* The value of a common symbol is its size, not its address.
- Ignore it. */
+ if (SC_IS_UNDEF(ext_in->asym.sc) || ext_in->asym.sc == scNil)
+ continue;
+
+
+ /* Pass 3 over files, over local syms: fill in static symbols */
+ name = debug_info->ssext + ext_in->asym.iss;
+
+ /* Process ECOFF Symbol Types and Storage Classes */
+ switch (ext_in->asym.st)
+ {
+ case stProc:
+ /* Beginnning of Procedure */
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ break;
+ case stStaticProc:
+ /* Load time only static procs */
+ ms_type = mst_file_text;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ break;
+ case stGlobal:
+ /* External symbol */
+ if (SC_IS_COMMON (ext_in->asym.sc))
+ {
+ /* The value of a common symbol is its size, not its address.
+ Ignore it. */
+ continue;
+ }
+ else if (SC_IS_DATA (ext_in->asym.sc))
+ {
+ ms_type = mst_data;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
+ }
+ else if (SC_IS_BSS (ext_in->asym.sc))
+ {
+ ms_type = mst_bss;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
+ }
+ else
+ ms_type = mst_abs;
+ break;
+ case stLabel:
+ /* Label */
+ if (SC_IS_TEXT (ext_in->asym.sc))
+ {
+ ms_type = mst_file_text;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ }
+ else if (SC_IS_DATA (ext_in->asym.sc))
+ {
+ ms_type = mst_file_data;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
+ }
+ else if (SC_IS_BSS (ext_in->asym.sc))
+ {
+ ms_type = mst_file_bss;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
+ }
+ else
+ ms_type = mst_abs;
+ break;
+ case stLocal:
+ case stNil:
+ /* The alpha has the section start addresses in stLocal symbols
+ whose name starts with a `.'. Skip those but complain for all
+ other stLocal symbols.
+ Irix6 puts the section start addresses in stNil symbols, skip
+ those too.*/
+ if (name[0] == '.')
continue;
- }
- else if (ext_in->asym.sc == scData
- || ext_in->asym.sc == scSData
- || ext_in->asym.sc == scRData
- || ext_in->asym.sc == scPData
- || ext_in->asym.sc == scXData)
- {
- ms_type = mst_data;
- svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
- }
- else
- {
- ms_type = mst_bss;
- svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
- }
- break;
- case stLabel:
- if (ext_in->asym.sc == scAbs)
- ms_type = mst_abs;
- else if (ext_in->asym.sc == scText
- || ext_in->asym.sc == scInit
- || ext_in->asym.sc == scFini)
- {
- ms_type = mst_file_text;
- svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
- }
- else if (ext_in->asym.sc == scData
- || ext_in->asym.sc == scSData
- || ext_in->asym.sc == scRData
- || ext_in->asym.sc == scPData
- || ext_in->asym.sc == scXData)
- {
- ms_type = mst_file_data;
- svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
- }
- else
- {
- ms_type = mst_file_bss;
- svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
- }
- break;
- case stLocal:
- /* The alpha has the section start addresses in stLocal symbols
- whose name starts with a `.'. Skip those but complain for all
- other stLocal symbols. */
- if (name[0] == '.')
- continue;
- /* Fall through. */
- default:
- ms_type = mst_unknown;
- complain (&unknown_ext_complaint, name);
- }
- prim_record_minimal_symbol (name, svalue, ms_type, objfile);
- }
+ /* Fall through. */
+ default:
+ ms_type = mst_unknown;
+ complain (&unknown_ext_complaint, name);
+ }
+ if (!ECOFF_IN_ELF(cur_bfd))
+ prim_record_minimal_symbol (name, svalue, ms_type, objfile);
+ }
/* Pass 3 over files, over local syms: fill in static symbols */
for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
@@ -2532,7 +2641,7 @@ parse_partial_symbols (objfile, section_offsets)
{
if (sh.st == stProc || sh.st == stStaticProc)
{
- long procaddr;
+ CORE_ADDR procaddr;
long isym;
sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
@@ -2544,6 +2653,7 @@ parse_partial_symbols (objfile, section_offsets)
mst_file_text,
NULL,
SECT_OFF_TEXT,
+ NULL,
objfile);
}
procaddr = sh.value;
@@ -2559,7 +2669,7 @@ parse_partial_symbols (objfile, section_offsets)
&sh);
if (sh.st == stEnd)
{
- long high = procaddr + sh.value;
+ CORE_ADDR high = procaddr + sh.value;
/* Kludge for Irix 5.2 zero fh->adr. */
if (!relocatable
@@ -2574,6 +2684,7 @@ parse_partial_symbols (objfile, section_offsets)
switch (sh.sc)
{
case scUndefined:
+ case scSUndefined:
case scNil:
case scAbs:
break;
@@ -2590,10 +2701,13 @@ parse_partial_symbols (objfile, section_offsets)
mst_file_data,
NULL,
SECT_OFF_DATA,
+ NULL,
objfile);
break;
default:
+ /* FIXME! Shouldn't this use cases for bss,
+ then have the default be abs? */
namestring = debug_info->ss + fh->issBase + sh.iss;
sh.value += ANOFFSET (section_offsets, SECT_OFF_BSS);
prim_record_minimal_symbol_and_info (namestring,
@@ -2601,22 +2715,64 @@ parse_partial_symbols (objfile, section_offsets)
mst_file_bss,
NULL,
SECT_OFF_BSS,
+ NULL,
objfile);
break;
}
}
continue;
}
+ /* Handle stabs continuation */
+ {
+ char *stabstring = debug_info->ss + fh->issBase + sh.iss;
+ int len = strlen (stabstring);
+ while (stabstring[len-1] == '\\')
+ {
+ SYMR sh2;
+ char *stabstring1 = stabstring;
+ char *stabstring2;
+ int len2;
+
+ /* Ignore continuation char from 1st string */
+ len--;
+
+ /* Read next stabstring */
+ cur_sdx++;
+ (*swap_sym_in) (cur_bfd,
+ (((char *) debug_info->external_sym)
+ + (fh->isymBase + cur_sdx)
+ * external_sym_size),
+ &sh2);
+ stabstring2 = debug_info->ss + fh->issBase + sh2.iss;
+ len2 = strlen (stabstring2);
+
+ /* Concatinate stabstring2 with stabstring1 */
+ if (stabstring
+ && stabstring != debug_info->ss + fh->issBase + sh.iss)
+ stabstring = xrealloc (stabstring, len + len2 + 1);
+ else
+ stabstring = xmalloc (len + len2 + 1);
+ strcpy (stabstring, stabstring1);
+ strcpy (stabstring + len, stabstring2);
+ len += len2;
+ }
+
#define SET_NAMESTRING() \
- namestring = debug_info->ss + fh->issBase + sh.iss
+ namestring = stabstring
#define CUR_SYMBOL_TYPE type_code
#define CUR_SYMBOL_VALUE sh.value
#define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms)\
pst = save_pst
-#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps) (void)0
+#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set) (void)0
#define HANDLE_RBRAC(val) \
if ((val) > save_pst->texthigh) save_pst->texthigh = (val);
#include "partial-stab.h"
+
+ if (stabstring
+ && stabstring != debug_info->ss + fh->issBase + sh.iss)
+ free (stabstring);
+ }
+ /* end - Handle continuation */
}
}
else
@@ -2639,7 +2795,7 @@ parse_partial_symbols (objfile, section_offsets)
}
/* Non absolute static symbols go into the minimal table. */
- if (sh.sc == scUndefined || sh.sc == scNil
+ if (SC_IS_UNDEF(sh.sc) || sh.sc == scNil
|| (sh.index == indexNil
&& (sh.st != stStatic || sh.sc == scAbs)))
{
@@ -2653,6 +2809,7 @@ parse_partial_symbols (objfile, section_offsets)
switch (sh.sc)
{
case scText:
+ case scRConst:
/* The value of a stEnd symbol is the displacement from the
corresponding start symbol value, do not relocate it. */
if (sh.st != stEnd)
@@ -2673,14 +2830,15 @@ parse_partial_symbols (objfile, section_offsets)
switch (sh.st)
{
- long high;
- long procaddr;
+ CORE_ADDR high;
+ CORE_ADDR procaddr;
int new_sdx;
case stStaticProc:
prim_record_minimal_symbol_and_info (name, sh.value,
mst_file_text, NULL,
- SECT_OFF_TEXT, objfile);
+ SECT_OFF_TEXT, NULL,
+ objfile);
/* FALLTHROUGH */
@@ -2700,12 +2858,12 @@ parse_partial_symbols (objfile, section_offsets)
add_psymbol_to_list (name, strlen (name),
VAR_NAMESPACE, LOC_BLOCK,
&objfile->global_psymbols,
- sh.value, 0, psymtab_language, objfile);
+ 0, sh.value, psymtab_language, objfile);
else
add_psymbol_to_list (name, strlen (name),
VAR_NAMESPACE, LOC_BLOCK,
&objfile->static_psymbols,
- sh.value, 0, psymtab_language, objfile);
+ 0, sh.value, psymtab_language, objfile);
/* Skip over procedure to next one. */
if (sh.index >= hdr->iauxMax)
@@ -2749,19 +2907,17 @@ parse_partial_symbols (objfile, section_offsets)
continue;
case stStatic: /* Variable */
- if (sh.sc == scData
- || sh.sc == scSData
- || sh.sc == scRData
- || sh.sc == scPData
- || sh.sc == scXData)
+ if (SC_IS_DATA (sh.sc))
prim_record_minimal_symbol_and_info (name, sh.value,
mst_file_data, NULL,
SECT_OFF_DATA,
+ NULL,
objfile);
else
prim_record_minimal_symbol_and_info (name, sh.value,
mst_file_bss, NULL,
SECT_OFF_BSS,
+ NULL,
objfile);
class = LOC_STATIC;
break;
@@ -2789,14 +2945,14 @@ parse_partial_symbols (objfile, section_offsets)
/* Do not create a partial symbol for cc unnamed aggregates
and gcc empty aggregates. */
if ((sh.sc == scInfo
- || sh.sc == scCommon || sh.sc == scSCommon)
+ || SC_IS_COMMON(sh.sc))
&& sh.iss != 0
&& sh.index != cur_sdx + 2)
{
add_psymbol_to_list (name, strlen (name),
STRUCT_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
- sh.value, 0,
+ 0, (CORE_ADDR) 0,
psymtab_language, objfile);
}
handle_psymbol_enumerators (objfile, fh, sh.st, sh.value);
@@ -2834,8 +2990,8 @@ parse_partial_symbols (objfile, section_offsets)
/* Use this gdb symbol */
add_psymbol_to_list (name, strlen (name),
VAR_NAMESPACE, class,
- &objfile->static_psymbols, sh.value,
- 0, psymtab_language, objfile);
+ &objfile->static_psymbols,
+ 0, sh.value, psymtab_language, objfile);
skip:
cur_sdx++; /* Go to next file symbol */
}
@@ -2857,13 +3013,14 @@ parse_partial_symbols (objfile, section_offsets)
psh = &ext_ptr->asym;
/* Do not add undefined symbols to the partial symbol table. */
- if (psh->sc == scUndefined || psh->sc == scNil)
+ if (SC_IS_UNDEF(psh->sc) || psh->sc == scNil)
continue;
svalue = psh->value;
switch (psh->sc)
{
case scText:
+ case scRConst:
svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
break;
case scData:
@@ -2901,7 +3058,7 @@ parse_partial_symbols (objfile, section_offsets)
case stGlobal:
/* Global common symbols are resolved by the runtime loader,
ignore them. */
- if (psh->sc == scCommon || psh->sc == scSCommon)
+ if (SC_IS_COMMON(psh->sc))
continue;
class = LOC_STATIC;
@@ -2921,7 +3078,7 @@ parse_partial_symbols (objfile, section_offsets)
fdr_to_pst[f_idx].pst = end_psymtab (save_pst,
psymtab_include_list, includes_used,
-1, save_pst->texthigh,
- dependency_list, dependencies_used);
+ dependency_list, dependencies_used, textlow_not_set);
includes_used = 0;
dependencies_used = 0;
@@ -3046,7 +3203,9 @@ handle_psymbol_enumerators (objfile, fh, stype, svalue)
and its auxiliary index is indexNil or its auxiliary entry
is a plain btNil or btVoid.
Alpha cc -migrate enums are recognized by a zero index and
- a zero symbol value. */
+ a zero symbol value.
+ DU 4.0 cc enums are recognized by a member type of btEnum without
+ qualifiers and a zero symbol value. */
(*swap_sym_in) (cur_bfd, ext_sym, &sh);
if (sh.st != stMember)
return;
@@ -3058,7 +3217,10 @@ handle_psymbol_enumerators (objfile, fh, stype, svalue)
&(debug_info->external_aux
+ fh->iauxBase + sh.index)->a_ti,
&tir);
- if ((tir.bt != btNil && tir.bt != btVoid) || tir.tq0 != tqNil)
+ if ((tir.bt != btNil
+ && tir.bt != btVoid
+ && (tir.bt != btEnum || svalue != 0))
+ || tir.tq0 != tqNil)
return;
break;
@@ -3080,7 +3242,7 @@ handle_psymbol_enumerators (objfile, fh, stype, svalue)
add_psymbol_to_list (name, strlen (name),
VAR_NAMESPACE, LOC_CONST,
&objfile->static_psymbols, 0,
- 0, psymtab_language, objfile);
+ (CORE_ADDR) 0, psymtab_language, objfile);
ext_sym += external_sym_size;
}
}
@@ -3219,7 +3381,8 @@ psymtab_to_symtab_1 (pst, filename)
&sh);
name = debug_info->ss + fh->issBase + sh.iss;
valu = sh.value;
- if (ECOFF_IS_STAB (&sh))
+ /* XXX This is a hack. It will go away! */
+ if (ECOFF_IS_STAB (&sh) || (name[0] == '#'))
{
int type_code = ECOFF_UNMARK_STAB (sh.index);
@@ -3231,6 +3394,12 @@ psymtab_to_symtab_1 (pst, filename)
process_one_symbol (type_code, 0, valu, name,
pst->section_offsets, pst->objfile);
}
+ /* Similarly a hack. */
+ else if (name[0] == '#')
+ {
+ process_one_symbol (N_SLINE, 0, valu, name,
+ pst->section_offsets, pst->objfile);
+ }
if (type_code == N_FUN)
{
/* Make up special symbol to contain
@@ -3319,7 +3488,7 @@ psymtab_to_symtab_1 (pst, filename)
pdr_in = pr_block;
pdr_in_end = pdr_in + fh->cpd;
for (; pdr_in < pdr_in_end; pdr_in++)
- parse_procedure (pdr_in, st, lowest_pdr_addr, pst);
+ parse_procedure (pdr_in, st, pst);
do_cleanups (old_chain);
}
@@ -3433,7 +3602,7 @@ psymtab_to_symtab_1 (pst, filename)
pdr_in = pr_block;
pdr_in_end = pdr_in + fh->cpd;
for (; pdr_in < pdr_in_end; pdr_in++)
- parse_procedure (pdr_in, 0, lowest_pdr_addr, pst);
+ parse_procedure (pdr_in, 0, pst);
do_cleanups (old_chain);
}
@@ -3607,7 +3776,7 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name)
|| (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
&& sh.st != stStruct && sh.st != stUnion
&& sh.st != stEnum))
- && (sh.st != stBlock || (sh.sc != scCommon && sh.sc != scSCommon)))
+ && (sh.st != stBlock || !SC_IS_COMMON(sh.sc)))
{
/* File indirect entry is corrupt. */
*pname = "<illegal>";
@@ -3946,7 +4115,8 @@ new_symtab (name, maxsyms, maxlines, objfile)
BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
s->free_code = free_linetable;
-
+ s->debugformat = obsavestring ("ECOFF", 5,
+ &objfile -> symbol_obstack);
return (s);
}
@@ -4083,7 +4253,8 @@ new_symbol (name)
sizeof (struct symbol)));
memset ((PTR) s, 0, sizeof (*s));
- SYMBOL_NAME (s) = name;
+ SYMBOL_NAME (s) = obsavestring (name, strlen (name),
+ &current_objfile->symbol_obstack);
SYMBOL_LANGUAGE (s) = psymtab_language;
SYMBOL_INIT_DEMANGLED_NAME (s, &current_objfile->symbol_obstack);
return s;
@@ -4142,7 +4313,10 @@ elfmdebug_build_psymtabs (objfile, swap, sec, section_offsets)
/* FIXME: This function is called only by mips-tdep.c. It needs to be
here because it calls functions defined in this file, but perhaps
- this could be handled in a better way. */
+ this could be handled in a better way. Only compile it in when
+ tm-mips.h is included. */
+
+#ifdef TM_MIPS_H
void
fixup_sigtramp ()
@@ -4244,6 +4418,8 @@ fixup_sigtramp ()
BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s;
}
+#endif /* TM_MIPS_H */
+
void
_initialize_mdebugread ()
{
diff --git a/contrib/gdb/gdb/mem-break.c b/contrib/gdb/gdb/mem-break.c
index f31e2fb..b0a1b4f 100644
--- a/contrib/gdb/gdb/mem-break.c
+++ b/contrib/gdb/gdb/mem-break.c
@@ -20,11 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
-/* Either BREAKPOINT should be defined, or both of LITTLE_BREAKPOINT,
- BIG_BREAKPOINT should be defined. */
-
-#if defined (BREAKPOINT) || (defined (LITTLE_BREAKPOINT) && defined (BIG_BREAKPOINT))
-
/* This file is only useful if BREAKPOINT is set. If not, we punt. */
#include "symtab.h"
@@ -32,21 +27,52 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "inferior.h"
#include "target.h"
-/* If the target isn't bi-endian, just pretend it is. */
-#if defined(BREAKPOINT) && !defined (LITTLE_BREAKPOINT) && !defined (BIG_BREAKPOINT)
-#define LITTLE_BREAKPOINT BREAKPOINT
-#define BIG_BREAKPOINT BREAKPOINT
-#endif
-/* This is the sequence of bytes we insert for a breakpoint. On some
- machines, breakpoints are handled by the target environment and we
- don't have to worry about them here. */
-
-static unsigned char big_break_insn[] = BIG_BREAKPOINT;
-static unsigned char little_break_insn[] = LITTLE_BREAKPOINT;
+/* Use the program counter to determine the contents and size
+ of a breakpoint instruction. If no target-dependent macro
+ BREAKPOINT_FROM_PC has been defined to implement this function,
+ assume that the breakpoint doesn't depend on the PC, and
+ use the values of the BIG_BREAKPOINT and LITTLE_BREAKPOINT macros.
+ Return a pointer to a string of bytes that encode a breakpoint
+ instruction, stores the length of the string to *lenptr,
+ and optionally adjust the pc to point to the correct memory location
+ for inserting the breakpoint. */
+
+unsigned char *
+memory_breakpoint_from_pc (pcptr, lenptr)
+ CORE_ADDR *pcptr;
+ int *lenptr;
+{
+ /* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a
+ breakpoint. On some machines, breakpoints are handled by the
+ target environment and we don't have to worry about them here. */
+#ifdef BIG_BREAKPOINT
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ {
+ static unsigned char big_break_insn[] = BIG_BREAKPOINT;
+ *lenptr = sizeof (big_break_insn);
+ return big_break_insn;
+ }
+#endif
+#ifdef LITTLE_BREAKPOINT
+ if (TARGET_BYTE_ORDER != BIG_ENDIAN)
+ {
+ static unsigned char little_break_insn[] = LITTLE_BREAKPOINT;
+ *lenptr = sizeof (little_break_insn);
+ return little_break_insn;
+ }
+#endif
+#ifdef BREAKPOINT
+ {
+ static unsigned char break_insn[] = BREAKPOINT;
+ *lenptr = sizeof (break_insn);
+ return break_insn;
+ }
+#endif
+ *lenptr = 0;
+ return NULL;
+}
-/* FIXME: We assume big and little breakpoints are the same size. */
-#define BREAKPOINT_LEN (sizeof (big_break_insn))
/* Insert a breakpoint on targets that don't have any better breakpoint
support. We read the contents of the target location and stash it,
@@ -62,18 +88,20 @@ memory_insert_breakpoint (addr, contents_cache)
char *contents_cache;
{
int val;
+ unsigned char *bp;
+ int bplen;
+
+ /* Determine appropriate breakpoint contents and size for this address. */
+ bp = BREAKPOINT_FROM_PC (&addr, &bplen);
+ if (bp == NULL)
+ error ("Software breakpoints not implemented for this target.");
- val = target_read_memory (addr, contents_cache, BREAKPOINT_LEN);
+ /* Save the memory contents. */
+ val = target_read_memory (addr, contents_cache, bplen);
+ /* Write the breakpoint. */
if (val == 0)
- {
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
- val = target_write_memory (addr, (char *)big_break_insn,
- BREAKPOINT_LEN);
- else
- val = target_write_memory (addr, (char *)little_break_insn,
- BREAKPOINT_LEN);
- }
+ val = target_write_memory (addr, (char *)bp, bplen);
return val;
}
@@ -84,38 +112,13 @@ memory_remove_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
- return target_write_memory (addr, contents_cache, BREAKPOINT_LEN);
-}
-
+ unsigned char *bp;
+ int bplen;
-/* FIXME: This is a hack and should depend on the debugging target.
- See comment in breakpoint.c where this is used. */
+ /* Determine appropriate breakpoint contents and size for this address. */
+ bp = BREAKPOINT_FROM_PC (&addr, &bplen);
+ if (bp == NULL)
+ error ("Software breakpoints not implemented for this target.");
-int memory_breakpoint_size = BREAKPOINT_LEN;
-
-
-#else /* BREAKPOINT */
-
-char nogo[] = "Breakpoints not implemented for this target.";
-
-int
-memory_insert_breakpoint (addr, contents_cache)
- CORE_ADDR addr;
- char *contents_cache;
-{
- error (nogo);
- return 0; /* lint */
+ return target_write_memory (addr, contents_cache, bplen);
}
-
-int
-memory_remove_breakpoint (addr, contents_cache)
- CORE_ADDR addr;
- char *contents_cache;
-{
- error (nogo);
- return 0; /* lint */
-}
-
-int memory_breakpoint_size = -1;
-
-#endif /* BREAKPOINT */
diff --git a/contrib/gdb/gdb/minsyms.c b/contrib/gdb/gdb/minsyms.c
index 6c22d6c..a271c91 100644
--- a/contrib/gdb/gdb/minsyms.c
+++ b/contrib/gdb/gdb/minsyms.c
@@ -1,5 +1,5 @@
/* GDB routines for manipulating the minimal symbol tables.
- Copyright 1992, 1993, 1994, 1996, 1996 Free Software Foundation, Inc.
+ Copyright 1992, 93, 94, 96, 97, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
@@ -142,7 +142,7 @@ lookup_minimal_symbol (name, sfile, objf)
#endif
break;
- case mst_solib_trampoline:
+ case mst_solib_trampoline:
/* If a trampoline symbol is found, we prefer to
keep looking for the *real* symbol. If the
@@ -302,25 +302,33 @@ lookup_minimal_symbol_solib_trampoline (name, sfile, objf)
}
-/* Search through the minimal symbol table for each objfile and find the
- symbol whose address is the largest address that is still less than or
- equal to PC. Returns a pointer to the minimal symbol if such a symbol
- is found, or NULL if PC is not in a suitable range. Note that we need
- to look through ALL the minimal symbol tables before deciding on the
- symbol that comes closest to the specified PC. This is because objfiles
- can overlap, for example objfile A has .text at 0x100 and .data at 0x40000
- and objfile B has .text at 0x234 and .data at 0x40048. */
+/* Search through the minimal symbol table for each objfile and find
+ the symbol whose address is the largest address that is still less
+ than or equal to PC, and matches SECTION (if non-null). Returns a
+ pointer to the minimal symbol if such a symbol is found, or NULL if
+ PC is not in a suitable range. Note that we need to look through
+ ALL the minimal symbol tables before deciding on the symbol that
+ comes closest to the specified PC. This is because objfiles can
+ overlap, for example objfile A has .text at 0x100 and .data at
+ 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. */
struct minimal_symbol *
-lookup_minimal_symbol_by_pc (pc)
- register CORE_ADDR pc;
+lookup_minimal_symbol_by_pc_section (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
- register int lo;
- register int hi;
- register int new;
- register struct objfile *objfile;
- register struct minimal_symbol *msymbol;
- register struct minimal_symbol *best_symbol = NULL;
+ int lo;
+ int hi;
+ int new;
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *best_symbol = NULL;
+
+ /* pc has to be in a known section. This ensures that anything beyond
+ the end of the last segment doesn't appear to be part of the last
+ function in the last segment. */
+ if (find_pc_section (pc) == NULL)
+ return NULL;
for (objfile = object_files;
objfile != NULL;
@@ -355,7 +363,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! */
+ /* Should also require that pc is <= end of objfile. FIXME! */
if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo]))
{
while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc)
@@ -399,6 +407,13 @@ lookup_minimal_symbol_by_pc (pc)
&& msymbol[hi].type == mst_abs)
--hi;
+ /* If "section" specified, skip any symbol from wrong section */
+ /* This is the new code that distinguishes it from the old function */
+ if (section)
+ while (hi >= 0
+ && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
+ --hi;
+
if (hi >= 0
&& ((best_symbol == NULL) ||
(SYMBOL_VALUE_ADDRESS (best_symbol) <
@@ -412,6 +427,16 @@ lookup_minimal_symbol_by_pc (pc)
return (best_symbol);
}
+/* Backward compatibility: search through the minimal symbol table
+ for a matching PC (no section given) */
+
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc (pc)
+ CORE_ADDR pc;
+{
+ return lookup_minimal_symbol_by_pc_section (pc, find_pc_mapped_section (pc));
+}
+
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
CORE_ADDR
find_stab_function_addr (namestring, pst, objfile)
@@ -427,11 +452,20 @@ find_stab_function_addr (namestring, pst, objfile)
if (p == NULL)
p = namestring;
n = p - namestring;
- p = alloca (n + 1);
+ p = alloca (n + 2);
strncpy (p, namestring, n);
p[n] = 0;
msym = lookup_minimal_symbol (p, pst->filename, objfile);
+ if (msym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal symbol name,
+ try again with an appended underscore if the minimal symbol
+ was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, pst->filename, objfile);
+ }
return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
}
#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
@@ -494,19 +528,21 @@ prim_record_minimal_symbol (name, address, ms_type, objfile)
}
prim_record_minimal_symbol_and_info (name, address, ms_type,
- NULL, section, objfile);
+ NULL, section, NULL, objfile);
}
/* Record a minimal symbol in the msym bunches. Returns the symbol
newly created. */
+
struct minimal_symbol *
prim_record_minimal_symbol_and_info (name, address, ms_type, info, section,
- objfile)
+ bfd_section, objfile)
const char *name;
CORE_ADDR address;
enum minimal_symbol_type ms_type;
char *info;
int section;
+ asection *bfd_section;
struct objfile *objfile;
{
register struct msym_bunch *new;
@@ -541,10 +577,12 @@ prim_record_minimal_symbol_and_info (name, address, ms_type, info, section,
msym_bunch = new;
}
msymbol = &msym_bunch -> contents[msym_bunch_index];
- SYMBOL_NAME (msymbol) = (char *) name;
+ SYMBOL_NAME (msymbol) = obsavestring ((char *) name, strlen (name),
+ &objfile->symbol_obstack);
SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
SYMBOL_VALUE_ADDRESS (msymbol) = address;
SYMBOL_SECTION (msymbol) = section;
+ SYMBOL_BFD_SECTION (msymbol) = bfd_section;
MSYMBOL_TYPE (msymbol) = ms_type;
/* FIXME: This info, if it remains, needs its own field. */
@@ -556,7 +594,8 @@ prim_record_minimal_symbol_and_info (name, address, ms_type, info, section,
}
/* Compare two minimal symbols by address and return a signed result based
- on unsigned comparisons, so that we sort into unsigned numeric order. */
+ on unsigned comparisons, so that we sort into unsigned numeric order.
+ Within groups with the same address, sort by name. */
static int
compare_minimal_symbols (fn1p, fn2p)
@@ -571,15 +610,25 @@ compare_minimal_symbols (fn1p, fn2p)
if (SYMBOL_VALUE_ADDRESS (fn1) < SYMBOL_VALUE_ADDRESS (fn2))
{
- return (-1);
+ return (-1); /* addr 1 is less than addr 2 */
}
else if (SYMBOL_VALUE_ADDRESS (fn1) > SYMBOL_VALUE_ADDRESS (fn2))
{
- return (1);
+ return (1); /* addr 1 is greater than addr 2 */
}
- else
+ else /* addrs are equal: sort by name */
{
- return (0);
+ char *name1 = SYMBOL_NAME (fn1);
+ char *name2 = SYMBOL_NAME (fn2);
+
+ if (name1 && name2) /* both have names */
+ return strcmp (name1, name2);
+ else if (name2)
+ return 1; /* fn1 has no name, so it is "less" */
+ else if (name1) /* fn2 has no name, so it is "less" */
+ return -1;
+ else
+ return (0); /* neither has a name, so they're equal. */
}
}
diff --git a/contrib/gdb/gdb/mipsread.c b/contrib/gdb/gdb/mipsread.c
index e02e4b1..614c27e 100644
--- a/contrib/gdb/gdb/mipsread.c
+++ b/contrib/gdb/gdb/mipsread.c
@@ -1,5 +1,5 @@
/* Read a symbol table in MIPS' format (Third-Eye).
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 1998
Free Software Foundation, Inc.
Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work
by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
@@ -54,9 +54,6 @@ mipscoff_symfile_read PARAMS ((struct objfile *, struct section_offsets *,
static void
mipscoff_symfile_finish PARAMS ((struct objfile *));
-static struct section_offsets *
-mipscoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
-
static void
read_alphacoff_dynamic_symtab PARAMS ((struct section_offsets *,
struct objfile *objfile));
@@ -96,7 +93,7 @@ mipscoff_symfile_read (objfile, section_offsets, mainline)
struct cleanup * back_to;
init_minimal_symbol_collection ();
- back_to = make_cleanup (discard_minimal_symbols, 0);
+ back_to = make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
@@ -147,29 +144,6 @@ mipscoff_symfile_finish (objfile)
{
}
-/* Fake up identical offsets for all sections. */
-
-static struct section_offsets *
-mipscoff_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = ((struct section_offsets *)
- obstack_alloc (&objfile->psymbol_obstack,
- (sizeof (struct section_offsets)
- + (sizeof (section_offsets->offsets)
- * (SECT_OFF_MAX - 1)))));
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- ANOFFSET (section_offsets, i) = addr;
-
- return section_offsets;
-}
-
/* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
standard coff section. The ELF format for the symbols differs from
the format defined in elf/external.h. It seems that a normal ELF 32 bit
@@ -448,12 +422,7 @@ read_alphacoff_dynamic_symtab (section_offsets, objfile)
}
}
- prim_record_minimal_symbol (obsavestring (name,
- strlen (name),
- &objfile -> symbol_obstack),
- sym_value,
- ms_type,
- objfile);
+ prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
}
}
@@ -466,7 +435,7 @@ static struct sym_fns ecoff_sym_fns =
mipscoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */
mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */
- mipscoff_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
+ default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
NULL /* next: pointer to next struct sym_fns */
};
diff --git a/contrib/gdb/gdb/mon960-rom.c b/contrib/gdb/gdb/mon960-rom.c
index 5a79923..32dcaff 100644
--- a/contrib/gdb/gdb/mon960-rom.c
+++ b/contrib/gdb/gdb/mon960-rom.c
@@ -1,4 +1,4 @@
-/* Remote target glue for the Intel 960 ROM monitor.
+/* Remote target glue for the Intel 960 MON960 ROM monitor.
Copyright 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,39 +25,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "serial.h"
#include "srec.h"
#include "xmodem.h"
+#include "symtab.h"
+#include "symfile.h" /* for generic_load */
-#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
-#define HAVE_SGTTY
-#endif
-
-#ifdef HAVE_SGTTY
-#include <sys/ioctl.h>
-#endif
-
-#include <sys/types.h> /* Needed by file.h on Sys V */
-#include <sys/file.h>
-#include <signal.h>
-#include <sys/stat.h>
#define USE_GENERIC_LOAD
-int quiet = 0; /* 1 => stifle unnecessary messages */
-serial_t mon960_serial;
-char *mon960_ttyname; /* name of tty to talk to mon960 on, or null */
-static struct monitor_ops mon960_cmds;
+static struct target_ops mon960_ops;
-#ifdef USE_GENERIC_LOAD
-extern void generic_load PARAMS ((char* filename, int from_tty));
-#endif
static void mon960_open PARAMS ((char *args, int from_tty));
#ifdef USE_GENERIC_LOAD
+
static void
mon960_load_gen (filename, from_tty)
char *filename;
int from_tty;
{
extern int inferior_pid;
+
generic_load (filename, from_tty);
/* Finally, make the PC point at the start address */
if (exec_bfd)
@@ -67,6 +53,7 @@ mon960_load_gen (filename, from_tty)
}
#else
+
static void
mon960_load (desc, file, hashmark)
serial_t desc;
@@ -97,9 +84,9 @@ mon960_load (desc, file, hashmark)
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
s->vma + s->_raw_size);
gdb_flush (gdb_stdout);
- monitor_printf (mon960_cmds.load, s->vma);
- if (mon960_cmds.loadresp)
- monitor_expect (mon960_cmds.loadresp, NULL, 0);
+ monitor_printf (current_monitor->load, s->vma);
+ if (current_monitor->loadresp)
+ monitor_expect (current_monitor->loadresp, NULL, 0);
xmodem_init_xfer (desc);
section_size = bfd_section_size (abfd, s);
for (i = 0; i < section_size; i += XMODEM_DATASIZE)
@@ -122,7 +109,8 @@ mon960_load (desc, file, hashmark)
if (hashmark)
putchar_unfiltered ('\n');
}
-#endif
+
+#endif /* USE_GENERIC_LOAD */
/* This array of registers need to match the indexes used by GDB.
This exists because the various ROM monitors use different strings
@@ -133,126 +121,133 @@ mon960_load (desc, file, hashmark)
/* g0-g14, fp, pfp, sp, rip,r3-15, pc, ac, tc, fp0-3 */
/* NOTE: "ip" is documented as "ir" in the Mon960 UG. */
/* NOTE: "ir" can't be accessed... but there's an ip and rip. */
-static char *mon960_regnames[NUM_REGS] = {
- /* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7", \
- /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",\
- /* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
- /* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp", \
- /* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",\
+static char *full_regnames[NUM_REGS] = {
+ /* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
+ /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ /* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ /* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
+ /* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",
};
+static char *mon960_regnames[NUM_REGS];
+
/* Define the monitor command strings. Since these are passed directly
through to a printf style function, we may include formatting
strings. We also need a CR or LF on the end. */
-static struct target_ops mon960_ops;
-
/* need to pause the monitor for timing reasons, so slow it down */
-static char *mon960_inits[] = {"\n\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r\n\r\n", NULL}; /* Exits sub-command mode & download cmds */
-static struct monitor_ops mon960_cmds =
+#if 0
+/* FIXME: this extremely long init string causes MON960 to return two NAKS
+ instead of performing the autobaud recognition, at least when gdb
+ is running on GNU/Linux. The short string below works on Linux, and on
+ SunOS using a tcp serial connection. Must retest on SunOS using a
+ direct serial connection; if that works, get rid of the long string. */
+static char *mon960_inits[] = {"\n\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r\n\r\n", NULL};
+#else
+static char *mon960_inits[] = { "\r", NULL};
+#endif
+
+static struct monitor_ops mon960_cmds ;
+
+static void
+init_mon960_cmds (void)
{
- MO_CLR_BREAK_USES_ADDR
- | MO_NO_ECHO_ON_OPEN
- | MO_SEND_BREAK_ON_STOP
- | MO_GETMEM_READ_SINGLE, /* flags */
- mon960_inits, /* Init strings */
- "go\n\r", /* continue command */
- "st\n\r", /* single step */
- "\n\r", /* break interrupts the program */
- NULL, /* set a breakpoint */
- /* can't use "br" because only 2 hw bps are supported */
- NULL, /* clear a breakpoint - "de" is for hw bps */
+ mon960_cmds.flags = MO_CLR_BREAK_USES_ADDR
+ | MO_NO_ECHO_ON_OPEN | MO_SEND_BREAK_ON_STOP | MO_GETMEM_READ_SINGLE ; /* flags */
+ mon960_cmds.init = mon960_inits; /* Init strings */
+ mon960_cmds.cont = "go\n\r"; /* continue command */
+ mon960_cmds.step = "st\n\r"; /* single step */
+ mon960_cmds.stop = NULL; /* break interrupts the program */
+ mon960_cmds.set_break = NULL; /* set a breakpoint */
+ mon960_cmds.clr_break = /* can't use "br" because only 2 hw bps are supported */
+ mon960_cmds.clr_all_break = NULL; /* clear a breakpoint - "de" is for hw bps */
NULL, /* clear all breakpoints */
- NULL, /* fill (start end val) */
- /* can't use "fi" because it takes words, not bytes */
- {
- /* can't use "mb", "md" or "mo" because they require interaction */
- NULL, /* setmem.cmdb (addr, value) */
- "md %x %x\n\r", /* setmem.cmdw (addr, value) */
- NULL, /* setmem.cmdl (addr, value) */
- NULL, /* setmem.cmdll (addr, value) */
- NULL, /* setmem.resp_delim */
- NULL, /* setmem.term */
- NULL, /* setmem.term_cmd */
- },
- {
- /* since the parsing of multiple bytes is difficult due to
- interspersed addresses, we'll only read 1 value at a time,
- even tho these can handle a count */
- "db %x\n\r", /* getmem.cmdb (addr, #bytes) */
- "ds %x\n\r", /* getmem.cmdw (addr, #swords) */
- "di %x\n\r", /* getmem.cmdl (addr, #words) */
- "dd %x\n\r", /* getmem.cmdll (addr, #dwords) */
- " : ", /* getmem.resp_delim */
- NULL, /* getmem.term */
- NULL, /* getmem.term_cmd */
- },
- {
- "md %s %x\n\r", /* setreg.cmd (name, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL /* setreg.term_cmd */
- },
- {
- "di %s\n\r", /* getreg.cmd (name) */
- " : ", /* getreg.resp_delim */
- NULL, /* getreg.term */
- NULL, /* getreg.term_cmd */
- },
- "re\n\r", /* dump_registers */
- "\\(\\w+\\)=\\([0-9a-fA-F]+\\)", /* register_pattern */
- NULL, /* supply_register */
+ mon960_cmds.fill = NULL; /* fill (start end val) */
+ /* can't use "fi" because it takes words, not bytes */
+ /* can't use "mb", "md" or "mo" because they require interaction */
+ mon960_cmds.setmem.cmdb = NULL; /* setmem.cmdb (addr, value) */
+ mon960_cmds.setmem.cmdw = NULL; /* setmem.cmdw (addr, value) */
+ mon960_cmds.setmem.cmdl = "md %x %x\n\r"; /* setmem.cmdl (addr, value) */
+ mon960_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ mon960_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ mon960_cmds.setmem.term = NULL; /* setmem.term */
+ mon960_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ /* since the parsing of multiple bytes is difficult due to
+ interspersed addresses, we'll only read 1 value at a time,
+ even tho these can handle a count */
+ mon960_cmds.getmem.cmdb = "db %x\n\r"; /* getmem.cmdb (addr, #bytes) */
+ mon960_cmds.getmem.cmdw = "ds %x\n\r"; /* getmem.cmdw (addr, #swords) */
+ mon960_cmds.getmem.cmdl = "di %x\n\r"; /* getmem.cmdl (addr, #words) */
+ mon960_cmds.getmem.cmdll = "dd %x\n\r"; /* getmem.cmdll (addr, #dwords) */
+ mon960_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */
+ mon960_cmds.getmem.term = NULL; /* getmem.term */
+ mon960_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ mon960_cmds.setreg.cmd = "md %s %x\n\r"; /* setreg.cmd (name, value) */
+ mon960_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ mon960_cmds.setreg.term = NULL; /* setreg.term */
+ mon960_cmds.setreg.term_cmd = NULL, /* setreg.term_cmd */
+ mon960_cmds.getreg.cmd = "di %s\n\r"; /* getreg.cmd (name) */
+ mon960_cmds.getreg.resp_delim = " : "; /* getreg.resp_delim */
+ mon960_cmds.getreg.term = NULL; /* getreg.term */
+ mon960_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ mon960_cmds.dump_registers = "re\n\r"; /* dump_registers */
+ mon960_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
+ mon960_cmds.supply_register = NULL; /* supply_register */
#ifdef USE_GENERIC_LOAD
- NULL, /* load_routine (defaults to SRECs) */
- NULL, /* download command */
- NULL, /* load response */
+ mon960_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ mon960_cmds.load = NULL; /* download command */
+ mon960_cmds.loadresp = NULL; /* load response */
#else
- mon960_load, /* load_routine (defaults to SRECs) */
- "do\n\r", /* download command */
- "Downloading\n\r", /* load response */
+ mon960_cmds.load_routine = mon960_load ; /* load_routine (defaults to SRECs) */
+ mon960_cmds.load = "do\n\r"; /* download command */
+ mon960_cmds.loadresp = "Downloading\n\r" ;/* load response */
#endif
- "=>", /* monitor command prompt */
- "\n\r", /* end-of-command delimitor */
- NULL, /* optional command terminator */
- &mon960_ops, /* target operations */
- SERIAL_1_STOPBITS, /* number of stop bits */
- mon960_regnames, /* registers names */
- MONITOR_OPS_MAGIC /* magic */
+ mon960_cmds.prompt = "=>"; /* monitor command prompt */
+ mon960_cmds.line_term = "\n\r"; /* end-of-command delimitor */
+ mon960_cmds.cmd_end = NULL; /* optional command terminator */
+ mon960_cmds.target = &mon960_ops; /* target operations */
+ mon960_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ mon960_cmds.regnames = mon960_regnames; /* registers names */
+ mon960_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
};
-/* invoked from monitor.c - opens the serial port */
static void
mon960_open (args, from_tty)
char *args;
int from_tty;
{
- char *serial_port_name = args;
- if (args)
- {
- char *cursor = serial_port_name = strsave (args);
+ char buf[64];
- while (*cursor && *cursor != ' ')
- cursor++;
+ monitor_open (args, &mon960_cmds, from_tty);
- if (*cursor)
- *cursor++ = 0;
+ /* Attempt to fetch the value of the first floating point register (fp0).
+ If the monitor returns a string containing the word "Bad" we'll assume
+ this processor has no floating point registers, and nullify the
+ regnames entries that refer to FP registers. */
- while (*cursor == ' ')
- cursor++;
+ monitor_printf (mon960_cmds.getreg.cmd, full_regnames[FP0_REGNUM]); /* di fp0 */
+ if (monitor_expect_prompt (buf, sizeof(buf)) != -1)
+ if (strstr(buf, "Bad") != NULL)
+ {
+ int i;
- }
- monitor_open (serial_port_name, &mon960_cmds, from_tty);
+ for (i = FP0_REGNUM; i < FP0_REGNUM + 4; i++)
+ mon960_regnames[i] = NULL;
+ }
}
-
void
_initialize_mon960 ()
{
+ memcpy(mon960_regnames, full_regnames, sizeof(full_regnames));
+
+ init_mon960_cmds ();
+
init_monitor_ops (&mon960_ops);
mon960_ops.to_shortname = "mon960"; /* for the target command */
- mon960_ops.to_longname = "Intel 960 rom monitor";
+ mon960_ops.to_longname = "Intel 960 MON960 monitor";
#ifdef USE_GENERIC_LOAD
mon960_ops.to_load = mon960_load_gen; /* FIXME - should go back and try "do" */
#endif
@@ -261,10 +256,9 @@ _initialize_mon960 ()
mon960_ops.to_remove_breakpoint = memory_remove_breakpoint;
mon960_ops.to_doc =
- "Debug on an Intel 960 eval board running the Mon960 rom monitor.\n"
- "Specify the serial device it is connected to (e.g. /dev/ttya).";
+ "Use an Intel 960 board running the MON960 debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
mon960_ops.to_open = mon960_open;
add_target (&mon960_ops);
}
-
diff --git a/contrib/gdb/gdb/monitor.c b/contrib/gdb/gdb/monitor.c
index db8913c..dc47d8c 100644
--- a/contrib/gdb/gdb/monitor.c
+++ b/contrib/gdb/gdb/monitor.c
@@ -1,5 +1,5 @@
/* Remote debugging interface for boot monitors, for GDB.
- Copyright 1990, 1991, 1992, 1993, 1995, 1996
+ Copyright 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1999
Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
Resurrected from the ashes by Stu Grossman.
@@ -30,6 +30,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
(or possibly TELNET) stream to a terminal multiplexor,
which in turn talks to the target board. */
+/* FIXME 32x64: This code assumes that registers and addresses are at
+ most 32 bits long. If they can be larger, you will need to declare
+ values as LONGEST and use %llx or some such to print values when
+ building commands to send to the monitor. Since we don't know of
+ any actual 64-bit targets with ROM monitors that use this code,
+ it's not an issue right now. -sts 4/18/96 */
+
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
@@ -52,6 +59,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "dcache.h"
#include "srec.h"
+static char *dev_name;
+static struct target_ops *targ_ops;
+
+static void monitor_vsprintf PARAMS ((char *sndbuf, char *pattern, va_list args));
+
static int readchar PARAMS ((int timeout));
static void monitor_command PARAMS ((char *args, int fromtty));
@@ -59,12 +71,14 @@ static void monitor_command PARAMS ((char *args, int fromtty));
static void monitor_fetch_register PARAMS ((int regno));
static void monitor_store_register PARAMS ((int regno));
+static int monitor_printable_string PARAMS ((char *newstr, char *oldstr));
+static void monitor_error PARAMS ((char *format, CORE_ADDR memaddr, int len, char *string, int final_char));
static void monitor_detach PARAMS ((char *args, int from_tty));
static void monitor_resume PARAMS ((int pid, int step, enum target_signal sig));
static void monitor_interrupt PARAMS ((int signo));
static void monitor_interrupt_twice PARAMS ((int signo));
static void monitor_interrupt_query PARAMS ((void));
-static void monitor_wait_cleanup PARAMS ((int old_timeout));
+static void monitor_wait_cleanup PARAMS ((void *old_timeout));
static int monitor_wait PARAMS ((int pid, struct target_waitstatus *status));
static void monitor_fetch_registers PARAMS ((int regno));
@@ -78,15 +92,23 @@ static void monitor_kill PARAMS ((void));
static void monitor_load PARAMS ((char *file, int from_tty));
static void monitor_mourn_inferior PARAMS ((void));
static void monitor_stop PARAMS ((void));
-static void monitor_debug PARAMS ((char *prefix, char *string, char *suffix));
static int monitor_read_memory PARAMS ((CORE_ADDR addr, char *myaddr,int len));
static int monitor_write_memory PARAMS ((CORE_ADDR addr, char *myaddr,int len));
-
+static int monitor_write_memory_bytes PARAMS ((CORE_ADDR addr,
+ char *myaddr,int len));
+static int monitor_write_memory_block PARAMS((
+ CORE_ADDR memaddr ,
+ char * myaddr ,
+ int len)) ;
static int monitor_expect_regexp PARAMS ((struct re_pattern_buffer *pat,
char *buf, int buflen));
+static void monitor_dump_regs PARAMS((void)) ;
+#if 0
static int from_hex PARAMS ((int a));
static unsigned long get_hex_word PARAMS ((void));
+#endif
+static void parse_register_dump PARAMS ((char *, int));
static struct monitor_ops *current_monitor;
@@ -98,6 +120,12 @@ static int in_monitor_wait = 0; /* Non-zero means we are in monitor_wait() */
static void (*ofunc)(); /* Old SIGINT signal handler */
+/* Extra remote debugging for developing a new rom monitor variation */
+#if ! defined(EXTRA_RDEBUG)
+#define EXTRA_RDEBUG 0
+#endif
+#define RDEBUG(stuff) { if (EXTRA_RDEBUG && remote_debug) printf stuff ; }
+
/* Descriptor for I/O to remote machine. Initialize it to NULL so
that monitor_open knows that we don't have a file open when the
program starts. */
@@ -116,55 +144,156 @@ static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when
monitor_wait wakes up. */
static DCACHE *remote_dcache;
+static int first_time=0; /* is this the first time we're executing after
+ gaving created the child proccess? */
-/* monitor_debug is like fputs_unfiltered, except it prints special
- characters in printable fashion. */
+/* Convert a string into a printable representation, Return # byte in the
+ new string. */
+
+static int
+monitor_printable_string (newstr, oldstr)
+ char *newstr;
+ char *oldstr;
+{
+ char *save = newstr;
+ int ch;
+
+ while ((ch = *oldstr++) != '\0')
+ {
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ *newstr++ = ch;
+
+ else
+ {
+ sprintf (newstr, "\\x%02x", ch & 0xff);
+ newstr += 4;
+ }
+ break;
+
+ case '\\': *newstr++ = '\\'; *newstr++ = '\\'; break;
+ case '\b': *newstr++ = '\\'; *newstr++ = 'b'; break;
+ case '\f': *newstr++ = '\\'; *newstr++ = 't'; break;
+ case '\n': *newstr++ = '\\'; *newstr++ = 'n'; break;
+ case '\r': *newstr++ = '\\'; *newstr++ = 'r'; break;
+ case '\t': *newstr++ = '\\'; *newstr++ = 't'; break;
+ case '\v': *newstr++ = '\\'; *newstr++ = 'v'; break;
+ }
+ }
+
+ *newstr++ = '\0';
+ return newstr - save;
+}
+
+/* Print monitor errors with a string, converting the string to printable
+ representation. */
static void
-monitor_debug (prefix, string, suffix)
- char *prefix;
+monitor_error (format, memaddr, len, string, final_char)
+ char *format;
+ CORE_ADDR memaddr;
+ int len;
char *string;
- char *suffix;
+ int final_char;
{
+ int real_len = (len == 0 && string != (char *)0) ? strlen (string) : len;
+ char *safe_string = alloca ((real_len * 4) + 1);
+ char *p, *q;
int ch;
+ int safe_len = monitor_printable_string (safe_string, string);
- /* print prefix and suffix after each line */
- static int new_line=1;
- if (new_line==1) { /* print prefix if last char was a newline */
- fputs_unfiltered (prefix, gdb_stderr);
- new_line=0;
- }
- if (strchr(string,'\n')) /* save state for next call */
- new_line=1;
+ if (final_char)
+ error (format, (int)memaddr, p - safe_string, safe_string, final_char);
+ else
+ error (format, (int)memaddr, p - safe_string, safe_string);
+}
- while ((ch = *string++) != '\0')
- {
- switch (ch) {
- default:
- if (isprint (ch))
- fputc_unfiltered (ch, gdb_stderr);
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (a)
+ int a;
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else
+ if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10 ;
+ else error ("Invalid hex digit %d", a);
+}
- else
- fprintf_unfiltered (gdb_stderr, "\\%03o", ch);
+/* monitor_vsprintf - similar to vsprintf but handles 64-bit addresses
- break;
+ This function exists to get around the problem that many host platforms
+ don't have a printf that can print 64-bit addresses. The %A format
+ specification is recognized as a special case, and causes the argument
+ to be printed as a 64-bit hexadecimal address.
- case '\\': fputs_unfiltered ("\\\\", gdb_stderr); break;
- case '\b': fputs_unfiltered ("\\b", gdb_stderr); break;
- case '\f': fputs_unfiltered ("\\f", gdb_stderr); break;
- case '\n': fputs_unfiltered ("\\n", gdb_stderr); break;
- case '\r': fputs_unfiltered ("\\r", gdb_stderr); break;
- case '\t': fputs_unfiltered ("\\t", gdb_stderr); break;
- case '\v': fputs_unfiltered ("\\v", gdb_stderr); break;
- }
- }
+ Only format specifiers of the form "[0-9]*[a-z]" are recognized.
+ If it is a '%s' format, the argument is a string; otherwise the
+ argument is assumed to be a long integer.
- if (new_line==1) { /* print suffix if last char was a newline */
- fputs_unfiltered (suffix, gdb_stderr);
- fputs_unfiltered ("\n", gdb_stderr);
- }
+ %% is also turned into a single %.
+*/
+
+static void
+monitor_vsprintf (sndbuf, pattern, args)
+ char *sndbuf;
+ char *pattern;
+ va_list args;
+{
+ char format[10];
+ char fmt;
+ char *p;
+ int i;
+ long arg_int;
+ CORE_ADDR arg_addr;
+ char *arg_string;
+
+ for (p = pattern; *p; p++)
+ {
+ if (*p == '%')
+ {
+ /* Copy the format specifier to a separate buffer. */
+ format[0] = *p++;
+ for (i = 1; *p >= '0' && *p <= '9' && i < (int) sizeof (format) - 2;
+ i++, p++)
+ format[i] = *p;
+ format[i] = fmt = *p;
+ format[i+1] = '\0';
+
+ /* Fetch the next argument and print it. */
+ switch (fmt)
+ {
+ case '%':
+ strcpy (sndbuf, "%");
+ break;
+ case 'A':
+ arg_addr = va_arg (args, CORE_ADDR);
+ strcpy (sndbuf, paddr_nz (arg_addr));
+ break;
+ case 's':
+ arg_string = va_arg (args, char *);
+ sprintf (sndbuf, format, arg_string);
+ break;
+ default:
+ arg_int = va_arg (args, long);
+ sprintf (sndbuf, format, arg_int);
+ break;
+ }
+ sndbuf += strlen (sndbuf);
+ }
+ else
+ *sndbuf++ = *p;
+ }
+ *sndbuf = '\0';
}
+
/* monitor_printf_noecho -- Send data to monitor, but don't expect an echo.
Works just like printf. */
@@ -188,18 +317,25 @@ monitor_printf_noecho (va_alist)
pattern = va_arg (args, char *);
#endif
- vsprintf (sndbuf, pattern, args);
-
- if (remote_debug > 0)
- monitor_debug ("sent -->", sndbuf, "<--");
+ monitor_vsprintf (sndbuf, pattern, args);
len = strlen (sndbuf);
-
if (len + 1 > sizeof sndbuf)
abort ();
- if (SERIAL_WRITE(monitor_desc, sndbuf, len))
- fprintf_unfiltered (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
+#if 0
+ if (remote_debug > 0)
+ puts_debug ("sent -->", sndbuf, "<--");
+#endif
+ if (EXTRA_RDEBUG
+ && remote_debug)
+ {
+ char *safe_string = (char *) alloca ((strlen (sndbuf) * 4) + 1);
+ monitor_printable_string (safe_string, sndbuf);
+ printf ("sent[%s]\n", safe_string);
+ }
+
+ monitor_write (sndbuf, len);
}
/* monitor_printf -- Send data to monitor and check the echo. Works just like
@@ -225,26 +361,78 @@ monitor_printf (va_alist)
pattern = va_arg (args, char *);
#endif
- vsprintf (sndbuf, pattern, args);
-
- if (remote_debug > 0)
- monitor_debug ("sent -->", sndbuf, "<--");
+ monitor_vsprintf (sndbuf, pattern, args);
len = strlen (sndbuf);
-
if (len + 1 > sizeof sndbuf)
abort ();
- if (SERIAL_WRITE(monitor_desc, sndbuf, len))
- fprintf_unfiltered (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
+#if 0
+ if (remote_debug > 0)
+ puts_debug ("sent -->", sndbuf, "<--");
+#endif
+ if (EXTRA_RDEBUG
+ && remote_debug)
+ {
+ char *safe_string = (char *) alloca ((len * 4) + 1);
+ monitor_printable_string (safe_string, sndbuf);
+ printf ("sent[%s]\n", safe_string);
+ }
+
+ monitor_write (sndbuf, len);
/* We used to expect that the next immediate output was the characters we
just output, but sometimes some extra junk appeared before the characters
we expected, like an extra prompt, or a portmaster sending telnet negotiations.
So, just start searching for what we sent, and skip anything unknown. */
+ RDEBUG(("ExpectEcho\n"))
monitor_expect (sndbuf, (char *)0, 0);
}
+
+/* Write characters to the remote system. */
+
+void
+monitor_write (buf, buflen)
+ char *buf;
+ int buflen;
+{
+ if (SERIAL_WRITE(monitor_desc, buf, buflen))
+ fprintf_unfiltered (gdb_stderr, "SERIAL_WRITE failed: %s\n",
+ safe_strerror (errno));
+}
+
+
+/* Read a binary character from the remote system, doing all the fancy
+ timeout stuff, but without interpreting the character in any way,
+ and without printing remote debug information. */
+
+int
+monitor_readchar ()
+{
+ int c;
+ int looping;
+
+ do
+ {
+ looping = 0;
+ c = SERIAL_READCHAR (monitor_desc, timeout);
+
+ if (c >= 0)
+ c &= 0xff; /* don't lose bit 7 */
+ }
+ while (looping);
+
+ if (c >= 0)
+ return c;
+
+ if (c == SERIAL_TIMEOUT)
+ error ("Timeout reading from remote system.");
+
+ perror_with_name ("remote-monitor");
+}
+
+
/* Read a character from the remote system, doing all the fancy
timeout stuff. */
@@ -264,13 +452,18 @@ readchar (timeout)
if (c >= 0)
{
c &= 0x7f;
+#if 0
+ /* This seems to interfere with proper function of the
+ input stream */
if (remote_debug > 0)
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
- monitor_debug ("read -->", buf, "<--");
+ puts_debug ("read -->", buf, "<--");
}
+
+#endif
}
/* Canonicialize \n\r combinations into one \r */
@@ -299,11 +492,12 @@ readchar (timeout)
return c;
if (c == SERIAL_TIMEOUT)
-#ifdef MAINTENANCE_CMDS
+#if 0 /* MAINTENANCE_CMDS */
+ /* I fail to see how detaching here can be useful */
if (in_monitor_wait) /* Watchdog went off */
{
target_mourn_inferior ();
- error ("Watchdog has expired. Target detached.\n");
+ error ("GDB serial timeout has expired. Target detached.\n");
}
else
#endif
@@ -328,6 +522,15 @@ monitor_expect (string, buf, buflen)
char *p = string;
int obuflen = buflen;
int c;
+ extern struct target_ops *targ_ops;
+
+ if (EXTRA_RDEBUG
+ && remote_debug)
+ {
+ char *safe_string = (char *) alloca ((strlen (string) * 4) + 1);
+ monitor_printable_string (safe_string, string);
+ printf ("MON Expecting '%s'\n", safe_string);
+ }
immediate_quit = 1;
while (1)
@@ -368,6 +571,12 @@ monitor_expect (string, buf, buflen)
return 0;
}
}
+ else if ((c == '\021' || c == '\023') &&
+ (STREQ (targ_ops->to_shortname, "m32r")
+ || STREQ (targ_ops->to_shortname, "mon2000")))
+ { /* m32r monitor emits random DC1/DC3 chars */
+ continue;
+ }
else
{
p = string;
@@ -387,7 +596,7 @@ monitor_expect_regexp (pat, buf, buflen)
{
char *mybuf;
char *p;
-
+ RDEBUG(("MON Expecting regexp\n")) ;
if (buf)
mybuf = buf;
else
@@ -425,26 +634,27 @@ monitor_expect_regexp (pat, buf, buflen)
o give your command
o *then* wait for the prompt.
- Thus the last thing that a procedure does with the serial line
- will be an monitor_expect_prompt(). Exception: monitor_resume does not
- wait for the prompt, because the terminal is being handed over
- to the inferior. However, the next thing which happens after that
- is a monitor_wait which does wait for the prompt.
- Note that this includes abnormal exit, e.g. error(). This is
- necessary to prevent getting into states from which we can't
- recover. */
+ Thus the last thing that a procedure does with the serial line will
+ be an monitor_expect_prompt(). Exception: monitor_resume does not
+ wait for the prompt, because the terminal is being handed over to
+ the inferior. However, the next thing which happens after that is
+ a monitor_wait which does wait for the prompt. Note that this
+ includes abnormal exit, e.g. error(). This is necessary to prevent
+ getting into states from which we can't recover. */
int
monitor_expect_prompt (buf, buflen)
char *buf;
int buflen;
{
- return monitor_expect (PROMPT, buf, buflen);
+ RDEBUG(("MON Expecting prompt\n"))
+ return monitor_expect (current_monitor->prompt, buf, buflen);
}
/* Get N 32-bit words from remote, each preceded by a space, and put
them in registers starting at REGNO. */
+#if 0
static unsigned long
get_hex_word ()
{
@@ -468,6 +678,7 @@ get_hex_word ()
return val;
}
+#endif
static void
compile_pattern (pattern, compiled_pattern, fastmap)
@@ -476,7 +687,7 @@ compile_pattern (pattern, compiled_pattern, fastmap)
char *fastmap;
{
int tmp;
- char *val;
+ const char *val;
compiled_pattern->fastmap = fastmap;
@@ -496,9 +707,6 @@ compile_pattern (pattern, compiled_pattern, fastmap)
/* Open a connection to a remote debugger. NAME is the filename used
for communication. */
-static char *dev_name;
-static struct target_ops *targ_ops;
-
void
monitor_open (args, mon_ops, from_tty)
char *args;
@@ -506,7 +714,6 @@ monitor_open (args, mon_ops, from_tty)
int from_tty;
{
char *name;
- int i;
char **p;
if (mon_ops->magic != MONITOR_OPS_MAGIC)
@@ -569,7 +776,8 @@ monitor_open (args, mon_ops, from_tty)
monitor_stop ();
if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0)
{
- monitor_expect_prompt (NULL, 0);
+ RDEBUG(("EXP Open echo\n")) ;
+ monitor_expect_prompt (NULL, 0);
}
}
@@ -607,8 +815,10 @@ monitor_open (args, mon_ops, from_tty)
monitor_printf (current_monitor->line_term);
- remote_dcache = dcache_init (monitor_read_memory, monitor_write_memory);
-
+ if (current_monitor->flags & MO_HAS_BLOCKWRITES)
+ remote_dcache = dcache_init (monitor_read_memory, monitor_write_memory_block);
+ else
+ remote_dcache = dcache_init (monitor_read_memory, monitor_write_memory);
start_remote ();
}
@@ -644,11 +854,12 @@ monitor_supply_register (regno, valstr)
int regno;
char *valstr;
{
- unsigned LONGEST val;
+ unsigned int val;
unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
char *p;
val = strtoul (valstr, &p, 16);
+ RDEBUG(("Supplying Register %d %s\n",regno,valstr)) ;
if (val == 0 && valstr == p)
error ("monitor_supply_register (%d): bad value from monitor: %s.",
@@ -665,17 +876,35 @@ monitor_supply_register (regno, valstr)
/* Tell the remote machine to resume. */
+void
+flush_monitor_dcache ()
+{
+ dcache_flush (remote_dcache);
+}
+
static void
monitor_resume (pid, step, sig)
int pid, step;
enum target_signal sig;
{
+ /* Some monitors require a different command when starting a program */
+ RDEBUG(("MON resume\n")) ;
+ if (current_monitor->flags & MO_RUN_FIRST_TIME && first_time == 1)
+ {
+ first_time = 0;
+ monitor_printf ("run\r");
+ if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
+ dump_reg_flag = 1;
+ return;
+ }
dcache_flush (remote_dcache);
if (step)
- monitor_printf (STEP_CMD);
+ monitor_printf (current_monitor->step);
else
{
- monitor_printf (CONT_CMD);
+ if (current_monitor->continue_hook)
+ (*current_monitor->continue_hook)() ;
+ else monitor_printf (current_monitor->cont);
if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
dump_reg_flag = 1;
}
@@ -686,11 +915,12 @@ monitor_resume (pid, step, sig)
form REG=VAL. Each description is split up into a name and a value
string which are passed down to monitor specific code. */
-static char *
+static void
parse_register_dump (buf, len)
char *buf;
int len;
{
+ RDEBUG(("MON Parsing register dump\n"))
while (1)
{
int regnamelen, vallen;
@@ -699,6 +929,8 @@ parse_register_dump (buf, len)
points to the start of the register value. */
struct re_registers register_strings;
+ memset (&register_strings, 0, sizeof (struct re_registers));
+
if (re_search (&register_pattern, buf, len, 0, len,
&register_strings) == -1)
break;
@@ -763,13 +995,47 @@ Give up (and stop debugging it)? "))
static void
monitor_wait_cleanup (old_timeout)
- int old_timeout;
+ void *old_timeout;
{
- timeout = old_timeout;
+ timeout = *(int*)old_timeout;
signal (SIGINT, ofunc);
in_monitor_wait = 0;
}
+
+
+void monitor_wait_filter(char * buf,
+ int bufmax,
+ int * ext_resp_len,
+ struct target_waitstatus * status
+ )
+{
+ int resp_len ;
+ do
+ {
+ resp_len = monitor_expect_prompt (buf, bufmax);
+ * ext_resp_len =resp_len ;
+
+ if (resp_len <= 0)
+ fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf);
+ }
+ while (resp_len < 0);
+
+ /* Print any output characters that were preceded by ^O. */
+ /* FIXME - This would be great as a user settabgle flag */
+ if (remote_debug ||
+ current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT)
+ {
+ int i;
+
+ for (i = 0; i < resp_len - 1; i++)
+ if (buf[i] == 0x0f)
+ putchar_unfiltered (buf[++i]);
+ }
+}
+
+
+
/* Wait until the remote machine stops, then return, storing status in
status just as `wait' would. */
@@ -786,9 +1052,11 @@ monitor_wait (pid, status)
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
- old_chain = make_cleanup (monitor_wait_cleanup, old_timeout);
+ old_chain = make_cleanup (monitor_wait_cleanup, &old_timeout);
+ RDEBUG(("MON wait\n"))
-#ifdef MAINTENANCE_CMDS
+#if 0 /* MAINTENANCE_CMDS */
+ /* This is somthing other than a maintenance command */
in_monitor_wait = 1;
timeout = watchdog > 0 ? watchdog : -1;
#else
@@ -797,6 +1065,11 @@ monitor_wait (pid, status)
ofunc = (void (*)()) signal (SIGINT, monitor_interrupt);
+ if (current_monitor->wait_filter)
+ (*current_monitor->wait_filter)(buf,sizeof (buf),&resp_len,status) ;
+ else monitor_wait_filter(buf,sizeof (buf),&resp_len,status) ;
+
+#if 0 /* Transferred to monitor wait filter */
do
{
resp_len = monitor_expect_prompt (buf, sizeof (buf));
@@ -806,20 +1079,36 @@ monitor_wait (pid, status)
}
while (resp_len < 0);
+ /* Print any output characters that were preceded by ^O. */
+ /* FIXME - This would be great as a user settabgle flag */
+ if (remote_debug ||
+ current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT)
+ {
+ int i;
+
+ for (i = 0; i < resp_len - 1; i++)
+ if (buf[i] == 0x0f)
+ putchar_unfiltered (buf[++i]);
+ }
+#endif
+
signal (SIGINT, ofunc);
timeout = old_timeout;
-
+#if 0
if (dump_reg_flag && current_monitor->dump_registers)
{
dump_reg_flag = 0;
-
monitor_printf (current_monitor->dump_registers);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
}
if (current_monitor->register_pattern)
parse_register_dump (buf, resp_len);
+#else
+ RDEBUG(("Wait fetching registers after stop\n")) ;
+ monitor_dump_regs() ;
+#endif
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TRAP;
@@ -843,10 +1132,11 @@ monitor_fetch_register (regno)
char regbuf[MAX_REGISTER_RAW_SIZE * 2 + 1];
int i;
- name = REGNAMES (regno);
+ name = current_monitor->regnames[regno];
+ RDEBUG(("MON fetchreg %d '%s'\n",regno,name))
- if (!name)
- {
+ if (!name || (*name == '\0'))
+ { RDEBUG(("No register known for %d\n",regno))
supply_register (regno, zerobuf);
return;
}
@@ -860,7 +1150,30 @@ monitor_fetch_register (regno)
searching from the start of the buf. */
if (current_monitor->getreg.resp_delim)
- monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ {
+ RDEBUG(("EXP getreg.resp_delim\n"))
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ /* Handle case of first 32 registers listed in pairs. */
+ if (current_monitor->flags & MO_32_REGS_PAIRED
+ && regno & 1 == 1 && regno < 32)
+ { RDEBUG(("EXP getreg.resp_delim\n")) ;
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ }
+ }
+
+ /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
+ if (current_monitor->flags & MO_HEX_PREFIX)
+ {
+ int c;
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+ if ((c == '0') && ((c = readchar (timeout)) == 'x'))
+ ;
+ else
+ error ("Bad value returned from monitor while fetching register %x.",
+ regno);
+ }
/* Read upto the maximum number of hex digits for this register, skipping
spaces, but stop reading if something else is seen. Some monitors
@@ -880,6 +1193,7 @@ monitor_fetch_register (regno)
}
regbuf[i] = '\000'; /* terminate the number */
+ RDEBUG(("REGVAL '%s'\n",regbuf)) ;
/* If TERM is present, we wait for that to show up. Also, (if TERM
is present), we will send TERM_CMD if that is present. In any
@@ -888,30 +1202,49 @@ monitor_fetch_register (regno)
if (current_monitor->getreg.term)
{
+ RDEBUG(("EXP getreg.term\n"))
monitor_expect (current_monitor->getreg.term, NULL, 0); /* get response */
+ }
- if (current_monitor->getreg.term_cmd)
- {
- monitor_printf (current_monitor->getreg.term_cmd);
- monitor_expect_prompt (NULL, 0);
- }
+ if (current_monitor->getreg.term_cmd)
+ { RDEBUG(("EMIT getreg.term.cmd\n"))
+ monitor_printf (current_monitor->getreg.term_cmd);
}
- else
+ if (! current_monitor->getreg.term || /* Already expected or */
+ current_monitor->getreg.term_cmd) /* ack expected */
monitor_expect_prompt (NULL, 0); /* get response */
monitor_supply_register (regno, regbuf);
}
+/* Sometimes, it takes several commands to dump the registers */
+/* This is a primitive for use by variations of monitor interfaces in
+ case they need to compose the operation.
+ */
+int monitor_dump_reg_block(char * block_cmd)
+{
+ char buf[1024];
+ int resp_len;
+ monitor_printf (block_cmd);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ parse_register_dump (buf, resp_len);
+ return 1 ;
+}
+
+
/* Read the remote registers into the block regs. */
+/* Call the specific function if it has been provided */
-static void monitor_dump_regs ()
+static void
+monitor_dump_regs ()
{
- if (current_monitor->dump_registers)
- {
- char buf[200];
- int resp_len;
-
- monitor_printf (current_monitor->dump_registers);
+ char buf[1024];
+ int resp_len;
+ if (current_monitor->dumpregs)
+ (*(current_monitor->dumpregs))() ; /* call supplied function */
+ else
+ if (current_monitor->dump_registers) /* default version */
+ { monitor_printf (current_monitor->dump_registers);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
parse_register_dump (buf, resp_len);
}
@@ -923,6 +1256,7 @@ static void
monitor_fetch_registers (regno)
int regno;
{
+ RDEBUG(("MON fetchregs\n")) ;
if (current_monitor->getreg.cmd)
{
if (regno >= 0)
@@ -946,25 +1280,41 @@ monitor_store_register (regno)
int regno;
{
char *name;
- unsigned LONGEST val;
+ unsigned int val;
- name = REGNAMES (regno);
- if (!name)
- return;
+ name = current_monitor->regnames[regno];
+ if (!name || (*name == '\0'))
+ { RDEBUG(("MON Cannot store unknown register\n"))
+ return;
+ }
val = read_register (regno);
+ RDEBUG(("MON storeg %d %08x\n",regno,(unsigned int)val))
- /* send the register deposit command */
-
- monitor_printf (current_monitor->setreg.cmd, name, val);
+ /* send the register deposit command */
-/* It's possible that there are actually some monitors out there that
- will prompt you when you set a register. In that case, you may
- need to add some code here to deal with TERM and TERM_CMD (see
- monitor_fetch_register to get an idea of what's needed...) */
+ if (current_monitor->flags & MO_REGISTER_VALUE_FIRST)
+ monitor_printf (current_monitor->setreg.cmd, val, name);
+ else if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf (current_monitor->setreg.cmd, name);
+ else
+ monitor_printf (current_monitor->setreg.cmd, name, val);
- monitor_expect_prompt (NULL, 0);
-}
+ if (current_monitor->setreg.term)
+ { RDEBUG(("EXP setreg.term\n"))
+ monitor_expect (current_monitor->setreg.term, NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%x\r", val);
+ monitor_expect_prompt (NULL, 0);
+ }
+ else
+ monitor_expect_prompt (NULL, 0);
+ if (current_monitor->setreg.term_cmd) /* Mode exit required */
+ { RDEBUG(("EXP setreg_termcmd\n")) ;
+ monitor_printf("%s",current_monitor->setreg.term_cmd) ;
+ monitor_expect_prompt(NULL,0) ;
+ }
+} /* monitor_store_register */
/* Store the remote registers. */
@@ -1007,10 +1357,15 @@ monitor_write_memory (memaddr, myaddr, len)
char *myaddr;
int len;
{
- unsigned LONGEST val;
+ unsigned int val, hostval ;
char *cmd;
int i;
+ RDEBUG(("MON write %d %08x\n",len,(unsigned long)memaddr))
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+
/* Use memory fill command for leading 0 bytes. */
if (current_monitor->fill)
@@ -1021,10 +1376,11 @@ monitor_write_memory (memaddr, myaddr, len)
if (i > 4) /* More than 4 zeros is worth doing */
{
- if (current_monitor->flags & MO_FILL_USES_ADDR)
- monitor_printf (current_monitor->fill, memaddr, memaddr + i, 0);
- else
- monitor_printf (current_monitor->fill, memaddr, i, 0);
+ RDEBUG(("MON FILL %d\n",i))
+ if (current_monitor->flags & MO_FILL_USES_ADDR)
+ monitor_printf (current_monitor->fill, memaddr, (memaddr + i)-1, 0);
+ else
+ monitor_printf (current_monitor->fill, memaddr, i, 0);
monitor_expect_prompt (NULL, 0);
@@ -1032,12 +1388,16 @@ monitor_write_memory (memaddr, myaddr, len)
}
}
+#if 0
+ /* Can't actually use long longs if VAL is an int (nice idea, though). */
if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->setmem.cmdll)
{
len = 8;
cmd = current_monitor->setmem.cmdll;
}
- else if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl)
+ else
+#endif
+ if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl)
{
len = 4;
cmd = current_monitor->setmem.cmdl;
@@ -1054,14 +1414,226 @@ monitor_write_memory (memaddr, myaddr, len)
}
val = extract_unsigned_integer (myaddr, len);
+
+ if (len == 4)
+ { hostval = * (unsigned int *) myaddr ;
+ RDEBUG(("Hostval(%08x) val(%08x)\n",hostval,val)) ;
+ }
- monitor_printf (cmd, memaddr, val);
+
+ if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM)
+ monitor_printf_noecho (cmd, memaddr, val);
+ else if (current_monitor->flags & MO_SETMEM_INTERACTIVE)
+ {
+
+ monitor_printf_noecho (cmd, memaddr);
+
+ if (current_monitor->setmem.term)
+ { RDEBUG(("EXP setmem.term")) ;
+ monitor_expect (current_monitor->setmem.term, NULL, 0);
+ monitor_printf ("%x\r", val);
+ }
+ if (current_monitor->setmem.term_cmd)
+ { /* Emit this to get out of the memory editing state */
+ monitor_printf("%s",current_monitor->setmem.term_cmd) ;
+ /* Drop through to expecting a prompt */
+ }
+ }
+ else
+ monitor_printf (cmd, memaddr, val);
monitor_expect_prompt (NULL, 0);
return len;
}
+
+static int
+monitor_write_even_block(memaddr,myaddr,len)
+ CORE_ADDR memaddr ;
+ char * myaddr ;
+ int len ;
+{
+ unsigned int val ;
+ int written = 0 ;;
+ /* Enter the sub mode */
+ monitor_printf(current_monitor->setmem.cmdl,memaddr) ;
+ monitor_expect_prompt(NULL,0) ;
+
+ while (len)
+ {
+ val = extract_unsigned_integer(myaddr,4) ; /* REALLY */
+ monitor_printf("%x\r",val) ;
+ myaddr += 4 ;
+ memaddr += 4 ;
+ written += 4 ;
+ RDEBUG((" @ %08x\n",memaddr))
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt(NULL,0) ;
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt(NULL,0) ;
+ return written ;
+}
+
+
+static int monitor_write_memory_bytes(memaddr,myaddr,len)
+ CORE_ADDR memaddr ;
+ char * myaddr ;
+ int len ;
+{
+ unsigned char val ;
+ int written = 0 ;
+ if (len == 0) return 0 ;
+ /* Enter the sub mode */
+ monitor_printf(current_monitor->setmem.cmdb,memaddr) ;
+ monitor_expect_prompt(NULL,0) ;
+ while (len)
+ {
+ val = *myaddr ;
+ monitor_printf("%x\r",val) ;
+ myaddr++ ;
+ memaddr++ ;
+ written++ ;
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt(NULL,0) ;
+ len-- ;
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt(NULL,0) ;
+ return written ;
+}
+
+
+static void
+longlongendswap (unsigned char * a)
+{
+ int i,j ;
+ unsigned char x ;
+ i = 0 ; j = 7 ;
+ while (i < 4)
+ { x = *(a+i) ;
+ *(a+i) = *(a+j) ;
+ *(a+j) = x ;
+ i++ , j-- ;
+ }
+}
+/* Format 32 chars of long long value, advance the pointer */
+static char * hexlate = "0123456789abcdef" ;
+static char * longlong_hexchars(unsigned long long value,
+ char * outbuff )
+{
+ if (value == 0) { *outbuff++ = '0' ; return outbuff ; }
+ else
+ { static unsigned char disbuf[8] ; /* disassembly buffer */
+ unsigned char * scan , * limit ; /* loop controls */
+ unsigned char c , nib ;
+ int leadzero = 1 ;
+ scan = disbuf ; limit = scan + 8 ;
+ { unsigned long long * dp ;
+ dp = (unsigned long long *) scan ;
+ *dp = value ;
+ }
+ longlongendswap(disbuf) ; /* FIXME: ONly on big endian hosts */
+ while (scan < limit)
+ { c = *scan++ ; /* a byte of our long long value */
+ if (leadzero)
+ if (c == 0) continue ;
+ else leadzero = 0 ; /* henceforth we print even zeroes */
+ nib = c >> 4 ; /* high nibble bits */
+ *outbuff++ = hexlate[nib] ;
+ nib = c & 0x0f ; /* low nibble bits */
+ *outbuff++ = hexlate[nib] ;
+ }
+ return outbuff ;
+ }
+} /* longlong_hexchars */
+
+
+
+/* I am only going to call this when writing virtual byte streams.
+ Which possably entails endian conversions
+ */
+static int monitor_write_memory_longlongs(memaddr,myaddr,len)
+ CORE_ADDR memaddr ;
+ char * myaddr ;
+ int len ;
+{
+ static char hexstage[20] ; /* At least 16 digits required, plus null */
+ char * endstring ;
+ long long * llptr ;
+ long long value ;
+ int written = 0 ;
+ llptr = (unsigned long long *) myaddr ;
+ if (len == 0 ) return 0 ;
+ monitor_printf(current_monitor->setmem.cmdll,memaddr) ;
+ monitor_expect_prompt(NULL,0) ;
+ while (len >= 8 )
+ {
+ value = *llptr ;
+ endstring = longlong_hexchars(*llptr,hexstage) ;
+ *endstring = '\0' ; /* NUll terminate for printf */
+ monitor_printf("%s\r",hexstage) ;
+ llptr++ ;
+ memaddr += 8 ;
+ written += 8 ;
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt(NULL,0) ;
+ len -= 8 ;
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt(NULL,0) ;
+ return written ;
+} /* */
+
+
+
+/* ----- MONITOR_WRITE_MEMORY_BLOCK ---------------------------- */
+/* This is for the large blocks of memory which may occur in downloading.
+ And for monitors which use interactive entry,
+ And for monitors which do not have other downloading methods.
+ Without this, we will end up calling monitor_write_memory many times
+ and do the entry and exit of the sub mode many times
+ This currently assumes...
+ MO_SETMEM_INTERACTIVE
+ ! MO_NO_ECHO_ON_SETMEM
+ To use this, the you have to patch the monitor_cmds block with
+ this function. Otherwise, its not tuned up for use by all
+ monitor variations.
+ */
+
+static int monitor_write_memory_block(memaddr,myaddr,len)
+ CORE_ADDR memaddr ;
+ char * myaddr ;
+ int len ;
+{
+ int written ;
+ written = 0 ;
+ /* FIXME: This would be a good place to put the zero test */
+#if 1
+ if ((len > 8) && (((len & 0x07)) == 0) && current_monitor->setmem.cmdll)
+ {
+ return monitor_write_memory_longlongs(memaddr,myaddr,len) ;
+ }
+#endif
+#if 0
+ if (len > 4)
+ {
+ int sublen ;
+ written = monitor_write_even_block(memaddr,myaddr,len) ;
+ /* Adjust calling parameters by written amount */
+ memaddr += written ;
+ myaddr += written ;
+ len -= written ;
+ }
+#endif
+ written = monitor_write_memory_bytes(memaddr,myaddr,len) ;
+ return written ;
+}
+
/* This is an alternate form of monitor_read_memory which is used for monitors
which can only read a single byte/word/etc. at a time. */
@@ -1071,18 +1643,25 @@ monitor_read_memory_single (memaddr, myaddr, len)
char *myaddr;
int len;
{
- unsigned LONGEST val;
- char membuf[sizeof(LONGEST) * 2 + 1];
+ unsigned int val;
+ char membuf[sizeof(int) * 2 + 1];
char *p;
char *cmd;
int i;
+ RDEBUG(("MON read single\n")) ;
+#if 0
+ /* Can't actually use long longs (nice idea, though). In fact, the
+ call to strtoul below will fail if it tries to convert a value
+ that's too big to fit in a long. */
if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->getmem.cmdll)
{
len = 8;
cmd = current_monitor->getmem.cmdll;
}
- else if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->getmem.cmdl)
+ else
+#endif
+ if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->getmem.cmdl)
{
len = 4;
cmd = current_monitor->getmem.cmdl;
@@ -1098,20 +1677,36 @@ monitor_read_memory_single (memaddr, myaddr, len)
cmd = current_monitor->getmem.cmdb;
}
-/* Send the examine command. */
+ /* Send the examine command. */
monitor_printf (cmd, memaddr);
-/* If RESP_DELIM is specified, we search for that as a leading delimiter for
- the register value. Otherwise, we just start searching from the start of
- the buf. */
+ /* If RESP_DELIM is specified, we search for that as a leading
+ delimiter for the memory value. Otherwise, we just start
+ searching from the start of the buf. */
if (current_monitor->getmem.resp_delim)
- monitor_expect_regexp (&getmem_resp_delim_pattern, NULL, 0);
+ { RDEBUG(("EXP getmem.resp_delim\n")) ;
+ monitor_expect_regexp (&getmem_resp_delim_pattern, NULL, 0);
+ }
-/* Now, read the appropriate number of hex digits for this loc, skipping
- spaces. */
+ /* Now, read the appropriate number of hex digits for this loc,
+ skipping spaces. */
+ /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set. */
+ if (current_monitor->flags & MO_HEX_PREFIX)
+ {
+ int c;
+
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+ if ((c == '0') && ((c = readchar (timeout)) == 'x'))
+ ;
+ else
+ monitor_error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
+ memaddr, i, membuf, c);
+ }
for (i = 0; i < len * 2; i++)
{
int c;
@@ -1124,8 +1719,8 @@ monitor_read_memory_single (memaddr, myaddr, len)
if (c == ' ')
continue;
- error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
- memaddr, i, membuf, c);
+ monitor_error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
+ memaddr, i, membuf, c);
}
membuf[i] = c;
@@ -1154,8 +1749,8 @@ monitor_read_memory_single (memaddr, myaddr, len)
val = strtoul (membuf, &p, 16);
if (val == 0 && membuf == p)
- error ("monitor_read_memory_single (0x%x): bad value from monitor: %s.",
- memaddr, membuf);
+ monitor_error ("monitor_read_memory_single (0x%x): bad value from monitor: %s.",
+ memaddr, 0, membuf, 0);
/* supply register stores in target byte order, so swap here */
@@ -1164,9 +1759,9 @@ monitor_read_memory_single (memaddr, myaddr, len)
return len;
}
-/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory
- at MEMADDR. Returns length moved. Currently, we only do one byte at a
- time. */
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+ memory at MEMADDR. Returns length moved. Currently, we do no more
+ than 16 bytes at a time. */
static int
monitor_read_memory (memaddr, myaddr, len)
@@ -1174,41 +1769,63 @@ monitor_read_memory (memaddr, myaddr, len)
char *myaddr;
int len;
{
- unsigned LONGEST val;
- unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+ unsigned int val;
char buf[512];
char *p, *p1;
- char *name;
int resp_len;
int i;
+ CORE_ADDR dumpaddr;
+
+ if (len <= 0)
+ {
+ RDEBUG (("Zero length call to monitor_read_memory\n"));
+ return 0;
+ }
+
+ if (remote_debug) printf("MON read block ta(%08x) ha(%08x) %d\n",
+ (unsigned long) memaddr , (unsigned long)myaddr, len);
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
return monitor_read_memory_single (memaddr, myaddr, len);
len = min (len, 16);
-/* See if xfer would cross a 16 byte boundary. If so, clip it. */
+ /* Some dumpers align the first data with the preceeding 16
+ byte boundary. Some print blanks and start at the
+ requested boundary. EXACT_DUMPADDR
+ */
+
+ dumpaddr = (current_monitor->flags & MO_EXACT_DUMPADDR)
+ ? memaddr : memaddr & ~ 0x0f ;
+
+ /* See if xfer would cross a 16 byte boundary. If so, clip it. */
if (((memaddr ^ (memaddr + len - 1)) & ~0xf) != 0)
len = ((memaddr + len) & ~0xf) - memaddr;
- /* send the memory examine command */
+ /* send the memory examine command */
if (current_monitor->flags & MO_GETMEM_NEEDS_RANGE)
monitor_printf (current_monitor->getmem.cmdb, memaddr, memaddr + len - 1);
+ else if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ monitor_printf (current_monitor->getmem.cmdb, dumpaddr);
else
monitor_printf (current_monitor->getmem.cmdb, memaddr, len);
-/* If TERM is present, we wait for that to show up. Also, (if TERM is
- present), we will send TERM_CMD if that is present. In any case, we collect
- all of the output into buf, and then wait for the normal prompt. */
+ /* If TERM is present, we wait for that to show up. Also, (if TERM
+ is present), we will send TERM_CMD if that is present. In any
+ case, we collect all of the output into buf, and then wait for
+ the normal prompt. */
if (current_monitor->getmem.term)
{
resp_len = monitor_expect (current_monitor->getmem.term, buf, sizeof buf); /* get response */
if (resp_len <= 0)
- error ("monitor_read_memory (0x%x): excessive response from monitor: %.*s.",
- memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): excessive response from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
if (current_monitor->getmem.term_cmd)
{
@@ -1222,32 +1839,63 @@ monitor_read_memory (memaddr, myaddr, len)
p = buf;
- /* If RESP_DELIM is specified, we search for that as a leading delimiter for
- the values. Otherwise, we just start searching from the start of the buf.
- */
+ /* If RESP_DELIM is specified, we search for that as a leading
+ delimiter for the values. Otherwise, we just start searching
+ from the start of the buf. */
if (current_monitor->getmem.resp_delim)
{
int retval, tmp;
struct re_registers resp_strings;
+ RDEBUG(("MON getmem.resp_delim %s\n",current_monitor->getmem.resp_delim)) ;
+ memset (&resp_strings, 0, sizeof (struct re_registers));
tmp = strlen (p);
retval = re_search (&getmem_resp_delim_pattern, p, tmp, 0, tmp,
&resp_strings);
if (retval < 0)
- error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
- memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
p += resp_strings.end[0];
#if 0
p = strstr (p, current_monitor->getmem.resp_delim);
if (!p)
- error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
- memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
p += strlen (current_monitor->getmem.resp_delim);
#endif
}
+ if (remote_debug) printf("MON scanning %d ,%08x '%s'\n",len,p,p) ;
+ if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ {
+ char c ;
+ int fetched = 0 ;
+ i = len;
+ c = *p ;
+
+
+ while (!(c == '\000' || c == '\n' || c == '\r') && i > 0)
+ { if (isxdigit (c))
+ { if ((dumpaddr >= memaddr) && (i > 0))
+ { val = fromhex (c) * 16 + fromhex (*(p+1));
+ *myaddr++ = val;
+ if (remote_debug) printf("[%02x]",val) ;
+ --i;
+ fetched++ ;
+ }
+ ++dumpaddr;
+ ++p;
+ }
+ ++p; /* skip a blank or other non hex char */
+ c = *p ;
+ }
+ if (fetched == 0) error("Failed to read via monitor") ;
+ if (remote_debug) printf("\n") ;
+ return fetched ; /* Return the number of bytes actually read */
+ }
+ RDEBUG(("MON scanning bytes\n")) ;
for (i = len; i > 0; i--)
{
@@ -1257,16 +1905,18 @@ monitor_read_memory (memaddr, myaddr, len)
{
if (isxdigit (*p))
break;
+
if (*p == '\000' || *p == '\n' || *p == '\r')
- error ("monitor_read_memory (0x%x): badly terminated response from monitor: %.*s", memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): badly terminated response from monitor: %.*s",
+ memaddr, resp_len, buf, 0);
p++;
}
val = strtoul (p, &p1, 16);
if (val == 0 && p == p1)
- error ("monitor_read_memory (0x%x): bad value from monitor: %.*s.", memaddr,
- resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): bad value from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
*myaddr++ = val;
@@ -1308,6 +1958,7 @@ monitor_create_inferior (exec_file, args, env)
if (args && (*args != '\000'))
error ("Args are not supported by the monitor.");
+ first_time = 1;
clear_proceed_status ();
proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
}
@@ -1336,15 +1987,26 @@ monitor_insert_breakpoint (addr, shadow)
char *shadow;
{
int i;
- static unsigned char break_insn[] = BREAKPOINT;
+ unsigned char *bp;
+ int bplen;
+
+ RDEBUG(("MON inst bkpt %08x\n",addr))
+ if (current_monitor->set_break == NULL)
+ error ("No set_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
+ /* Determine appropriate breakpoint size for this address. */
+ bp = memory_breakpoint_from_pc (&addr, &bplen);
for (i = 0; i < NUM_MONITOR_BREAKPOINTS; i++)
{
if (breakaddr[i] == 0)
{
breakaddr[i] = addr;
- monitor_read_memory (addr, shadow, sizeof (break_insn));
- monitor_printf (SET_BREAK_CMD, addr);
+ monitor_read_memory (addr, shadow, bplen);
+ monitor_printf (current_monitor->set_break, addr);
monitor_expect_prompt (NULL, 0);
return 0;
}
@@ -1362,21 +2024,58 @@ monitor_remove_breakpoint (addr, shadow)
{
int i;
+ RDEBUG(("MON rmbkpt %08x\n",addr))
+ if (current_monitor->clr_break == NULL)
+ error ("No clr_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
for (i = 0; i < NUM_MONITOR_BREAKPOINTS; i++)
{
if (breakaddr[i] == addr)
{
breakaddr[i] = 0;
/* some monitors remove breakpoints based on the address */
- if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
- monitor_printf (CLR_BREAK_CMD, addr);
+ if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
+ monitor_printf (current_monitor->clr_break, addr);
+ else if (current_monitor->flags & MO_CLR_BREAK_1_BASED)
+ monitor_printf (current_monitor->clr_break, i + 1);
else
- monitor_printf (CLR_BREAK_CMD, i);
+ monitor_printf (current_monitor->clr_break, i);
monitor_expect_prompt (NULL, 0);
return 0;
}
}
- fprintf_unfiltered (stderr, "Can't find breakpoint associated with 0x%x\n", addr);
+ fprintf_unfiltered (gdb_stderr,
+ "Can't find breakpoint associated with 0x%x\n", addr);
+ return 1;
+}
+
+/* monitor_wait_srec_ack -- wait for the target to send an acknowledgement for
+ an S-record. Return non-zero if the ACK is received properly. */
+
+static int
+monitor_wait_srec_ack ()
+{
+ int i, ch;
+
+ if (current_monitor->flags & MO_SREC_ACK_PLUS)
+ {
+ return (readchar (timeout) == '+');
+ }
+ else if (current_monitor->flags & MO_SREC_ACK_ROTATE)
+ {
+ /* Eat two backspaces, a "rotating" char (|/-\), and a space. */
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ }
return 1;
}
@@ -1388,16 +2087,31 @@ monitor_load (file, from_tty)
int from_tty;
{
dcache_flush (remote_dcache);
+ RDEBUG(("MON load\n"))
if (current_monitor->load_routine)
current_monitor->load_routine (monitor_desc, file, hashmark);
else
{ /* The default is ascii S-records */
- monitor_printf (LOAD_CMD); /* tell the monitor to load */
+ int n;
+ unsigned long load_offset;
+ char buf[128];
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+ n = sscanf (file, "%s 0x%lx", buf, &load_offset);
+ if (n > 1)
+ file = buf;
+ else
+ load_offset = 0;
+
+ monitor_printf (current_monitor->load);
if (current_monitor->loadresp)
monitor_expect (current_monitor->loadresp, NULL, 0);
- load_srec (monitor_desc, file, 32, SREC_ALL, hashmark);
+ load_srec (monitor_desc, file, (bfd_vma) load_offset,
+ 32, SREC_ALL, hashmark,
+ current_monitor->flags & MO_SREC_ACK ?
+ monitor_wait_srec_ack : NULL);
monitor_expect_prompt (NULL, 0);
}
@@ -1421,6 +2135,7 @@ monitor_load (file, from_tty)
static void
monitor_stop ()
{
+ RDEBUG(("MON stop\n")) ;
if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0)
SERIAL_SEND_BREAK (monitor_desc);
if (current_monitor->stop)
@@ -1443,7 +2158,7 @@ monitor_command (args, from_tty)
if (monitor_desc == NULL)
error ("monitor target not open.");
- p = PROMPT;
+ p = current_monitor->prompt;
/* Send the command. Note that if no args were supplied, then we're
just sending the monitor a newline, which is sometimes useful. */
@@ -1457,6 +2172,7 @@ monitor_command (args, from_tty)
/* Convert hex digit A to a number. */
+#if 0
static int
from_hex (a)
int a;
@@ -1470,50 +2186,83 @@ from_hex (a)
error ("Reply contains invalid hex digit 0x%x", a);
}
+#endif
+
+char *
+monitor_get_dev_name ()
+{
+ return dev_name;
+}
-static struct target_ops monitor_ops =
+static struct target_ops monitor_ops;
+
+static void
+init_base_monitor_ops (void)
{
- NULL, /* to_shortname */
- NULL, /* to_longname */
- NULL, /* to_doc */
- NULL, /* to_open */
- monitor_close, /* to_close */
- NULL, /* to_attach */
- monitor_detach, /* to_detach */
- monitor_resume, /* to_resume */
- monitor_wait, /* to_wait */
- monitor_fetch_registers, /* to_fetch_registers */
- monitor_store_registers, /* to_store_registers */
- monitor_prepare_to_store, /* to_prepare_to_store */
- monitor_xfer_memory, /* to_xfer_memory */
- monitor_files_info, /* to_files_info */
- monitor_insert_breakpoint, /* to_insert_breakpoint */
- monitor_remove_breakpoint, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- monitor_kill, /* to_kill */
- monitor_load, /* to_load */
- 0, /* to_lookup_symbol */
- monitor_create_inferior, /* to_create_inferior */
- monitor_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- monitor_stop, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+ monitor_ops.to_shortname = NULL;
+ monitor_ops.to_longname = NULL;
+ monitor_ops.to_doc = NULL;
+ monitor_ops.to_open = NULL;
+ monitor_ops.to_close = monitor_close;
+ monitor_ops.to_attach = NULL;
+ monitor_ops.to_post_attach = NULL;
+ monitor_ops.to_require_attach = NULL;
+ monitor_ops.to_detach = monitor_detach;
+ monitor_ops.to_require_detach = NULL;
+ monitor_ops.to_resume = monitor_resume;
+ monitor_ops.to_wait = monitor_wait;
+ monitor_ops.to_post_wait = NULL;
+ monitor_ops.to_fetch_registers = monitor_fetch_registers;
+ monitor_ops.to_store_registers = monitor_store_registers;
+ monitor_ops.to_prepare_to_store = monitor_prepare_to_store;
+ monitor_ops.to_xfer_memory = monitor_xfer_memory;
+ monitor_ops.to_files_info = monitor_files_info;
+ monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint;
+ monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint;
+ monitor_ops.to_terminal_init = 0;
+ monitor_ops.to_terminal_inferior = 0;
+ monitor_ops.to_terminal_ours_for_output = 0;
+ monitor_ops.to_terminal_ours = 0;
+ monitor_ops.to_terminal_info = 0;
+ monitor_ops.to_kill = monitor_kill;
+ monitor_ops.to_load = monitor_load;
+ monitor_ops.to_lookup_symbol = 0;
+ monitor_ops.to_create_inferior = monitor_create_inferior;
+ monitor_ops.to_post_startup_inferior = NULL;
+ monitor_ops.to_acknowledge_created_inferior = NULL;
+ monitor_ops.to_clone_and_follow_inferior = NULL;
+ monitor_ops.to_post_follow_inferior_by_clone = NULL;
+ monitor_ops.to_insert_fork_catchpoint = NULL;
+ monitor_ops.to_remove_fork_catchpoint = NULL;
+ monitor_ops.to_insert_vfork_catchpoint = NULL;
+ monitor_ops.to_remove_vfork_catchpoint = NULL;
+ monitor_ops.to_has_forked = NULL;
+ monitor_ops.to_has_vforked = NULL;
+ monitor_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ monitor_ops.to_post_follow_vfork = NULL;
+ monitor_ops.to_insert_exec_catchpoint = NULL;
+ monitor_ops.to_remove_exec_catchpoint = NULL;
+ monitor_ops.to_has_execd = NULL;
+ monitor_ops.to_reported_exec_events_per_exec_call = NULL;
+ monitor_ops.to_has_exited = NULL;
+ monitor_ops.to_mourn_inferior = monitor_mourn_inferior;
+ monitor_ops.to_can_run = 0;
+ monitor_ops.to_notice_signals = 0;
+ monitor_ops.to_thread_alive = 0;
+ monitor_ops.to_stop = monitor_stop;
+ monitor_ops.to_pid_to_exec_file = NULL;
+ monitor_ops.to_core_file_to_sym_file = NULL;
+ monitor_ops.to_stratum = process_stratum;
+ monitor_ops.DONT_USE = 0;
+ monitor_ops.to_has_all_memory = 1;
+ monitor_ops.to_has_memory = 1;
+ monitor_ops.to_has_stack = 1;
+ monitor_ops.to_has_registers = 1;
+ monitor_ops.to_has_execution = 1;
+ monitor_ops.to_sections = 0;
+ monitor_ops.to_sections_end = 0;
+ monitor_ops.to_magic = OPS_MAGIC;
+} /* init_base_monitor_ops */
/* Init the target_ops structure pointed at by OPS */
@@ -1521,6 +2270,9 @@ void
init_monitor_ops (ops)
struct target_ops *ops;
{
+ if (monitor_ops.to_magic != OPS_MAGIC)
+ init_base_monitor_ops ();
+
memcpy (ops, &monitor_ops, sizeof monitor_ops);
}
@@ -1529,6 +2281,7 @@ init_monitor_ops (ops)
void
_initialize_remote_monitors ()
{
+ init_base_monitor_ops ();
add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
(char *)&hashmark,
"Set display of activity while downloading a file.\n\
@@ -1539,3 +2292,5 @@ When enabled, a hashmark \'#\' is displayed.",
add_com ("monitor", class_obscure, monitor_command,
"Send a command to the debug monitor.");
}
+
+
diff --git a/contrib/gdb/gdb/monitor.h b/contrib/gdb/gdb/monitor.h
index daad1ca..4ccddd5 100644
--- a/contrib/gdb/gdb/monitor.h
+++ b/contrib/gdb/gdb/monitor.h
@@ -1,53 +1,55 @@
-/* Remote debugging interface ROM monitors.
- * Copyright 1990, 1991, 1992, 1996 Free Software Foundation, Inc.
- * Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
- *
- * This file is part of GDB.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
+/* Definitions for remote debugging interface for ROM monitors.
+ Copyright 1990, 1991, 1992, 1996 Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
#include "serial.h"
/* This structure describes the strings necessary to give small command
sequences to the monitor, and parse the response.
- CMD is the actual command typed at the monitor. Usually this has embedded
- sequences ala printf, which are substituted with the arguments appropriate
- to that type of command. Ie: to examine a register, we substitute the
- register name for the first arg. To modify memory, we substitute the memory
- location and the new contents for the first and second args, etc...
+ CMD is the actual command typed at the monitor. Usually this has
+ embedded sequences ala printf, which are substituted with the
+ arguments appropriate to that type of command. Ie: to examine a
+ register, we substitute the register name for the first arg. To
+ modify memory, we substitute the memory location and the new
+ contents for the first and second args, etc...
RESP_DELIM used to home in on the response string, and is used to
- disambiguate the answer within the pile of text returned by the monitor.
- This should be a unique string that immediately precedes the answer. Ie: if
- your monitor prints out `PC: 00000001= ' in response to asking for the PC,
- you should use `: ' as the RESP_DELIM. RESP_DELIM may be NULL if the res-
- ponse is going to be ignored, or has no particular leading text.
-
- TERM is the string that the monitor outputs to indicate that it is idle, and
- waiting for input. This is usually a prompt of some sort. In the previous
- example, it would be `= '. It is important that TERM really means that the
- monitor is idle, otherwise GDB may try to type at it when it isn't ready for
- input. This is a problem because many monitors cannot deal with type-ahead.
- TERM may be NULL if the normal prompt is output.
-
- TERM_CMD is used to quit out of the subcommand mode and get back to the main
- prompt. TERM_CMD may be NULL if it isn't necessary. It will also be
- ignored if TERM is NULL.
-*/
+ disambiguate the answer within the pile of text returned by the
+ monitor. This should be a unique string that immediately precedes
+ the answer. Ie: if your monitor prints out `PC: 00000001= ' in
+ response to asking for the PC, you should use `: ' as the
+ RESP_DELIM. RESP_DELIM may be NULL if the res- ponse is going to
+ be ignored, or has no particular leading text.
+
+ TERM is the string that the monitor outputs to indicate that it is
+ idle, and waiting for input. This is usually a prompt of some
+ sort. In the previous example, it would be `= '. It is important
+ that TERM really means that the monitor is idle, otherwise GDB may
+ try to type at it when it isn't ready for input. This is a problem
+ because many monitors cannot deal with type-ahead. TERM may be
+ NULL if the normal prompt is output.
+
+ TERM_CMD is used to quit out of the subcommand mode and get back to
+ the main prompt. TERM_CMD may be NULL if it isn't necessary. It
+ will also be ignored if TERM is NULL. */
struct memrw_cmd
{
@@ -91,8 +93,16 @@ struct monitor_ops
GDB with the value of a register. */
char *dump_registers; /* Command to dump all regs at once */
char *register_pattern; /* Pattern that picks out register from reg dump */
- void (*supply_register) PARAMS ((char *name, int namelen, char *val, int vallen));
- void (*load_routine) PARAMS ((serial_t desc, char *file, int hashmark)); /* Download routine */
+ void (*supply_register) PARAMS ((char *name, int namelen,
+ char *val, int vallen));
+ void (*load_routine) PARAMS ((serial_t desc, char *file,
+ int hashmark)); /* Download routine */
+ int (*dumpregs) PARAMS((void)) ; /* routine to dump all registers */
+ int (*continue_hook) PARAMS((void)) ; /* Emit the continue command */
+ int (*wait_filter) PARAMS((char * buf, /* Maybe contains registers */
+ int bufmax ,
+ int * response_length,
+ struct target_waitstatus * status)) ;
char *load; /* load command */
char *loadresp; /* Response to load command */
char *prompt; /* monitor command prompt */
@@ -104,68 +114,123 @@ struct monitor_ops
int magic; /* Check value */
};
+/* The monitor ops magic number, used to detect if an ops structure doesn't
+ have the right number of entries filled in. */
+
#define MONITOR_OPS_MAGIC 600925
-/* Flag defintions */
-
-#define MO_CLR_BREAK_USES_ADDR 0x1 /* If set, then clear breakpoint command
- uses address, otherwise it uses an index
- returned by the monitor. */
-#define MO_FILL_USES_ADDR 0x2 /* If set, then memory fill command uses
- STARTADDR, ENDADDR+1, VALUE as args, else it
- uses STARTADDR, LENGTH, VALUE as args. */
-#define MO_NEED_REGDUMP_AFTER_CONT 0x4 /* If set, then monitor doesn't auto-
- matically supply register dump when
- coming back after a continue. */
-#define MO_GETMEM_NEEDS_RANGE 0x8 /* getmem needs start addr and end addr */
-#define MO_GETMEM_READ_SINGLE 0x10 /* getmem can only read one loc at a time */
-#define MO_HANDLE_NL 0x20 /* handle \r\n combinations */
-
-#define MO_NO_ECHO_ON_OPEN 0x40 /* don't expect echos in monitor_open */
-
-#define MO_SEND_BREAK_ON_STOP 0x80 /* If set, send break to stop monitor */
-
-extern struct monitor_ops *current_monitor;
-
-#define LOADTYPES (current_monitor->loadtypes)
-#define LOADPROTOS (current_monitor->loadprotos)
-#define INIT_CMD (current_monitor->init)
-#define CONT_CMD (current_monitor->cont)
-#define STEP_CMD (current_monitor->step)
-#define SET_BREAK_CMD (current_monitor->set_break)
-#define CLR_BREAK_CMD (current_monitor->clr_break)
-#define SET_MEM (current_monitor->setmem)
-#define GET_MEM (current_monitor->getmem)
-#define LOAD_CMD (current_monitor->load)
-#define GET_REG (current_monitor->regget)
-#define SET_REG (current_monitor->regset)
-#define CMD_END (current_monitor->cmd_end)
-#define CMD_DELIM (current_monitor->cmd_delim)
-#define PROMPT (current_monitor->prompt)
-#define TARGET_OPS (current_monitor->target)
-#define TARGET_NAME (current_monitor->target->to_shortname)
-#define BAUDRATES (current_monitor->baudrates)
-#define STOPBITS (current_monitor->stopbits)
-#define REGNAMES(x) (current_monitor->regnames[x])
-#define ROMCMD(x) (x.cmd)
-#define ROMDELIM(x) (x.delim)
-#define ROMRES(x) (x.result)
-
-#define push_monitor(x) current_monitor = x;
+/* Flag definitions. */
+
+/* If set, then clear breakpoint command uses address, otherwise it
+ uses an index returned by the monitor. */
+
+#define MO_CLR_BREAK_USES_ADDR 0x1
+
+/* If set, then memory fill command uses STARTADDR, ENDADDR+1, VALUE
+ as args, else it uses STARTADDR, LENGTH, VALUE as args. */
+
+#define MO_FILL_USES_ADDR 0x2
+
+/* If set, then monitor doesn't automatically supply register dump
+ when coming back after a continue. */
+
+#define MO_NEED_REGDUMP_AFTER_CONT 0x4
+
+/* getmem needs start addr and end addr */
+
+#define MO_GETMEM_NEEDS_RANGE 0x8
+
+/* getmem can only read one loc at a time */
+
+#define MO_GETMEM_READ_SINGLE 0x10
+
+/* handle \r\n combinations */
+
+#define MO_HANDLE_NL 0x20
+
+/* don't expect echos in monitor_open */
+
+#define MO_NO_ECHO_ON_OPEN 0x40
+
+/* If set, send break to stop monitor */
+
+#define MO_SEND_BREAK_ON_STOP 0x80
+
+/* If set, target sends an ACK after each S-record */
+
+#define MO_SREC_ACK 0x100
+
+/* Allow 0x prefix on addresses retured from monitor */
+
+#define MO_HEX_PREFIX 0x200
+
+/* Some monitors require a different command when starting a program */
+
+#define MO_RUN_FIRST_TIME 0x400
+
+/* Don't expect echos when getting memory */
+
+#define MO_NO_ECHO_ON_SETMEM 0x800
+
+/* If set, then register store command expects value BEFORE regname */
+
+#define MO_REGISTER_VALUE_FIRST 0x1000
+
+/* If set, then the monitor displays registers as pairs. */
+
+#define MO_32_REGS_PAIRED 0x2000
+
+/* If set, then register setting happens interactively. */
+
+#define MO_SETREG_INTERACTIVE 0x4000
+
+/* If set, then memory setting happens interactively. */
+
+#define MO_SETMEM_INTERACTIVE 0x8000
+
+/* If set, then memory dumps are always on 16-byte boundaries, even
+ when less is desired. */
+
+#define MO_GETMEM_16_BOUNDARY 0x10000
+
+/* If set, then the monitor numbers its breakpoints starting from 1. */
+
+#define MO_CLR_BREAK_1_BASED 0x20000
+
+/* If set, then the monitor acks srecords with a plus sign. */
+
+#define MO_SREC_ACK_PLUS 0x40000
+
+/* If set, then the monitor "acks" srecords with rotating lines. */
+
+#define MO_SREC_ACK_ROTATE 0x80000
+
+/* If set, then remove useless address bits from memory addresses. */
+
+#define MO_ADDR_BITS_REMOVE 0x100000
+
+/* If set, then display target program output if prefixed by ^O. */
+
+#define MO_PRINT_PROGRAM_OUTPUT 0x200000
+
+/* Some dump bytes commands align the first data with the preceeding
+16 byte boundary. Some print blanks and start at the exactly the
+requested boundary. */
+
+#define MO_EXACT_DUMPADDR 0x400000
+
+/* Rather entering and exiting the write memory dialog for each word byte,
+ we can save time by transferring the whole block without exiting
+ the memory editing mode. You only need to worry about this
+ if you are doing memory downloading.
+ This engages a new write function registered with dcache.
+ */
+#define MO_HAS_BLOCKWRITES 0x800000
#define SREC_SIZE 160
-/*
- * FIXME: These are to temporarily maintain compatability with the
- * old monitor structure till remote-mon.c is fixed to work
- * like the *-rom.c files.
- */
-#define MEM_PROMPT (current_monitor->loadtypes)
-#define MEM_SET_CMD (current_monitor->setmem)
-#define MEM_DIS_CMD (current_monitor->getmem)
-#define REG_DELIM (current_monitor->regset.delim)
-
-extern void monitor_open PARAMS ((char *args, struct monitor_ops *ops, int from_tty));
+extern void monitor_open PARAMS ((char *args, struct monitor_ops *ops,
+ int from_tty));
extern void monitor_close PARAMS ((int quitting));
extern char *monitor_supply_register PARAMS ((int regno, char *valstr));
extern int monitor_expect PARAMS ((char *prompt, char *buf, int buflen));
@@ -174,4 +239,9 @@ extern void monitor_printf PARAMS ((char *, ...))
ATTR_FORMAT(printf, 1, 2);
extern void monitor_printf_noecho PARAMS ((char *, ...))
ATTR_FORMAT(printf, 1, 2);
+extern void monitor_write PARAMS ((char *buf, int buflen));
+extern int monitor_readchar PARAMS ((void));
+extern char *monitor_get_dev_name PARAMS ((void));
extern void init_monitor_ops PARAMS ((struct target_ops *));
+extern int monitor_dump_reg_block PARAMS((char * dump_cmd)) ;
+extern void flush_monitor_dcache PARAMS ((void));
diff --git a/contrib/gdb/gdb/mpw-config.in b/contrib/gdb/gdb/mpw-config.in
index 47e7186..ed07878 100644
--- a/contrib/gdb/gdb/mpw-config.in
+++ b/contrib/gdb/gdb/mpw-config.in
@@ -41,7 +41,6 @@ Else If "{target_canonical}" =~ /mips-idt-ecoff/
forward-include "{srcdir}"config:mips:tm-mips.h 'mips/tm-mips.h'
Set tdepfiles '"{o}"mips-tdep.c.o "{o}"remote-mips.c.o'
-
Else If "{target_canonical}" =~ /sh-hitachi-hms/
forward-include "{srcdir}"config:sh:tm-sh.h tm.h
Set tdepfiles '"{o}"sh-tdep.c.o'
diff --git a/contrib/gdb/gdb/mpw-make.sed b/contrib/gdb/gdb/mpw-make.sed
index 9cfaaa3..ce6a9ec 100644
--- a/contrib/gdb/gdb/mpw-make.sed
+++ b/contrib/gdb/gdb/mpw-make.sed
@@ -16,7 +16,7 @@
/^MMALLOC_DIR = /s/::mmalloc/mmalloc:/
/^MMALLOC_SRC = /s/"{srcdir}"/"{topsrcdir}"/
/^MMALLOC =/s/=.*$/=/
-/#MMALLOC_DISABLE/s/^#//
+/MMALLOC_CFLAGS =/s/=.*$/= -u USE_MMALLOC/
/^BFD_DIR = /s/::bfd/bfd:/
/^BFD = /s/{BFD_DIR}:libbfd/{BFD_DIR}libbfd/
@@ -32,16 +32,19 @@
/^TERMCAP =/s/ =.*$/ =/
+# Whack out various autoconf vars that we don't need.
+/@CONFIG_LDFLAGS@/s/@CONFIG_LDFLAGS@//g
+/@HLDFLAGS@/s/@HLDFLAGS@//g
/@DEFS@/s/@DEFS@//g
-
/@YACC@/s/@YACC@/byacc/g
-
/@ENABLE_OBS@/s/@ENABLE_OBS@//g
-
/@ENABLE_CLIBS@/s/@ENABLE_CLIBS@//g
-
/@LIBS@/s/@LIBS@//g
+# Whack out autoconf hook for thread debugging.
+/@THREAD_DB_OBS@/s/@THREAD_DB_OBS@//g
+
+# Fix up paths to include directories.
/INCLUDE_DIR/s/"{s}"{INCLUDE_DIR}/{INCLUDE_DIR}/g
/INCLUDE_DIR/s/{INCLUDE_DIR}:/{INCLUDE_DIR}/g
/INCLUDE_DIR/s/"{INCLUDE_DIR}":/"{INCLUDE_DIR}"/g
@@ -59,8 +62,6 @@
readline_headers =\
-/{MMALLOC_CHECK}/s/{MMALLOC_CHECK}//g
-
# This isn't really useful, and seems to cause nonsensical complaints.
/{ALLDEPFILES}/s/{ALLDEPFILES}//g
@@ -69,6 +70,7 @@ readline_headers =\
# Fix the syntax of bits of C code that go into version.c.
/char /s/'char .Option-x/'char */
+# Point at files in the obj dir rather than src dir.
/version/s/"{s}"version\.c/"{o}"version.c/g
/version/s/^version\.c/"{o}"version.c/
/config/s/"{s}"config\.h/"{o}"config.h/g
@@ -91,6 +93,7 @@ readline_headers =\
/init/s/"{s}"init\.c/"{o}"init.c/g
/init/s/^init\.c/"{o}"init.c/
+# Fix up the generation of version.c.
/"{o}"version.c \\Option-f Makefile/,/^$/c\
"{o}"version.c \\Option-f Makefile\
echo -n 'char *version = "' >"{o}"version.c\
@@ -104,6 +107,8 @@ readline_headers =\
echo '";' >>"{o}"version.c\
+/ansidecl/s/include "{s}""ansidecl.h"/include "ansidecl.h"/
+
# Open-brace in a command causes much confusion; replace with the
# result from a script.
/initialize_all_files ()/c\
@@ -111,8 +116,9 @@ readline_headers =\
open-brace >> "{o}"init.c-tmp
# Replace the whole sed bit for init.c; it's simpler that way...
-/filename=`echo $i | sed/,/esac/c\
- set filename "`Echo {i} | sed \\Option-d\
+/echo {OBS} {TSOBS}/,/echo '}'/c\
+ For i in {OBS} {TSOBS}\
+ Set filename "`Echo {i} | sed \\Option-d\
-e '/^Onindy.c.o/d' \\Option-d\
-e '/^nindy.c.o/d' \\Option-d\
-e '/ttyflush.c.o/d' \\Option-d\
@@ -129,7 +135,9 @@ readline_headers =\
If "{filename}" != ""\
sed <"{s}""{filename}" >>"{o}"init.c-tmp -n \\Option-d\
-e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\\([a-z_0-9A-Z]*\\).*/ {extern void \\1 (); \\1 ();}/p'\
- End If
+ End If\
+ End For\
+ Echo '}' >>"{o}"init.c-tmp
# Fix the main compile/link command.
/{CC_LD} {INTERNAL_LDFLAGS} -o gdb/,/"{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {LOADLIBES}/c\
@@ -137,10 +145,12 @@ readline_headers =\
{MAKEPEF} gdb{PROG_EXT} -o gdb {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\
{REZ} "{s}"mac-gdb.r -o gdb -append -d PROG_NAME='"'gdb'"' -d VERSION_STRING='"'{version}'"'\
+# Replace the install actions with MPW-friendly script.
/^install \\Option-f /,/^$/c\
install \\Option-f all install-only\
\
install-only \\Option-f \
+ NewFolderRecursive "{bindir}"\
Duplicate -y gdb "{bindir}"gdb\
If "`Exists SiowGDB`" != ""\
Duplicate -y SiowGDB "{bindir}"SiowGDB\
@@ -154,6 +164,7 @@ install-only \\Option-f \
/^config.status \\Option-f/,/^$/d
/^Makefile \\Option-f/,/^$/d
+# Don't test config.h dependencies.
/^"{o}"config.h \\Option-f/s/^/#/
# Add an action to build SIOWgdb.
diff --git a/contrib/gdb/gdb/nindy-tdep.c b/contrib/gdb/gdb/nindy-tdep.c
index 76f04e4..2e0b10c 100644
--- a/contrib/gdb/gdb/nindy-tdep.c
+++ b/contrib/gdb/gdb/nindy-tdep.c
@@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "symtab.h"
#include "frame.h"
+#include "gdbcore.h"
/* 'start_frame' is a variable in the NINDY runtime startup routine
that contains the frame pointer of the 'start' routine (the routine
@@ -33,7 +34,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
int
nindy_frame_chain_valid (chain, curframe)
- unsigned int chain;
+ CORE_ADDR chain;
struct frame_info *curframe;
{
struct symbol *sym;
diff --git a/contrib/gdb/gdb/nlm/Makefile.in b/contrib/gdb/gdb/nlm/Makefile.in
index c17bcff..5451138 100644
--- a/contrib/gdb/gdb/nlm/Makefile.in
+++ b/contrib/gdb/gdb/nlm/Makefile.in
@@ -1,4 +1,4 @@
-#Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+#Copyright 1989, 1990, 91, 92, 93, 94, 95, 1999 Free Software Foundation, Inc.
# This file is part of GDB.
@@ -25,12 +25,12 @@ exec_prefix = @exec_prefix@
host_alias = @host_alias@
target_alias = @target_alias@
program_transform_name = @program_transform_name@
-bindir = $(exec_prefix)/bin
-libdir = $(exec_prefix)/lib
+bindir = @bindir@
+libdir = @libdir@
tooldir = $(libdir)/$(target_alias)
-datadir = $(prefix)/lib
-mandir = $(prefix)/man
+datadir = @datadir@
+mandir = @mandir@
man1dir = $(mandir)/man1
man2dir = $(mandir)/man2
man3dir = $(mandir)/man3
@@ -40,11 +40,10 @@ man6dir = $(mandir)/man6
man7dir = $(mandir)/man7
man8dir = $(mandir)/man8
man9dir = $(mandir)/man9
-infodir = $(prefix)/info
-includedir = $(prefix)/include
-docdir = $(datadir)/doc
+infodir = @infodir@
+includedir = @includedir@
-SHELL = /bin/sh
+SHELL = @SHELL@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/contrib/gdb/gdb/nlm/configure b/contrib/gdb/gdb/nlm/configure
index 0b62dc1..3918fee 100644
--- a/contrib/gdb/gdb/nlm/configure
+++ b/contrib/gdb/gdb/nlm/configure
@@ -1,8 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.3
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+# Generated automatically using autoconf version 2.12.2
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
@@ -33,9 +33,25 @@ target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
ac_prev=
for ac_option
@@ -57,9 +73,14 @@ do
case "$ac_option" in
- -build | --build | --buil | --bui | --bu | --b)
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
build="$ac_optarg" ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
@@ -69,6 +90,12 @@ do
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file="$ac_optarg" ;;
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
-disable-* | --disable-*)
ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
# Reject names that are not valid shell variable names.
@@ -119,12 +146,29 @@ Configuration:
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
- --exec-prefix=PREFIX install architecture-dependent files in PREFIX
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
--srcdir=DIR find the sources in DIR [configure dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
Host type:
--build=BUILD configure for building on BUILD [BUILD=HOST]
--host=HOST configure for HOST [guessed]
@@ -136,8 +180,10 @@ Features and packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X library files are in DIR
---enable and --with options recognized:$ac_help
EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
exit 0 ;;
-host | --host | --hos | --ho)
@@ -145,6 +191,44 @@ EOF
-host=* | --host=* | --hos=* | --ho=*)
host="$ac_optarg" ;;
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
@@ -157,6 +241,15 @@ EOF
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
@@ -197,6 +290,23 @@ EOF
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
@@ -207,6 +317,13 @@ EOF
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir="$ac_optarg" ;;
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
@@ -216,7 +333,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.3"
+ echo "configure generated by autoconf version 2.12.2"
exit 0 ;;
-with-* | --with-*)
@@ -262,7 +379,7 @@ EOF
-*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
- *)
+ *)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
echo "configure: warning: $ac_option: invalid host type" 1>&2
fi
@@ -318,11 +435,14 @@ do
done
# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
@@ -382,9 +502,12 @@ fi
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+ac_exeext=
+ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
@@ -425,7 +548,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
#
# The rules are:
# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
+# same time.
# 2. Host defaults to nonopt.
# 3. If nonopt is not specified, then host defaults to the current host,
# as determined by config.guess.
@@ -441,31 +564,33 @@ esac
# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
host_alias=$host
case "$host_alias" in
NONE)
case $nonopt in
NONE)
- if host_alias=`$ac_config_guess`; then :
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
fi ;;
*) host_alias=$nonopt ;;
esac ;;
esac
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -476,13 +601,14 @@ NONE)
esac ;;
esac
-target=`$ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -493,10 +619,10 @@ NONE)
esac ;;
esac
-build=`$ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$build" 1>&6
test "$host_alias" != "$target_alias" &&
@@ -507,8 +633,10 @@ test "$host_alias" != "$target_alias" &&
if test "$program_transform_name" = s,x,x,; then
program_transform_name=
else
- # Double any \ or $.
- echo 's,\\,\\\\,g; s,\$,$$,g' > conftestsed
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
rm -f conftestsed
fi
@@ -529,27 +657,30 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:666: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall installbsd scoinst install; do
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
@@ -560,11 +691,18 @@ else
;;
esac
done
- IFS="$ac_save_ifs"
- # As a last resort, use the slow shell script.
- test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh"
+ IFS="$ac_save_IFS"
+
fi
- INSTALL="$ac_cv_path_install"
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
fi
echo "$ac_t""$INSTALL" 1>&6
@@ -581,7 +719,7 @@ case "${target_cpu}" in
alpha) gdb_target_cpu=alpha ;;
c[12]) gdb_target_cpu=convex ;;
hppa*) gdb_target_cpu=pa ;;
-i[345]86) gdb_target_cpu=i386 ;;
+i[3456]86) gdb_target_cpu=i386 ;;
m68*) gdb_target_cpu=m68k ;;
np1) gdb_target_cpu=gould ;;
pn) gdb_target_cpu=gould ;;
@@ -629,11 +767,25 @@ cat > confcache <<\EOF
# --recheck option to rerun configure.
#
EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
- sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
- >> confcache
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
if cmp -s $cache_file confcache; then
:
else
@@ -665,7 +817,7 @@ trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%-D\1=\2%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
s%\[%\\&%g
s%\]%\\&%g
@@ -700,7 +852,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.3"
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.2"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -712,12 +864,15 @@ ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
+s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
@@ -727,6 +882,18 @@ s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
@@ -750,20 +917,56 @@ s%@target_makefile_frag@%%g
CEOF
EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
- # Adjust relative srcdir, etc. for subdirectories.
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
@@ -791,6 +994,7 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*) INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
+
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
@@ -799,14 +1003,16 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# $configure_input" ;;
*) ac_comsub= ;;
esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
-rm -f conftest.subs
+rm -f conftest.s*
EOF
@@ -853,7 +1059,11 @@ while test -n "$ac_sources"; do
{ echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
fi
done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+EOF
+cat >> $CONFIG_STATUS <<\EOF
exit 0
EOF
diff --git a/contrib/gdb/gdb/nlm/configure.in b/contrib/gdb/gdb/nlm/configure.in
index f70be82..845b486 100644
--- a/contrib/gdb/gdb/nlm/configure.in
+++ b/contrib/gdb/gdb/nlm/configure.in
@@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
-AC_PREREQ(2.3)dnl
+AC_PREREQ(2.12.1)dnl
AC_INIT(gdbserve.c)
AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
@@ -15,7 +15,7 @@ case "${target_cpu}" in
alpha) gdb_target_cpu=alpha ;;
c[12]) gdb_target_cpu=convex ;;
hppa*) gdb_target_cpu=pa ;;
-i[345]86) gdb_target_cpu=i386 ;;
+i[3456]86) gdb_target_cpu=i386 ;;
m68*) gdb_target_cpu=m68k ;;
np1) gdb_target_cpu=gould ;;
pn) gdb_target_cpu=gould ;;
diff --git a/contrib/gdb/gdb/nlmread.c b/contrib/gdb/gdb/nlmread.c
index b61dc97..afdea43 100644
--- a/contrib/gdb/gdb/nlmread.c
+++ b/contrib/gdb/gdb/nlmread.c
@@ -1,5 +1,5 @@
/* Read NLM (NetWare Loadable Module) format executable files for GDB.
- Copyright 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1998 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
This file is part of GDB.
@@ -43,14 +43,6 @@ nlm_symfile_finish PARAMS ((struct objfile *));
static void
nlm_symtab_read PARAMS ((bfd *, CORE_ADDR, struct objfile *));
-static struct section_offsets *
-nlm_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
-
-static void
-record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type,
- struct objfile *));
-
-
/* Initialize anything that needs initializing when a completely new symbol
file is specified (not just adding some symbols from another file, e.g. a
shared library).
@@ -82,18 +74,6 @@ nlm_symfile_init (ignore)
{
}
-static void
-record_minimal_symbol (name, address, ms_type, objfile)
- char *name;
- CORE_ADDR address;
- enum minimal_symbol_type ms_type;
- struct objfile *objfile;
-{
- name = obsavestring (name, strlen (name), &objfile -> symbol_obstack);
- prim_record_minimal_symbol (name, address, ms_type, objfile);
-}
-
-
/*
LOCAL FUNCTION
@@ -162,8 +142,8 @@ nlm_symtab_read (abfd, addr, objfile)
else
ms_type = mst_unknown;
- record_minimal_symbol ((char *) sym -> name, symaddr, ms_type,
- objfile);
+ prim_record_minimal_symbol (sym -> name, symaddr, ms_type,
+ objfile);
}
}
do_cleanups (back_to);
@@ -210,7 +190,7 @@ nlm_symfile_read (objfile, section_offsets, mainline)
struct symbol *mainsym;
init_minimal_symbol_collection ();
- back_to = make_cleanup (discard_minimal_symbols, 0);
+ back_to = make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
/* FIXME, should take a section_offsets param, not just an offset. */
@@ -260,34 +240,6 @@ nlm_symfile_finish (objfile)
}
}
-/* NLM specific parsing routine for section offsets.
- FIXME: This may or may not be necessary. All the symbol readers seem
- to have similar code. See if it can be generalized and moved elsewhere. */
-
-static
-struct section_offsets *
-nlm_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets) +
- sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- {
- ANOFFSET (section_offsets, i) = addr;
- }
-
- return (section_offsets);
-}
-
-
/* Register that we are able to handle NLM file format. */
static struct sym_fns nlm_sym_fns =
@@ -297,7 +249,8 @@ static struct sym_fns nlm_sym_fns =
nlm_symfile_init, /* sym_init: read initial info, setup for sym_read() */
nlm_symfile_read, /* sym_read: read a symbol file into symtab */
nlm_symfile_finish, /* sym_finish: finished with file, cleanup */
- nlm_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_symfile_offsets,
+ /* sym_offsets: Translate ext. to int. relocation */
NULL /* next: pointer to next struct sym_fns */
};
diff --git a/contrib/gdb/gdb/ns32k-tdep.c b/contrib/gdb/gdb/ns32k-tdep.c
index 58a0860..3edb7f5 100644
--- a/contrib/gdb/gdb/ns32k-tdep.c
+++ b/contrib/gdb/gdb/ns32k-tdep.c
@@ -25,3 +25,98 @@ _initialize_ns32k_tdep ()
{
tm_print_insn = print_insn_ns32k;
}
+
+sign_extend (value, bits)
+{
+ value = value & ((1 << bits) - 1);
+ return (value & (1 << (bits-1))
+ ? value | (~((1 << bits) - 1))
+ : value);
+}
+
+void
+flip_bytes (ptr, count)
+ char *ptr;
+ int count;
+{
+ char tmp;
+
+ while (count > 0)
+ {
+ tmp = *ptr;
+ ptr[0] = ptr[count-1];
+ ptr[count-1] = tmp;
+ ptr++;
+ count -= 2;
+ }
+}
+
+/* Return the number of locals in the current frame given a pc
+ pointing to the enter instruction. This is used in the macro
+ FRAME_FIND_SAVED_REGS. */
+
+int
+ns32k_localcount (enter_pc)
+ CORE_ADDR enter_pc;
+{
+ unsigned char localtype;
+ int localcount;
+
+ localtype = read_memory_integer (enter_pc+2, 1);
+ if ((localtype & 0x80) == 0)
+ localcount = localtype;
+ else if ((localtype & 0xc0) == 0x80)
+ localcount = (((localtype & 0x3f) << 8)
+ | (read_memory_integer (enter_pc+3, 1) & 0xff));
+ else
+ localcount = (((localtype & 0x3f) << 24)
+ | ((read_memory_integer (enter_pc+3, 1) & 0xff) << 16)
+ | ((read_memory_integer (enter_pc+4, 1) & 0xff) << 8 )
+ | (read_memory_integer (enter_pc+5, 1) & 0xff));
+ return localcount;
+}
+
+
+/* Nonzero if instruction at PC is a return instruction. */
+
+static int
+ns32k_about_to_return (pc)
+ CORE_ADDR pc;
+{
+ return (read_memory_integer (pc, 1) == 0x12);
+}
+
+
+/*
+ * Get the address of the enter opcode for the function
+ * containing PC, if there is an enter for the function,
+ * and if the pc is between the enter and exit.
+ * Returns positive address if pc is between enter/exit,
+ * 1 if pc before enter or after exit, 0 otherwise.
+ */
+
+CORE_ADDR
+ns32k_get_enter_addr (pc)
+ CORE_ADDR pc;
+{
+ CORE_ADDR enter_addr;
+ unsigned char op;
+
+ if (pc == 0)
+ return 0;
+
+ if (ns32k_about_to_return (pc))
+ return 1; /* after exit */
+
+ enter_addr = get_pc_function_start (pc);
+
+ if (pc == enter_addr)
+ return 1; /* before enter */
+
+ op = read_memory_integer (enter_addr, 1);
+
+ if (op != 0x82)
+ return 0; /* function has no enter/exit */
+
+ return enter_addr; /* pc is between enter and exit */
+}
diff --git a/contrib/gdb/gdb/ns32km3-nat.c b/contrib/gdb/gdb/ns32km3-nat.c
index 89696ba..cdafb9c 100644
--- a/contrib/gdb/gdb/ns32km3-nat.c
+++ b/contrib/gdb/gdb/ns32km3-nat.c
@@ -46,14 +46,16 @@ static int reg_offset[] =
{
REG_N_OFFSET(r0), REG_N_OFFSET(r1), REG_N_OFFSET(r2), REG_N_OFFSET(r3),
REG_N_OFFSET(r4), REG_N_OFFSET(r5), REG_N_OFFSET(r6), REG_N_OFFSET(r7),
- REG_F_OFFSET(l0a), REG_F_OFFSET(l1a),REG_F_OFFSET(l2a),REG_F_OFFSET(l3a),
- REG_F_OFFSET(l4a), REG_F_OFFSET(l5a),REG_F_OFFSET(l6a),REG_F_OFFSET(l7a),
+ REG_F_OFFSET(l0a), REG_F_OFFSET(l0b),REG_F_OFFSET(l2a),REG_F_OFFSET(l2b),
+ REG_F_OFFSET(l4a), REG_F_OFFSET(l4b),REG_F_OFFSET(l6a),REG_F_OFFSET(l6b),
REG_N_OFFSET(sp), REG_N_OFFSET(fp), REG_N_OFFSET(pc), REG_N_OFFSET(psr),
REG_F_OFFSET(fsr),
- REG_F_OFFSET(l0a), REG_F_OFFSET(l2a),REG_F_OFFSET(l4a),REG_F_OFFSET(l6a)
- /* @@@ 532 has more double length floating point regs, not accessed currently */
+ REG_F_OFFSET(l0a), REG_F_OFFSET(l1a),REG_F_OFFSET(l2a),REG_F_OFFSET(l3a),
+ REG_F_OFFSET(l4a), REG_F_OFFSET(l5a),REG_F_OFFSET(l6a),REG_F_OFFSET(l7a),
};
+#define REG_ADDRESS(state,regnum) ((char *)(state)+reg_offset[regnum])
+
/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
* Caller knows that the regs handled in one transaction are of same size.
*/
@@ -94,7 +96,7 @@ fetch_inferior_registers (regno)
&stateCnt);
if (ret != KERN_SUCCESS)
- message ("fetch_inferior_registers: %s ",
+ warning ("fetch_inferior_registers: %s ",
mach_error_string (ret));
#if 0
/* It may be more effective to store validate all of them,
@@ -142,7 +144,7 @@ store_inferior_registers (regno)
if (ret != KERN_SUCCESS)
{
- message ("store_inferior_registers (get): %s",
+ warning ("store_inferior_registers (get): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
@@ -173,7 +175,7 @@ store_inferior_registers (regno)
NS532_COMBINED_STATE_COUNT);
if (ret != KERN_SUCCESS)
- message ("store_inferior_registers (set): %s",
+ warning ("store_inferior_registers (set): %s",
mach_error_string (ret));
if (must_suspend_thread)
diff --git a/contrib/gdb/gdb/ns32knbsd-nat.c b/contrib/gdb/gdb/ns32knbsd-nat.c
new file mode 100644
index 0000000..c9f75ca
--- /dev/null
+++ b/contrib/gdb/gdb/ns32knbsd-nat.c
@@ -0,0 +1,353 @@
+/* Functions specific to running gdb native on an ns32k running NetBSD
+ Copyright 1989, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+
+#define RF(dst, src) \
+ memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
+
+#define RS(src, dst) \
+ memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
+
+void
+fetch_inferior_registers (regno)
+ int regno;
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fpregisters;
+
+ ptrace (PT_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+ ptrace (PT_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
+
+ RF(R0_REGNUM + 0, inferior_registers.r_r0);
+ RF(R0_REGNUM + 1, inferior_registers.r_r1);
+ RF(R0_REGNUM + 2, inferior_registers.r_r2);
+ RF(R0_REGNUM + 3, inferior_registers.r_r3);
+ RF(R0_REGNUM + 4, inferior_registers.r_r4);
+ RF(R0_REGNUM + 5, inferior_registers.r_r5);
+ RF(R0_REGNUM + 6, inferior_registers.r_r6);
+ RF(R0_REGNUM + 7, inferior_registers.r_r7);
+
+ RF(SP_REGNUM , inferior_registers.r_sp);
+ RF(FP_REGNUM , inferior_registers.r_fp);
+ RF(PC_REGNUM , inferior_registers.r_pc);
+ RF(PS_REGNUM , inferior_registers.r_psr);
+
+ RF(FPS_REGNUM , inferior_fpregisters.r_fsr);
+ RF(FP0_REGNUM +0, inferior_fpregisters.r_freg[0]);
+ RF(FP0_REGNUM +2, inferior_fpregisters.r_freg[2]);
+ RF(FP0_REGNUM +4, inferior_fpregisters.r_freg[4]);
+ RF(FP0_REGNUM +6, inferior_fpregisters.r_freg[6]);
+ RF(LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
+ RF(LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
+ RF(LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
+ RF(LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
+ registers_fetched ();
+}
+
+void
+store_inferior_registers (regno)
+ int regno;
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fpregisters;
+
+ RS(R0_REGNUM + 0, inferior_registers.r_r0);
+ RS(R0_REGNUM + 1, inferior_registers.r_r1);
+ RS(R0_REGNUM + 2, inferior_registers.r_r2);
+ RS(R0_REGNUM + 3, inferior_registers.r_r3);
+ RS(R0_REGNUM + 4, inferior_registers.r_r4);
+ RS(R0_REGNUM + 5, inferior_registers.r_r5);
+ RS(R0_REGNUM + 6, inferior_registers.r_r6);
+ RS(R0_REGNUM + 7, inferior_registers.r_r7);
+
+ RS(SP_REGNUM , inferior_registers.r_sp);
+ RS(FP_REGNUM , inferior_registers.r_fp);
+ RS(PC_REGNUM , inferior_registers.r_pc);
+ RS(PS_REGNUM , inferior_registers.r_psr);
+
+ RS(FPS_REGNUM , inferior_fpregisters.r_fsr);
+ RS(FP0_REGNUM +0, inferior_fpregisters.r_freg[0]);
+ RS(FP0_REGNUM +2, inferior_fpregisters.r_freg[2]);
+ RS(FP0_REGNUM +4, inferior_fpregisters.r_freg[4]);
+ RS(FP0_REGNUM +6, inferior_fpregisters.r_freg[6]);
+ RS(LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
+ RS(LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
+ RS(LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
+ RS(LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
+
+ ptrace (PT_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+ ptrace (PT_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
+}
+
+
+/* XXX - Add this to machine/regs.h instead? */
+struct coreregs {
+ struct reg intreg;
+ struct fpreg freg;
+};
+
+/* Get registers from a core file. */
+static void
+fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
+ char *core_reg_sect;
+ unsigned core_reg_size;
+ int which;
+ unsigned int reg_addr; /* Unused in this version */
+{
+ struct coreregs *core_reg;
+
+ core_reg = (struct coreregs *)core_reg_sect;
+
+ /*
+ * We have *all* registers
+ * in the first core section.
+ * Ignore which.
+ */
+
+ if (core_reg_size < sizeof(*core_reg)) {
+ fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n");
+ return;
+ }
+
+ /* Integer registers */
+ RF(R0_REGNUM + 0, core_reg->intreg.r_r0);
+ RF(R0_REGNUM + 1, core_reg->intreg.r_r1);
+ RF(R0_REGNUM + 2, core_reg->intreg.r_r2);
+ RF(R0_REGNUM + 3, core_reg->intreg.r_r3);
+ RF(R0_REGNUM + 4, core_reg->intreg.r_r4);
+ RF(R0_REGNUM + 5, core_reg->intreg.r_r5);
+ RF(R0_REGNUM + 6, core_reg->intreg.r_r6);
+ RF(R0_REGNUM + 7, core_reg->intreg.r_r7);
+
+ RF(SP_REGNUM , core_reg->intreg.r_sp);
+ RF(FP_REGNUM , core_reg->intreg.r_fp);
+ RF(PC_REGNUM , core_reg->intreg.r_pc);
+ RF(PS_REGNUM , core_reg->intreg.r_psr);
+
+ /* Floating point registers */
+ RF(FPS_REGNUM , core_reg->freg.r_fsr);
+ RF(FP0_REGNUM +0, core_reg->freg.r_freg[0]);
+ RF(FP0_REGNUM +2, core_reg->freg.r_freg[2]);
+ RF(FP0_REGNUM +4, core_reg->freg.r_freg[4]);
+ RF(FP0_REGNUM +6, core_reg->freg.r_freg[6]);
+ RF(LP0_REGNUM + 1, core_reg->freg.r_freg[1]);
+ RF(LP0_REGNUM + 3, core_reg->freg.r_freg[3]);
+ RF(LP0_REGNUM + 5, core_reg->freg.r_freg[5]);
+ RF(LP0_REGNUM + 7, core_reg->freg.r_freg[7]);
+ registers_fetched ();
+}
+
+/* Register that we are able to handle ns32knbsd core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns nat_core_fns =
+{
+ bfd_target_unknown_flavour,
+ fetch_core_registers,
+ NULL
+};
+
+void
+_initialize_ns32knbsd_nat ()
+{
+ add_core_fns (&nat_core_fns);
+}
+
+
+/*
+ * kernel_u_size() is not helpful on NetBSD because
+ * the "u" struct is NOT in the core dump file.
+ */
+
+#ifdef FETCH_KCORE_REGISTERS
+/*
+ * Get registers from a kernel crash dump or live kernel.
+ * Called by kcore-nbsd.c:get_kcore_registers().
+ */
+void
+fetch_kcore_registers (pcb)
+ struct pcb *pcb;
+{
+ struct switchframe sf;
+ struct reg intreg;
+ int dummy;
+
+ /* Integer registers */
+ if (target_read_memory((CORE_ADDR)pcb->pcb_ksp, (char *)&sf, sizeof sf))
+ error("Cannot read integer registers.");
+
+ /* We use the psr at kernel entry */
+ if (target_read_memory((CORE_ADDR)pcb->pcb_onstack, (char *)&intreg, sizeof intreg))
+ error("Cannot read processor status register.");
+
+ dummy = 0;
+ RF(R0_REGNUM + 0, dummy);
+ RF(R0_REGNUM + 1, dummy);
+ RF(R0_REGNUM + 2, dummy);
+ RF(R0_REGNUM + 3, sf.sf_r3);
+ RF(R0_REGNUM + 4, sf.sf_r4);
+ RF(R0_REGNUM + 5, sf.sf_r5);
+ RF(R0_REGNUM + 6, sf.sf_r6);
+ RF(R0_REGNUM + 7, sf.sf_r7);
+
+ dummy = pcb->pcb_kfp + 8;
+ RF(SP_REGNUM , dummy);
+ RF(FP_REGNUM , sf.sf_fp);
+ RF(PC_REGNUM , sf.sf_pc);
+ RF(PS_REGNUM , intreg.r_psr);
+
+ /* Floating point registers */
+ RF(FPS_REGNUM , pcb->pcb_fsr);
+ RF(FP0_REGNUM +0, pcb->pcb_freg[0]);
+ RF(FP0_REGNUM +2, pcb->pcb_freg[2]);
+ RF(FP0_REGNUM +4, pcb->pcb_freg[4]);
+ RF(FP0_REGNUM +6, pcb->pcb_freg[6]);
+ RF(LP0_REGNUM + 1, pcb->pcb_freg[1]);
+ RF(LP0_REGNUM + 3, pcb->pcb_freg[3]);
+ RF(LP0_REGNUM + 5, pcb->pcb_freg[5]);
+ RF(LP0_REGNUM + 7, pcb->pcb_freg[7]);
+ registers_fetched ();
+}
+#endif /* FETCH_KCORE_REGISTERS */
+
+void
+clear_regs()
+{
+ double zero = 0.0;
+ int null = 0;
+
+ /* Integer registers */
+ RF(R0_REGNUM + 0, null);
+ RF(R0_REGNUM + 1, null);
+ RF(R0_REGNUM + 2, null);
+ RF(R0_REGNUM + 3, null);
+ RF(R0_REGNUM + 4, null);
+ RF(R0_REGNUM + 5, null);
+ RF(R0_REGNUM + 6, null);
+ RF(R0_REGNUM + 7, null);
+
+ RF(SP_REGNUM , null);
+ RF(FP_REGNUM , null);
+ RF(PC_REGNUM , null);
+ RF(PS_REGNUM , null);
+
+ /* Floating point registers */
+ RF(FPS_REGNUM , zero);
+ RF(FP0_REGNUM +0, zero);
+ RF(FP0_REGNUM +2, zero);
+ RF(FP0_REGNUM +4, zero);
+ RF(FP0_REGNUM +6, zero);
+ RF(LP0_REGNUM + 0, zero);
+ RF(LP0_REGNUM + 1, zero);
+ RF(LP0_REGNUM + 2, zero);
+ RF(LP0_REGNUM + 3, zero);
+ return;
+}
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+int
+frame_num_args(fi)
+struct frame_info *fi;
+{
+ CORE_ADDR enter_addr;
+ CORE_ADDR argp;
+ int inst;
+ int args;
+ int i;
+
+ if (read_memory_integer (fi->frame, 4) == 0 && fi->pc < 0x10000) {
+ /* main is always called with three args */
+ return(3);
+ }
+ enter_addr = ns32k_get_enter_addr(fi->pc);
+ if (enter_addr = 0)
+ return(-1);
+ argp = enter_addr == 1 ? SAVED_PC_AFTER_CALL(fi) : FRAME_SAVED_PC(fi);
+ for (i = 0; i < 16; i++) {
+ /*
+ * After a bsr gcc may emit the following instructions
+ * to remove the arguments from the stack:
+ * cmpqd 0,tos - to remove 4 bytes from the stack
+ * cmpd tos,tos - to remove 8 bytes from the stack
+ * adjsp[bwd] -n - to remove n bytes from the stack
+ * Gcc sometimes delays emitting these instructions and
+ * may even throw a branch between our feet.
+ */
+ inst = read_memory_integer(argp , 4);
+ args = read_memory_integer(argp + 2, 4);
+ if ((inst & 0xff) == 0xea) { /* br */
+ args = ((inst >> 8) & 0xffffff) | (args << 24);
+ if (args & 0x80) {
+ if (args & 0x40) {
+ args = ntohl(args);
+ } else {
+ args = ntohs(args & 0xffff);
+ if (args & 0x2000)
+ args |= 0xc000;
+ }
+ } else {
+ args = args & 0xff;
+ if (args & 0x40)
+ args |= 0x80;
+ }
+ argp += args;
+ continue;
+ }
+ if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */
+ return(1);
+ else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */
+ return(2);
+ else if ((inst & 0xfffc) == 0xa57c) { /* adjsp[bwd] */
+ switch (inst & 3) {
+ case 0:
+ args = ((args & 0xff) + 0x80);
+ break;
+ case 1:
+ args = ((ntohs(args) & 0xffff) + 0x8000);
+ break;
+ case 3:
+ args = -ntohl(args);
+ break;
+ default:
+ return(-1);
+ }
+ if (args / 4 > 10 || (args & 3) != 0)
+ continue;
+ return(args / 4);
+ }
+ argp += 1;
+ }
+ return(-1);
+}
diff --git a/contrib/gdb/gdb/objfiles.c b/contrib/gdb/gdb/objfiles.c
index 97b05dc..971a7d4 100644
--- a/contrib/gdb/gdb/objfiles.c
+++ b/contrib/gdb/gdb/objfiles.c
@@ -37,7 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Prototypes for local functions */
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
static int
open_existing_mapped_file PARAMS ((char *, long, int));
@@ -45,10 +45,13 @@ open_existing_mapped_file PARAMS ((char *, long, int));
static int
open_mapped_file PARAMS ((char *filename, long mtime, int mapped));
-static CORE_ADDR
-map_to_address PARAMS ((void));
+static PTR
+map_to_file PARAMS ((int));
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
+
+static void
+add_to_objfile_sections PARAMS ((bfd *, sec_ptr, PTR));
/* Externally visible variables that are owned by this module.
See declarations in objfile.h for more info. */
@@ -64,6 +67,10 @@ int mapped_symbol_files; /* Try to use mapped symbol files */
objfile_p_char is a char * to get it through
bfd_map_over_sections; we cast it back to its proper type. */
+#ifndef TARGET_KEEP_SECTION
+#define TARGET_KEEP_SECTION(ASECT) 0
+#endif
+
static void
add_to_objfile_sections (abfd, asect, objfile_p_char)
bfd *abfd;
@@ -75,13 +82,16 @@ add_to_objfile_sections (abfd, asect, objfile_p_char)
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
- if (!(aflag & SEC_ALLOC))
+
+ if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION(asect)))
return;
+
if (0 == bfd_section_size (abfd, asect))
return;
section.offset = 0;
section.objfile = objfile;
section.the_bfd_section = asect;
+ section.ovly_mapped = 0;
section.addr = bfd_section_vma (abfd, asect);
section.endaddr = section.addr + bfd_section_size (abfd, asect);
obstack_grow (&objfile->psymbol_obstack, (char *) &section, sizeof(section));
@@ -113,19 +123,29 @@ build_objfile_section_table (objfile)
/* Given a pointer to an initialized bfd (ABFD) and a flag that indicates
whether or not an objfile is to be mapped (MAPPED), allocate a new objfile
struct, fill it in as best we can, link it into the list of all known
- objfiles, and return a pointer to the new objfile struct. */
+ objfiles, and return a pointer to the new objfile struct.
+
+ USER_LOADED is simply recorded in the objfile. This record offers a way for
+ run_command to remove old objfile entries which are no longer valid (i.e.,
+ are associated with an old inferior), but to preserve ones that the user
+ explicitly loaded via the add-symbol-file command.
+
+ IS_SOLIB is also simply recorded in the objfile. */
struct objfile *
-allocate_objfile (abfd, mapped)
+allocate_objfile (abfd, mapped, user_loaded, is_solib)
bfd *abfd;
int mapped;
+ int user_loaded;
+ int is_solib;
{
struct objfile *objfile = NULL;
struct objfile *last_one = NULL;
mapped |= mapped_symbol_files;
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
+ if (abfd != NULL)
{
/* If we can support mapped symbol files, try to open/reopen the
@@ -144,11 +164,9 @@ allocate_objfile (abfd, mapped)
mapped);
if (fd >= 0)
{
- CORE_ADDR mapto;
PTR md;
- if (((mapto = map_to_address ()) == 0) ||
- ((md = mmalloc_attach (fd, (PTR) mapto)) == NULL))
+ if ((md = map_to_file (fd)) == NULL)
{
close (fd);
}
@@ -209,7 +227,7 @@ allocate_objfile (abfd, mapped)
bfd_get_filename (abfd));
}
}
-#else /* defined(NO_MMALLOC) || !defined(HAVE_MMAP) */
+#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */
if (mapped)
{
@@ -222,7 +240,7 @@ allocate_objfile (abfd, mapped)
mapped_symbol_files = 0;
}
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
/* If we don't support mapped symbol files, didn't ask for the file to be
mapped, or failed to open the mapped file for some reason, then revert
@@ -252,15 +270,18 @@ allocate_objfile (abfd, mapped)
{
mfree (objfile -> md, objfile -> name);
}
- objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd));
- objfile -> mtime = bfd_get_mtime (abfd);
+ if (abfd != NULL)
+ {
+ objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd));
+ objfile -> mtime = bfd_get_mtime (abfd);
- /* Build section table. */
+ /* Build section table. */
- if (build_objfile_section_table (objfile))
- {
- error ("Can't find the file sections in `%s': %s",
- objfile -> name, bfd_errmsg (bfd_get_error ()));
+ if (build_objfile_section_table (objfile))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ objfile -> name, bfd_errmsg (bfd_get_error ()));
+ }
}
/* Add this file onto the tail of the linked list of other such files. */
@@ -275,6 +296,15 @@ allocate_objfile (abfd, mapped)
last_one = last_one -> next);
last_one -> next = objfile;
}
+
+ /* Record whether this objfile was created because the user explicitly
+ caused it (e.g., used the add-symbol-file command).
+ */
+ objfile -> user_loaded = user_loaded;
+
+ /* Record whether this objfile definitely represents a solib. */
+ objfile -> is_solib = is_solib;
+
return (objfile);
}
@@ -410,7 +440,7 @@ free_objfile (objfile)
case. Note that the mmalloc_detach or the mfree is the last thing
we can do with this objfile. */
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
if (objfile -> flags & OBJF_MAPPED)
{
@@ -424,7 +454,7 @@ free_objfile (objfile)
close (mmfd);
}
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
/* If we still have an objfile, then either we don't support reusable
objfiles or this one was not reusable. So free it normally. */
@@ -471,9 +501,9 @@ objfile_relocate (objfile, new_offsets)
struct objfile *objfile;
struct section_offsets *new_offsets;
{
- struct section_offsets *delta = (struct section_offsets *) alloca
- (sizeof (struct section_offsets)
- + objfile->num_sections * sizeof (delta->offsets));
+ struct section_offsets *delta = (struct section_offsets *)
+ alloca (sizeof (struct section_offsets)
+ + objfile->num_sections * sizeof (delta->offsets));
{
int i;
@@ -519,7 +549,7 @@ objfile_relocate (objfile, new_offsets)
b = BLOCKVECTOR_BLOCK (bv, i);
BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
- BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
+ BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
for (j = 0; j < BLOCK_NSYMS (b); ++j)
{
@@ -529,10 +559,11 @@ objfile_relocate (objfile, new_offsets)
But I'm leaving out that test, on the theory that
they can't possibly pass the tests below. */
if ((SYMBOL_CLASS (sym) == LOC_LABEL
- || SYMBOL_CLASS (sym) == LOC_STATIC)
+ || SYMBOL_CLASS (sym) == LOC_STATIC
+ || SYMBOL_CLASS (sym) == LOC_INDIRECT)
&& SYMBOL_SECTION (sym) >= 0)
{
- SYMBOL_VALUE_ADDRESS (sym) +=
+ SYMBOL_VALUE_ADDRESS (sym) +=
ANOFFSET (delta, SYMBOL_SECTION (sym));
}
#ifdef MIPS_EFI_SYMBOL_NAME
@@ -542,7 +573,8 @@ objfile_relocate (objfile, new_offsets)
if (SYMBOL_CLASS (sym) == LOC_CONST
&& SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE
&& STRCMP (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
- ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section));
+ ecoff_relocate_efi (sym, ANOFFSET (delta,
+ s->block_line_section));
#endif
}
}
@@ -566,12 +598,14 @@ objfile_relocate (objfile, new_offsets)
psym < objfile->global_psymbols.next;
psym++)
if (SYMBOL_SECTION (*psym) >= 0)
- SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
+ SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
+ SYMBOL_SECTION (*psym));
for (psym = objfile->static_psymbols.list;
psym < objfile->static_psymbols.next;
psym++)
if (SYMBOL_SECTION (*psym) >= 0)
- SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
+ SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
+ SYMBOL_SECTION (*psym));
}
{
@@ -605,42 +639,45 @@ objfile_relocate (objfile, new_offsets)
if (flags & SEC_CODE)
{
- s->addr += ANOFFSET (delta, SECT_OFF_TEXT);
+ s->addr += ANOFFSET (delta, SECT_OFF_TEXT);
s->endaddr += ANOFFSET (delta, SECT_OFF_TEXT);
}
else if (flags & (SEC_DATA | SEC_LOAD))
{
- s->addr += ANOFFSET (delta, SECT_OFF_DATA);
+ s->addr += ANOFFSET (delta, SECT_OFF_DATA);
s->endaddr += ANOFFSET (delta, SECT_OFF_DATA);
}
else if (flags & SEC_ALLOC)
{
- s->addr += ANOFFSET (delta, SECT_OFF_BSS);
+ s->addr += ANOFFSET (delta, SECT_OFF_BSS);
s->endaddr += ANOFFSET (delta, SECT_OFF_BSS);
}
}
}
- if (objfile->ei.entry_point != ~0)
+ if (objfile->ei.entry_point != ~(CORE_ADDR)0)
objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT);
if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
+ objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
}
if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
+ objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
}
if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
+ objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
objfile->ei.main_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
}
+
+ /* Relocate breakpoints as necessary, after things are relocated. */
+ breakpoint_re_set ();
}
/* Many places in gdb want to test just to see if we have any partial
@@ -681,6 +718,28 @@ have_full_symbols ()
return 0;
}
+
+/* This operations deletes all objfile entries that represent solibs that
+ weren't explicitly loaded by the user, via e.g., the add-symbol-file
+ command.
+ */
+void
+objfile_purge_solibs ()
+{
+ struct objfile * objf;
+ struct objfile * temp;
+
+ ALL_OBJFILES_SAFE (objf, temp)
+ {
+ /* We assume that the solib package has been purged already, or will
+ be soon.
+ */
+ if (! objf->user_loaded && objf->is_solib)
+ free_objfile (objf);
+ }
+}
+
+
/* Many places in gdb want to test just to see if we have any minimal
symbols available. This function returns zero if none are currently
available, nonzero otherwise. */
@@ -700,7 +759,7 @@ have_minimal_symbols ()
return 0;
}
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
/* Given the name of a mapped symbol file in SYMSFILENAME, and the timestamp
of the corresponding symbol file in MTIME, try to open an existing file
@@ -824,72 +883,90 @@ open_mapped_file (filename, mtime, mapped)
return (fd);
}
-/* Return the base address at which we would like the next objfile's
- mapped data to start.
-
- For now, we use the kludge that the configuration specifies a base
- address to which it is safe to map the first mmalloc heap, and an
- increment to add to this address for each successive heap. There are
- a lot of issues to deal with here to make this work reasonably, including:
-
- Avoid memory collisions with existing mapped address spaces
-
- Reclaim address spaces when their mmalloc heaps are unmapped
-
- When mmalloc heaps are shared between processes they have to be
- mapped at the same addresses in each
-
- Once created, a mmalloc heap that is to be mapped back in must be
- mapped at the original address. I.E. each objfile will expect to
- be remapped at it's original address. This becomes a problem if
- the desired address is already in use.
-
- etc, etc, etc.
-
- */
-
-
-static CORE_ADDR
-map_to_address ()
+static PTR
+map_to_file (fd)
+ int fd;
{
+ PTR md;
+ CORE_ADDR mapto;
-#if defined(MMAP_BASE_ADDRESS) && defined (MMAP_INCREMENT)
-
- static CORE_ADDR next = MMAP_BASE_ADDRESS;
- CORE_ADDR mapto = next;
-
- next += MMAP_INCREMENT;
- return (mapto);
-
-#else
-
- warning ("need to recompile gdb with MMAP_BASE_ADDRESS and MMAP_INCREMENT defined");
- return (0);
-
-#endif
-
+ md = mmalloc_attach (fd, (PTR) 0);
+ if (md != NULL)
+ {
+ mapto = (CORE_ADDR) mmalloc_getkey (md, 1);
+ md = mmalloc_detach (md);
+ if (md != NULL)
+ {
+ /* FIXME: should figure out why detach failed */
+ md = NULL;
+ }
+ else if (mapto != (CORE_ADDR) NULL)
+ {
+ /* This mapping file needs to be remapped at "mapto" */
+ md = mmalloc_attach (fd, (PTR) mapto);
+ }
+ else
+ {
+ /* This is a freshly created mapping file. */
+ mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024);
+ if (mapto != 0)
+ {
+ /* To avoid reusing the freshly created mapping file, at the
+ address selected by mmap, we must truncate it before trying
+ to do an attach at the address we want. */
+ ftruncate (fd, 0);
+ md = mmalloc_attach (fd, (PTR) mapto);
+ if (md != NULL)
+ {
+ mmalloc_setkey (md, 1, (PTR) mapto);
+ }
+ }
+ }
+ }
+ return (md);
}
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
-/* Returns a section whose range includes PC or NULL if none found. */
+/* Returns a section whose range includes PC and SECTION,
+ or NULL if none found. Note the distinction between the return type,
+ struct obj_section (which is defined in gdb), and the input type
+ struct sec (which is a bfd-defined data type). The obj_section
+ contains a pointer to the bfd struct sec section. */
struct obj_section *
-find_pc_section(pc)
+find_pc_sect_section (pc, section)
CORE_ADDR pc;
+ struct sec *section;
{
struct obj_section *s;
struct objfile *objfile;
ALL_OBJFILES (objfile)
for (s = objfile->sections; s < objfile->sections_end; ++s)
- if (s->addr <= pc
- && pc < s->endaddr)
+#if defined(HPUXHPPA)
+ if ((section == 0 || section == s->the_bfd_section) &&
+ s->addr <= pc && pc <= s->endaddr)
+#else
+ if ((section == 0 || section == s->the_bfd_section) &&
+ s->addr <= pc && pc < s->endaddr)
+#endif
return(s);
return(NULL);
}
+/* Returns a section whose range includes PC or NULL if none found.
+ Backward compatibility, no section. */
+
+struct obj_section *
+find_pc_section(pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_section (pc, find_pc_mapped_section (pc));
+}
+
+
/* In SVR4, we recognize a trampoline by it's section name.
That is, if the pc is in a section named ".plt" then we are in
a trampoline. */
diff --git a/contrib/gdb/gdb/objfiles.h b/contrib/gdb/gdb/objfiles.h
index b98b708..2a5df06 100644
--- a/contrib/gdb/gdb/objfiles.h
+++ b/contrib/gdb/gdb/objfiles.h
@@ -154,8 +154,29 @@ struct obj_section {
/* Objfile this section is part of. */
struct objfile *objfile;
+
+ /* True if this "overlay section" is mapped into an "overlay region". */
+ int ovly_mapped;
};
+/* An import entry contains information about a symbol that
+ is used in this objfile but not defined in it, and so needs
+ to be imported from some other objfile */
+/* Currently we just store the name; no attributes. 1997-08-05 */
+typedef char * ImportEntry;
+
+
+/* An export entry contains information about a symbol that
+ is defined in this objfile and available for use in other
+ objfiles */
+typedef struct {
+ char * name; /* name of exported symbol */
+ int address; /* offset subject to relocation */
+ /* Currently no other attributes 1997-08-05 */
+} ExportEntry;
+
+
+
/* The "objstats" structure provides a place for gdb to record some
interesting information about its internal state at runtime, on a
per objfile basis, such as information about the number of symbols
@@ -216,6 +237,22 @@ struct objfile
char *name;
+ /* TRUE if this objfile was created because the user explicitly caused
+ it (e.g., used the add-symbol-file command).
+ */
+ int user_loaded;
+
+ /* TRUE if this objfile was explicitly created to represent a solib.
+
+ (If FALSE, the objfile may actually be a solib. This can happen if
+ the user created the objfile by using the add-symbol-file command.
+ GDB doesn't in that situation actually check whether the file is a
+ solib. Rather, the target's implementation of the solib interface
+ is responsible for setting this flag when noticing solibs used by
+ an inferior.)
+ */
+ int is_solib;
+
/* Some flag bits for this objfile. */
unsigned short flags;
@@ -316,7 +353,7 @@ struct objfile
/* Information about stabs. Will be filled in with a dbx_symfile_info
struct by those readers that need it. */
- PTR sym_stab_info;
+ struct dbx_symfile_info *sym_stab_info;
/* Hook for information for use by the symbol reader (currently used
for information shared by sym_init and sym_read). It is
@@ -355,6 +392,14 @@ struct objfile
/* two auxiliary fields, used to hold the fp of separate symbol files */
FILE *auxf1, *auxf2;
+ /* Imported symbols */
+ ImportEntry * import_list;
+ int import_list_size;
+
+ /* Exported symbols */
+ ExportEntry * export_list;
+ int export_list_size;
+
/* Place to stash various statistics about this objfile */
OBJSTATS;
};
@@ -385,7 +430,12 @@ struct objfile
To avoid this penalty for normal object files, we use this flag,
whose setting is determined upon symbol table read in. */
-#define OBJF_REORDERED (2 << 1) /* Functions are reordered */
+#define OBJF_REORDERED (1 << 2) /* Functions are reordered */
+
+/* Distinguish between an objfile for a shared library and a
+ "vanilla" objfile. */
+
+#define OBJF_SHARED (1 << 3) /* From a shared library */
/* The object file that the main symbol table was loaded from (e.g. the
argument to the "symbol-file" or "file" command). */
@@ -420,7 +470,7 @@ extern struct objfile *object_files;
/* Declarations for functions defined in objfiles.c */
extern struct objfile *
-allocate_objfile PARAMS ((bfd *, int));
+allocate_objfile PARAMS ((bfd *, int, int, int));
extern int
build_objfile_section_table PARAMS ((struct objfile *));
@@ -445,6 +495,13 @@ have_partial_symbols PARAMS ((void));
extern int
have_full_symbols PARAMS ((void));
+/* This operation deletes all objfile entries that represent solibs that
+ weren't explicitly loaded by the user, via e.g., the add-symbol-file
+ command.
+ */
+extern void
+objfile_purge_solibs PARAMS ((void));
+
/* Functions for dealing with the minimal symbol table, really a misc
address<->symbol mapping for things we don't have debug symbols for. */
@@ -454,6 +511,12 @@ have_minimal_symbols PARAMS ((void));
extern struct obj_section *
find_pc_section PARAMS((CORE_ADDR pc));
+extern struct obj_section *
+find_pc_sect_section PARAMS((CORE_ADDR pc, asection *section));
+
+extern int
+in_plt_section PARAMS ((CORE_ADDR, char *));
+
/* Traverse all object files. ALL_OBJFILES_SAFE works even if you delete
the objfile during the traversal. */
@@ -499,4 +562,11 @@ find_pc_section PARAMS((CORE_ADDR pc));
if ((objfile)->msymbols) \
ALL_OBJFILE_MSYMBOLS (objfile, m)
+#define ALL_OBJFILE_OSECTIONS(objfile, osect) \
+ for (osect = objfile->sections; osect < objfile->sections_end; osect++)
+
+#define ALL_OBJSECTIONS(objfile, osect) \
+ ALL_OBJFILES (objfile) \
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+
#endif /* !defined (OBJFILES_H) */
diff --git a/contrib/gdb/gdb/ocd.c b/contrib/gdb/gdb/ocd.c
new file mode 100644
index 0000000..343fa62
--- /dev/null
+++ b/contrib/gdb/gdb/ocd.c
@@ -0,0 +1,1444 @@
+/* Target communications support for Macraigor Systems' On-Chip Debugging
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "wait.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "dcache.h"
+#include <sys/types.h>
+#include <signal.h>
+#include "serial.h"
+#include "ocd.h"
+
+/* Prototypes for local functions */
+
+static int ocd_read_bytes PARAMS ((CORE_ADDR memaddr,
+ char *myaddr, int len));
+
+static int ocd_start_remote PARAMS ((PTR dummy));
+
+static int readchar PARAMS ((int timeout));
+
+static void reset_packet PARAMS ((void));
+
+static void output_packet PARAMS ((void));
+
+static int get_quoted_char PARAMS ((int timeout));
+
+static void put_quoted_char PARAMS ((int c));
+
+static void ocd_interrupt PARAMS ((int signo));
+
+static void ocd_interrupt_twice PARAMS ((int signo));
+
+static void interrupt_query PARAMS ((void));
+
+static unsigned char * ocd_do_command PARAMS ((int cmd, int *statusp, int *lenp));
+
+static void ocd_put_packet PARAMS ((unsigned char *packet, int pktlen));
+
+static unsigned char * ocd_get_packet PARAMS ((int cmd, int *pktlen, int timeout));
+
+static struct target_ops *current_ops = NULL;
+
+static int last_run_status;
+
+/* This was 5 seconds, which is a long time to sit and wait.
+ Unless this is going though some terminal server or multiplexer or
+ other form of hairy serial connection, I would think 2 seconds would
+ be plenty. */
+
+#if 0
+/* FIXME: Change to allow option to set timeout value on a per target
+ basis. */
+static int remote_timeout = 2;
+#endif
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so that
+ ocd_open knows that we don't have a file open when the program
+ starts. */
+static serial_t ocd_desc = NULL;
+
+void
+ocd_error (s, error_code)
+ char *s;
+ int error_code;
+{
+ char buf[100];
+
+ fputs_filtered (s, gdb_stderr);
+ fputs_filtered (" ", gdb_stderr);
+
+ switch (error_code)
+ {
+ case 0x1: s = "Unknown fault"; break;
+ case 0x2: s = "Power failed"; break;
+ case 0x3: s = "Cable disconnected"; break;
+ case 0x4: s = "Couldn't enter OCD mode"; break;
+ case 0x5: s = "Target stuck in reset"; break;
+ case 0x6: s = "OCD hasn't been initialized"; break;
+ case 0x7: s = "Write verify failed"; break;
+ case 0x8: s = "Reg buff error (during MPC5xx fp reg read/write)"; break;
+ case 0x9: s = "Invalid CPU register access attempt failed"; break;
+ case 0x11: s = "Bus error"; break;
+ case 0x12: s = "Checksum error"; break;
+ case 0x13: s = "Illegal command"; break;
+ case 0x14: s = "Parameter error"; break;
+ case 0x15: s = "Internal error"; break;
+ case 0x80: s = "Flash erase error"; break;
+ default:
+ sprintf (buf, "Unknown error code %d", error_code);
+ s = buf;
+ }
+
+ error (s);
+}
+
+/* Return nonzero if the thread TH is still alive on the remote system. */
+
+int
+ocd_thread_alive (th)
+ int th;
+{
+ return 1;
+}
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+void
+ocd_close (quitting)
+ int quitting;
+{
+ if (ocd_desc)
+ SERIAL_CLOSE (ocd_desc);
+ ocd_desc = NULL;
+}
+
+/* Stub for catch_errors. */
+
+static int
+ocd_start_remote (dummy)
+ PTR dummy;
+{
+ unsigned char buf[10], *p;
+ int pktlen;
+ int status;
+ int error_code;
+ int speed;
+ enum ocd_target_type target_type;
+
+ target_type = *(enum ocd_target_type*)dummy;
+
+ immediate_quit = 1; /* Allow user to interrupt it */
+
+ SERIAL_SEND_BREAK (ocd_desc); /* Wake up the wiggler */
+
+ speed = 80; /* Divide clock by 4000 */
+
+ buf[0] = OCD_INIT;
+ buf[1] = speed >> 8;
+ buf[2] = speed & 0xff;
+ buf[3] = target_type;
+ ocd_put_packet (buf, 4); /* Init OCD params */
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ if (pktlen < 2)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("OCD_INIT:", error_code);
+
+ ocd_do_command (OCD_AYT, &status, &pktlen);
+
+ p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen);
+
+ printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
+ p[0], p[1], (p[2] << 16) | p[3]);
+
+#if 0
+ /* Reset the target */
+
+ ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
+/* ocd_do_command (OCD_RESET, &status, &pktlen);*/
+#endif
+
+ /* If processor is still running, stop it. */
+
+ if (!(status & OCD_FLAG_BDM))
+ ocd_stop ();
+
+#if 1
+ /* When using a target box, we want to asynchronously return status when
+ target stops. The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll
+ when using a parallel Wiggler */
+ buf[0] = OCD_SET_CTL_FLAGS;
+ buf[1] = 0;
+ buf[2] = 1;
+ ocd_put_packet (buf, 3);
+
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ if (pktlen < 2)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("OCD_SET_CTL_FLAGS:", error_code);
+#endif
+
+ immediate_quit = 0;
+
+/* This is really the job of start_remote however, that makes an assumption
+ that the target is about to print out a status message of some sort. That
+ doesn't happen here (in fact, it may not be possible to get the monitor to
+ send the appropriate packet). */
+
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame (), 0);
+ print_stack_frame (selected_frame, -1, 1);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 3; /* close existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 2; /* append to existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ return 1;
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static DCACHE *ocd_dcache;
+
+void
+ocd_open (name, from_tty, target_type, ops)
+ char *name;
+ int from_tty;
+ enum ocd_target_type target_type;
+ struct target_ops *ops;
+{
+ unsigned char buf[10], *p;
+ int status;
+ int pktlen;
+
+ if (name == 0)
+ error ("To open an OCD connection, you need to specify the\n\
+device the OCD device is attached to (e.g. /dev/ttya).");
+
+ target_preopen (from_tty);
+
+ current_ops = ops;
+
+ unpush_target (current_ops);
+
+ ocd_dcache = dcache_init (ocd_read_bytes, ocd_write_bytes);
+
+ if (strncmp(name,"wiggler",7) == 0)
+ {
+ ocd_desc = SERIAL_OPEN ("ocd");
+ if (!ocd_desc)
+ perror_with_name (name);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 1; /* open new or overwrite existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ buf[0] = OCD_SET_CONNECTION;
+ buf[1] = 0x01; /* atoi (name[11]); */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+ }
+ else /* not using Wigglers.dll */
+ {
+ ocd_desc = SERIAL_OPEN (name);
+ if (!ocd_desc)
+ perror_with_name (name);
+ }
+
+ if (baud_rate != -1)
+ {
+ if (SERIAL_SETBAUDRATE (ocd_desc, baud_rate))
+ {
+ SERIAL_CLOSE (ocd_desc);
+ perror_with_name (name);
+ }
+ }
+
+ SERIAL_RAW (ocd_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ SERIAL_FLUSH_INPUT (ocd_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote target wiggler connected to ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+ push_target (current_ops); /* Switch to using remote target now */
+
+ /* Without this, some commands which require an active target (such as kill)
+ won't work. This variable serves (at least) double duty as both the pid
+ of the target process (if it has such), and as a flag indicating that a
+ target is active. These functions should be split out into seperate
+ variables, especially since GDB will someday have a notion of debugging
+ several processes. */
+
+ inferior_pid = 42000;
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it
+ (we'd be in an inconsistent state otherwise). */
+ if (!catch_errors (ocd_start_remote, &target_type,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ pop_target();
+ error ("Failed to connect to OCD.");
+ }
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+void
+ocd_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+}
+
+/* Tell the remote machine to resume. */
+
+void
+ocd_resume (pid, step, siggnal)
+ int pid, step;
+ enum target_signal siggnal;
+{
+ int pktlen;
+
+ dcache_flush (ocd_dcache);
+
+ if (step)
+ ocd_do_command (OCD_STEP, &last_run_status, &pktlen);
+ else
+ ocd_do_command (OCD_RUN, &last_run_status, &pktlen);
+}
+
+void
+ocd_stop ()
+{
+ int status;
+ int pktlen;
+
+ ocd_do_command (OCD_STOP, &status, &pktlen);
+
+ if (!(status & OCD_FLAG_BDM))
+ error ("Can't stop target via BDM");
+}
+
+static volatile int ocd_interrupt_flag;
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+static void
+ocd_interrupt (signo)
+ int signo;
+{
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, ocd_interrupt_twice);
+
+ if (remote_debug)
+ printf_unfiltered ("ocd_interrupt called\n");
+
+ {
+ char buf[1];
+
+ ocd_stop ();
+ buf[0] = OCD_AYT;
+ ocd_put_packet (buf, 1);
+ ocd_interrupt_flag = 1;
+ }
+}
+
+static void (*ofunc)();
+
+/* The user typed ^C twice. */
+static void
+ocd_interrupt_twice (signo)
+ int signo;
+{
+ signal (signo, ofunc);
+
+ interrupt_query ();
+
+ signal (signo, ocd_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query ()
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ return_to_top_level (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+/* If nonzero, ignore the next kill. */
+static int kill_kludge;
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid" (though it's not clear what, if anything, that
+ means in the case of this target). */
+
+int
+ocd_wait ()
+{
+ unsigned char *p;
+ int error_code;
+ int pktlen;
+ char buf[1];
+
+ ocd_interrupt_flag = 0;
+
+ /* Target might already be stopped by the time we get here. */
+ /* If we aren't already stopped, we need to loop until we've dropped
+ back into BDM mode */
+
+ while (!(last_run_status & OCD_FLAG_BDM))
+ {
+ buf[0] = OCD_AYT;
+ ocd_put_packet (buf, 1);
+ p = ocd_get_packet (OCD_AYT, &pktlen, -1);
+
+ ofunc = (void (*)()) signal (SIGINT, ocd_interrupt);
+ signal (SIGINT, ofunc);
+
+ if (pktlen < 2)
+ error ("Truncated response packet from OCD device");
+
+ last_run_status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("target_wait:", error_code);
+
+ if (last_run_status & OCD_FLAG_PWF)
+ error ("OCD device lost VCC at BDM interface.");
+ else if (last_run_status & OCD_FLAG_CABLE_DISC)
+ error ("OCD device cable appears to have been disconnected.");
+ }
+
+ if (ocd_interrupt_flag)
+ return 1;
+ else
+ return 0;
+}
+
+/* Read registers from the OCD device. Specify the starting and ending
+ register number. Return the number of regs actually read in *NUMREGS.
+ Returns a pointer to a static array containing the register contents. */
+
+unsigned char *
+ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, reglen)
+ int first_bdm_regno;
+ int last_bdm_regno;
+ int *reglen;
+{
+ unsigned char buf[10];
+ int i;
+ unsigned char *p;
+ unsigned char *regs;
+ int error_code, status;
+ int pktlen;
+
+ buf[0] = OCD_READ_REGS;
+ buf[1] = first_bdm_regno >> 8;
+ buf[2] = first_bdm_regno & 0xff;
+ buf[3] = last_bdm_regno >> 8;
+ buf[4] = last_bdm_regno & 0xff;
+
+ ocd_put_packet (buf, 5);
+ p = ocd_get_packet (OCD_READ_REGS, &pktlen, remote_timeout);
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("read_bdm_registers:", error_code);
+
+ i = p[3];
+ if (i == 0)
+ i = 256;
+
+ if (i > pktlen - 4
+ || ((i & 3) != 0))
+ error ("Register block size bad: %d", i);
+
+ *reglen = i;
+
+ regs = p + 4;
+
+ return regs;
+}
+
+/* Read register BDM_REGNO and returns its value ala read_register() */
+
+CORE_ADDR
+ocd_read_bdm_register (bdm_regno)
+ int bdm_regno;
+{
+ int reglen;
+ unsigned char *p;
+ CORE_ADDR regval;
+
+ p = ocd_read_bdm_registers (bdm_regno, bdm_regno, &reglen);
+ regval = extract_unsigned_integer (p, reglen);
+
+ return regval;
+}
+
+void
+ocd_write_bdm_registers (first_bdm_regno, regptr, reglen)
+ int first_bdm_regno;
+ unsigned char *regptr;
+ int reglen;
+{
+ unsigned char *buf;
+ unsigned char *p;
+ int error_code, status;
+ int pktlen;
+
+ buf = alloca (4 + reglen);
+
+ buf[0] = OCD_WRITE_REGS;
+ buf[1] = first_bdm_regno >> 8;
+ buf[2] = first_bdm_regno & 0xff;
+ buf[3] = reglen;
+ memcpy (buf + 4, regptr, reglen);
+
+ ocd_put_packet (buf, 4 + reglen);
+ p = ocd_get_packet (OCD_WRITE_REGS, &pktlen, remote_timeout);
+
+ if (pktlen < 3)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("ocd_write_bdm_registers:", error_code);
+}
+
+void
+ocd_write_bdm_register (bdm_regno, reg)
+ int bdm_regno;
+ CORE_ADDR reg;
+{
+ unsigned char buf[4];
+
+ store_unsigned_integer (buf, 4, reg);
+
+ ocd_write_bdm_registers (bdm_regno, buf, 4);
+}
+
+void
+ocd_prepare_to_store ()
+{
+}
+
+/* Write memory data directly to the remote machine.
+ This does not inform the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int write_mem_command = OCD_WRITE_MEM;
+
+int
+ocd_write_bytes (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ char buf[256 + 10];
+ unsigned char *p;
+ int origlen;
+
+ origlen = len;
+
+ buf[0] = write_mem_command;
+ buf[5] = 1; /* Write as bytes */
+ buf[6] = 0; /* Don't verify */
+
+ while (len > 0)
+ {
+ int numbytes;
+ int pktlen;
+ int status, error_code;
+
+ numbytes = min (len, 256 - 8);
+
+ buf[1] = memaddr >> 24;
+ buf[2] = memaddr >> 16;
+ buf[3] = memaddr >> 8;
+ buf[4] = memaddr;
+
+ buf[7] = numbytes;
+
+ memcpy (&buf[8], myaddr, numbytes);
+ ocd_put_packet (buf, 8 + numbytes);
+ p = ocd_get_packet (OCD_WRITE_MEM, &pktlen, remote_timeout);
+ if (pktlen < 3)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code == 0x11) /* Got a bus error? */
+ {
+ CORE_ADDR error_address;
+
+ error_address = p[3] << 24;
+ error_address |= p[4] << 16;
+ error_address |= p[5] << 8;
+ error_address |= p[6];
+ numbytes = error_address - memaddr;
+
+ len -= numbytes;
+
+ errno = EIO;
+
+ break;
+ }
+ else if (error_code != 0)
+ ocd_error ("ocd_write_bytes:", error_code);
+
+ len -= numbytes;
+ memaddr += numbytes;
+ myaddr += numbytes;
+ }
+
+ return origlen - len;
+}
+
+/* Read memory data directly from the remote machine.
+ This does not use the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int
+ocd_read_bytes (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ char buf[256 + 10];
+ unsigned char *p;
+ int origlen;
+
+ origlen = len;
+
+ buf[0] = OCD_READ_MEM;
+ buf[5] = 1; /* Read as bytes */
+
+ while (len > 0)
+ {
+ int numbytes;
+ int pktlen;
+ int status, error_code;
+
+ numbytes = min (len, 256 - 7);
+
+ buf[1] = memaddr >> 24;
+ buf[2] = memaddr >> 16;
+ buf[3] = memaddr >> 8;
+ buf[4] = memaddr;
+
+ buf[6] = numbytes;
+
+ ocd_put_packet (buf, 7);
+ p = ocd_get_packet (OCD_READ_MEM, &pktlen, remote_timeout);
+ if (pktlen < 4)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code == 0x11) /* Got a bus error? */
+ {
+ CORE_ADDR error_address;
+
+ error_address = p[3] << 24;
+ error_address |= p[4] << 16;
+ error_address |= p[5] << 8;
+ error_address |= p[6];
+ numbytes = error_address - memaddr;
+
+ len -= numbytes;
+
+ errno = EIO;
+
+ break;
+ }
+ else if (error_code != 0)
+ ocd_error ("ocd_read_bytes:", error_code);
+
+ memcpy (myaddr, &p[4], numbytes);
+
+ len -= numbytes;
+ memaddr += numbytes;
+ myaddr += numbytes;
+ }
+
+ return origlen - len;
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
+ nonzero. Returns length of data written or read; 0 for error. */
+
+/* ARGSUSED */
+int
+ocd_xfer_memory (memaddr, myaddr, len, should_write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int should_write;
+ struct target_ops *target; /* ignored */
+{
+ return dcache_xfer_memory (ocd_dcache, memaddr, myaddr, len, should_write);
+}
+
+void
+ocd_files_info (ignore)
+ struct target_ops *ignore;
+{
+ puts_filtered ("Debugging a target over a serial line.\n");
+}
+
+/* Stuff for dealing with the packets which are part of this protocol.
+ See comment at top of file for details. */
+
+/* Read a single character from the remote side, handling wierd errors. */
+
+static int
+readchar (timeout)
+ int timeout;
+{
+ int ch;
+
+ ch = SERIAL_READCHAR (ocd_desc, timeout);
+
+ switch (ch)
+ {
+ case SERIAL_EOF:
+ error ("Remote connection closed");
+ case SERIAL_ERROR:
+ perror_with_name ("Remote communication error");
+ case SERIAL_TIMEOUT:
+ default:
+ return ch;
+ }
+}
+
+#if 0
+/* Read a character from the data stream, dequoting as necessary. SYN is
+ treated special. Any SYNs appearing in the data stream are returned as the
+ distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
+ mistaken for real data). */
+
+static int
+get_quoted_char (timeout)
+ int timeout;
+{
+ int ch;
+
+ ch = readchar (timeout);
+
+ switch (ch)
+ {
+ case SERIAL_TIMEOUT:
+ error ("Timeout in mid-packet, aborting");
+ case SYN:
+ return RAW_SYN;
+ case DLE:
+ ch = readchar (timeout);
+ if (ch == SYN)
+ return RAW_SYN;
+ return ch & ~0100;
+ default:
+ return ch;
+ }
+}
+
+static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
+
+static void
+reset_packet ()
+{
+ pktp = pkt;
+}
+
+static void
+output_packet ()
+{
+ if (SERIAL_WRITE (ocd_desc, pkt, pktp - pkt))
+ perror_with_name ("output_packet: write failed");
+
+ reset_packet ();
+}
+
+/* Output a quoted character. SYNs and DLEs are quoted. Everything else goes
+ through untouched. */
+
+static void
+put_quoted_char (c)
+ int c;
+{
+ switch (c)
+ {
+ case SYN:
+ case DLE:
+ *pktp++ = DLE;
+ c |= 0100;
+ }
+
+ *pktp++ = c;
+}
+
+/* Send a packet to the OCD device. The packet framed by a SYN character,
+ a byte count and a checksum. The byte count only counts the number of
+ bytes between the count and the checksum. A count of zero actually
+ means 256. Any SYNs within the packet (including the checksum and
+ count) must be quoted. The quote character must be quoted as well.
+ Quoting is done by replacing the character with the two-character sequence
+ DLE, {char} | 0100. Note that the quoting mechanism has no effect on the
+ byte count. */
+
+static void
+stu_put_packet (buf, len)
+ unsigned char *buf;
+ int len;
+{
+ unsigned char checksum;
+ unsigned char c;
+
+ if (len == 0 || len > 256)
+ abort (); /* Can't represent 0 length packet */
+
+ reset_packet ();
+
+ checksum = 0;
+
+ put_quoted_char (RAW_SYN);
+
+ c = len;
+
+ do
+ {
+ checksum += c;
+
+ put_quoted_char (c);
+
+ c = *buf++;
+ }
+ while (len-- > 0);
+
+ put_quoted_char (-checksum & 0xff);
+
+ output_packet ();
+}
+
+#else
+
+/* Send a packet to the OCD device. The packet framed by a SYN character,
+ a byte count and a checksum. The byte count only counts the number of
+ bytes between the count and the checksum. A count of zero actually
+ means 256. Any SYNs within the packet (including the checksum and
+ count) must be quoted. The quote character must be quoted as well.
+ Quoting is done by replacing the character with the two-character sequence
+ DLE, {char} | 0100. Note that the quoting mechanism has no effect on the
+ byte count. */
+
+static void
+ocd_put_packet (buf, len)
+ unsigned char *buf;
+ int len;
+{
+ unsigned char checksum;
+ unsigned char c;
+ unsigned char *packet, *packet_ptr;
+
+ packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
+ packet_ptr = packet;
+
+ checksum = 0;
+
+ *packet_ptr++ = 0x55;
+
+ while (len-- > 0)
+ {
+ c = *buf++;
+
+ checksum += c;
+ *packet_ptr++ = c;
+ }
+
+ *packet_ptr++ = -checksum;
+ if (SERIAL_WRITE (ocd_desc, packet, packet_ptr - packet))
+ perror_with_name ("output_packet: write failed");
+}
+#endif
+
+#if 0
+/* Get a packet from the OCD device. Timeout is only enforced for the
+ first byte of the packet. Subsequent bytes are expected to arrive in
+ time <= remote_timeout. Returns a pointer to a static buffer containing
+ the payload of the packet. *LENP contains the length of the packet.
+*/
+
+static unsigned char *
+stu_get_packet (cmd, lenp, timeout)
+ unsigned char cmd;
+ int *lenp;
+{
+ int ch;
+ int len;
+ static unsigned char buf[256 + 10], *p;
+ unsigned char checksum;
+
+ find_packet:
+
+ ch = get_quoted_char (timeout);
+
+ if (ch < 0)
+ error ("get_packet (readchar): %d", ch);
+
+ if (ch != RAW_SYN)
+ goto find_packet;
+
+ found_syn: /* Found the start of a packet */
+
+ p = buf;
+ checksum = 0;
+
+ len = get_quoted_char (remote_timeout);
+
+ if (len == RAW_SYN)
+ goto found_syn;
+
+ checksum += len;
+
+ if (len == 0)
+ len = 256;
+
+ len++; /* Include checksum */
+
+ while (len-- > 0)
+ {
+ ch = get_quoted_char (remote_timeout);
+ if (ch == RAW_SYN)
+ goto found_syn;
+
+ *p++ = ch;
+ checksum += ch;
+ }
+
+ if (checksum != 0)
+ goto find_packet;
+
+ if (cmd != buf[0])
+ error ("Response phase error. Got 0x%x, expected 0x%x", buf[0], cmd);
+
+ *lenp = p - buf - 1;
+ return buf;
+}
+
+#else
+
+/* Get a packet from the OCD device. Timeout is only enforced for the
+ first byte of the packet. Subsequent bytes are expected to arrive in
+ time <= remote_timeout. Returns a pointer to a static buffer containing
+ the payload of the packet. *LENP contains the length of the packet.
+*/
+
+static unsigned char *
+ocd_get_packet (cmd, lenp, timeout)
+ int cmd;
+ int *lenp;
+{
+ int ch;
+ int len;
+ int i;
+ static unsigned char packet[512];
+ unsigned char *packet_ptr;
+ unsigned char checksum;
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+
+ if (ch != 0x55)
+ error ("ocd_get_packet (readchar): %d", ch);
+
+/* Found the start of a packet */
+
+ packet_ptr = packet;
+ checksum = 0;
+
+/* Read command char. That sort of tells us how long the packet is. */
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+
+ *packet_ptr++ = ch;
+ checksum += ch;
+
+/* Get status. */
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+
+/* Get error code. */
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+
+ switch (ch) /* Figure out length of packet */
+ {
+ case 0x7: /* Write verify error? */
+ len = 8; /* write address, value read back */
+ break;
+ case 0x11: /* Bus error? */
+ /* write address, read flag */
+ case 0x15: /* Internal error */
+ len = 5; /* error code, vector */
+ break;
+ default: /* Error w/no params */
+ len = 0;
+ break;
+ case 0x0: /* Normal result */
+ switch (packet[0])
+ {
+ case OCD_AYT: /* Are You There? */
+ case OCD_SET_BAUD_RATE: /* Set Baud Rate */
+ case OCD_INIT: /* Initialize OCD device */
+ case OCD_SET_SPEED: /* Set Speed */
+ case OCD_SET_FUNC_CODE: /* Set Function Code */
+ case OCD_SET_CTL_FLAGS: /* Set Control Flags */
+ case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */
+ case OCD_RUN: /* Run Target from PC */
+ case OCD_RUN_ADDR: /* Run Target from Specified Address */
+ case OCD_STOP: /* Stop Target */
+ case OCD_RESET_RUN: /* Reset Target and Run */
+ case OCD_RESET: /* Reset Target and Halt */
+ case OCD_STEP: /* Single Step */
+ case OCD_WRITE_REGS: /* Write Register */
+ case OCD_WRITE_MEM: /* Write Memory */
+ case OCD_FILL_MEM: /* Fill Memory */
+ case OCD_MOVE_MEM: /* Move Memory */
+ case OCD_WRITE_INT_MEM: /* Write Internal Memory */
+ case OCD_JUMP: /* Jump to Subroutine */
+ case OCD_ERASE_FLASH: /* Erase flash memory */
+ case OCD_PROGRAM_FLASH: /* Write flash memory */
+ case OCD_EXIT_MON: /* Exit the flash programming monitor */
+ case OCD_ENTER_MON: /* Enter the flash programming monitor */
+ case OCD_LOG_FILE: /* Make Wigglers.dll save Wigglers.log */
+ case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */
+ len = 0;
+ break;
+ case OCD_GET_VERSION: /* Get Version */
+ len = 10;
+ break;
+ case OCD_GET_STATUS_MASK: /* Get Status Mask */
+ len = 1;
+ break;
+ case OCD_GET_CTRS: /* Get Error Counters */
+ case OCD_READ_REGS: /* Read Register */
+ case OCD_READ_MEM: /* Read Memory */
+ case OCD_READ_INT_MEM: /* Read Internal Memory */
+ len = 257;
+ break;
+ default:
+ error ("ocd_get_packet: unknown packet type 0x%x\n", ch);
+ }
+ }
+
+ if (len == 257) /* Byte stream? */
+ { /* Yes, byte streams contain the length */
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+ len = ch;
+ if (len == 0)
+ len = 256;
+ }
+
+ while (len-- >= 0) /* Do rest of packet and checksum */
+ {
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+ }
+
+ if (checksum != 0)
+ error ("ocd_get_packet: bad packet checksum");
+
+ if (cmd != -1 && cmd != packet[0])
+ error ("Response phase error. Got 0x%x, expected 0x%x", packet[0], cmd);
+
+ *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
+ return packet;
+}
+#endif
+
+/* Execute a simple (one-byte) command. Returns a pointer to the data
+ following the error code. */
+
+static unsigned char *
+ocd_do_command (cmd, statusp, lenp)
+ int cmd;
+ int *statusp;
+ int *lenp;
+{
+ unsigned char buf[100], *p;
+ int status, error_code;
+ char errbuf[100];
+
+ unsigned char logbuf[100];
+ int logpktlen;
+
+ buf[0] = cmd;
+ ocd_put_packet (buf, 1); /* Send command */
+ p = ocd_get_packet (*buf, lenp, remote_timeout);
+
+ if (*lenp < 3)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ {
+ sprintf (errbuf, "ocd_do_command (0x%x):", cmd);
+ ocd_error (errbuf, error_code);
+ }
+
+ if (status & OCD_FLAG_PWF)
+ error ("OCD device can't detect VCC at BDM interface.");
+ else if (status & OCD_FLAG_CABLE_DISC)
+ error ("BDM cable appears to be disconnected.");
+
+ *statusp = status;
+
+ logbuf[0] = OCD_LOG_FILE;
+ logbuf[1] = 3; /* close existing WIGGLERS.LOG */
+ ocd_put_packet (logbuf, 2);
+ ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
+
+ logbuf[0] = OCD_LOG_FILE;
+ logbuf[1] = 2; /* append to existing WIGGLERS.LOG */
+ ocd_put_packet (logbuf, 2);
+ ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
+
+ return p + 3;
+}
+
+void
+ocd_kill ()
+{
+ /* For some mysterious reason, wait_for_inferior calls kill instead of
+ mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
+ if (kill_kludge)
+ {
+ kill_kludge = 0;
+ target_mourn_inferior ();
+ return;
+ }
+
+ /* Don't wait for it to die. I'm not really sure it matters whether
+ we do or not. */
+ target_mourn_inferior ();
+}
+
+void
+ocd_mourn ()
+{
+ unpush_target (current_ops);
+ generic_mourn_inferior ();
+}
+
+/* All we actually do is set the PC to the start address of exec_bfd, and start
+ the program at that point. */
+
+void
+ocd_create_inferior (exec_file, args, env)
+ char *exec_file;
+ char *args;
+ char **env;
+{
+ if (args && (*args != '\000'))
+ error ("Args are not supported by BDM.");
+
+ clear_proceed_status ();
+ proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
+void
+ocd_load (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ generic_load (args, from_tty);
+
+ inferior_pid = 0;
+
+/* This is necessary because many things were based on the PC at the time that
+ we attached to the monitor, which is no longer valid now that we have loaded
+ new code (and just changed the PC). Another way to do this might be to call
+ normal_stop, except that the stack may not be valid, and things would get
+ horribly confused... */
+
+ clear_symtab_users ();
+}
+
+/* This should be defined for each target */
+/* But we want to be able to compile this file for some configurations
+ not yet supported fully */
+
+#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */
+#if 0
+#define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */
+#endif
+
+/* BDM (at least on CPU32) uses a different breakpoint */
+
+int
+ocd_insert_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ static char break_insn[] = BDM_BREAKPOINT;
+ int val;
+
+ val = target_read_memory (addr, contents_cache, sizeof (break_insn));
+
+ if (val == 0)
+ val = target_write_memory (addr, break_insn, sizeof (break_insn));
+
+ return val;
+}
+
+int
+ocd_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ static char break_insn[] = BDM_BREAKPOINT;
+ int val;
+
+ val = target_write_memory (addr, contents_cache, sizeof (break_insn));
+
+ return val;
+}
+
+static void
+bdm_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ error ("bdm command must be followed by `reset'");
+}
+
+static void
+bdm_reset_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int status, pktlen;
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ ocd_do_command (OCD_RESET, &status, &pktlen);
+ dcache_flush (ocd_dcache);
+ registers_changed ();
+}
+
+static void
+bdm_restart_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int status, pktlen;
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
+ last_run_status = status;
+ clear_proceed_status ();
+ wait_for_inferior ();
+ normal_stop ();
+}
+
+/* Temporary replacement for target_store_registers(). This prevents
+ generic_load from trying to set the PC. */
+
+static void
+noop_store_registers (regno)
+ int regno;
+{
+}
+
+static void
+bdm_update_flash_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int status, pktlen;
+ struct cleanup *old_chain;
+ void (*store_registers_tmp) PARAMS ((int));
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ if (!args)
+ error ("Must specify file containing new OCD code.");
+
+/* old_chain = make_cleanup (flash_cleanup, 0);*/
+
+ ocd_do_command (OCD_ENTER_MON, &status, &pktlen);
+
+ ocd_do_command (OCD_ERASE_FLASH, &status, &pktlen);
+
+ write_mem_command = OCD_PROGRAM_FLASH;
+ store_registers_tmp = current_target.to_store_registers;
+ current_target.to_store_registers = noop_store_registers;
+
+ generic_load (args, from_tty);
+
+ current_target.to_store_registers = store_registers_tmp;
+ write_mem_command = OCD_WRITE_MEM;
+
+ ocd_do_command (OCD_EXIT_MON, &status, &pktlen);
+
+/* discard_cleanups (old_chain);*/
+}
+
+static void
+bdm_read_register_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ /* XXX repeat should go on to the next register */
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ if (!args)
+ error ("Must specify BDM register number.");
+
+}
+
+void
+_initialize_remote_ocd ()
+{
+ extern struct cmd_list_element *cmdlist;
+ static struct cmd_list_element *ocd_cmd_list = NULL;
+
+ add_show_from_set (add_set_cmd ("remotetimeout", no_class,
+ var_integer, (char *)&remote_timeout,
+ "Set timeout value for remote read.\n", &setlist),
+ &showlist);
+
+ add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ",
+ 0, &cmdlist);
+
+ add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list);
+ add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list);
+ add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list);
+ /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list);*/
+}
diff --git a/contrib/gdb/gdb/ocd.h b/contrib/gdb/gdb/ocd.h
new file mode 100644
index 0000000..020d3e2
--- /dev/null
+++ b/contrib/gdb/gdb/ocd.h
@@ -0,0 +1,139 @@
+/* Definitions for the Macraigor Systems BDM Wiggler
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef OCD_H
+#define OCD_H
+
+/* Wiggler serial protocol definitions */
+
+#define DLE 020 /* Quote char */
+#define SYN 026 /* Start of packet */
+#define RAW_SYN ((026 << 8) | 026) /* get_quoted_char found a naked SYN */
+
+/* Status flags */
+
+#define OCD_FLAG_RESET 0x01 /* Target is being reset */
+#define OCD_FLAG_STOPPED 0x02 /* Target is halted */
+#define OCD_FLAG_BDM 0x04 /* Target is in BDM */
+#define OCD_FLAG_PWF 0x08 /* Power failed */
+#define OCD_FLAG_CABLE_DISC 0x10 /* BDM cable disconnected */
+
+/* Commands */
+
+#define OCD_AYT 0x0 /* Are you there? */
+#define OCD_GET_VERSION 0x1 /* Get Version */
+#define OCD_SET_BAUD_RATE 0x2 /* Set Baud Rate */
+#define OCD_INIT 0x10 /* Initialize Wiggler */
+#define OCD_SET_SPEED 0x11 /* Set Speed */
+#define OCD_GET_STATUS_MASK 0x12 /* Get Status Mask */
+#define OCD_GET_CTRS 0x13 /* Get Error Counters */
+#define OCD_SET_FUNC_CODE 0x14 /* Set Function Code */
+#define OCD_SET_CTL_FLAGS 0x15 /* Set Control Flags */
+#define OCD_SET_BUF_ADDR 0x16 /* Set Register Buffer Address */
+#define OCD_RUN 0x20 /* Run Target from PC */
+#define OCD_RUN_ADDR 0x21 /* Run Target from Specified Address */
+#define OCD_STOP 0x22 /* Stop Target */
+#define OCD_RESET_RUN 0x23 /* Reset Target and Run */
+#define OCD_RESET 0x24 /* Reset Target and Halt */
+#define OCD_STEP 0x25 /* Single step */
+#define OCD_READ_REGS 0x30 /* Read Registers */
+#define OCD_WRITE_REGS 0x31 /* Write Registers */
+#define OCD_READ_MEM 0x32 /* Read Memory */
+#define OCD_WRITE_MEM 0x33 /* Write Memory */
+#define OCD_FILL_MEM 0x34 /* Fill Memory */
+#define OCD_MOVE_MEM 0x35 /* Move Memory */
+
+#define OCD_READ_INT_MEM 0x80 /* Read Internal Memory */
+#define OCD_WRITE_INT_MEM 0x81 /* Write Internal Memory */
+#define OCD_JUMP 0x82 /* Jump to Subroutine */
+
+#define OCD_ERASE_FLASH 0x90 /* Erase flash memory */
+#define OCD_PROGRAM_FLASH 0x91 /* Write flash memory */
+#define OCD_EXIT_MON 0x93 /* Exit the flash programming monitor */
+#define OCD_ENTER_MON 0x94 /* Enter the flash programming monitor */
+
+#define OCD_SET_STATUS 0x0a /* Set status */
+#define OCD_SET_CONNECTION 0xf0 /* Set connection (init Wigglers.dll) */
+#define OCD_LOG_FILE 0xf1 /* Cmd to get Wigglers.dll to log cmds */
+#define OCD_FLAG_STOP 0x0 /* Stop the target, enter BDM */
+#define OCD_FLAG_START 0x01 /* Start the target at PC */
+#define OCD_FLAG_RETURN_STATUS 0x04 /* Return async status */
+
+/* Target type (for OCD_INIT command) */
+
+enum ocd_target_type {
+ OCD_TARGET_CPU32=0x0, /* Moto cpu32 family */
+ OCD_TARGET_CPU16=0x1,
+ OCD_TARGET_MOTO_PPC=0x2, /* Motorola PPC 5xx/8xx */
+ OCD_TARGET_IBM_PPC=0x3}; /* IBM PPC 4xx */
+
+void ocd_open PARAMS ((char *name, int from_tty, enum ocd_target_type,
+ struct target_ops *ops));
+
+void ocd_close PARAMS ((int quitting));
+
+void ocd_detach PARAMS ((char *args, int from_tty));
+
+void ocd_resume PARAMS ((int pid, int step, enum target_signal siggnal));
+
+void ocd_prepare_to_store PARAMS ((void));
+
+void ocd_stop PARAMS ((void));
+
+void ocd_files_info PARAMS ((struct target_ops *ignore));
+
+
+int ocd_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct target_ops *target));
+
+void ocd_mourn PARAMS ((void));
+
+void ocd_create_inferior PARAMS ((char *exec_file,
+ char *args,
+ char **env));
+
+int ocd_thread_alive PARAMS ((int th));
+
+void ocd_error PARAMS ((char *s, int error_code));
+
+void ocd_kill PARAMS ((void));
+
+void ocd_load PARAMS((char *args, int from_tty));
+
+unsigned char * ocd_read_bdm_registers PARAMS ((int first_bdm_regno,
+ int last_bdm_regno,
+ int *reglen));
+
+CORE_ADDR ocd_read_bdm_register PARAMS ((int bdm_regno));
+
+void ocd_write_bdm_registers PARAMS ((int first_bdm_regno,
+ unsigned char *regptr,
+ int reglen));
+
+void ocd_write_bdm_register PARAMS ((int bdm_regno, CORE_ADDR reg));
+
+int ocd_wait PARAMS ((void));
+
+int ocd_insert_breakpoint PARAMS ((CORE_ADDR addr, char *contents_cache));
+int ocd_remove_breakpoint PARAMS ((CORE_ADDR addr, char *contents_cache));
+
+int ocd_write_bytes PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+
+#endif /* OCD_H */
diff --git a/contrib/gdb/gdb/op50-rom.c b/contrib/gdb/gdb/op50-rom.c
index f8cb7fa..3262091 100644
--- a/contrib/gdb/gdb/op50-rom.c
+++ b/contrib/gdb/gdb/op50-rom.c
@@ -55,73 +55,68 @@ static struct target_ops op50n_ops;
static char *op50n_inits[] = {".\r", NULL};
-static struct monitor_ops op50n_cmds =
+static struct monitor_ops op50n_cmds ;
+
+static void
+init_op50n_cmds(void)
{
- MO_CLR_BREAK_USES_ADDR /*| MO_GETMEM_READ_SINGLE*/, /* flags */
- op50n_inits, /* Init strings */
- "g\r", /* continue command */
- "t\r", /* single step */
- "\003.\r", /* Interrupt char */
- "b %x\r", /* set a breakpoint */
- "b %x,0\r", /* clear breakpoint at addr */
- "bx\r", /* clear all breakpoints */
- "fx %x s%x %x\r", /* memory fill cmd (addr, len, val) */
- {
- "sx %x %x\r", /* setmem.cmdb (addr, value) */
- "sh %x %x\r", /* setmem.cmdw (addr, value) */
- "s %x %x\r", /* setmem.cmdl (addr, value) */
- NULL, /* setmem.cmdll (addr, value) */
- NULL, /* setmem.resp_delim */
- NULL, /* setmem.term */
- NULL, /* setmem.term_cmd */
- },
+ op50n_cmds.flags = MO_CLR_BREAK_USES_ADDR /*| MO_GETMEM_READ_SINGLE*/; /* flags */
+ op50n_cmds.init = op50n_inits; /* Init strings */
+ op50n_cmds.cont = "g\r"; /* continue command */
+ op50n_cmds.step = "t\r"; /* single step */
+ op50n_cmds.stop = "\003.\r"; /* Interrupt char */
+ op50n_cmds.set_break = "b %x\r"; /* set a breakpoint */
+ op50n_cmds.clr_break = "b %x;0\r"; /* clear breakpoint at addr */
+ op50n_cmds.clr_all_break = "bx\r"; /* clear all breakpoints */
+ op50n_cmds.fill = "fx %x s%x %x\r"; /* memory fill cmd (addr, len, val) */
+ op50n_cmds.setmem.cmdb = "sx %x %x\r"; /* setmem.cmdb (addr, value) */
+ op50n_cmds.setmem.cmdw = "sh %x %x\r"; /* setmem.cmdw (addr, value) */
+ op50n_cmds.setmem.cmdl = "s %x %x\r"; /* setmem.cmdl (addr, value) */
+ op50n_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ op50n_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ op50n_cmds.setmem.term = NULL; /* setmem.term */
+ op50n_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
#if 0
{
"sx %x\r", /* getmem.cmdb (addr, len) */
- "sh %x\r", /* getmem.cmdw (addr, len) */
- "s %x\r", /* getmem.cmdl (addr, len) */
- NULL, /* getmem.cmdll (addr, len) */
- " : ", /* getmem.resp_delim */
- " ", /* getmem.term */
- ".\r", /* getmem.term_cmd */
- },
+ "sh %x\r", /* getmem.cmdw (addr, len) */
+ "s %x\r", /* getmem.cmdl (addr, len) */
+ NULL, /* getmem.cmdll (addr, len) */
+ " : ", /* getmem.resp_delim */
+ " ", /* getmem.term */
+ ".\r", /* getmem.term_cmd */
+ } ;
#else
- {
- "dx %x s%x\r", /* getmem.cmdb (addr, len) */
- NULL, /* getmem.cmdw (addr, len) */
- NULL, /* getmem.cmdl (addr, len) */
- NULL, /* getmem.cmdll (addr, len) */
- " : ", /* getmem.resp_delim */
- NULL, /* getmem.term */
- NULL, /* getmem.term_cmd */
- },
+ op50n_cmds.getmem.cmdb = "dx %x s%x\r"; /* getmem.cmdb (addr, len) */
+ op50n_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
+ op50n_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
+ op50n_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ op50n_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */
+ op50n_cmds.getmem.term = NULL; /* getmem.term */
+ op50n_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
#endif
- {
- "x %s %x\r", /* setreg.cmd (name, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL, /* setreg.term_cmd */
- },
- {
- "x %s\r", /* getreg.cmd (name) */
- "=", /* getreg.resp_delim */
- " ", /* getreg.term */
- ".\r", /* getreg.term_cmd */
- },
- NULL, /* dump_registers */
- NULL, /* register_pattern */
- NULL, /* supply_register */
- NULL, /* load routine */
- "r 0\r", /* download command */
- NULL, /* load response */
- "\n#", /* monitor command prompt */
- "\r", /* end-of-command delimitor */
- NULL, /* optional command terminator */
- &op50n_ops, /* target operations */
- SERIAL_1_STOPBITS, /* number of stop bits */
- op50n_regnames, /* register names */
- MONITOR_OPS_MAGIC /* magic */
- };
+ op50n_cmds.setreg.cmd = "x %s %x\r"; /* setreg.cmd (name, value) */
+ op50n_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ op50n_cmds.setreg.term = NULL; /* setreg.term */
+ op50n_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ op50n_cmds.getreg.cmd = "x %s\r"; /* getreg.cmd (name) */
+ op50n_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ op50n_cmds.getreg.term = " "; /* getreg.term */
+ op50n_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
+ op50n_cmds.dump_registers = NULL; /* dump_registers */
+ op50n_cmds.register_pattern = NULL; /* register_pattern */
+ op50n_cmds.supply_register = NULL; /* supply_register */
+ op50n_cmds.load_routine = NULL; /* load routine */
+ op50n_cmds.load = "r 0\r"; /* download command */
+ op50n_cmds.loadresp = NULL; /* load response */
+ op50n_cmds.prompt = "\n#"; /* monitor command prompt */
+ op50n_cmds.line_term = "\r"; /* end-of-command delimitor */
+ op50n_cmds.cmd_end = NULL; /* optional command terminator */
+ op50n_cmds.target = &op50n_ops; /* target operations */
+ op50n_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ op50n_cmds.regnames = op50n_regnames; /* register names */
+ op50n_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+};
static void
op50n_open (args, from_tty)
@@ -134,6 +129,7 @@ op50n_open (args, from_tty)
void
_initialize_op50n ()
{
+ init_op50n_cmds() ;
init_monitor_ops (&op50n_ops);
op50n_ops.to_shortname = "op50n";
diff --git a/contrib/gdb/gdb/os9kread.c b/contrib/gdb/gdb/os9kread.c
index f80cb1b..673d415 100644
--- a/contrib/gdb/gdb/os9kread.c
+++ b/contrib/gdb/gdb/os9kread.c
@@ -1,5 +1,5 @@
/* Read os9/os9k symbol tables and convert to internal format, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 96, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -42,10 +42,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif
#include "obstack.h"
-#include <sys/param.h>
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
#include "gdb_stat.h"
#include <ctype.h>
#include "symtab.h"
@@ -125,6 +121,10 @@ static struct complaint lbrac_mismatch_complaint =
#endif
/* Local function prototypes */
+
+static void
+read_minimal_symbols PARAMS ((struct objfile *, struct section_offsets *));
+
static void
os9k_read_ofile_symtab PARAMS ((struct partial_symtab *));
@@ -228,9 +228,7 @@ record_minimal_symbol (name, address, type, objfile, section_offsets)
ms_type = mst_unknown; break;
}
- prim_record_minimal_symbol
- (obsavestring (name, strlen(name), &objfile->symbol_obstack),
- address, ms_type, objfile);
+ prim_record_minimal_symbol (name, address, ms_type, objfile);
}
/* read and process .stb file and store in minimal symbol table */
@@ -334,10 +332,10 @@ os9k_symfile_read (objfile, section_offsets, mainline)
objfile->static_psymbols.size == 0)
init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
- pending_blocks = 0;
- back_to = make_cleanup (really_free_pendings, 0);
+ free_pending_blocks ();
+ back_to = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
read_minimal_symbols (objfile, section_offsets);
/* Now that the symbol table data of the executable file are all in core,
@@ -402,7 +400,7 @@ os9k_symfile_init (objfile)
objfile->auxf1 = minfile;
/* Allocate struct to keep track of the symfile */
- objfile->sym_stab_info = (PTR)
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL;
@@ -1005,7 +1003,7 @@ os9k_end_psymtab (pst, include_list, num_includes, capping_symbol_cnt,
CORE_ADDR capping_text;
struct partial_symtab **dependency_list;
int number_dependencies;
-/* struct partial_symbol *capping_global, *capping_static;*/
+ /* struct partial_symbol *capping_global, *capping_static; */
{
int i;
struct partial_symtab *p1;
@@ -1162,22 +1160,10 @@ os9k_end_psymtab (pst, include_list, num_includes, capping_symbol_cnt,
&& pst->n_static_syms == 0) {
/* Throw away this psymtab, it's empty. We can't deallocate it, since
it is on the obstack, but we can forget to chain it on the list. */
- struct partial_symtab *prev_pst;
-
- /* First, snip it out of the psymtab chain */
-
- if (pst->objfile->psymtabs == pst)
- pst->objfile->psymtabs = pst->next;
- else
- for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
- if (prev_pst->next == pst)
- prev_pst->next = pst->next;
+ /* Indicate that psymtab was thrown away. */
- /* Next, put it on a free list for recycling */
- pst->next = pst->objfile->free_psymtabs;
- pst->objfile->free_psymtabs = pst;
+ discard_psymtab (pst);
- /* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *)NULL;
}
return pst;
@@ -1223,7 +1209,7 @@ os9k_psymtab_to_symtab_1 (pst)
/* Init stuff necessary for reading in symbols */
stabsread_init ();
buildsym_init ();
- old_chain = make_cleanup (really_free_pendings, 0);
+ old_chain = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
/* Read in this file's symbols */
os9k_read_ofile_symtab (pst);
@@ -1446,9 +1432,9 @@ os9k_process_one_symbol (type, desc, valu, name, section_offsets, objfile)
seeing a source file name. */
if (last_source_file == NULL && type != (unsigned char)N_SO)
{
- /* Ignore any symbols which appear before an N_SO symbol. Currently
- no one puts symbols there, but we should deal gracefully with the
- case. A complain()t might be in order (if !IGNORE_SYMBOL (type)),
+ /* Ignore any symbols which appear before an N_SO symbol.
+ Currently no one puts symbols there, but we should deal
+ gracefully with the case. A complain()t might be in order,
but this should not be an error (). */
return;
}
@@ -1572,6 +1558,7 @@ os9k_process_one_symbol (type, desc, valu, name, section_offsets, objfile)
start_stabs ();
os9k_stabs = 1;
start_symtab (n, dirn, valu);
+ record_debugformat ("OS9");
} else {
push_subfile();
start_subfile (n, dirn!=NULL ? dirn : current_subfile->dirname);
@@ -1617,30 +1604,7 @@ os9k_process_one_symbol (type, desc, valu, name, section_offsets, objfile)
}
previous_stab_code = type;
}
-
-/* Parse the user's idea of an offset for dynamic linking, into our idea
- of how to represent it for fast symbol reading. */
-static struct section_offsets *
-os9k_symfile_offsets (objfile, addr)
- struct objfile *objfile;
- CORE_ADDR addr;
-{
- struct section_offsets *section_offsets;
- int i;
-
- objfile->num_sections = SECT_OFF_MAX;
- section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets)
- + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
-
- for (i = 0; i < SECT_OFF_MAX; i++)
- ANOFFSET (section_offsets, i) = addr;
-
- return section_offsets;
-}
-
static struct sym_fns os9k_sym_fns =
{
bfd_target_os9k_flavour,
@@ -1648,7 +1612,8 @@ static struct sym_fns os9k_sym_fns =
os9k_symfile_init, /* sym_init: read initial info, setup for sym_read() */
os9k_symfile_read, /* sym_read: read a symbol file into symtab */
os9k_symfile_finish, /* sym_finish: finished with file, cleanup */
- os9k_symfile_offsets, /* sym_offsets: parse user's offsets to internal form*/
+ default_symfile_offsets,
+ /* sym_offsets: parse user's offsets to internal form*/
NULL /* next: pointer to next struct sym_fns */
};
diff --git a/contrib/gdb/gdb/osfsolib.c b/contrib/gdb/gdb/osfsolib.c
index 85afa24..31c9bf9 100644
--- a/contrib/gdb/gdb/osfsolib.c
+++ b/contrib/gdb/gdb/osfsolib.c
@@ -1,5 +1,5 @@
/* Handle OSF/1 shared libraries for GDB, the GNU Debugger.
- Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1993, 94, 95, 96, 98, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -193,8 +193,8 @@ next_link_map_member PARAMS ((struct so_list *));
static void
xfer_link_map_member PARAMS ((struct so_list *, struct link_map *));
-static void
-solib_map_sections PARAMS ((struct so_list *));
+static int
+solib_map_sections PARAMS ((char *));
/*
@@ -204,7 +204,7 @@ LOCAL FUNCTION
SYNOPSIS
- static void solib_map_sections (struct so_list *so)
+ static int solib_map_sections (struct so_list *so)
DESCRIPTION
@@ -223,10 +223,11 @@ FIXMES
expansion stuff?).
*/
-static void
-solib_map_sections (so)
- struct so_list *so;
+static int
+solib_map_sections (arg)
+ char *arg;
{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
char *scratch_pathname;
int scratch_chan;
@@ -288,6 +289,8 @@ solib_map_sections (so)
/* Free the file names, close the file now. */
do_cleanups (old_chain);
+
+ return (1);
}
/*
@@ -485,7 +488,9 @@ xfer_link_map_member (so_list_ptr, lm)
}
#endif
- solib_map_sections (so_list_ptr);
+ catch_errors (solib_map_sections, (char *) so_list_ptr,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
}
}
@@ -566,10 +571,28 @@ symbol_add_stub (arg)
char *arg;
{
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+
+ if (so -> textsection)
+ text_addr = so -> textsection -> addr;
+ else if (so -> abfd != NULL)
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ lowest_sect = bfd_get_section_by_name (so -> abfd, ".text");
+ if (lowest_sect == NULL)
+ bfd_map_over_sections (so -> abfd, find_lowest_section,
+ (PTR) &lowest_sect);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so -> abfd, lowest_sect) + LM_OFFSET (so);
+ }
so -> objfile = symbol_file_add (so -> so_name, so -> from_tty,
- so -> textsection -> addr,
- 0, 0, 0);
+ text_addr,
+ 0, 0, 0, 0, 1);
return (1);
}
@@ -812,6 +835,8 @@ clear_solib()
struct so_list *next;
char *bfd_filename;
+ disable_breakpoints_in_shlibs (1);
+
while (so_list_head)
{
if (so_list_head -> sections)
@@ -828,7 +853,7 @@ clear_solib()
else
/* This happens for the executable on SVR4. */
bfd_filename = NULL;
-
+
next = so_list_head -> next;
if (bfd_filename)
free ((PTR)bfd_filename);
diff --git a/contrib/gdb/gdb/parse.c b/contrib/gdb/gdb/parse.c
index 92f9465..af68fbf 100644
--- a/contrib/gdb/gdb/parse.c
+++ b/contrib/gdb/gdb/parse.c
@@ -1,5 +1,5 @@
/* Parse expressions for GDB.
- Copyright (C) 1986, 1989, 1990, 1991, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1986, 89, 90, 91, 94, 1998 Free Software Foundation, Inc.
Modified from expread.y by the Department of Computer Science at the
State University of New York at Buffalo, 1991.
@@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdb_string.h"
+#include <ctype.h>
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
@@ -38,6 +39,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "command.h"
#include "language.h"
#include "parser-defs.h"
+#include "gdbcmd.h"
+#include "symfile.h" /* for overlay functions */
/* Global variables declared in parser-defs.h (and commented there). */
struct expression *expout;
@@ -53,15 +56,18 @@ char *namecopy;
int paren_depth;
int comma_terminates;
+#ifdef MAINTENANCE_CMDS
+static int expressiondebug = 0;
+#endif
+
+extern int hp_som_som_object_present;
+
static void
free_funcalls PARAMS ((void));
static void
prefixify_expression PARAMS ((struct expression *));
-static int
-length_of_subexp PARAMS ((struct expression *, int));
-
static void
prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int));
@@ -104,6 +110,44 @@ unsigned num_std_regs = (sizeof std_regs / sizeof std_regs[0]);
#endif
+/* The generic method for targets to specify how their registers are
+ named. The mapping can be derived from three sources:
+ REGISTER_NAME; std_regs; or a target specific alias hook. */
+
+int
+target_map_name_to_register (str, len)
+ char *str;
+ int len;
+{
+ int i;
+
+ /* First try target specific aliases. We try these first because on some
+ systems standard names can be context dependent (eg. $pc on a
+ multiprocessor can be could be any of several PCs). */
+#ifdef REGISTER_NAME_ALIAS_HOOK
+ i = REGISTER_NAME_ALIAS_HOOK (str, len);
+ if (i >= 0)
+ return i;
+#endif
+
+ /* Search architectural register name space. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (REGISTER_NAME (i) && len == strlen (REGISTER_NAME (i))
+ && STREQN (str, REGISTER_NAME (i), len))
+ {
+ return i;
+ }
+
+ /* Try standard aliases */
+ for (i = 0; i < num_std_regs; i++)
+ if (std_regs[i].name && len == strlen (std_regs[i].name)
+ && STREQN (str, std_regs[i].name, len))
+ {
+ return std_regs[i].regnum;
+ }
+
+ return -1;
+}
/* Begin counting arguments for a function call,
saving the data about any containing call. */
@@ -371,9 +415,16 @@ write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
struct type *text_symbol_type;
struct type *data_symbol_type;
{
+ CORE_ADDR addr;
+
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (lookup_pointer_type (builtin_type_void));
- write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
+
+ addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ if (overlay_debugging)
+ addr = symbol_overlayed_address (addr, SYMBOL_BFD_SECTION (msymbol));
+ write_exp_elt_longcst ((LONGEST) addr);
+
write_exp_elt_opcode (OP_LONG);
write_exp_elt_opcode (UNOP_MEMVAL);
@@ -429,6 +480,9 @@ write_dollar_variable (str)
/* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
and $$digits (equivalent to $<-digits> if you could type that). */
+ struct symbol * sym = NULL;
+ struct minimal_symbol * msym = NULL;
+
int negate = 0;
int i = 1;
/* Double dollar means negate the number and add -1 as well.
@@ -458,20 +512,33 @@ write_dollar_variable (str)
/* Handle tokens that refer to machine registers:
$ followed by a register name. */
- for (i = 0; i < NUM_REGS; i++)
- if (str.length - 1 == strlen (reg_names[i])
- && STREQN (str.ptr + 1, reg_names[i], str.length - 1))
- {
- goto handle_register;
- }
- for (i = 0; i < num_std_regs; i++)
- if (str.length - 1 == strlen (std_regs[i].name)
- && STREQN (str.ptr + 1, std_regs[i].name, str.length - 1))
- {
- i = std_regs[i].regnum;
- goto handle_register;
- }
+ i = target_map_name_to_register( str.ptr + 1, str.length - 1 );
+ if( i >= 0 )
+ goto handle_register;
+
+ /* On HP-UX, certain system routines (millicode) have names beginning
+ with $ or $$, e.g. $$dyncall, which handles inter-space procedure
+ calls on PA-RISC. Check for those, first. */
+ sym = lookup_symbol (copy_name (str), (struct block *) NULL,
+ VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL);
+ if (sym)
+ {
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (block_found); /* set by lookup_symbol */
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return;
+ }
+ msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
+ if (msym)
+ {
+ write_exp_msymbol (msym,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ return;
+ }
+
/* Any other names starting in $ are debugger internal variables. */
write_exp_elt_opcode (OP_INTERNALVAR);
@@ -489,6 +556,257 @@ write_dollar_variable (str)
write_exp_elt_opcode (OP_REGISTER);
return;
}
+
+
+/* Parse a string that is possibly a namespace / nested class
+ specification, i.e., something of the form A::B::C::x. Input
+ (NAME) is the entire string; LEN is the current valid length; the
+ output is a string, TOKEN, which points to the largest recognized
+ prefix which is a series of namespaces or classes. CLASS_PREFIX is
+ another output, which records whether a nested class spec was
+ recognized (= 1) or a fully qualified variable name was found (=
+ 0). ARGPTR is side-effected (if non-NULL) to point to beyond the
+ string recognized and consumed by this routine.
+
+ The return value is a pointer to the symbol for the base class or
+ variable if found, or NULL if not found. Callers must check this
+ first -- if NULL, the outputs may not be correct.
+
+ This function is used c-exp.y. This is used specifically to get
+ around HP aCC (and possibly other compilers), which insists on
+ generating names with embedded colons for namespace or nested class
+ members.
+
+ (Argument LEN is currently unused. 1997-08-27)
+
+ Callers must free memory allocated for the output string TOKEN. */
+
+static const char coloncolon[2] = {':',':'};
+
+struct symbol *
+parse_nested_classes_for_hpacc (name, len, token, class_prefix, argptr)
+ char * name;
+ int len;
+ char ** token;
+ int * class_prefix;
+ char ** argptr;
+{
+ /* Comment below comes from decode_line_1 which has very similar
+ code, which is called for "break" command parsing. */
+
+ /* We have what looks like a class or namespace
+ scope specification (A::B), possibly with many
+ levels of namespaces or classes (A::B::C::D).
+
+ Some versions of the HP ANSI C++ compiler (as also possibly
+ other compilers) generate class/function/member names with
+ embedded double-colons if they are inside namespaces. To
+ handle this, we loop a few times, considering larger and
+ larger prefixes of the string as though they were single
+ symbols. So, if the initially supplied string is
+ A::B::C::D::foo, we have to look up "A", then "A::B",
+ then "A::B::C", then "A::B::C::D", and finally
+ "A::B::C::D::foo" as single, monolithic symbols, because
+ A, B, C or D may be namespaces.
+
+ Note that namespaces can nest only inside other
+ namespaces, and not inside classes. So we need only
+ consider *prefixes* of the string; there is no need to look up
+ "B::C" separately as a symbol in the previous example. */
+
+ register char * p;
+ char * start, * end;
+ char * prefix = NULL;
+ char * tmp;
+ struct symbol * sym_class = NULL;
+ struct symbol * sym_var = NULL;
+ struct type * t;
+ register int i;
+ int colons_found = 0;
+ int prefix_len = 0;
+ int done = 0;
+ char * q;
+
+ /* Check for HP-compiled executable -- in other cases
+ return NULL, and caller must default to standard GDB
+ behaviour. */
+
+ if (!hp_som_som_object_present)
+ return (struct symbol *) NULL;
+
+ p = name;
+
+ /* Skip over whitespace and possible global "::" */
+ while (*p && (*p == ' ' || *p == '\t')) p++;
+ if (p[0] == ':' && p[1] == ':')
+ p += 2;
+ while (*p && (*p == ' ' || *p == '\t')) p++;
+
+ while (1)
+ {
+ /* Get to the end of the next namespace or class spec. */
+ /* If we're looking at some non-token, fail immediately */
+ start = p;
+ if (!(isalpha (*p) || *p == '$' || *p == '_'))
+ return (struct symbol *) NULL;
+ p++;
+ while (*p && (isalnum (*p) || *p == '$' || *p == '_')) p++;
+
+ if (*p == '<')
+ {
+ /* If we have the start of a template specification,
+ scan right ahead to its end */
+ q = find_template_name_end (p);
+ if (q)
+ p = q;
+ }
+
+ end = p;
+
+ /* Skip over "::" and whitespace for next time around */
+ while (*p && (*p == ' ' || *p == '\t')) p++;
+ if (p[0] == ':' && p[1] == ':')
+ p += 2;
+ while (*p && (*p == ' ' || *p == '\t')) p++;
+
+ /* Done with tokens? */
+ if (!*p || !(isalpha (*p) || *p == '$' || *p == '_'))
+ done = 1;
+
+ tmp = (char *) alloca (prefix_len + end - start + 3);
+ if (prefix)
+ {
+ memcpy (tmp, prefix, prefix_len);
+ memcpy (tmp + prefix_len, coloncolon, 2);
+ memcpy (tmp + prefix_len + 2, start, end - start);
+ tmp[prefix_len + 2 + end - start] = '\000';
+ }
+ else
+ {
+ memcpy (tmp, start, end - start);
+ tmp[end - start] = '\000';
+ }
+
+ prefix = tmp;
+ prefix_len = strlen (prefix);
+
+#if 0 /* DEBUGGING */
+ printf ("Searching for nested class spec: Prefix is %s\n", prefix);
+#endif
+
+ /* See if the prefix we have now is something we know about */
+
+ if (!done)
+ {
+ /* More tokens to process, so this must be a class/namespace */
+ sym_class = lookup_symbol (prefix, 0, STRUCT_NAMESPACE,
+ 0, (struct symtab **) NULL);
+ }
+ else
+ {
+ /* No more tokens, so try as a variable first */
+ sym_var = lookup_symbol (prefix, 0, VAR_NAMESPACE,
+ 0, (struct symtab **) NULL);
+ /* If failed, try as class/namespace */
+ if (!sym_var)
+ sym_class = lookup_symbol (prefix, 0, STRUCT_NAMESPACE,
+ 0, (struct symtab **) NULL);
+ }
+
+ if (sym_var ||
+ (sym_class &&
+ (t = check_typedef (SYMBOL_TYPE (sym_class)),
+ (TYPE_CODE (t) == TYPE_CODE_STRUCT
+ || TYPE_CODE (t) == TYPE_CODE_UNION))))
+ {
+ /* We found a valid token */
+ *token = (char *) xmalloc (prefix_len + 1 );
+ memcpy (*token, prefix, prefix_len);
+ (*token)[prefix_len] = '\000';
+ break;
+ }
+
+ /* No variable or class/namespace found, no more tokens */
+ if (done)
+ return (struct symbol *) NULL;
+ }
+
+ /* Out of loop, so we must have found a valid token */
+ if (sym_var)
+ *class_prefix = 0;
+ else
+ *class_prefix = 1;
+
+ if (argptr)
+ *argptr = done ? p : end;
+
+#if 0 /* DEBUGGING */
+ printf ("Searching for nested class spec: Token is %s, class_prefix %d\n", *token, *class_prefix);
+#endif
+
+ return sym_var ? sym_var : sym_class; /* found */
+}
+
+char *
+find_template_name_end (p)
+ char * p;
+{
+ int depth = 1;
+ int just_seen_right = 0;
+ int just_seen_colon = 0;
+ int just_seen_space = 0;
+
+ if (!p || (*p != '<'))
+ return 0;
+
+ while (*++p)
+ {
+ switch (*p)
+ {
+ case '\'': case '\"':
+ case '{': case '}':
+ /* In future, may want to allow these?? */
+ return 0;
+ case '<':
+ depth++; /* start nested template */
+ if (just_seen_colon || just_seen_right || just_seen_space)
+ return 0; /* but not after : or :: or > or space */
+ break;
+ case '>':
+ if (just_seen_colon || just_seen_right)
+ return 0; /* end a (nested?) template */
+ just_seen_right = 1; /* but not after : or :: */
+ if (--depth == 0) /* also disallow >>, insist on > > */
+ return ++p; /* if outermost ended, return */
+ break;
+ case ':':
+ if (just_seen_space || (just_seen_colon > 1))
+ return 0; /* nested class spec coming up */
+ just_seen_colon++; /* we allow :: but not :::: */
+ break;
+ case ' ':
+ break;
+ default:
+ if (!((*p >= 'a' && *p <= 'z') || /* allow token chars */
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9') ||
+ (*p == '_') || (*p == ',') || /* commas for template args */
+ (*p == '&') || (*p == '*') || /* pointer and ref types */
+ (*p == '(') || (*p == ')') || /* function types */
+ (*p == '[') || (*p == ']') )) /* array types */
+ return 0;
+ }
+ if (*p != ' ')
+ just_seen_space = 0;
+ if (*p != ':')
+ just_seen_colon = 0;
+ if (*p != '>')
+ just_seen_right = 0;
+ }
+ return 0;
+}
+
+
/* Return a null-terminated temporary copy of the name
of a string token. */
@@ -525,7 +843,7 @@ prefixify_expression (expr)
/* Return the number of exp_elements in the subexpression of EXPR
whose last exp_element is at index ENDPOS - 1 in EXPR. */
-static int
+int
length_of_subexp (expr, endpos)
register struct expression *expr;
register int endpos;
@@ -848,7 +1166,7 @@ parse_exp_1 (stringptr, block, comma)
if (lexptr == 0 || *lexptr == 0)
error_no_arg ("expression to compute");
- old_chain = make_cleanup (free_funcalls, 0);
+ old_chain = make_cleanup ((make_cleanup_func) free_funcalls, 0);
funcall_chain = 0;
expression_context_block = block ? block : get_selected_block ();
@@ -859,7 +1177,7 @@ parse_exp_1 (stringptr, block, comma)
expout = (struct expression *)
xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
expout->language_defn = current_language;
- make_cleanup (free_current_contents, &expout);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expout);
if (current_language->la_parser ())
current_language->la_error (NULL);
@@ -878,9 +1196,19 @@ parse_exp_1 (stringptr, block, comma)
/* Convert expression from postfix form as generated by yacc
parser, to a prefix form. */
- DUMP_EXPRESSION (expout, gdb_stdout, "before conversion to prefix form");
+#ifdef MAINTENANCE_CMDS
+ if (expressiondebug)
+ dump_prefix_expression (expout, gdb_stdout,
+ "before conversion to prefix form");
+#endif /* MAINTENANCE_CMDS */
+
prefixify_expression (expout);
- DUMP_EXPRESSION (expout, gdb_stdout, "after conversion to prefix form");
+
+#ifdef MAINTENANCE_CMDS
+ if (expressiondebug)
+ dump_postfix_expression (expout, gdb_stdout,
+ "after conversion to prefix form");
+#endif /* MAINTENANCE_CMDS */
*stringptr = lexptr;
return expout;
@@ -1010,4 +1338,14 @@ _initialize_parse ()
init_type (TYPE_CODE_INT, 1, 0,
"<variable (not text or data), no debug info>",
NULL);
+
+#ifdef MAINTENANCE_CMDS
+ add_show_from_set (
+ add_set_cmd ("expressiondebug", class_maintenance, var_zinteger,
+ (char *)&expressiondebug,
+ "Set expression debugging.\n\
+When non-zero, the internal representation of expressions will be printed.",
+ &setlist),
+ &showlist);
+#endif
}
diff --git a/contrib/gdb/gdb/parser-defs.h b/contrib/gdb/gdb/parser-defs.h
index 60c12e6..3226fdd 100644
--- a/contrib/gdb/gdb/parser-defs.h
+++ b/contrib/gdb/gdb/parser-defs.h
@@ -112,6 +112,10 @@ extern void write_exp_msymbol PARAMS ((struct minimal_symbol *,
extern void write_dollar_variable PARAMS ((struct stoken str));
+extern struct symbol * parse_nested_classes_for_hpacc PARAMS ((char *, int, char **, int *, char **));
+
+extern char * find_template_name_end PARAMS ((char *));
+
extern void
start_arglist PARAMS ((void));
@@ -133,6 +137,9 @@ pop_type PARAMS ((void));
extern int
pop_type_int PARAMS ((void));
+extern int
+length_of_subexp PARAMS ((struct expression *, int));
+
extern struct type *follow_types PARAMS ((struct type *));
/* During parsing of a C expression, the pointer to the next character
diff --git a/contrib/gdb/gdb/partial-stab.h b/contrib/gdb/gdb/partial-stab.h
index d006809..d74c1c9 100644
--- a/contrib/gdb/gdb/partial-stab.h
+++ b/contrib/gdb/gdb/partial-stab.h
@@ -1,5 +1,5 @@
/* Shared code to pre-read a stab (dbx-style), when building a psymtab.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -106,7 +106,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
symnum * symbol_size,
CUR_SYMBOL_VALUE > pst->texthigh
? CUR_SYMBOL_VALUE : pst->texthigh,
- dependency_list, dependencies_used);
+ dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
@@ -145,7 +145,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
case N_UNDF:
#ifdef DBXREAD_ONLY
- if (processing_acc_compilation && bufp->n_strx == 1) {
+ if (processing_acc_compilation && CUR_SYMBOL_STRX == 1) {
/* Deal with relative offsets in the string table
used in ELF+STAB under Solaris. If we want to use the
n_strx field, which contains the name of the file,
@@ -154,7 +154,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
past_first_source_file = 1;
file_string_table_offset = next_file_string_table_offset;
next_file_string_table_offset =
- file_string_table_offset + bufp->n_value;
+ file_string_table_offset + CUR_SYMBOL_VALUE;
if (next_file_string_table_offset < file_string_table_offset)
error ("string table offset backs up at %d", symnum);
/* FIXME -- replace error() with complaint. */
@@ -197,16 +197,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static int prev_so_symnum = -10;
static int first_so_symnum;
char *p;
+ int prev_textlow_not_set;
valu = CUR_SYMBOL_VALUE + ANOFFSET (section_offsets, SECT_OFF_TEXT);
+
+ prev_textlow_not_set = textlow_not_set;
+
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* A zero value is probably an indication for the SunPRO 3.0
compiler. end_psymtab explicitly tests for zero, so
don't relocate it. */
+
if (CUR_SYMBOL_VALUE == 0)
- valu = 0;
+ {
+ textlow_not_set = 1;
+ valu = 0;
+ }
+ else
+ textlow_not_set = 0;
+#else
+ textlow_not_set = 0;
#endif
-
past_first_source_file = 1;
if (prev_so_symnum != symnum - 1)
@@ -218,7 +229,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
END_PSYMTAB (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
valu > pst->texthigh ? valu : pst->texthigh,
- dependency_list, dependencies_used);
+ dependency_list, dependencies_used,
+ prev_textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
@@ -278,6 +290,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|| psymtab_language != language_cplus))
psymtab_language = tmp_language;
+ if (pst == NULL)
+ {
+ /* FIXME: we should not get here without a PST to work on.
+ Attempt to recover. */
+ complain (&unclaimed_bincl_complaint, namestring, symnum);
+ continue;
+ }
add_bincl_to_list (pst, namestring, CUR_SYMBOL_VALUE);
/* Mark down an include file in the current psymtab */
@@ -370,7 +389,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef DBXREAD_ONLY
/* See if this is an end of function stab. */
- if (CUR_SYMBOL_TYPE == N_FUN && ! strcmp (namestring, ""))
+ if (CUR_SYMBOL_TYPE == N_FUN && *namestring == '\000')
{
unsigned long valu;
@@ -554,9 +573,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
value for the bottom of the text seg in those cases. */
- if (pst && pst->textlow == 0 && !symfile_relocatable)
- pst->textlow =
- find_stab_function_addr (namestring, pst, objfile);
+ if (pst && textlow_not_set)
+ {
+ pst->textlow =
+ find_stab_function_addr (namestring, pst, objfile);
+ textlow_not_set = 0;
+ }
#endif
#if 0
if (startup_file_end == 0)
@@ -568,16 +590,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
the bounds created by N_SO symbols. If that's the case
use the address of this function as the low bound for
the partial symbol table. */
- if (pst->textlow == 0
+ if (textlow_not_set
|| (CUR_SYMBOL_VALUE < pst->textlow
&& CUR_SYMBOL_VALUE
!= ANOFFSET (section_offsets, SECT_OFF_TEXT)))
- pst->textlow = CUR_SYMBOL_VALUE;
+ {
+ pst->textlow = CUR_SYMBOL_VALUE;
+ textlow_not_set = 0;
+ }
#endif /* DBXREAD_ONLY */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
- &objfile->static_psymbols, CUR_SYMBOL_VALUE,
- 0, psymtab_language, objfile);
+ &objfile->static_psymbols,
+ 0, CUR_SYMBOL_VALUE,
+ psymtab_language, objfile);
continue;
/* Global functions were ignored here, but now they
@@ -594,9 +620,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
value for the bottom of the text seg in those cases. */
- if (pst && pst->textlow == 0 && !symfile_relocatable)
- pst->textlow =
- find_stab_function_addr (namestring, pst, objfile);
+ if (pst && textlow_not_set)
+ {
+ pst->textlow =
+ find_stab_function_addr (namestring, pst, objfile);
+ textlow_not_set = 0;
+ }
#endif
#if 0
if (startup_file_end == 0)
@@ -607,16 +636,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
the bounds created by N_SO symbols. If that's the case
use the address of this function as the low bound for
the partial symbol table. */
- if (pst->textlow == 0
+ if (textlow_not_set
|| (CUR_SYMBOL_VALUE < pst->textlow
&& CUR_SYMBOL_VALUE
!= ANOFFSET (section_offsets, SECT_OFF_TEXT)))
- pst->textlow = CUR_SYMBOL_VALUE;
+ {
+ pst->textlow = CUR_SYMBOL_VALUE;
+ textlow_not_set = 0;
+ }
#endif /* DBXREAD_ONLY */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
- &objfile->global_psymbols, CUR_SYMBOL_VALUE,
- 0, psymtab_language, objfile);
+ &objfile->global_psymbols,
+ 0, CUR_SYMBOL_VALUE,
+ psymtab_language, objfile);
continue;
/* Two things show up here (hopefully); static symbols of
@@ -635,6 +668,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
case '8':
case '9':
case '-':
+ case '#': /* for symbol identification (used in live ranges) */
+ /* added to support cfront stabs strings */
+ case 'Z': /* for definition continuations */
+ case 'P': /* for prototypes */
continue;
case ':':
@@ -725,7 +762,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
END_PSYMTAB (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
(CORE_ADDR) 0,
- dependency_list, dependencies_used);
+ dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
@@ -758,6 +795,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
case N_LBRAC:
case N_NSYMS: /* Ultrix 4.0: symbol count */
case N_DEFD: /* GNU Modula-2 */
+ case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
case N_OBJ: /* useless types from Solaris */
case N_OPT:
diff --git a/contrib/gdb/gdb/ppc-bdm.c b/contrib/gdb/gdb/ppc-bdm.c
new file mode 100644
index 0000000..e6b6adfd
--- /dev/null
+++ b/contrib/gdb/gdb/ppc-bdm.c
@@ -0,0 +1,387 @@
+/* Remote target communications for the Macraigor Systems BDM Wiggler
+ talking to a Motorola PPC 8xx ADS board
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "wait.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include <sys/types.h>
+#include <signal.h>
+#include "serial.h"
+#include "ocd.h"
+
+static void bdm_ppc_open PARAMS ((char *name, int from_tty));
+
+static int bdm_ppc_wait PARAMS ((int pid,
+ struct target_waitstatus *target_status));
+
+static void bdm_ppc_fetch_registers PARAMS ((int regno));
+
+static void bdm_ppc_store_registers PARAMS ((int regno));
+
+extern struct target_ops bdm_ppc_ops; /* Forward decl */
+
+/*#define BDM_NUM_REGS 71*/
+#define BDM_NUM_REGS 24
+
+#define BDM_REGMAP \
+ 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
+ 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
+ 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
+ 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
+\
+ 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
+ 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
+ 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
+ 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
+\
+ 26, /* pc (SRR0 (SPR 26)) */ \
+ 2146, /* ps (MSR) */ \
+ 2144, /* cnd (CR) */ \
+ 8, /* lr (SPR 8) */ \
+ 9, /* cnt (CTR (SPR 9)) */ \
+ 1, /* xer (SPR 1) */ \
+ 0, /* mq (SPR 0) */
+
+
+char nowatchdog[4] = {0xff,0xff,0xff,0x88};
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static void
+bdm_ppc_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ CORE_ADDR watchdogaddr = 0xff000004;
+
+ ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
+
+ /* We want interrupts to drop us into debugging mode. */
+ /* Modify the DER register to accomplish this. */
+ ocd_write_bdm_register (149, 0x20024000);
+
+ /* Disable watchdog timer on the board */
+ ocd_write_bytes (watchdogaddr, nowatchdog, 4);
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid" (though it's not clear what, if anything, that
+ means in the case of this target). */
+
+static int
+bdm_ppc_wait (pid, target_status)
+ int pid;
+ struct target_waitstatus *target_status;
+{
+ int stop_reason;
+
+ target_status->kind = TARGET_WAITKIND_STOPPED;
+
+ stop_reason = ocd_wait ();
+
+ if (stop_reason)
+ {
+ target_status->value.sig = TARGET_SIGNAL_INT;
+ return inferior_pid;
+ }
+
+ target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
+
+#if 0
+ {
+ unsigned long ecr, der;
+
+ ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
+ der = ocd_read_bdm_register (149); /* Read the debug enables register */
+ fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
+ }
+#endif
+
+ return inferior_pid;
+}
+
+static int bdm_regmap[] = {BDM_REGMAP};
+
+/* Read the remote registers into regs.
+ Fetch register REGNO, or all registers if REGNO == -1
+
+ The Wiggler uses the following codes to access the registers:
+
+ 0 -> 1023 SPR 0 -> 1023
+ 0 - SPR 0 - MQ
+ 1 - SPR 1 - XER
+ 8 - SPR 8 - LR
+ 9 - SPR 9 - CTR (known as cnt in GDB)
+ 26 - SPR 26 - SRR0 - pc
+ 1024 -> 2047 DCR 0 -> DCR 1023 (IBM PPC 4xx only)
+ 2048 -> 2079 R0 -> R31
+ 2080 -> 2143 FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
+ 2144 CR (known as cnd in GDB)
+ 2145 FPCSR
+ 2146 MSR (known as ps in GDB)
+ */
+
+static void
+bdm_ppc_fetch_registers (regno)
+ int regno;
+{
+ int i;
+ unsigned char *regs, *beginregs, *endregs, *almostregs;
+ unsigned char midregs[32];
+ unsigned char mqreg[1];
+ int first_regno, last_regno;
+ int first_bdm_regno, last_bdm_regno;
+ int reglen, beginreglen, endreglen;
+
+#if 1
+ for (i = 0; i < (FPLAST_REGNUM - FP0_REGNUM + 1); i++)
+ {
+ midregs[i] = -1;
+ }
+ mqreg[0] = -1;
+#endif
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+
+ first_bdm_regno = 0;
+ last_bdm_regno = BDM_NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+
+ first_bdm_regno = bdm_regmap [regno];
+ last_bdm_regno = bdm_regmap [regno];
+ }
+
+ if (first_bdm_regno == -1)
+ {
+ supply_register (first_regno, NULL);
+ return; /* Unsupported register */
+ }
+
+#if 1
+ /* Can't ask for floating point regs on ppc 8xx, also need to
+ avoid asking for the mq register. */
+ if (first_regno == last_regno) /* only want one reg */
+ {
+/* printf("Asking for register %d\n", first_regno); */
+
+ /* if asking for an invalid register */
+ if ((first_regno == MQ_REGNUM) ||
+ ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
+ {
+/* printf("invalid reg request!\n"); */
+ supply_register (first_regno, NULL);
+ return; /* Unsupported register */
+ }
+ else
+ {
+ regs = ocd_read_bdm_registers (first_bdm_regno,
+ last_bdm_regno, &reglen);
+ }
+ }
+ else /* want all regs */
+ {
+/* printf("Asking for registers %d to %d\n", first_regno, last_regno); */
+ beginregs = ocd_read_bdm_registers (first_bdm_regno,
+ FP0_REGNUM - 1, &beginreglen);
+ endregs = (strcat (midregs,
+ ocd_read_bdm_registers (FPLAST_REGNUM + 1,
+ last_bdm_regno - 1, &endreglen)));
+ almostregs = (strcat (beginregs, endregs));
+ regs = (strcat (almostregs, mqreg));
+ reglen = beginreglen + 32 + endreglen + 1;
+ }
+
+#endif
+#if 0
+ regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
+#endif
+
+ for (i = first_regno; i <= last_regno; i++)
+ {
+ int bdm_regno, regoffset;
+
+ bdm_regno = bdm_regmap [i];
+ if (bdm_regno != -1)
+ {
+ regoffset = bdm_regno - first_bdm_regno;
+
+ if (regoffset >= reglen / 4)
+ continue;
+
+ supply_register (i, regs + 4 * regoffset);
+ }
+ else
+ supply_register (i, NULL); /* Unsupported register */
+ }
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. FIXME: ignores errors. */
+
+static void
+bdm_ppc_store_registers (regno)
+ int regno;
+{
+ int i;
+ int first_regno, last_regno;
+ int first_bdm_regno, last_bdm_regno;
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+
+ first_bdm_regno = 0;
+ last_bdm_regno = BDM_NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+
+ first_bdm_regno = bdm_regmap [regno];
+ last_bdm_regno = bdm_regmap [regno];
+ }
+
+ if (first_bdm_regno == -1)
+ return; /* Unsupported register */
+
+ for (i = first_regno; i <= last_regno; i++)
+ {
+ int bdm_regno;
+
+ bdm_regno = bdm_regmap [i];
+
+ /* only attempt to write if it's a valid ppc 8xx register */
+ /* (need to avoid FP regs and MQ reg) */
+ if ((i != MQ_REGNUM) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
+ {
+/* printf("write valid reg %d\n", bdm_regno); */
+ ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
+ }
+/*
+ else if (i == MQ_REGNUM)
+ printf("don't write invalid reg %d (MQ_REGNUM)\n", bdm_regno);
+ else
+ printf("don't write invalid reg %d\n", bdm_regno);
+*/
+ }
+}
+
+/* Define the target subroutine names */
+
+struct target_ops bdm_ppc_ops ;
+
+static void
+init_bdm_ppc_ops(void)
+{
+ bdm_ppc_ops.to_shortname = "ocd";
+ bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
+ bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
+specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
+a wiggler, specify wiggler and then the port it is connected to\n\
+(e.g. wiggler lpt1)." ; /* to_doc */
+ bdm_ppc_ops.to_open = bdm_ppc_open;
+ bdm_ppc_ops.to_close = ocd_close;
+ bdm_ppc_ops.to_attach = NULL;
+ bdm_ppc_ops.to_post_attach = NULL;
+ bdm_ppc_ops.to_require_attach = NULL;
+ bdm_ppc_ops.to_detach = ocd_detach;
+ bdm_ppc_ops.to_require_detach = NULL;
+ bdm_ppc_ops.to_resume = ocd_resume;
+ bdm_ppc_ops.to_wait = bdm_ppc_wait;
+ bdm_ppc_ops.to_post_wait = NULL;
+ bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
+ bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
+ bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
+ bdm_ppc_ops.to_xfer_memory = ocd_xfer_memory;
+ bdm_ppc_ops.to_files_info = ocd_files_info;
+ bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
+ bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
+ bdm_ppc_ops.to_terminal_init = NULL;
+ bdm_ppc_ops.to_terminal_inferior = NULL;
+ bdm_ppc_ops.to_terminal_ours_for_output = NULL;
+ bdm_ppc_ops.to_terminal_ours = NULL;
+ bdm_ppc_ops.to_terminal_info = NULL;
+ bdm_ppc_ops.to_kill = ocd_kill;
+ bdm_ppc_ops.to_load = ocd_load;
+ bdm_ppc_ops.to_lookup_symbol = NULL;
+ bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
+ bdm_ppc_ops.to_post_startup_inferior = NULL;
+ bdm_ppc_ops.to_acknowledge_created_inferior = NULL;
+ bdm_ppc_ops.to_clone_and_follow_inferior = NULL;
+ bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL;
+ bdm_ppc_ops.to_insert_fork_catchpoint = NULL;
+ bdm_ppc_ops.to_remove_fork_catchpoint = NULL;
+ bdm_ppc_ops.to_insert_vfork_catchpoint = NULL;
+ bdm_ppc_ops.to_remove_vfork_catchpoint = NULL;
+ bdm_ppc_ops.to_has_forked = NULL;
+ bdm_ppc_ops.to_has_vforked = NULL;
+ bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ bdm_ppc_ops.to_post_follow_vfork = NULL;
+ bdm_ppc_ops.to_insert_exec_catchpoint = NULL;
+ bdm_ppc_ops.to_remove_exec_catchpoint = NULL;
+ bdm_ppc_ops.to_has_execd = NULL;
+ bdm_ppc_ops.to_reported_exec_events_per_exec_call = NULL;
+ bdm_ppc_ops.to_has_exited = NULL;
+ bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
+ bdm_ppc_ops.to_can_run = 0;
+ bdm_ppc_ops.to_notice_signals = 0;
+ bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
+ bdm_ppc_ops.to_stop = ocd_stop;
+ bdm_ppc_ops.to_pid_to_exec_file = NULL;
+ bdm_ppc_ops.to_core_file_to_sym_file = NULL;
+ bdm_ppc_ops.to_stratum = process_stratum;
+ bdm_ppc_ops.DONT_USE = NULL;
+ bdm_ppc_ops.to_has_all_memory = 1;
+ bdm_ppc_ops.to_has_memory = 1;
+ bdm_ppc_ops.to_has_stack = 1;
+ bdm_ppc_ops.to_has_registers = 1;
+ bdm_ppc_ops.to_has_execution = 1;
+ bdm_ppc_ops.to_sections = NULL;
+ bdm_ppc_ops.to_sections_end = NULL;
+ bdm_ppc_ops.to_magic = OPS_MAGIC ;
+} /* init_bdm_ppc_ops */
+
+void
+_initialize_bdm_ppc ()
+{
+ init_bdm_ppc_ops() ;
+ add_target (&bdm_ppc_ops);
+}
diff --git a/contrib/gdb/gdb/ppcbug-rom.c b/contrib/gdb/gdb/ppcbug-rom.c
index 6c7432b..9496916 100644
--- a/contrib/gdb/gdb/ppcbug-rom.c
+++ b/contrib/gdb/gdb/ppcbug-rom.c
@@ -132,65 +132,60 @@ static struct target_ops ppcbug_ops1;
static char *ppcbug_inits[] = {"\r", NULL};
-#define PPC_CMDS(LOAD_CMD, OPS) \
-{ \
- MO_CLR_BREAK_USES_ADDR | MO_HANDLE_NL, \
- ppcbug_inits, /* Init strings */ \
- "g\r", /* continue command */ \
- "t\r", /* single step */ \
- NULL, /* interrupt command */ \
- "br %x\r", /* set a breakpoint */ \
- "nobr %x\r", /* clear a breakpoint */ \
- "nobr\r", /* clear all breakpoints */ \
- "bf %x:%x %x;b\r", /* fill (start count val) */ \
- { \
- "ms %x %02x\r", /* setmem.cmdb (addr, value) */ \
- "ms %x %04x\r", /* setmem.cmdw (addr, value) */ \
- "ms %x %08x\r", /* setmem.cmdl (addr, value) */ \
- NULL, /* setmem.cmdll (addr, value) */ \
- NULL, /* setreg.resp_delim */ \
- NULL, /* setreg.term */ \
- NULL, /* setreg.term_cmd */ \
- }, \
- { \
- "md %x:%x;b\r", /* getmem.cmdb (addr, len) */ \
- "md %x:%x;b\r", /* getmem.cmdw (addr, len) */ \
- "md %x:%x;b\r", /* getmem.cmdl (addr, len) */ \
- NULL, /* getmem.cmdll (addr, len) */ \
- " ", /* getmem.resp_delim */ \
- NULL, /* getmem.term */ \
- NULL, /* getmem.term_cmd */ \
- }, \
- { \
- "rs %s %x\r", /* setreg.cmd (name, value) */ \
- NULL, /* setreg.resp_delim */ \
- NULL, /* setreg.term */ \
- NULL /* setreg.term_cmd */ \
- }, \
- { \
- "rs %s\r", /* getreg.cmd (name) */ \
- "=", /* getreg.resp_delim */ \
- NULL, /* getreg.term */ \
- NULL /* getreg.term_cmd */ \
- }, \
- "rd\r", /* dump_registers */ \
- "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)", /* register_pattern */ \
- ppcbug_supply_register, /* supply_register */ \
- NULL, /* load_routine (defaults to SRECs) */ \
- LOAD_CMD, /* download command */ \
- NULL, /* load response */ \
- "PPC1-Bug>", /* monitor command prompt */ \
- "\r", /* end-of-line terminator */ \
- NULL, /* optional command terminator */ \
- &OPS, /* target operations */ \
- SERIAL_1_STOPBITS, /* number of stop bits */ \
- ppcbug_regnames, /* registers names */ \
- MONITOR_OPS_MAGIC /* magic */ \
+static void
+init_ppc_cmds (char * LOAD_CMD,
+ struct monitor_ops * OPS,
+ struct target_ops * targops)
+{
+ OPS->flags = MO_CLR_BREAK_USES_ADDR | MO_HANDLE_NL;
+ OPS->init = ppcbug_inits; /* Init strings */
+ OPS->cont = "g\r"; /* continue command */
+ OPS->step = "t\r"; /* single step */
+ OPS->stop = NULL; /* interrupt command */
+ OPS->set_break = "br %x\r"; /* set a breakpoint */
+ OPS->clr_break = "nobr %x\r"; /* clear a breakpoint */
+ OPS->clr_all_break = "nobr\r"; /* clear all breakpoints */
+ OPS->fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
+ OPS->setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
+ OPS->setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
+ OPS->setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
+ OPS->setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ OPS->setmem.resp_delim = NULL; /* setreg.resp_delim */
+ OPS->setmem.term = NULL; /* setreg.term */
+ OPS->setmem.term_cmd = NULL; /* setreg.term_cmd */
+ OPS->getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
+ OPS->getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
+ OPS->getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
+ OPS->getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ OPS->getmem.resp_delim = " "; /* getmem.resp_delim */
+ OPS->getmem.term = NULL; /* getmem.term */
+ OPS->getmem.term_cmd = NULL; /* getmem.term_cmd */
+ OPS->setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */
+ OPS->setreg.resp_delim = NULL; /* setreg.resp_delim */
+ OPS->setreg.term = NULL; /* setreg.term */
+ OPS->setreg.term_cmd = NULL ; /* setreg.term_cmd */
+ OPS->getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */
+ OPS->getreg.resp_delim = "="; /* getreg.resp_delim */
+ OPS->getreg.term = NULL; /* getreg.term */
+ OPS->getreg.term_cmd = NULL ; /* getreg.term_cmd */
+ OPS->register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ OPS->supply_register = ppcbug_supply_register; /* supply_register */
+ OPS->dump_registers = "rd\r"; /* dump all registers */
+ OPS->load_routine = NULL; /* load_routine (defaults to SRECs) */
+ OPS->load = LOAD_CMD; /* download command */
+ OPS->loadresp = NULL; /* load response */
+ OPS->prompt = "PPC1-Bug>"; /* monitor command prompt */
+ OPS->line_term = "\r"; /* end-of-line terminator */
+ OPS->cmd_end = NULL; /* optional command terminator */
+ OPS->target = targops ; /* target operations */
+ OPS->stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ OPS->regnames = ppcbug_regnames; /* registers names */
+ OPS->magic = MONITOR_OPS_MAGIC; /* magic */
}
-static struct monitor_ops ppcbug_cmds0 = PPC_CMDS("lo 0\r", ppcbug_ops0);
-static struct monitor_ops ppcbug_cmds1 = PPC_CMDS("lo 1\r", ppcbug_ops1);
+static struct monitor_ops ppcbug_cmds0 ;
+static struct monitor_ops ppcbug_cmds1 ;
static void
ppcbug_open0(args, from_tty)
@@ -211,6 +206,8 @@ ppcbug_open1(args, from_tty)
void
_initialize_ppcbug_rom ()
{
+ init_ppc_cmds("lo 0\r", &ppcbug_cmds0, &ppcbug_ops0) ;
+ init_ppc_cmds("lo 1\r", &ppcbug_cmds1, &ppcbug_ops1);
init_monitor_ops (&ppcbug_ops0);
ppcbug_ops0.to_shortname = "ppcbug";
diff --git a/contrib/gdb/gdb/printcmd.c b/contrib/gdb/gdb/printcmd.c
index 29f0572..0f0b8ab 100644
--- a/contrib/gdb/gdb/printcmd.c
+++ b/contrib/gdb/gdb/printcmd.c
@@ -1,5 +1,5 @@
/* Print values for GNU debugger GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1994, 1995
+ Copyright 1986, 87, 88, 89, 90, 91, 93, 94, 95, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -33,6 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "demangle.h"
#include "valprint.h"
#include "annotate.h"
+#include "symfile.h" /* for overlay functions */
+#include "objfiles.h" /* ditto */
extern int asm_demangle; /* Whether to demangle syms in asm printouts */
extern int addressprint; /* Whether to print hex addresses in HLL " */
@@ -56,6 +58,10 @@ static char last_size = 'w';
static CORE_ADDR next_address;
+/* Default section to examine next. */
+
+static asection *next_section;
+
/* Last address examined. */
static CORE_ADDR last_examine_address;
@@ -110,11 +116,13 @@ static struct display *display_chain;
static int display_number;
-/* Pointer to the target-dependent disassembly function. */
+/* Prototypes for exported functions. */
+
+void output_command PARAMS ((char *, int));
-int (*tm_print_insn) PARAMS ((bfd_vma, disassemble_info *));
+void _initialize_printcmd PARAMS ((void));
-/* Prototypes for local functions. */
+/* Prototypes for local functions. */
static void delete_display PARAMS ((int));
@@ -139,14 +147,12 @@ static void free_display PARAMS ((struct display *));
static void display_command PARAMS ((char *, int));
-static void x_command PARAMS ((char *, int));
+void x_command PARAMS ((char *, int));
static void address_info PARAMS ((char *, int));
static void set_command PARAMS ((char *, int));
-static void output_command PARAMS ((char *, int));
-
static void call_command PARAMS ((char *, int));
static void inspect_command PARAMS ((char *, int));
@@ -157,7 +163,7 @@ static void print_command_1 PARAMS ((char *, int, int));
static void validate_format PARAMS ((struct format_data, char *));
-static void do_examine PARAMS ((struct format_data, CORE_ADDR));
+static void do_examine PARAMS ((struct format_data, CORE_ADDR addr, asection *section));
static void print_formatted PARAMS ((value_ptr, int, int));
@@ -165,6 +171,8 @@ static struct format_data decode_format PARAMS ((char **, int, int));
static int print_insn PARAMS ((CORE_ADDR, GDB_FILE *));
+static void sym_info PARAMS ((char *, int));
+
/* Decode a format specification. *STRING_PTR should point to it.
OFORMAT and OSIZE are used as defaults for the format and size
@@ -275,24 +283,32 @@ print_formatted (val, format, size)
int len = TYPE_LENGTH (type);
if (VALUE_LVAL (val) == lval_memory)
- next_address = VALUE_ADDRESS (val) + len;
+ {
+ next_address = VALUE_ADDRESS (val) + len;
+ next_section = VALUE_BFD_SECTION (val);
+ }
switch (format)
{
case 's':
+ /* FIXME: Need to handle wchar_t's here... */
next_address = VALUE_ADDRESS (val)
- + val_print_string (VALUE_ADDRESS (val), 0, gdb_stdout);
+ + val_print_string (VALUE_ADDRESS (val), -1, 1, gdb_stdout);
+ next_section = VALUE_BFD_SECTION (val);
break;
case 'i':
/* The old comment says
"Force output out, print_insn not using _filtered".
I'm not completely sure what that means, I suspect most print_insn
- now do use _filtered, so I guess it's obsolete. */
+ now do use _filtered, so I guess it's obsolete.
+ --Yes, it does filter now, and so this is obsolete. -JB */
+
/* We often wrap here if there are long symbolic names. */
wrap_here (" ");
next_address = VALUE_ADDRESS (val)
+ print_insn (VALUE_ADDRESS (val), gdb_stdout);
+ next_section = VALUE_BFD_SECTION (val);
break;
default:
@@ -301,8 +317,16 @@ print_formatted (val, format, size)
|| TYPE_CODE (type) == TYPE_CODE_STRING
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION)
+ /* If format is 0, use the 'natural' format for
+ * that type of value. If the type is non-scalar,
+ * we have to use language rules to print it as
+ * a series of scalars.
+ */
value_print (val, gdb_stdout, format, Val_pretty_default);
else
+ /* User specified format, so don't look to the
+ * the type to tell us what to do.
+ */
print_scalar_formatted (VALUE_CONTENTS (val), type,
format, size, gdb_stdout);
}
@@ -344,7 +368,21 @@ print_scalar_formatted (valaddr, type, format, size, stream)
desired format. */
/* FIXME: we should be using the size field to give us a
minimum field width to print. */
- val_print_type_code_int (type, valaddr, stream);
+
+ if( format == 'o' )
+ print_octal_chars (stream, valaddr, len);
+ else if( format == 'd' )
+ print_decimal_chars (stream, valaddr, len );
+ else if( format == 't' )
+ print_binary_chars (stream, valaddr, len);
+ else
+
+ /* replace with call to print_hex_chars? Looks
+ like val_print_type_code_int is redoing
+ work. - edie */
+
+ val_print_type_code_int (type, valaddr, stream);
+
return;
}
@@ -423,6 +461,7 @@ print_scalar_formatted (valaddr, type, format, size, stream)
/* Binary; 't' stands for "two". */
{
char bits[8*(sizeof val_long) + 1];
+ char buf[8*(sizeof val_long) + 32];
char *cp = bits;
int width;
@@ -460,9 +499,10 @@ print_scalar_formatted (valaddr, type, format, size, stream)
if (*cp == '\0')
cp--;
}
- fprintf_filtered (stream, local_binary_format_prefix());
- fprintf_filtered (stream, cp);
- fprintf_filtered (stream, local_binary_format_suffix());
+ strcpy (buf, local_binary_format_prefix());
+ strcat (buf, cp);
+ strcat (buf, local_binary_format_suffix());
+ fprintf_filtered (stream, buf);
}
break;
@@ -506,6 +546,28 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
struct symtab *symtab = 0;
CORE_ADDR name_location = 0;
char *name = "";
+ asection *section = 0;
+ int unmapped = 0;
+
+ /* Determine if the address is in an overlay, and whether it is mapped. */
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (addr);
+ if (pc_in_unmapped_range (addr, section))
+ {
+ unmapped = 1;
+ addr = overlay_mapped_address (addr, section);
+ }
+ }
+
+ /* On some targets, add in extra "flag" bits to PC for
+ disassembly. This should ensure that "rounding errors" in
+ symbol addresses that are masked for disassembly favour the
+ the correct symbol. */
+
+#ifdef GDB_TARGET_UNMASK_DISAS_PC
+ addr = GDB_TARGET_UNMASK_DISAS_PC (addr);
+#endif
/* First try to find the address in the symbol table, then
in the minsyms. Take the closest one. */
@@ -516,19 +578,18 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
save some memory, but for many debug format--ELF/DWARF or
anything/stabs--it would be inconvenient to eliminate those minimal
symbols anyway). */
- symbol = find_pc_function (addr);
- if (symbol)
- name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
+ msymbol = lookup_minimal_symbol_by_pc_section (addr, section);
+ symbol = find_pc_sect_function (addr, section);
if (symbol)
{
+ name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
if (do_demangle)
name = SYMBOL_SOURCE_NAME (symbol);
else
name = SYMBOL_LINKAGE_NAME (symbol);
}
- msymbol = lookup_minimal_symbol_by_pc (addr);
if (msymbol != NULL)
{
if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
@@ -547,6 +608,14 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
if (symbol == NULL && msymbol == NULL)
return;
+ /* On some targets, mask out extra "flag" bits from PC for handsome
+ disassembly. */
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ name_location = GDB_TARGET_MASK_DISAS_PC (name_location);
+ addr = GDB_TARGET_MASK_DISAS_PC (addr);
+#endif
+
/* If the nearest symbol is too far away, don't print anything symbolic. */
/* For when CORE_ADDR is larger than unsigned int, we do math in
@@ -559,7 +628,10 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
return;
fputs_filtered (leadin, stream);
- fputs_filtered ("<", stream);
+ if (unmapped)
+ fputs_filtered ("<*", stream);
+ else
+ fputs_filtered ("<", stream);
fputs_filtered (name, stream);
if (addr != name_location)
fprintf_filtered (stream, "+%u", (unsigned int)(addr - name_location));
@@ -570,7 +642,8 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
{
struct symtab_and_line sal;
- sal = find_pc_line (addr, 0);
+ sal = find_pc_sect_line (addr, section, 0);
+
if (sal.symtab)
fprintf_filtered (stream, " at %s:%d", sal.symtab->filename, sal.line);
else if (symtab && symbol && symbol->line)
@@ -578,9 +651,13 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
else if (symtab)
fprintf_filtered (stream, " in %s", symtab->filename);
}
- fputs_filtered (">", stream);
+ if (unmapped)
+ fputs_filtered ("*>", stream);
+ else
+ fputs_filtered (">", stream);
}
+
/* Print address ADDR on STREAM. USE_LOCAL means the same thing as for
print_longest. */
void
@@ -591,7 +668,7 @@ print_address_numeric (addr, use_local, stream)
{
/* This assumes a CORE_ADDR can fit in a LONGEST. Probably a safe
assumption. */
- print_longest (stream, 'x', use_local, (unsigned LONGEST) addr);
+ print_longest (stream, 'x', use_local, (ULONGEST) addr);
}
/* Print address ADDR symbolically on STREAM.
@@ -637,6 +714,8 @@ print_address_demangle (addr, stream, do_demangle)
/* These are the types that $__ will get after an examine command of one
of these sizes. */
+static struct type *examine_i_type;
+
static struct type *examine_b_type;
static struct type *examine_h_type;
static struct type *examine_w_type;
@@ -646,9 +725,10 @@ static struct type *examine_g_type;
Fetch it from memory and print on gdb_stdout. */
static void
-do_examine (fmt, addr)
+do_examine (fmt, addr, sect)
struct format_data fmt;
CORE_ADDR addr;
+ asection *sect;
{
register char format = 0;
register char size;
@@ -661,13 +741,16 @@ do_examine (fmt, addr)
size = fmt.size;
count = fmt.count;
next_address = addr;
+ next_section = sect;
/* String or instruction format implies fetch single bytes
regardless of the specified size. */
if (format == 's' || format == 'i')
size = 'b';
- if (size == 'b')
+ if (format == 'i')
+ val_type = examine_i_type;
+ else if (size == 'b')
val_type = examine_b_type;
else if (size == 'h')
val_type = examine_h_type;
@@ -700,7 +783,24 @@ do_examine (fmt, addr)
/* Note that print_formatted sets next_address for the next
object. */
last_examine_address = next_address;
- last_examine_value = value_at (val_type, next_address);
+
+ if (last_examine_value)
+ value_free (last_examine_value);
+
+ /* The value to be displayed is not fetched greedily.
+ Instead, to avoid the posibility of a fetched value not
+ being used, its retreval is delayed until the print code
+ uses it. When examining an instruction stream, the
+ disassembler will perform its own memory fetch using just
+ the address stored in LAST_EXAMINE_VALUE. FIXME: Should
+ the disassembler be modified so that LAST_EXAMINE_VALUE
+ is left with the byte sequence from the last complete
+ instruction fetched from memory? */
+ last_examine_value = value_at_lazy (val_type, next_address, sect);
+
+ if (last_examine_value)
+ release_value (last_examine_value);
+
print_formatted (last_examine_value, format, size);
}
printf_filtered ("\n");
@@ -763,7 +863,8 @@ print_command_1 (exp, inspect, voidprint)
extern int objectprint;
struct type *type;
expr = parse_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &expr);
cleanup = 1;
val = evaluate_expression (expr);
@@ -856,7 +957,7 @@ call_command (exp, from_tty)
}
/* ARGSUSED */
-static void
+void
output_command (exp, from_tty)
char *exp;
int from_tty;
@@ -876,7 +977,7 @@ output_command (exp, from_tty)
}
expr = parse_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
val = evaluate_expression (expr);
@@ -897,13 +998,60 @@ set_command (exp, from_tty)
{
struct expression *expr = parse_expression (exp);
register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
+ = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
evaluate_expression (expr);
do_cleanups (old_chain);
}
/* ARGSUSED */
static void
+sym_info (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct obj_section *osect;
+ asection *sect;
+ CORE_ADDR addr, sect_addr;
+ int matches = 0;
+ unsigned int offset;
+
+ if (!arg)
+ error_no_arg ("address");
+
+ addr = parse_and_eval_address (arg);
+ ALL_OBJSECTIONS (objfile, osect)
+ {
+ sect = osect->the_bfd_section;
+ sect_addr = overlay_mapped_address (addr, sect);
+
+ if (osect->addr <= sect_addr && sect_addr < osect->endaddr &&
+ (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, sect)))
+ {
+ matches = 1;
+ offset = sect_addr - SYMBOL_VALUE_ADDRESS (msymbol);
+ if (offset)
+ printf_filtered ("%s + %u in ",
+ SYMBOL_SOURCE_NAME (msymbol), offset);
+ else
+ printf_filtered ("%s in ",
+ SYMBOL_SOURCE_NAME (msymbol));
+ if (pc_in_unmapped_range (addr, sect))
+ printf_filtered ("load address range of ");
+ if (section_is_overlay (sect))
+ printf_filtered ("%s overlay ",
+ section_is_mapped (sect) ? "mapped" : "unmapped");
+ printf_filtered ("section %s", sect->name);
+ printf_filtered ("\n");
+ }
+ }
+ if (matches == 0)
+ printf_filtered ("No symbol matches %s.\n", arg);
+}
+
+/* ARGSUSED */
+static void
address_info (exp, from_tty)
char *exp;
int from_tty;
@@ -912,6 +1060,8 @@ address_info (exp, from_tty)
register struct minimal_symbol *msymbol;
register long val;
register long basereg;
+ asection *section;
+ CORE_ADDR load_addr;
int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero
if exp is a field of `this'. */
@@ -935,13 +1085,23 @@ address_info (exp, from_tty)
if (msymbol != NULL)
{
+ load_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
printf_filtered ("Symbol \"");
fprintf_symbol_filtered (gdb_stdout, exp,
current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is at ");
- print_address_numeric (SYMBOL_VALUE_ADDRESS (msymbol), 1,
- gdb_stdout);
- printf_filtered (" in a file compiled without debugging.\n");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in a file compiled without debugging");
+ section = SYMBOL_BFD_SECTION (msymbol);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ printf_filtered (".\n");
}
else
error ("No symbol \"%s\" in current context.", exp);
@@ -952,8 +1112,9 @@ address_info (exp, from_tty)
fprintf_symbol_filtered (gdb_stdout, SYMBOL_NAME (sym),
current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is ");
- val = SYMBOL_VALUE (sym);
+ val = SYMBOL_VALUE (sym);
basereg = SYMBOL_BASEREG (sym);
+ section = SYMBOL_BFD_SECTION (sym);
switch (SYMBOL_CLASS (sym))
{
@@ -964,24 +1125,54 @@ address_info (exp, from_tty)
case LOC_LABEL:
printf_filtered ("a label at address ");
- print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
break;
case LOC_REGISTER:
- printf_filtered ("a variable in register %s", reg_names[val]);
+ printf_filtered ("a variable in register %s", REGISTER_NAME (val));
break;
case LOC_STATIC:
printf_filtered ("static storage at address ");
- print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_INDIRECT:
+ printf_filtered ("external global (indirect addressing), at address *(");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ printf_filtered (")");
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
break;
case LOC_REGPARM:
- printf_filtered ("an argument in register %s", reg_names[val]);
+ printf_filtered ("an argument in register %s", REGISTER_NAME (val));
break;
case LOC_REGPARM_ADDR:
- printf_filtered ("address of an argument in register %s", reg_names[val]);
+ printf_filtered ("address of an argument in register %s", REGISTER_NAME (val));
break;
case LOC_ARG:
@@ -1002,12 +1193,12 @@ address_info (exp, from_tty)
case LOC_BASEREG:
printf_filtered ("a variable at offset %ld from register %s",
- val, reg_names[basereg]);
+ val, REGISTER_NAME (basereg));
break;
case LOC_BASEREG_ARG:
printf_filtered ("an argument at offset %ld from register %s",
- val, reg_names[basereg]);
+ val, REGISTER_NAME (basereg));
break;
case LOC_TYPEDEF:
@@ -1016,8 +1207,21 @@ address_info (exp, from_tty)
case LOC_BLOCK:
printf_filtered ("a function at address ");
- print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
- gdb_stdout);
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ print_address_numeric
+ (load_addr= GDB_TARGET_MASK_DISAS_PC (BLOCK_START (SYMBOL_BLOCK_VALUE (sym))),
+ 1, gdb_stdout);
+#else
+ print_address_numeric (load_addr=BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
+ 1, gdb_stdout);
+#endif
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
break;
case LOC_UNRESOLVED:
@@ -1029,12 +1233,27 @@ address_info (exp, from_tty)
printf_filtered ("unresolved");
else
{
+ section = SYMBOL_BFD_SECTION (msym);
printf_filtered ("static storage at address ");
- print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1, gdb_stdout);
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (msym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
}
}
break;
+ case LOC_THREAD_LOCAL_STATIC:
+ printf_filtered (
+ "a thread-local variable at offset %ld from the thread base register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
case LOC_OPTIMIZED_OUT:
printf_filtered ("optimized out");
break;
@@ -1046,7 +1265,7 @@ address_info (exp, from_tty)
printf_filtered (".\n");
}
-static void
+void
x_command (exp, from_tty)
char *exp;
int from_tty;
@@ -1076,7 +1295,8 @@ x_command (exp, from_tty)
But don't clobber a user-defined command's definition. */
if (from_tty)
*exp = 0;
- old_chain = make_cleanup (free_current_contents, &expr);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &expr);
val = evaluate_expression (expr);
if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF)
val = value_ind (val);
@@ -1088,10 +1308,12 @@ x_command (exp, from_tty)
next_address = VALUE_ADDRESS (val);
else
next_address = value_as_pointer (val);
+ if (VALUE_BFD_SECTION (val))
+ next_section = VALUE_BFD_SECTION (val);
do_cleanups (old_chain);
}
- do_examine (fmt, next_address);
+ do_examine (fmt, next_address, next_section);
/* If the examine succeeds, we remember its size and format for next time. */
last_size = fmt.size;
@@ -1108,7 +1330,13 @@ x_command (exp, from_tty)
(LONGEST) last_examine_address));
/* Make contents of last address examined available to the user as $__.*/
- set_internalvar (lookup_internalvar ("__"), last_examine_value);
+ /* If the last value has not been fetched from memory then don't
+ fetch it now - instead mark it by voiding the $__ variable. */
+ if (VALUE_LAZY (last_examine_value))
+ set_internalvar (lookup_internalvar ("__"),
+ allocate_value (builtin_type_void));
+ else
+ set_internalvar (lookup_internalvar ("__"), last_examine_value);
}
}
@@ -1124,46 +1352,56 @@ display_command (exp, from_tty)
struct format_data fmt;
register struct expression *expr;
register struct display *new;
+ int display_it = 1;
- if (exp == 0)
- {
- do_displays ();
- return;
- }
+#if defined(TUI)
+ if (tui_version && *exp == '$')
+ display_it = ((TuiStatus)tuiDo(
+ (TuiOpaqueFuncPtr)tui_vSetLayoutTo, exp) == TUI_FAILURE);
+#endif
- if (*exp == '/')
- {
- exp++;
- fmt = decode_format (&exp, 0, 0);
- if (fmt.size && fmt.format == 0)
- fmt.format = 'x';
- if (fmt.format == 'i' || fmt.format == 's')
- fmt.size = 'b';
- }
- else
+ if (display_it)
{
- fmt.format = 0;
- fmt.size = 0;
- fmt.count = 0;
- }
+ if (exp == 0)
+ {
+ do_displays ();
+ return;
+ }
- innermost_block = 0;
- expr = parse_expression (exp);
+ if (*exp == '/')
+ {
+ exp++;
+ fmt = decode_format (&exp, 0, 0);
+ if (fmt.size && fmt.format == 0)
+ fmt.format = 'x';
+ if (fmt.format == 'i' || fmt.format == 's')
+ fmt.size = 'b';
+ }
+ else
+ {
+ fmt.format = 0;
+ fmt.size = 0;
+ fmt.count = 0;
+ }
- new = (struct display *) xmalloc (sizeof (struct display));
+ innermost_block = 0;
+ expr = parse_expression (exp);
- new->exp = expr;
- new->block = innermost_block;
- new->next = display_chain;
- new->number = ++display_number;
- new->format = fmt;
- new->status = enabled;
- display_chain = new;
+ new = (struct display *) xmalloc (sizeof (struct display));
- if (from_tty && target_has_execution)
- do_one_display (new);
+ new->exp = expr;
+ new->block = innermost_block;
+ new->next = display_chain;
+ new->number = ++display_number;
+ new->format = fmt;
+ new->status = enabled;
+ display_chain = new;
- dont_repeat ();
+ if (from_tty && target_has_execution)
+ do_one_display (new);
+
+ dont_repeat ();
+ }
}
static void
@@ -1289,6 +1527,7 @@ do_one_display (d)
if (d->format.size)
{
CORE_ADDR addr;
+ value_ptr val;
annotate_display_format ();
@@ -1310,13 +1549,14 @@ do_one_display (d)
else
printf_filtered (" ");
- addr = value_as_pointer (evaluate_expression (d->exp));
+ val = evaluate_expression (d->exp);
+ addr = value_as_pointer (val);
if (d->format.format == 'i')
addr = ADDR_BITS_REMOVE (addr);
annotate_display_value ();
- do_examine (d->format, addr);
+ do_examine (d->format, addr, VALUE_BFD_SECTION (val));
}
else
{
@@ -1656,8 +1896,15 @@ print_frame_args (func, fi, num, stream)
annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val));
if (val)
- val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
- stream, 0, 0, 2, Val_no_prettyprint);
+ {
+#ifdef GDB_TARGET_IS_D10V
+ if (SYMBOL_CLASS(sym) == LOC_REGPARM && TYPE_CODE(VALUE_TYPE(val)) == TYPE_CODE_PTR)
+ TYPE_LENGTH(VALUE_TYPE(val)) = 2;
+#endif
+ val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
+ VALUE_ADDRESS (val),
+ stream, 0, 0, 2, Val_no_prettyprint);
+ }
else
fputs_filtered ("???", stream);
@@ -1736,9 +1983,9 @@ printf_command (arg, from_tty)
char *arg;
int from_tty;
{
- register char *f;
+ register char *f = NULL;
register char *s = arg;
- char *string;
+ char *string = NULL;
value_ptr *val_args;
char *substrings;
char *current_substring;
@@ -1747,7 +1994,8 @@ printf_command (arg, from_tty)
struct cleanup *old_cleanups;
val_args = (value_ptr *) xmalloc (allocated_args * sizeof (value_ptr));
- old_cleanups = make_cleanup (free_current_contents, &val_args);
+ old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents,
+ &val_args);
if (s == 0)
error_no_arg ("format-control string and values to print");
@@ -1951,14 +2199,15 @@ printf_command (arg, from_tty)
{
char c;
QUIT;
- read_memory (tem + j, &c, 1);
+ read_memory_section (tem + j, &c, 1,
+ VALUE_BFD_SECTION (val_args[i]));
if (c == 0)
break;
}
/* Copy the string contents into a string inside GDB. */
str = (char *) alloca (j + 1);
- read_memory (tem, str, j);
+ read_memory_section (tem, str, j, VALUE_BFD_SECTION (val_args[i]));
str[j] = 0;
printf_filtered (current_substring, str);
@@ -1987,8 +2236,8 @@ printf_command (arg, from_tty)
printf_filtered (current_substring, val);
break;
}
- default:
- error ("internal error in printf_command");
+ default: /* purecov: deadcode */
+ error ("internal error in printf_command"); /* purecov: deadcode */
}
/* Skip to the next substring. */
current_substring += strlen (current_substring) + 1;
@@ -2014,8 +2263,11 @@ disassemble_command (arg, from_tty)
{
CORE_ADDR low, high;
char *name;
- CORE_ADDR pc;
+ CORE_ADDR pc, pc_masked;
char *space_index;
+#if 0
+ asection *section;
+#endif
name = NULL;
if (!arg)
@@ -2026,6 +2278,13 @@ disassemble_command (arg, from_tty)
pc = get_frame_pc (selected_frame);
if (find_pc_partial_function (pc, &name, &low, &high) == 0)
error ("No function contains program counter for selected frame.\n");
+#if defined(TUI)
+ else if (tui_version)
+ low = (CORE_ADDR)tuiDo((TuiOpaqueFuncPtr)tui_vGetLowDisassemblyAddress,
+ (Opaque)low,
+ (Opaque)pc);
+#endif
+ low += FUNCTION_START_OFFSET;
}
else if (!(space_index = (char *) strchr (arg, ' ')))
{
@@ -2033,6 +2292,27 @@ disassemble_command (arg, from_tty)
pc = parse_and_eval_address (arg);
if (find_pc_partial_function (pc, &name, &low, &high) == 0)
error ("No function contains specified address.\n");
+#if defined(TUI)
+ else if (tui_version)
+ low = (CORE_ADDR)tuiDo((TuiOpaqueFuncPtr)tui_vGetLowDisassemblyAddress,
+ (Opaque)low,
+ (Opaque)pc);
+#endif
+#if 0
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (pc);
+ if (pc_in_unmapped_range (pc, section))
+ {
+ /* find_pc_partial_function will have returned low and high
+ relative to the symbolic (mapped) address range. Need to
+ translate them back to the unmapped range where PC is. */
+ low = overlay_unmapped_address (low, section);
+ high = overlay_unmapped_address (high, section);
+ }
+ }
+#endif
+ low += FUNCTION_START_OFFSET;
}
else
{
@@ -2042,33 +2322,60 @@ disassemble_command (arg, from_tty)
high = parse_and_eval_address (space_index + 1);
}
- printf_filtered ("Dump of assembler code ");
- if (name != NULL)
+#if defined(TUI)
+ if (!tui_version ||
+ m_winPtrIsNull(disassemWin) || !disassemWin->generic.isVisible)
+#endif
{
- printf_filtered ("for function %s:\n", name);
+ printf_filtered ("Dump of assembler code ");
+ if (name != NULL)
+ {
+ printf_filtered ("for function %s:\n", name);
+ }
+ else
+ {
+ printf_filtered ("from ");
+ print_address_numeric (low, 1, gdb_stdout);
+ printf_filtered (" to ");
+ print_address_numeric (high, 1, gdb_stdout);
+ printf_filtered (":\n");
+ }
+
+ /* Dump the specified range. */
+ pc = low;
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ pc_masked = GDB_TARGET_MASK_DISAS_PC (pc);
+#else
+ pc_masked = pc;
+#endif
+
+ while (pc_masked < high)
+ {
+ QUIT;
+ print_address (pc_masked, gdb_stdout);
+ printf_filtered (":\t");
+ /* We often wrap here if there are long symbolic names. */
+ wrap_here (" ");
+ pc += print_insn (pc, gdb_stdout);
+ printf_filtered ("\n");
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ pc_masked = GDB_TARGET_MASK_DISAS_PC (pc);
+#else
+ pc_masked = pc;
+#endif
+ }
+ printf_filtered ("End of assembler dump.\n");
+ gdb_flush (gdb_stdout);
}
+#if defined(TUI)
else
{
- printf_filtered ("from ");
- print_address_numeric (low, 1, gdb_stdout);
- printf_filtered (" to ");
- print_address_numeric (high, 1, gdb_stdout);
- printf_filtered (":\n");
+ tuiDo((TuiOpaqueFuncPtr)tui_vAddWinToLayout, DISASSEM_WIN);
+ tuiDo((TuiOpaqueFuncPtr)tui_vUpdateSourceWindowsWithAddr, low);
}
-
- /* Dump the specified range. */
- for (pc = low; pc < high; )
- {
- QUIT;
- print_address (pc, gdb_stdout);
- printf_filtered (":\t");
- /* We often wrap here if there are long symbolic names. */
- wrap_here (" ");
- pc += print_insn (pc, gdb_stdout);
- printf_filtered ("\n");
- }
- printf_filtered ("End of assembler dump.\n");
- gdb_flush (gdb_stdout);
+#endif
}
/* Print the instruction at address MEMADDR in debugged memory,
@@ -2079,18 +2386,16 @@ print_insn (memaddr, stream)
CORE_ADDR memaddr;
GDB_FILE *stream;
{
- disassemble_info info;
-
- INIT_DISASSEMBLE_INFO (info, stream, (fprintf_ftype)fprintf_filtered);
- info.read_memory_func = dis_asm_read_memory;
- info.memory_error_func = dis_asm_memory_error;
- info.print_address_func = dis_asm_print_address;
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_BIG;
+ else
+ TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_LITTLE;
- /* If there's no disassembler, something is very wrong. */
- if (tm_print_insn == NULL)
- abort ();
+ if (TARGET_ARCHITECTURE != NULL)
+ TARGET_PRINT_INSN_INFO->mach = TARGET_ARCHITECTURE->mach;
+ /* else: should set .mach=0 but some disassemblers don't grok this */
- return (*tm_print_insn) (memaddr, &info);
+ return TARGET_PRINT_INSN (memaddr, TARGET_PRINT_INSN_INFO);
}
@@ -2100,7 +2405,11 @@ _initialize_printcmd ()
current_display_number = -1;
add_info ("address", address_info,
- "Describe where variable VAR is stored.");
+ "Describe where symbol SYM is stored.");
+
+ add_info ("symbol", sym_info,
+ "Describe what symbol is at location ADDR.\n\
+Only for symbols with fixed locations (global or static scope).");
add_com ("x", class_vars, x_command,
concat ("Examine memory: x/FMT ADDRESS.\n\
@@ -2120,6 +2429,8 @@ with this command or \"print\".", NULL));
Default is the function surrounding the pc of the selected frame.\n\
With a single argument, the function surrounding that address is dumped.\n\
Two arguments are taken as a range of memory to dump.");
+ if (xdb_commands)
+ add_com_alias ("va", "disassemble", class_xdb, 0);
#if 0
add_com ("whereis", class_vars, whereis_command,
@@ -2183,6 +2494,16 @@ variable in the program being debugged. EXP is any valid expression.\n",
\nWith a subcommand, this command modifies parts of the gdb environment.\n\
You can see these environment settings with the \"show\" command.", NULL),
&setlist, "set ", 1, &cmdlist);
+ if (dbx_commands)
+ add_com("assign", class_vars, set_command, concat ("Evaluate expression \
+EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example). VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged. EXP is any valid expression.\n",
+"Use \"set variable\" for variables with names identical to set subcommands.\n\
+\nWith a subcommand, this command modifies parts of the gdb environment.\n\
+You can see these environment settings with the \"show\" command.", NULL));
/* "call" is the same as "set", but handy for dbx users to call fns. */
add_com ("call", class_vars, call_command,
@@ -2241,8 +2562,14 @@ environment, the value is printed in its own window.");
&setprintlist),
&showprintlist);
+ /* For examine/instruction a single byte quantity is specified as
+ the data. This avoids problems with value_at_lazy() requiring a
+ valid data type (and rejecting VOID). */
+ examine_i_type = init_type (TYPE_CODE_INT, 1, 0, "examine_i_type", NULL);
+
examine_b_type = init_type (TYPE_CODE_INT, 1, 0, "examine_b_type", NULL);
examine_h_type = init_type (TYPE_CODE_INT, 2, 0, "examine_h_type", NULL);
examine_w_type = init_type (TYPE_CODE_INT, 4, 0, "examine_w_type", NULL);
examine_g_type = init_type (TYPE_CODE_INT, 8, 0, "examine_g_type", NULL);
+
}
diff --git a/contrib/gdb/gdb/procfs.c b/contrib/gdb/gdb/procfs.c
index edc062b..ff20240 100644
--- a/contrib/gdb/gdb/procfs.c
+++ b/contrib/gdb/gdb/procfs.c
@@ -1,6 +1,7 @@
/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
- Written by Fred Fish at Cygnus Support.
+ Copyright 1991, 1992-98, 1999 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support. Changes for sysv4.2mp procfs
+ compatibility by Geoffrey Noer at Cygnus Solutions.
This file is part of GDB.
@@ -24,8 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
For information on the details of using /proc consult section proc(4)
in the UNIX System V Release 4 System Administrator's Reference Manual.
-The general register and floating point register sets are manipulated by
-separate ioctl's. This file makes the assumption that if FP0_REGNUM is
+The general register and floating point register sets are manipulated
+separately. This file makes the assumption that if FP0_REGNUM is
defined, then support for the floating point register set is desired,
regardless of whether or not the actual target has floating point hardware.
@@ -51,15 +52,109 @@ regardless of whether or not the actual target has floating point hardware.
#include "target.h"
#include "command.h"
#include "gdbcore.h"
-#include "thread.h"
+#include "gdbthread.h"
+
+#if !defined(SYS_lwp_create) && defined(SYS_lwpcreate)
+# define SYS_lwp_create SYS_lwpcreate
+#endif
+
+#if !defined(SYS_lwp_exit) && defined(SYS_lwpexit)
+# define SYS_lwp_exit SYS_lwpexit
+#endif
+
+#if !defined(SYS_lwp_wait) && defined(SYS_lwpwait)
+# define SYS_lwp_wait SYS_lwpwait
+#endif
+
+#if !defined(SYS_lwp_self) && defined(SYS_lwpself)
+# define SYS_lwp_self SYS_lwpself
+#endif
+
+#if !defined(SYS_lwp_info) && defined(SYS_lwpinfo)
+# define SYS_lwp_info SYS_lwpinfo
+#endif
+
+#if !defined(SYS_lwp_private) && defined(SYS_lwpprivate)
+# define SYS_lwp_private SYS_lwpprivate
+#endif
+
+#if !defined(SYS_lwp_kill) && defined(SYS_lwpkill)
+# define SYS_lwp_kill SYS_lwpkill
+#endif
+
+#if !defined(SYS_lwp_suspend) && defined(SYS_lwpsuspend)
+# define SYS_lwp_suspend SYS_lwpsuspend
+#endif
+
+#if !defined(SYS_lwp_continue) && defined(SYS_lwpcontinue)
+# define SYS_lwp_continue SYS_lwpcontinue
+#endif
+
+/* the name of the proc status struct depends on the implementation */
+/* Wrap Light Weight Process member in THE_PR_LWP macro for clearer code */
+#ifndef HAVE_PSTATUS_T
+ typedef prstatus_t gdb_prstatus_t;
+#define THE_PR_LWP(a) a
+#else /* HAVE_PSTATUS_T */
+ typedef pstatus_t gdb_prstatus_t;
+#define THE_PR_LWP(a) a.pr_lwp
+#if !defined(HAVE_PRRUN_T) && defined(HAVE_MULTIPLE_PROC_FDS)
+ /* Fallback definitions - for using configure information directly */
+#ifndef UNIXWARE
+#define UNIXWARE 1
+#endif
+#if !defined(PROCFS_USE_READ_WRITE) && !defined(HAVE_PROCFS_PIOCSET)
+#define PROCFS_USE_READ_WRITE 1
+#endif
+#endif /* !HAVE_PRRUN_T && HAVE_MULTIPLE_PROC_FDS */
+#endif /* HAVE_PSTATUS_T */
#define MAX_SYSCALLS 256 /* Maximum number of syscalls for table */
-#ifndef PROC_NAME_FMT
-#define PROC_NAME_FMT "/proc/%05d"
+/* proc name formats may vary depending on the proc implementation */
+#ifdef HAVE_MULTIPLE_PROC_FDS
+# ifndef CTL_PROC_NAME_FMT
+# define CTL_PROC_NAME_FMT "/proc/%d/ctl"
+# define AS_PROC_NAME_FMT "/proc/%d/as"
+# define MAP_PROC_NAME_FMT "/proc/%d/map"
+# define STATUS_PROC_NAME_FMT "/proc/%d/status"
+# endif
+#else /* HAVE_MULTIPLE_PROC_FDS */
+# ifndef CTL_PROC_NAME_FMT
+# define CTL_PROC_NAME_FMT "/proc/%05d"
+# define AS_PROC_NAME_FMT "/proc/%05d"
+# define MAP_PROC_NAME_FMT "/proc/%05d"
+# define STATUS_PROC_NAME_FMT "/proc/%05d"
+# endif
+#endif /* HAVE_MULTIPLE_PROC_FDS */
+
+
+/* These #ifdefs are for sol2.x in particular. sol2.x has
+ both a "gregset_t" and a "prgregset_t", which have
+ similar uses but different layouts. sol2.x gdb tries to
+ use prgregset_t (and prfpregset_t) everywhere. */
+
+#ifdef GDB_GREGSET_TYPE
+ typedef GDB_GREGSET_TYPE gdb_gregset_t;
+#else
+ typedef gregset_t gdb_gregset_t;
+#endif
+
+#ifdef GDB_FPREGSET_TYPE
+ typedef GDB_FPREGSET_TYPE gdb_fpregset_t;
+#else
+ typedef fpregset_t gdb_fpregset_t;
#endif
-extern struct target_ops procfs_ops; /* Forward declaration */
+
+#define MAX_PROC_NAME_SIZE sizeof("/proc/1234567890/status")
+
+struct target_ops procfs_ops;
+
+int procfs_suppress_run = 0; /* Non-zero if procfs should pretend not to
+ be a runnable target. Used by targets
+ that can sit atop procfs, such as solaris
+ thread support. */
#if 1 /* FIXME: Gross and ugly hack to resolve coredep.c global */
CORE_ADDR kernel_u_addr;
@@ -72,6 +167,52 @@ CORE_ADDR kernel_u_addr;
#define si_uid _data._proc._pdata._kill.uid
#endif /* BROKEN_SIGINFO_H */
+/* Define structures for passing commands to /proc/pid/ctl file. Note that
+ while we create these for the PROCFS_USE_READ_WRITE world, we use them
+ and ignore the extra cmd int in other proc schemes.
+*/
+/* generic ctl msg */
+struct proc_ctl {
+ int cmd;
+ long data;
+};
+
+/* set general registers */
+struct greg_ctl {
+ int cmd;
+ gdb_gregset_t gregset;
+};
+
+/* set fp registers */
+struct fpreg_ctl {
+ int cmd;
+ gdb_fpregset_t fpregset;
+};
+
+/* set signals to be traced */
+struct sig_ctl {
+ int cmd;
+ sigset_t sigset;
+};
+
+/* set faults to be traced */
+struct flt_ctl {
+ int cmd;
+ fltset_t fltset;
+};
+
+/* set system calls to be traced */
+struct sys_ctl {
+ int cmd;
+ sysset_t sysset;
+};
+
+/* set current signal to be traced */
+struct sigi_ctl {
+ int cmd;
+ siginfo_t siginfo;
+};
+
/* All access to the inferior, either one started by gdb or one that has
been attached to, is controlled by an instance of a procinfo structure,
defined below. Since gdb currently only handles one inferior at a time,
@@ -84,35 +225,44 @@ CORE_ADDR kernel_u_addr;
struct procinfo {
struct procinfo *next;
int pid; /* Process ID of inferior */
- int fd; /* File descriptor for /proc entry */
+ int ctl_fd; /* File descriptor for /proc ctl file */
+ int status_fd; /* File descriptor for /proc status file */
+ int as_fd; /* File descriptor for /proc as file */
+ int map_fd; /* File descriptor for /proc map file */
char *pathname; /* Pathname to /proc entry */
int had_event; /* poll/select says something happened */
int was_stopped; /* Nonzero if was stopped prior to attach */
int nopass_next_sigstop; /* Don't pass a sigstop on next resume */
+#ifdef HAVE_PRRUN_T
prrun_t prrun; /* Control state when it is run */
- prstatus_t prstatus; /* Current process status info */
- gregset_t gregset; /* General register set */
- fpregset_t fpregset; /* Floating point register set */
- fltset_t fltset; /* Current traced hardware fault set */
- sigset_t trace; /* Current traced signal set */
- sysset_t exitset; /* Current traced system call exit set */
- sysset_t entryset; /* Current traced system call entry set */
- fltset_t saved_fltset; /* Saved traced hardware fault set */
- sigset_t saved_trace; /* Saved traced signal set */
- sigset_t saved_sighold; /* Saved held signal set */
- sysset_t saved_exitset; /* Saved traced system call exit set */
- sysset_t saved_entryset; /* Saved traced system call entry set */
+#endif
+ gdb_prstatus_t prstatus; /* Current process status info */
+ struct greg_ctl gregset; /* General register set */
+ struct fpreg_ctl fpregset; /* Floating point register set */
+ struct flt_ctl fltset; /* Current traced hardware fault set */
+ struct sig_ctl trace; /* Current traced signal set */
+ struct sys_ctl exitset; /* Current traced system call exit set */
+ struct sys_ctl entryset; /* Current traced system call entry set */
+ struct sig_ctl saved_sighold; /* Saved held signal set */
+ struct flt_ctl saved_fltset; /* Saved traced hardware fault set */
+ struct sig_ctl saved_trace; /* Saved traced signal set */
+ struct sys_ctl saved_exitset; /* Saved traced system call exit set */
+ struct sys_ctl saved_entryset;/* Saved traced system call entry set */
+ int num_syscall_handlers; /* Number of syscall trap handlers
+ currently installed */
+ /* Pointer to list of syscall trap handlers */
+ struct procfs_syscall_handler *syscall_handlers;
+ int saved_rtnval; /* return value and status for wait(), */
+ int saved_statval; /* as supplied by a syscall handler. */
+ int new_child; /* Non-zero if it's a new thread */
};
/* List of inferior process information */
static struct procinfo *procinfo_list = NULL;
-
static struct pollfd *poll_list; /* pollfds used for waiting on /proc */
static int num_poll_list = 0; /* Number of entries in poll_list */
-static int last_resume_pid = -1; /* Last pid used with procfs_resume */
-
/* Much of the information used in the /proc interface, particularly for
printing status information, is kept as tables of structures of the
following form. These tables can be used to map numeric values to
@@ -168,6 +318,15 @@ static struct trans pr_flag_table[] =
#if defined (PR_PCOMPAT)
{ PR_PCOMPAT, "PR_PCOMPAT", "Ptrace compatibility mode in effect" },
#endif
+#if defined (PR_MSACCT)
+ { PR_MSACCT, "PR_MSACCT", "Microstate accounting enabled" },
+#endif
+#if defined (PR_BPTADJ)
+ { PR_BPTADJ, "PR_BPTADJ", "Breakpoint PC adjustment in effect" },
+#endif
+#if defined (PR_ASLWP)
+ { PR_ASLWP, "PR_ASLWP", "Asynchronus signal LWP" },
+#endif
{ 0, NULL, NULL }
};
@@ -181,9 +340,6 @@ static struct trans pr_why_table[] =
#if defined (PR_SIGNALLED)
{ PR_SIGNALLED, "PR_SIGNALLED", "Receipt of a traced signal" },
#endif
-#if defined (PR_FAULTED)
- { PR_FAULTED, "PR_FAULTED", "Incurred a traced hardware fault" },
-#endif
#if defined (PR_SYSENTRY)
{ PR_SYSENTRY, "PR_SYSENTRY", "Entry to a traced system call" },
#endif
@@ -193,9 +349,15 @@ static struct trans pr_why_table[] =
#if defined (PR_JOBCONTROL)
{ PR_JOBCONTROL, "PR_JOBCONTROL", "Default job control stop signal action" },
#endif
+#if defined (PR_FAULTED)
+ { PR_FAULTED, "PR_FAULTED", "Incurred a traced hardware fault" },
+#endif
#if defined (PR_SUSPENDED)
{ PR_SUSPENDED, "PR_SUSPENDED", "Process suspended" },
#endif
+#if defined (PR_CHECKPOINT)
+ { PR_CHECKPOINT, "PR_CHECKPOINT", "(???)" },
+#endif
{ 0, NULL, NULL }
};
@@ -360,6 +522,50 @@ static char *syscall_table[MAX_SYSCALLS];
/* Prototypes for local functions */
+static void procfs_stop PARAMS ((void));
+
+static int procfs_thread_alive PARAMS ((int));
+
+static int procfs_can_run PARAMS ((void));
+
+static void procfs_mourn_inferior PARAMS ((void));
+
+static void procfs_fetch_registers PARAMS ((int));
+
+static int procfs_wait PARAMS ((int, struct target_waitstatus *));
+
+static void procfs_open PARAMS ((char *, int));
+
+static void procfs_files_info PARAMS ((struct target_ops *));
+
+static void procfs_prepare_to_store PARAMS ((void));
+
+static void procfs_detach PARAMS ((char *, int));
+
+static void procfs_attach PARAMS ((char *, int));
+
+static void proc_set_exec_trap PARAMS ((void));
+
+static void procfs_init_inferior PARAMS ((int));
+
+static struct procinfo *create_procinfo PARAMS ((int));
+
+static void procfs_store_registers PARAMS ((int));
+
+static int procfs_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
+
+static void procfs_kill_inferior PARAMS ((void));
+
+static char *sigcodedesc PARAMS ((siginfo_t *));
+
+static char *sigcodename PARAMS ((siginfo_t *));
+
+static struct procinfo *wait_fd PARAMS ((void));
+
+static void remove_fd PARAMS ((struct procinfo *));
+
+static void add_fd PARAMS ((struct procinfo *));
+
static void set_proc_siginfo PARAMS ((struct procinfo *, int));
static void init_syscall_table PARAMS ((void));
@@ -372,13 +578,13 @@ static char *errnoname PARAMS ((int));
static int proc_address_to_fd PARAMS ((struct procinfo *, CORE_ADDR, int));
-static int open_proc_file PARAMS ((int, struct procinfo *, int));
+static int open_proc_file PARAMS ((int, struct procinfo *, int, int));
static void close_proc_file PARAMS ((struct procinfo *));
static void unconditionally_kill_inferior PARAMS ((struct procinfo *));
-static NORETURN void proc_init_failed PARAMS ((struct procinfo *, char *)) ATTR_NORETURN;
+static NORETURN void proc_init_failed PARAMS ((struct procinfo *, char *, int)) ATTR_NORETURN;
static void info_proc PARAMS ((char *, int));
@@ -410,18 +616,69 @@ static void procfs_create_inferior PARAMS ((char *, char *, char **));
static void procfs_notice_signals PARAMS ((int pid));
+static void notice_signals PARAMS ((struct procinfo *, struct sig_ctl *));
+
static struct procinfo *find_procinfo PARAMS ((pid_t pid, int okfail));
+static int procfs_write_pcwstop PARAMS ((struct procinfo *));
+static int procfs_read_status PARAMS ((struct procinfo *));
+static void procfs_write_pckill PARAMS ((struct procinfo *));
+
+typedef int syscall_func_t PARAMS ((struct procinfo *pi, int syscall_num,
+ int why, int *rtnval, int *statval));
+
+static void procfs_set_syscall_trap PARAMS ((struct procinfo *pi,
+ int syscall_num, int flags,
+ syscall_func_t *func));
+
+static void procfs_clear_syscall_trap PARAMS ((struct procinfo *pi,
+ int syscall_num, int errok));
+
+#define PROCFS_SYSCALL_ENTRY 0x1 /* Trap on entry to sys call */
+#define PROCFS_SYSCALL_EXIT 0x2 /* Trap on exit from sys call */
+
+static syscall_func_t procfs_exit_handler;
+
+static syscall_func_t procfs_exec_handler;
+
+#ifdef SYS_sproc
+static syscall_func_t procfs_sproc_handler;
+static syscall_func_t procfs_fork_handler;
+#endif
+
+#ifdef SYS_lwp_create
+static syscall_func_t procfs_lwp_creation_handler;
+#endif
+
+static void modify_inherit_on_fork_flag PARAMS ((int fd, int flag));
+static void modify_run_on_last_close_flag PARAMS ((int fd, int flag));
+
+/* */
+
+struct procfs_syscall_handler
+{
+ int syscall_num; /* The number of the system call being handled */
+ /* The function to be called */
+ syscall_func_t *func;
+};
+
+static void procfs_resume PARAMS ((int pid, int step,
+ enum target_signal signo));
+
+static void init_procfs_ops PARAMS ((void));
+
/* External function prototypes that can't be easily included in any
header file because the args are typedefs in system include files. */
-extern void supply_gregset PARAMS ((gregset_t *));
+extern void supply_gregset PARAMS ((gdb_gregset_t *));
-extern void fill_gregset PARAMS ((gregset_t *, int));
+extern void fill_gregset PARAMS ((gdb_gregset_t *, int));
-extern void supply_fpregset PARAMS ((fpregset_t *));
+#ifdef FP0_REGNUM
+extern void supply_fpregset PARAMS ((gdb_fpregset_t *));
-extern void fill_fpregset PARAMS ((fpregset_t *, int));
+extern void fill_fpregset PARAMS ((gdb_fpregset_t *, int));
+#endif
/*
@@ -501,12 +758,32 @@ add_fd (pi)
poll_list = (struct pollfd *) xrealloc (poll_list,
(num_poll_list + 1)
* sizeof (struct pollfd));
- poll_list[num_poll_list].fd = pi->fd;
+ poll_list[num_poll_list].fd = pi->ctl_fd;
+#ifdef UNIXWARE
+ poll_list[num_poll_list].events = POLLWRNORM;
+#else
poll_list[num_poll_list].events = POLLPRI;
+#endif
num_poll_list++;
}
+/*
+
+LOCAL FUNCTION
+
+ remove_fd -- Remove the fd from the poll/select list
+
+SYNOPSIS
+
+ static void remove_fd (struct procinfo *);
+
+DESCRIPTION
+
+ Remove the fd of the supplied procinfo from the list of fds used
+ for poll/select operations.
+ */
+
static void
remove_fd (pi)
struct procinfo *pi;
@@ -515,10 +792,10 @@ remove_fd (pi)
for (i = 0; i < num_poll_list; i++)
{
- if (poll_list[i].fd == pi->fd)
+ if (poll_list[i].fd == pi->ctl_fd)
{
if (i != num_poll_list - 1)
- memcpy (poll_list, poll_list + i + 1,
+ memcpy (poll_list + i, poll_list + i + 1,
(num_poll_list - i - 1) * sizeof (struct pollfd));
num_poll_list--;
@@ -534,25 +811,132 @@ remove_fd (pi)
}
}
-#define LOSING_POLL unixware_sux
+/*
+
+LOCAL FUNCTION
+
+ procfs_read_status - get procfs fd status
+
+SYNOPSIS
+
+ static int procfs_read_status (pi) struct procinfo *pi;
+
+DESCRIPTION
+
+ Given a pointer to a procinfo struct, get the status of
+ the status_fd in the appropriate way. Returns 0 on failure,
+ 1 on success.
+ */
+
+static int
+procfs_read_status (pi)
+ struct procinfo *pi;
+{
+#ifdef PROCFS_USE_READ_WRITE
+ if ((lseek (pi->status_fd, 0, SEEK_SET) < 0) ||
+ (read (pi->status_fd, (char *) &pi->prstatus,
+ sizeof (gdb_prstatus_t)) != sizeof (gdb_prstatus_t)))
+#else
+ if (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) < 0)
+#endif
+ return 0;
+ else
+ return 1;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_write_pcwstop - send a PCWSTOP to procfs fd
+
+SYNOPSIS
+
+ static int procfs_write_pcwstop (pi) struct procinfo *pi;
+
+DESCRIPTION
+
+ Given a pointer to a procinfo struct, send a PCWSTOP to
+ the ctl_fd in the appropriate way. Returns 0 on failure,
+ 1 on success.
+ */
+
+static int
+procfs_write_pcwstop (pi)
+ struct procinfo *pi;
+{
+#ifdef PROCFS_USE_READ_WRITE
+ long cmd = PCWSTOP;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) < 0)
+#endif
+ return 0;
+ else
+ return 1;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_write_pckill - send a kill to procfs fd
+
+SYNOPSIS
+
+ static void procfs_write_pckill (pi) struct procinfo *pi;
+
+DESCRIPTION
+
+ Given a pointer to a procinfo struct, send a kill to
+ the ctl_fd in the appropriate way. Returns 0 on failure,
+ 1 on success.
+ */
+
+static void
+procfs_write_pckill (pi)
+ struct procinfo *pi;
+{
+#ifdef PROCFS_USE_READ_WRITE
+ struct proc_ctl pctl;
+ pctl.cmd = PCKILL;
+ pctl.data = SIGKILL;
+ write (pi->ctl_fd, &pctl, sizeof (struct proc_ctl));
+#else
+ int signo = SIGKILL;
+ ioctl (pi->ctl_fd, PIOCKILL, &signo);
+#endif
+}
static struct procinfo *
wait_fd ()
{
- struct procinfo *pi;
+ struct procinfo *pi, *next_pi;
+#ifndef LOSING_POLL
int num_fds;
int i;
+#endif
set_sigint_trap (); /* Causes SIGINT to be passed on to the
attached process. */
set_sigio_trap ();
+ wait_again:
#ifndef LOSING_POLL
- num_fds = poll (poll_list, num_poll_list, -1);
-#else
+ while (1)
+ {
+ num_fds = poll (poll_list, num_poll_list, -1);
+ if (num_fds > 0)
+ break;
+ if (num_fds < 0 && errno == EINTR)
+ continue;
+ print_sys_errmsg ("poll failed", errno);
+ error ("Poll failed, returned %d", num_fds);
+ }
+#else /* LOSING_POLL */
pi = current_procinfo;
- while (ioctl (pi->fd, PIOCWSTOP, &pi->prstatus) < 0)
+ while (!procfs_write_pcwstop (pi))
{
if (errno == ENOENT)
{
@@ -563,43 +947,53 @@ wait_fd ()
else if (errno != EINTR)
{
print_sys_errmsg (pi->pathname, errno);
- error ("PIOCWSTOP failed");
+ error ("procfs_write_pcwstop failed");
}
}
pi->had_event = 1;
-#endif
+#endif /* LOSING_POLL */
clear_sigint_trap ();
clear_sigio_trap ();
#ifndef LOSING_POLL
- if (num_fds <= 0)
- {
- print_sys_errmsg ("poll failed\n", errno);
- error ("Poll failed, returned %d", num_fds);
- }
-
for (i = 0; i < num_poll_list && num_fds > 0; i++)
{
- if ((poll_list[i].revents & (POLLPRI|POLLERR|POLLHUP|POLLNVAL)) == 0)
+ if (0 == (poll_list[i].revents &
+ (POLLWRNORM | POLLPRI | POLLERR | POLLHUP | POLLNVAL)))
continue;
- for (pi = procinfo_list; pi; pi = pi->next)
+ for (pi = procinfo_list; pi; pi = next_pi)
{
- if (poll_list[i].fd == pi->fd)
+ next_pi = pi->next;
+ if (poll_list[i].fd == pi->ctl_fd)
{
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- error ("PIOCSTATUS failed");
- }
num_fds--;
+ if ((poll_list[i].revents & POLLHUP) != 0 ||
+ !procfs_read_status(pi))
+ { /* The LWP has apparently terminated. */
+ if (num_poll_list <= 1)
+ {
+ pi->prstatus.pr_flags = 0;
+ pi->had_event = 1;
+ break;
+ }
+ if (info_verbose)
+ printf_filtered ("LWP %d exited.\n",
+ (pi->pid >> 16) & 0xffff);
+ close_proc_file (pi);
+ i--; /* don't skip deleted entry */
+ if (num_fds != 0)
+ break; /* already another event to process */
+ else
+ goto wait_again; /* wait for another event */
+ }
pi->had_event = 1;
break;
}
}
if (!pi)
- error ("procfs_wait: Couldn't find procinfo for fd %d\n",
+ error ("wait_fd: Couldn't find procinfo for fd %d\n",
poll_list[i].fd);
}
#endif /* LOSING_POLL */
@@ -776,18 +1170,15 @@ syscallname (syscallnum)
int syscallnum;
{
static char locbuf[32];
- char *rtnval;
- if (syscallnum >= 0 && syscallnum < MAX_SYSCALLS)
- {
- rtnval = syscall_table[syscallnum];
- }
+ if (syscallnum >= 0 && syscallnum < MAX_SYSCALLS
+ && syscall_table[syscallnum] != NULL)
+ return syscall_table[syscallnum];
else
{
sprintf (locbuf, "syscall %u", syscallnum);
- rtnval = locbuf;
+ return locbuf;
}
- return (rtnval);
}
/*
@@ -971,6 +1362,9 @@ init_syscall_table ()
#if defined (SYS_sys3b)
syscall_table[SYS_sys3b] = "sys3b";
#endif
+#if defined (SYS_sysi86)
+ syscall_table[SYS_sysi86] = "sysi86";
+#endif
#if defined (SYS_acct)
syscall_table[SYS_acct] = "acct";
#endif
@@ -1187,6 +1581,246 @@ init_syscall_table ()
#if defined (SYS_sproc)
syscall_table[SYS_sproc] = "sproc";
#endif
+#if defined (SYS_keyctl)
+ syscall_table[SYS_keyctl] = "keyctl";
+#endif
+#if defined (SYS_secsys)
+ syscall_table[SYS_secsys] = "secsys";
+#endif
+#if defined (SYS_filepriv)
+ syscall_table[SYS_filepriv] = "filepriv";
+#endif
+#if defined (SYS_procpriv)
+ syscall_table[SYS_procpriv] = "procpriv";
+#endif
+#if defined (SYS_devstat)
+ syscall_table[SYS_devstat] = "devstat";
+#endif
+#if defined (SYS_aclipc)
+ syscall_table[SYS_aclipc] = "aclipc";
+#endif
+#if defined (SYS_fdevstat)
+ syscall_table[SYS_fdevstat] = "fdevstat";
+#endif
+#if defined (SYS_flvlfile)
+ syscall_table[SYS_flvlfile] = "flvlfile";
+#endif
+#if defined (SYS_lvlfile)
+ syscall_table[SYS_lvlfile] = "lvlfile";
+#endif
+#if defined (SYS_lvlequal)
+ syscall_table[SYS_lvlequal] = "lvlequal";
+#endif
+#if defined (SYS_lvlproc)
+ syscall_table[SYS_lvlproc] = "lvlproc";
+#endif
+#if defined (SYS_lvlipc)
+ syscall_table[SYS_lvlipc] = "lvlipc";
+#endif
+#if defined (SYS_acl)
+ syscall_table[SYS_acl] = "acl";
+#endif
+#if defined (SYS_auditevt)
+ syscall_table[SYS_auditevt] = "auditevt";
+#endif
+#if defined (SYS_auditctl)
+ syscall_table[SYS_auditctl] = "auditctl";
+#endif
+#if defined (SYS_auditdmp)
+ syscall_table[SYS_auditdmp] = "auditdmp";
+#endif
+#if defined (SYS_auditlog)
+ syscall_table[SYS_auditlog] = "auditlog";
+#endif
+#if defined (SYS_auditbuf)
+ syscall_table[SYS_auditbuf] = "auditbuf";
+#endif
+#if defined (SYS_lvldom)
+ syscall_table[SYS_lvldom] = "lvldom";
+#endif
+#if defined (SYS_lvlvfs)
+ syscall_table[SYS_lvlvfs] = "lvlvfs";
+#endif
+#if defined (SYS_mkmld)
+ syscall_table[SYS_mkmld] = "mkmld";
+#endif
+#if defined (SYS_mldmode)
+ syscall_table[SYS_mldmode] = "mldmode";
+#endif
+#if defined (SYS_secadvise)
+ syscall_table[SYS_secadvise] = "secadvise";
+#endif
+#if defined (SYS_online)
+ syscall_table[SYS_online] = "online";
+#endif
+#if defined (SYS_setitimer)
+ syscall_table[SYS_setitimer] = "setitimer";
+#endif
+#if defined (SYS_getitimer)
+ syscall_table[SYS_getitimer] = "getitimer";
+#endif
+#if defined (SYS_gettimeofday)
+ syscall_table[SYS_gettimeofday] = "gettimeofday";
+#endif
+#if defined (SYS_settimeofday)
+ syscall_table[SYS_settimeofday] = "settimeofday";
+#endif
+#if defined (SYS_lwp_create)
+ syscall_table[SYS_lwp_create] = "_lwp_create";
+#endif
+#if defined (SYS_lwp_exit)
+ syscall_table[SYS_lwp_exit] = "_lwp_exit";
+#endif
+#if defined (SYS_lwp_wait)
+ syscall_table[SYS_lwp_wait] = "_lwp_wait";
+#endif
+#if defined (SYS_lwp_self)
+ syscall_table[SYS_lwp_self] = "_lwp_self";
+#endif
+#if defined (SYS_lwp_info)
+ syscall_table[SYS_lwp_info] = "_lwp_info";
+#endif
+#if defined (SYS_lwp_private)
+ syscall_table[SYS_lwp_private] = "_lwp_private";
+#endif
+#if defined (SYS_processor_bind)
+ syscall_table[SYS_processor_bind] = "processor_bind";
+#endif
+#if defined (SYS_processor_exbind)
+ syscall_table[SYS_processor_exbind] = "processor_exbind";
+#endif
+#if defined (SYS_prepblock)
+ syscall_table[SYS_prepblock] = "prepblock";
+#endif
+#if defined (SYS_block)
+ syscall_table[SYS_block] = "block";
+#endif
+#if defined (SYS_rdblock)
+ syscall_table[SYS_rdblock] = "rdblock";
+#endif
+#if defined (SYS_unblock)
+ syscall_table[SYS_unblock] = "unblock";
+#endif
+#if defined (SYS_cancelblock)
+ syscall_table[SYS_cancelblock] = "cancelblock";
+#endif
+#if defined (SYS_pread)
+ syscall_table[SYS_pread] = "pread";
+#endif
+#if defined (SYS_pwrite)
+ syscall_table[SYS_pwrite] = "pwrite";
+#endif
+#if defined (SYS_truncate)
+ syscall_table[SYS_truncate] = "truncate";
+#endif
+#if defined (SYS_ftruncate)
+ syscall_table[SYS_ftruncate] = "ftruncate";
+#endif
+#if defined (SYS_lwp_kill)
+ syscall_table[SYS_lwp_kill] = "_lwp_kill";
+#endif
+#if defined (SYS_sigwait)
+ syscall_table[SYS_sigwait] = "sigwait";
+#endif
+#if defined (SYS_fork1)
+ syscall_table[SYS_fork1] = "fork1";
+#endif
+#if defined (SYS_forkall)
+ syscall_table[SYS_forkall] = "forkall";
+#endif
+#if defined (SYS_modload)
+ syscall_table[SYS_modload] = "modload";
+#endif
+#if defined (SYS_moduload)
+ syscall_table[SYS_moduload] = "moduload";
+#endif
+#if defined (SYS_modpath)
+ syscall_table[SYS_modpath] = "modpath";
+#endif
+#if defined (SYS_modstat)
+ syscall_table[SYS_modstat] = "modstat";
+#endif
+#if defined (SYS_modadm)
+ syscall_table[SYS_modadm] = "modadm";
+#endif
+#if defined (SYS_getksym)
+ syscall_table[SYS_getksym] = "getksym";
+#endif
+#if defined (SYS_lwp_suspend)
+ syscall_table[SYS_lwp_suspend] = "_lwp_suspend";
+#endif
+#if defined (SYS_lwp_continue)
+ syscall_table[SYS_lwp_continue] = "_lwp_continue";
+#endif
+#if defined (SYS_priocntllst)
+ syscall_table[SYS_priocntllst] = "priocntllst";
+#endif
+#if defined (SYS_sleep)
+ syscall_table[SYS_sleep] = "sleep";
+#endif
+#if defined (SYS_lwp_sema_wait)
+ syscall_table[SYS_lwp_sema_wait] = "_lwp_sema_wait";
+#endif
+#if defined (SYS_lwp_sema_post)
+ syscall_table[SYS_lwp_sema_post] = "_lwp_sema_post";
+#endif
+#if defined (SYS_lwp_sema_trywait)
+ syscall_table[SYS_lwp_sema_trywait] = "lwp_sema_trywait";
+#endif
+#if defined(SYS_fstatvfs64)
+ syscall_table[SYS_fstatvfs64] = "fstatvfs64";
+#endif
+#if defined(SYS_statvfs64)
+ syscall_table[SYS_statvfs64] = "statvfs64";
+#endif
+#if defined(SYS_ftruncate64)
+ syscall_table[SYS_ftruncate64] = "ftruncate64";
+#endif
+#if defined(SYS_truncate64)
+ syscall_table[SYS_truncate64] = "truncate64";
+#endif
+#if defined(SYS_getrlimit64)
+ syscall_table[SYS_getrlimit64] = "getrlimit64";
+#endif
+#if defined(SYS_setrlimit64)
+ syscall_table[SYS_setrlimit64] = "setrlimit64";
+#endif
+#if defined(SYS_lseek64)
+ syscall_table[SYS_lseek64] = "lseek64";
+#endif
+#if defined(SYS_mmap64)
+ syscall_table[SYS_mmap64] = "mmap64";
+#endif
+#if defined(SYS_pread64)
+ syscall_table[SYS_pread64] = "pread64";
+#endif
+#if defined(SYS_creat64)
+ syscall_table[SYS_creat64] = "creat64";
+#endif
+#if defined(SYS_dshmsys)
+ syscall_table[SYS_dshmsys] = "dshmsys";
+#endif
+#if defined(SYS_invlpg)
+ syscall_table[SYS_invlpg] = "invlpg";
+#endif
+#if defined(SYS_cg_ids)
+ syscall_table[SYS_cg_ids] = "cg_ids";
+#endif
+#if defined(SYS_cg_processors)
+ syscall_table[SYS_cg_processors] = "cg_processors";
+#endif
+#if defined(SYS_cg_info)
+ syscall_table[SYS_cg_info] = "cg_info";
+#endif
+#if defined(SYS_cg_bind)
+ syscall_table[SYS_cg_bind] = "cg_bind";
+#endif
+#if defined(SYS_cg_current)
+ syscall_table[SYS_cg_current] = "cg_current";
+#endif
+#if defined(SYS_cg_memloc)
+ syscall_table[SYS_cg_memloc] = "cg_memloc";
+#endif
}
/*
@@ -1244,18 +1878,16 @@ static void
unconditionally_kill_inferior (pi)
struct procinfo *pi;
{
- int signo;
int ppid;
+ struct proc_ctl pctl;
ppid = pi->prstatus.pr_ppid;
- signo = SIGKILL;
-
#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
/* Alpha OSF/1-3.x procfs needs a clear of the current signal
before the PIOCKILL, otherwise it might generate a corrupted core
file for the inferior. */
- ioctl (pi->fd, PIOCSSIG, NULL);
+ ioctl (pi->ctl_fd, PIOCSSIG, NULL);
#endif
#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL
/* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal
@@ -1267,16 +1899,16 @@ unconditionally_kill_inferior (pi)
struct siginfo newsiginfo;
memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
- newsiginfo.si_signo = signo;
+ newsiginfo.si_signo = SIGKILL;
newsiginfo.si_code = 0;
newsiginfo.si_errno = 0;
newsiginfo.si_pid = getpid ();
newsiginfo.si_uid = getuid ();
- ioctl (pi->fd, PIOCSSIG, &newsiginfo);
+ ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo);
}
-#else
- ioctl (pi->fd, PIOCKILL, &signo);
-#endif
+#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
+ procfs_write_pckill (pi);
+#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
close_proc_file (pi);
@@ -1327,15 +1959,15 @@ procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
pi = current_procinfo;
- if (lseek(pi->fd, (off_t) memaddr, 0) == (off_t) memaddr)
+ if (lseek(pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
{
if (dowrite)
{
- nbytes = write (pi->fd, myaddr, len);
+ nbytes = write (pi->as_fd, myaddr, len);
}
else
{
- nbytes = read (pi->fd, myaddr, len);
+ nbytes = read (pi->as_fd, myaddr, len);
}
if (nbytes < 0)
{
@@ -1388,15 +2020,32 @@ procfs_store_registers (regno)
int regno;
{
struct procinfo *pi;
+#ifdef PROCFS_USE_READ_WRITE
+ struct greg_ctl greg;
+ struct fpreg_ctl fpreg;
+#endif
pi = current_procinfo;
+#ifdef PROCFS_USE_READ_WRITE
+ if (regno != -1)
+ {
+ procfs_read_status (pi);
+ memcpy ((char *) &greg.gregset,
+ (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs,
+ sizeof (gdb_gregset_t));
+ }
+ fill_gregset (&greg.gregset, regno);
+ greg.cmd = PCSREG;
+ write (pi->ctl_fd, &greg, sizeof (greg));
+#else /* PROCFS_USE_READ_WRITE */
if (regno != -1)
{
- ioctl (pi->fd, PIOCGREG, &pi->gregset);
+ ioctl (pi->ctl_fd, PIOCGREG, &pi->gregset.gregset);
}
- fill_gregset (&pi->gregset, regno);
- ioctl (pi->fd, PIOCSREG, &pi->gregset);
+ fill_gregset (&pi->gregset.gregset, regno);
+ ioctl (pi->ctl_fd, PIOCSREG, &pi->gregset.gregset);
+#endif /* PROCFS_USE_READ_WRITE */
#if defined (FP0_REGNUM)
@@ -1404,12 +2053,25 @@ procfs_store_registers (regno)
target has floating point hardware. Since we ignore the returned value,
we'll never know whether it worked or not anyway. */
+#ifdef PROCFS_USE_READ_WRITE
if (regno != -1)
{
- ioctl (pi->fd, PIOCGFPREG, &pi->fpregset);
+ procfs_read_status (pi);
+ memcpy ((char *) &fpreg.fpregset,
+ (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs,
+ sizeof (gdb_fpregset_t));
}
- fill_fpregset (&pi->fpregset, regno);
- ioctl (pi->fd, PIOCSFPREG, &pi->fpregset);
+ fill_fpregset (&fpreg.fpregset, regno);
+ fpreg.cmd = PCSFPREG;
+ write (pi->ctl_fd, &fpreg, sizeof (fpreg));
+#else /* PROCFS_USE_READ_WRITE */
+ if (regno != -1)
+ {
+ ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset.fpregset);
+ }
+ fill_fpregset (&pi->fpregset.fpregset, regno);
+ ioctl (pi->ctl_fd, PIOCSFPREG, &pi->fpregset.fpregset);
+#endif /* PROCFS_USE_READ_WRITE */
#endif /* FP0_REGNUM */
@@ -1419,17 +2081,17 @@ procfs_store_registers (regno)
LOCAL FUNCTION
- create_procinfo - initialize access to a /proc entry
+ init_procinfo - setup a procinfo struct and connect it to a process
SYNOPSIS
- struct procinfo * create_procinfo (int pid)
+ struct procinfo * init_procinfo (int pid)
DESCRIPTION
Allocate a procinfo structure, open the /proc file and then set up the
set of signals and faults that are to be traced. Returns a pointer to
- the new procinfo structure.
+ the new procinfo structure.
NOTES
@@ -1439,19 +2101,22 @@ NOTES
*/
static struct procinfo *
-create_procinfo (pid)
+init_procinfo (pid, kill)
int pid;
+ int kill;
{
- struct procinfo *pi;
+ struct procinfo *pi = (struct procinfo *)
+ xmalloc (sizeof (struct procinfo));
+ struct sig_ctl sctl;
+ struct flt_ctl fctl;
- pi = find_procinfo (pid, 1);
- if (pi != NULL)
- return pi; /* All done! It already exists */
+ memset ((char *) pi, 0, sizeof (*pi));
+ if (!open_proc_file (pid, pi, O_RDWR, 1))
+ proc_init_failed (pi, "can't open process file", kill);
- pi = (struct procinfo *) xmalloc (sizeof (struct procinfo));
+ /* open_proc_file may modify pid. */
- if (!open_proc_file (pid, pi, O_RDWR))
- proc_init_failed (pi, "can't open process file");
+ pid = pi -> pid;
/* Add new process to process info list */
@@ -1460,21 +2125,103 @@ create_procinfo (pid)
add_fd (pi); /* Add to list for poll/select */
+ /* Remember some things about the inferior that we will, or might, change
+ so that we can restore them when we detach. */
+#ifdef UNIXWARE
+ memcpy ((char *) &pi->saved_trace.sigset,
+ (char *) &pi->prstatus.pr_sigtrace, sizeof (sigset_t));
+ memcpy ((char *) &pi->saved_fltset.fltset,
+ (char *) &pi->prstatus.pr_flttrace, sizeof (fltset_t));
+ memcpy ((char *) &pi->saved_entryset.sysset,
+ (char *) &pi->prstatus.pr_sysentry, sizeof (sysset_t));
+ memcpy ((char *) &pi->saved_exitset.sysset,
+ (char *) &pi->prstatus.pr_sysexit, sizeof (sysset_t));
+
+ /* Set up trace and fault sets, as gdb expects them. */
+
+ prfillset (&sctl.sigset);
+ notice_signals (pi, &sctl);
+ prfillset (&fctl.fltset);
+ prdelset (&fctl.fltset, FLTPAGE);
+
+#else /* ! UNIXWARE */
+ ioctl (pi->ctl_fd, PIOCGTRACE, &pi->saved_trace.sigset);
+ ioctl (pi->ctl_fd, PIOCGHOLD, &pi->saved_sighold.sigset);
+ ioctl (pi->ctl_fd, PIOCGFAULT, &pi->saved_fltset.fltset);
+ ioctl (pi->ctl_fd, PIOCGENTRY, &pi->saved_entryset.sysset);
+ ioctl (pi->ctl_fd, PIOCGEXIT, &pi->saved_exitset.sysset);
+
+ /* Set up trace and fault sets, as gdb expects them. */
+
memset ((char *) &pi->prrun, 0, sizeof (pi->prrun));
prfillset (&pi->prrun.pr_trace);
procfs_notice_signals (pid);
prfillset (&pi->prrun.pr_fault);
prdelset (&pi->prrun.pr_fault, FLTPAGE);
-
#ifdef PROCFS_DONT_TRACE_FAULTS
premptyset (&pi->prrun.pr_fault);
#endif
+#endif /* UNIXWARE */
+
+ if (!procfs_read_status (pi))
+ proc_init_failed (pi, "procfs_read_status failed", kill);
+
+ return pi;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ create_procinfo - initialize access to a /proc entry
+
+SYNOPSIS
+
+ struct procinfo * create_procinfo (int pid)
+
+DESCRIPTION
+
+ Allocate a procinfo structure, open the /proc file and then set up the
+ set of signals and faults that are to be traced. Returns a pointer to
+ the new procinfo structure.
+
+NOTES
+
+ If proc_init_failed ever gets called, control returns to the command
+ processing loop via the standard error handling code.
+
+ */
- if (ioctl (pi->fd, PIOCWSTOP, &pi->prstatus) < 0)
- proc_init_failed (pi, "PIOCWSTOP failed");
+static struct procinfo *
+create_procinfo (pid)
+ int pid;
+{
+ struct procinfo *pi;
+ struct sig_ctl sctl;
+ struct flt_ctl fctl;
+
+ pi = find_procinfo (pid, 1);
+ if (pi != NULL)
+ return pi; /* All done! It already exists */
- if (ioctl (pi->fd, PIOCSFAULT, &pi->prrun.pr_fault) < 0)
- proc_init_failed (pi, "PIOCSFAULT failed");
+ pi = init_procinfo (pid, 1);
+
+#ifndef UNIXWARE
+/* A bug in Solaris (2.5 at least) causes PIOCWSTOP to hang on LWPs that are
+ already stopped, even if they all have PR_ASYNC set. */
+ if (!(pi->prstatus.pr_flags & PR_STOPPED))
+#endif
+ if (!procfs_write_pcwstop (pi))
+ proc_init_failed (pi, "procfs_write_pcwstop failed", 1);
+
+#ifdef PROCFS_USE_READ_WRITE
+ fctl.cmd = PCSFAULT;
+ if (write (pi->ctl_fd, (char *) &fctl, sizeof (struct flt_ctl)) < 0)
+ proc_init_failed (pi, "PCSFAULT failed", 1);
+#else
+ if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault) < 0)
+ proc_init_failed (pi, "PIOCSFAULT failed", 1);
+#endif
return pi;
}
@@ -1483,6 +2230,305 @@ create_procinfo (pid)
LOCAL FUNCTION
+ procfs_exit_handler - handle entry into the _exit syscall
+
+SYNOPSIS
+
+ int procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp)
+
+DESCRIPTION
+
+ This routine is called when an inferior process enters the _exit()
+ system call. It continues the process, and then collects the exit
+ status and pid which are returned in *statvalp and *rtnvalp. After
+ that it returns non-zero to indicate that procfs_wait should wake up.
+
+NOTES
+ There is probably a better way to do this.
+
+ */
+
+static int
+procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp)
+ struct procinfo *pi;
+ int syscall_num;
+ int why;
+ int *rtnvalp;
+ int *statvalp;
+{
+ struct procinfo *temp_pi, *next_pi;
+ struct proc_ctl pctl;
+
+#ifdef UNIXWARE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+#else
+ pi->prrun.pr_flags = PRCFAULT;
+#endif
+
+#ifdef PROCFS_USE_READ_WRITE
+ if (write (pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif
+ perror_with_name (pi->pathname);
+
+ if (attach_flag)
+ {
+ /* Claim it exited (don't call wait). */
+ if (info_verbose)
+ printf_filtered ("(attached process has exited)\n");
+ *statvalp = 0;
+ *rtnvalp = inferior_pid;
+ }
+ else
+ {
+ *rtnvalp = wait (statvalp);
+ if (*rtnvalp >= 0)
+ *rtnvalp = pi->pid;
+ }
+
+ /* Close ALL open proc file handles,
+ except the one that called SYS_exit. */
+ for (temp_pi = procinfo_list; temp_pi; temp_pi = next_pi)
+ {
+ next_pi = temp_pi->next;
+ if (temp_pi == pi)
+ continue; /* Handled below */
+ close_proc_file (temp_pi);
+ }
+ return 1;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_exec_handler - handle exit from the exec family of syscalls
+
+SYNOPSIS
+
+ int procfs_exec_handler (pi, syscall_num, why, rtnvalp, statvalp)
+
+DESCRIPTION
+
+ This routine is called when an inferior process is about to finish any
+ of the exec() family of system calls. It pretends that we got a
+ SIGTRAP (for compatibility with ptrace behavior), and returns non-zero
+ to tell procfs_wait to wake up.
+
+NOTES
+ This need for compatibility with ptrace is questionable. In the
+ future, it shouldn't be necessary.
+
+ */
+
+static int
+procfs_exec_handler (pi, syscall_num, why, rtnvalp, statvalp)
+ struct procinfo *pi;
+ int syscall_num;
+ int why;
+ int *rtnvalp;
+ int *statvalp;
+{
+ *statvalp = (SIGTRAP << 8) | 0177;
+
+ return 1;
+}
+
+#if defined(SYS_sproc) && !defined(UNIXWARE)
+/* IRIX lwp creation system call */
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_sproc_handler - handle exit from the sproc syscall
+
+SYNOPSIS
+
+ int procfs_sproc_handler (pi, syscall_num, why, rtnvalp, statvalp)
+
+DESCRIPTION
+
+ This routine is called when an inferior process is about to finish an
+ sproc() system call. This is the system call that IRIX uses to create
+ a lightweight process. When the target process gets this event, we can
+ look at rval1 to find the new child processes ID, and create a new
+ procinfo struct from that.
+
+ After that, it pretends that we got a SIGTRAP, and returns non-zero
+ to tell procfs_wait to wake up. Subsequently, wait_for_inferior gets
+ woken up, sees the new process and continues it.
+
+NOTES
+ We actually never see the child exiting from sproc because we will
+ shortly stop the child with PIOCSTOP, which is then registered as the
+ event of interest.
+ */
+
+static int
+procfs_sproc_handler (pi, syscall_num, why, rtnvalp, statvalp)
+ struct procinfo *pi;
+ int syscall_num;
+ int why;
+ int *rtnvalp;
+ int *statvalp;
+{
+/* We've just detected the completion of an sproc system call. Now we need to
+ setup a procinfo struct for this thread, and notify the thread system of the
+ new arrival. */
+
+/* If sproc failed, then nothing interesting happened. Continue the process
+ and go back to sleep. */
+
+ if (pi->prstatus.pr_errno != 0)
+ {
+ pi->prrun.pr_flags &= PRSTEP;
+ pi->prrun.pr_flags |= PRCFAULT;
+
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+ perror_with_name (pi->pathname);
+
+ return 0;
+ }
+
+ /* At this point, the new thread is stopped at it's first instruction, and
+ the parent is stopped at the exit from sproc. */
+
+ /* Notify the caller of the arrival of a new thread. */
+ create_procinfo (pi->prstatus.pr_rval1);
+
+ *rtnvalp = pi->prstatus.pr_rval1;
+ *statvalp = (SIGTRAP << 8) | 0177;
+
+ return 1;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_fork_handler - handle exit from the fork syscall
+
+SYNOPSIS
+
+ int procfs_fork_handler (pi, syscall_num, why, rtnvalp, statvalp)
+
+DESCRIPTION
+
+ This routine is called when an inferior process is about to finish a
+ fork() system call. We will open up the new process, and then close
+ it, which releases it from the clutches of the debugger.
+
+ After that, we continue the target process as though nothing had
+ happened.
+
+NOTES
+ This is necessary for IRIX because we have to set PR_FORK in order
+ to catch the creation of lwps (via sproc()). When an actual fork
+ occurs, it becomes necessary to reset the forks debugger flags and
+ continue it because we can't hack multiple processes yet.
+ */
+
+static int
+procfs_fork_handler (pi, syscall_num, why, rtnvalp, statvalp)
+ struct procinfo *pi;
+ int syscall_num;
+ int why;
+ int *rtnvalp;
+ int *statvalp;
+{
+ struct procinfo *pitemp;
+
+/* At this point, we've detected the completion of a fork (or vfork) call in
+ our child. The grandchild is also stopped because we set inherit-on-fork
+ earlier. (Note that nobody has the grandchilds' /proc file open at this
+ point.) We will release the grandchild from the debugger by opening it's
+ /proc file and then closing it. Since run-on-last-close is set, the
+ grandchild continues on its' merry way. */
+
+
+ pitemp = create_procinfo (pi->prstatus.pr_rval1);
+ if (pitemp)
+ close_proc_file (pitemp);
+
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+ perror_with_name (pi->pathname);
+
+ return 0;
+}
+#endif /* SYS_sproc && !UNIXWARE */
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_set_inferior_syscall_traps - setup the syscall traps
+
+SYNOPSIS
+
+ void procfs_set_inferior_syscall_traps (struct procinfo *pip)
+
+DESCRIPTION
+
+ Called for each "procinfo" (process, thread, or LWP) in the
+ inferior, to register for notification of and handlers for
+ syscall traps in the inferior.
+
+ */
+
+static void
+procfs_set_inferior_syscall_traps (pip)
+ struct procinfo *pip;
+{
+ procfs_set_syscall_trap (pip, SYS_exit, PROCFS_SYSCALL_ENTRY,
+ procfs_exit_handler);
+
+#ifndef PRFS_STOPEXEC
+#ifdef SYS_exec
+ procfs_set_syscall_trap (pip, SYS_exec, PROCFS_SYSCALL_EXIT,
+ procfs_exec_handler);
+#endif
+#ifdef SYS_execv
+ procfs_set_syscall_trap (pip, SYS_execv, PROCFS_SYSCALL_EXIT,
+ procfs_exec_handler);
+#endif
+#ifdef SYS_execve
+ procfs_set_syscall_trap (pip, SYS_execve, PROCFS_SYSCALL_EXIT,
+ procfs_exec_handler);
+#endif
+#endif /* PRFS_STOPEXEC */
+
+ /* Setup traps on exit from sproc() */
+
+#ifdef SYS_sproc
+ procfs_set_syscall_trap (pip, SYS_sproc, PROCFS_SYSCALL_EXIT,
+ procfs_sproc_handler);
+ procfs_set_syscall_trap (pip, SYS_fork, PROCFS_SYSCALL_EXIT,
+ procfs_fork_handler);
+#ifdef SYS_vfork
+ procfs_set_syscall_trap (pip, SYS_vfork, PROCFS_SYSCALL_EXIT,
+ procfs_fork_handler);
+#endif
+/* Turn on inherit-on-fork flag so that all children of the target process
+ start with tracing flags set. This allows us to trap lwp creation. Note
+ that we also have to trap on fork and vfork in order to disable all tracing
+ in the targets child processes. */
+
+ modify_inherit_on_fork_flag (pip->ctl_fd, 1);
+#endif
+
+#ifdef SYS_lwp_create
+ procfs_set_syscall_trap (pip, SYS_lwp_create, PROCFS_SYSCALL_EXIT,
+ procfs_lwp_creation_handler);
+#endif
+}
+
+/*
+
+LOCAL FUNCTION
+
procfs_init_inferior - initialize target vector and access to a
/proc entry
@@ -1496,7 +2542,8 @@ DESCRIPTION
process immediately after the fork. It waits for the child to stop
on the return from the exec system call (the child itself takes care
of ensuring that this is set up), then sets up the set of signals
- and faults that are to be traced.
+ and faults that are to be traced. Returns the pid, which may have had
+ the thread-id added to it.
NOTES
@@ -1505,14 +2552,25 @@ NOTES
*/
-static void
+static void
procfs_init_inferior (pid)
int pid;
{
+ struct procinfo *pip;
+
push_target (&procfs_ops);
- create_procinfo (pid);
- add_thread (pid); /* Setup initial thread */
+ pip = create_procinfo (pid);
+
+ procfs_set_inferior_syscall_traps (pip);
+
+ /* create_procinfo may change the pid, so we have to update inferior_pid
+ here before calling other gdb routines that need the right pid. */
+
+ pid = pip -> pid;
+ inferior_pid = pid;
+
+ add_thread (pip -> pid); /* Setup initial thread */
#ifdef START_INFERIOR_TRAPS_EXPECTED
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
@@ -1551,25 +2609,50 @@ static void
procfs_notice_signals (pid)
int pid;
{
- int signo;
struct procinfo *pi;
+ struct sig_ctl sctl;
pi = find_procinfo (pid, 0);
+#ifndef HAVE_PRRUN_T
+ premptyset (&sctl.sigset);
+#else
+ sctl.sigset = pi->prrun.pr_trace;
+#endif
+
+ notice_signals (pi, &sctl);
+
+#ifdef HAVE_PRRUN_T
+ pi->prrun.pr_trace = sctl.sigset;
+#endif
+}
+
+static void
+notice_signals (pi, sctl)
+ struct procinfo *pi;
+ struct sig_ctl *sctl;
+{
+ int signo;
+
for (signo = 0; signo < NSIG; signo++)
{
if (signal_stop_state (target_signal_from_host (signo)) == 0 &&
signal_print_state (target_signal_from_host (signo)) == 0 &&
signal_pass_state (target_signal_from_host (signo)) == 1)
{
- prdelset (&pi->prrun.pr_trace, signo);
+ prdelset (&sctl->sigset, signo);
}
else
{
- praddset (&pi->prrun.pr_trace, signo);
+ praddset (&sctl->sigset, signo);
}
}
- if (ioctl (pi->fd, PIOCSTRACE, &pi->prrun.pr_trace))
+#ifdef PROCFS_USE_READ_WRITE
+ sctl->cmd = PCSTRACE;
+ if (write (pi->ctl_fd, (char *) sctl, sizeof (struct sig_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSTRACE, &sctl->sigset))
+#endif
{
print_sys_errmsg ("PIOCSTRACE failed", errno);
}
@@ -1609,22 +2692,26 @@ NOTE
static void
proc_set_exec_trap ()
{
- sysset_t exitset;
- sysset_t entryset;
- auto char procname[32];
+ struct sys_ctl exitset;
+ struct sys_ctl entryset;
+ char procname[MAX_PROC_NAME_SIZE];
int fd;
- sprintf (procname, PROC_NAME_FMT, getpid ());
+ sprintf (procname, CTL_PROC_NAME_FMT, getpid ());
+#ifdef UNIXWARE
+ if ((fd = open (procname, O_WRONLY)) < 0)
+#else
if ((fd = open (procname, O_RDWR)) < 0)
+#endif
{
perror (procname);
gdb_flush (gdb_stderr);
_exit (127);
}
- premptyset (&exitset);
- premptyset (&entryset);
+ premptyset (&exitset.sysset);
+ premptyset (&entryset.sysset);
-#ifdef PIOCSSPCACT
+#ifdef PRFS_STOPEXEC
/* Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
exits from exec system calls because of the user level loader. */
{
@@ -1644,33 +2731,43 @@ proc_set_exec_trap ()
_exit (127);
}
}
-#else
+#else /* PRFS_STOPEXEC */
/* GW: Rationale...
Not all systems with /proc have all the exec* syscalls with the same
names. On the SGI, for example, there is no SYS_exec, but there
*is* a SYS_execv. So, we try to account for that. */
#ifdef SYS_exec
- praddset (&exitset, SYS_exec);
+ praddset (&exitset.sysset, SYS_exec);
#endif
#ifdef SYS_execve
- praddset (&exitset, SYS_execve);
+ praddset (&exitset.sysset, SYS_execve);
#endif
#ifdef SYS_execv
- praddset (&exitset, SYS_execv);
+ praddset (&exitset.sysset, SYS_execv);
#endif
- if (ioctl (fd, PIOCSEXIT, &exitset) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ exitset.cmd = PCSEXIT;
+ if (write (fd, (char *) &exitset, sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (fd, PIOCSEXIT, &exitset.sysset) < 0)
+#endif
{
perror (procname);
gdb_flush (gdb_stderr);
_exit (127);
}
-#endif
+#endif /* PRFS_STOPEXEC */
- praddset (&entryset, SYS_exit);
+ praddset (&entryset.sysset, SYS_exit);
- if (ioctl (fd, PIOCSENTRY, &entryset) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ entryset.cmd = PCSENTRY;
+ if (write (fd, (char *) &entryset, sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (fd, PIOCSENTRY, &entryset.sysset) < 0)
+#endif
{
perror (procname);
gdb_flush (gdb_stderr);
@@ -1680,32 +2777,35 @@ proc_set_exec_trap ()
/* Turn off inherit-on-fork flag so that all grand-children of gdb
start with tracing flags cleared. */
-#if defined (PIOCRESET) /* New method */
- {
- long pr_flags;
- pr_flags = PR_FORK;
- ioctl (fd, PIOCRESET, &pr_flags);
- }
-#else
-#if defined (PIOCRFORK) /* Original method */
- ioctl (fd, PIOCRFORK, NULL);
-#endif
-#endif
+ modify_inherit_on_fork_flag (fd, 0);
/* Turn on run-on-last-close flag so that this process will not hang
if GDB goes away for some reason. */
-#if defined (PIOCSET) /* New method */
+ modify_run_on_last_close_flag (fd, 1);
+
+#ifndef UNIXWARE /* since this is a solaris-ism, we don't want it */
+ /* NOTE: revisit when doing thread support for UW */
+#ifdef PR_ASYNC
{
- long pr_flags;
- pr_flags = PR_RLC;
- (void) ioctl (fd, PIOCSET, &pr_flags);
- }
+ long pr_flags;
+ struct proc_ctl pctl;
+
+/* Solaris needs this to make procfs treat all threads seperately. Without
+ this, all threads halt whenever something happens to any thread. Since
+ GDB wants to control all this itself, it needs to set PR_ASYNC. */
+
+ pr_flags = PR_ASYNC;
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCSET;
+ pctl.data = PR_FORK|PR_ASYNC;
+ write (fd, (char *) &pctl, sizeof (struct proc_ctl));
#else
-#if defined (PIOCSRLC) /* Original method */
- (void) ioctl (fd, PIOCSRLC, 0);
-#endif
+ ioctl (fd, PIOCSET, &pr_flags);
#endif
+ }
+#endif /* PR_ASYNC */
+#endif /* !UNIXWARE */
}
/*
@@ -1727,6 +2827,48 @@ DESCRIPTION
the end of the mappings or the function returns nonzero.
*/
+#ifdef UNIXWARE
+int
+proc_iterate_over_mappings (func)
+ int (*func) PARAMS ((int, CORE_ADDR));
+{
+ int nmap;
+ int fd;
+ int funcstat = 0;
+ prmap_t *prmaps;
+ prmap_t *prmap;
+ struct procinfo *pi;
+ struct stat sbuf;
+
+ pi = current_procinfo;
+
+ if (fstat (pi->map_fd, &sbuf) < 0)
+ return 0;
+
+ nmap = sbuf.st_size / sizeof (prmap_t);
+ prmaps = (prmap_t *) alloca (nmap * sizeof(prmap_t));
+ if ((lseek (pi->map_fd, 0, SEEK_SET) == 0) &&
+ (read (pi->map_fd, (char *) prmaps, nmap * sizeof (prmap_t)) ==
+ (nmap * sizeof (prmap_t))))
+ {
+ int i = 0;
+ for (prmap = prmaps; i < nmap && funcstat == 0; ++prmap, ++i)
+ {
+ char name[sizeof ("/proc/1234567890/object") +
+ sizeof (prmap->pr_mapname)];
+ sprintf (name, "/proc/%d/object/%s", pi->pid, prmap->pr_mapname);
+ if ((fd = open (name, O_RDONLY)) == -1)
+ {
+ funcstat = 1;
+ break;
+ }
+ funcstat = (*func) (fd, (CORE_ADDR) prmap->pr_vaddr);
+ close (fd);
+ }
+ }
+ return (funcstat);
+}
+#else /* UNIXWARE */
int
proc_iterate_over_mappings (func)
int (*func) PARAMS ((int, CORE_ADDR));
@@ -1740,10 +2882,10 @@ proc_iterate_over_mappings (func)
pi = current_procinfo;
- if (ioctl (pi->fd, PIOCNMAP, &nmap) == 0)
+ if (ioctl (pi->map_fd, PIOCNMAP, &nmap) == 0)
{
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pi->fd, PIOCMAP, prmaps) == 0)
+ if (ioctl (pi->map_fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size && funcstat == 0; ++prmap)
{
@@ -1755,6 +2897,7 @@ proc_iterate_over_mappings (func)
}
return (funcstat);
}
+#endif /* UNIXWARE */
#if 0 /* Currently unused */
/*
@@ -1790,10 +2933,10 @@ proc_base_address (addr)
pi = current_procinfo;
- if (ioctl (pi->fd, PIOCNMAP, &nmap) == 0)
+ if (ioctl (pi->map_fd, PIOCNMAP, &nmap) == 0)
{
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pi->fd, PIOCMAP, prmaps) == 0)
+ if (ioctl (pi->map_fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
{
@@ -1811,6 +2954,7 @@ proc_base_address (addr)
#endif /* 0 */
+#ifndef UNIXWARE
/*
LOCAL FUNCTION
@@ -1839,7 +2983,7 @@ proc_address_to_fd (pi, addr, complain)
{
int fd = -1;
- if ((fd = ioctl (pi->fd, PIOCOPENM, (caddr_t *) &addr)) < 0)
+ if ((fd = ioctl (pi->ctl_fd, PIOCOPENM, (caddr_t *) &addr)) < 0)
{
if (complain)
{
@@ -1849,7 +2993,7 @@ proc_address_to_fd (pi, addr, complain)
}
return (fd);
}
-
+#endif /* !UNIXWARE */
/* Attach to process PID, then initialize for debugging it
and wait for the trace-trap that results from attaching. */
@@ -1882,8 +3026,7 @@ procfs_attach (args, from_tty)
gdb_flush (gdb_stdout);
}
- do_attach (pid);
- inferior_pid = pid;
+ inferior_pid = pid = do_attach (pid);
push_target (&procfs_ops);
}
@@ -1982,107 +3125,92 @@ static int
do_attach (pid)
int pid;
{
- int result;
struct procinfo *pi;
+ struct sig_ctl sctl;
+ struct flt_ctl fctl;
+ int nlwp, *lwps;
- pi = (struct procinfo *) xmalloc (sizeof (struct procinfo));
+ pi = init_procinfo (pid, 0);
- if (!open_proc_file (pid, pi, O_RDWR))
- {
- free (pi);
- perror_with_name (pi->pathname);
- /* NOTREACHED */
- }
-
- /* Add new process to process info list */
-
- pi->next = procinfo_list;
- procinfo_list = pi;
+#ifdef PIOCLWPIDS
+ nlwp = pi->prstatus.pr_nlwp;
+ lwps = alloca ((2 * nlwp + 2) * sizeof (id_t));
- add_fd (pi); /* Add to list for poll/select */
-
- /* Get current status of process and if it is not already stopped,
- then stop it. Remember whether or not it was stopped when we first
- examined it. */
-
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
+ if (ioctl (pi->ctl_fd, PIOCLWPIDS, lwps))
{
- print_sys_errmsg (pi->pathname, errno);
- close_proc_file (pi);
- error ("PIOCSTATUS failed");
- }
- if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
- {
- pi->was_stopped = 1;
+ print_sys_errmsg (pi -> pathname, errno);
+ error ("PIOCLWPIDS failed");
}
- else
+#else /* PIOCLWPIDS */
+ nlwp = 1;
+ lwps = alloca ((2 * nlwp + 2) * sizeof *lwps);
+ lwps[0] = 0;
+#endif
+ for (; nlwp > 0; nlwp--, lwps++)
{
- pi->was_stopped = 0;
- if (1 || query ("Process is currently running, stop it? "))
+ /* First one has already been created above. */
+ if ((pi = find_procinfo ((*lwps << 16) | pid, 1)) == 0)
+ pi = init_procinfo ((*lwps << 16) | pid, 0);
+
+ if (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))
{
- /* Make it run again when we close it. */
-#if defined (PIOCSET) /* New method */
- {
- long pr_flags;
- pr_flags = PR_RLC;
- result = ioctl (pi->fd, PIOCSET, &pr_flags);
- }
+ pi->was_stopped = 1;
+ }
+ else
+ {
+ pi->was_stopped = 0;
+ if (1 || query ("Process is currently running, stop it? "))
+ {
+ long cmd;
+ /* Make it run again when we close it. */
+ modify_run_on_last_close_flag (pi->ctl_fd, 1);
+#ifdef PROCFS_USE_READ_WRITE
+ cmd = PCSTOP;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
#else
-#if defined (PIOCSRLC) /* Original method */
- result = ioctl (pi->fd, PIOCSRLC, 0);
+ if (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) < 0)
#endif
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ close_proc_file (pi);
+ error ("PIOCSTOP failed");
+ }
+#ifdef UNIXWARE
+ if (!procfs_read_status (pi))
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ close_proc_file (pi);
+ error ("procfs_read_status failed");
+ }
#endif
- if (result < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- close_proc_file (pi);
- error ("PIOCSRLC or PIOCSET failed");
+ pi->nopass_next_sigstop = 1;
}
- if (ioctl (pi->fd, PIOCSTOP, &pi->prstatus) < 0)
+ else
{
- print_sys_errmsg (pi->pathname, errno);
- close_proc_file (pi);
- error ("PIOCSTOP failed");
+ printf_unfiltered ("Ok, gdb will wait for %s to stop.\n",
+ target_pid_to_str (pi->pid));
}
- pi->nopass_next_sigstop = 1;
}
- else
+
+#ifdef PROCFS_USE_READ_WRITE
+ fctl.cmd = PCSFAULT;
+ if (write (pi->ctl_fd, (char *) &fctl, sizeof (struct flt_ctl)) < 0)
+ print_sys_errmsg ("PCSFAULT failed", errno);
+#else /* PROCFS_USE_READ_WRITE */
+ if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault))
{
- printf_unfiltered ("Ok, gdb will wait for %s to stop.\n", target_pid_to_str (pid));
+ print_sys_errmsg ("PIOCSFAULT failed", errno);
}
- }
-
- /* Remember some things about the inferior that we will, or might, change
- so that we can restore them when we detach. */
-
- ioctl (pi->fd, PIOCGTRACE, &pi->saved_trace);
- ioctl (pi->fd, PIOCGHOLD, &pi->saved_sighold);
- ioctl (pi->fd, PIOCGFAULT, &pi->saved_fltset);
- ioctl (pi->fd, PIOCGENTRY, &pi->saved_entryset);
- ioctl (pi->fd, PIOCGEXIT, &pi->saved_exitset);
-
- /* Set up trace and fault sets, as gdb expects them. */
-
- memset (&pi->prrun, 0, sizeof (pi->prrun));
- prfillset (&pi->prrun.pr_trace);
- procfs_notice_signals (pid);
- prfillset (&pi->prrun.pr_fault);
- prdelset (&pi->prrun.pr_fault, FLTPAGE);
-
-#ifdef PROCFS_DONT_TRACE_FAULTS
- premptyset (&pi->prrun.pr_fault);
-#endif
-
- if (ioctl (pi->fd, PIOCSFAULT, &pi->prrun.pr_fault))
- {
- print_sys_errmsg ("PIOCSFAULT failed", errno);
- }
- if (ioctl (pi->fd, PIOCSTRACE, &pi->prrun.pr_trace))
- {
- print_sys_errmsg ("PIOCSTRACE failed", errno);
+ if (ioctl (pi->ctl_fd, PIOCSTRACE, &pi->prrun.pr_trace))
+ {
+ print_sys_errmsg ("PIOCSTRACE failed", errno);
+ }
+ add_thread (pi->pid);
+ procfs_set_inferior_syscall_traps (pi);
+#endif /* PROCFS_USE_READ_WRITE */
}
attach_flag = 1;
- return (pid);
+ return (pi->pid);
}
/*
@@ -2118,85 +3246,106 @@ static void
do_detach (signal)
int signal;
{
- int result;
struct procinfo *pi;
- pi = current_procinfo;
-
- if (signal)
- {
- set_proc_siginfo (pi, signal);
- }
- if (ioctl (pi->fd, PIOCSEXIT, &pi->saved_exitset) < 0)
+ for (pi = procinfo_list; pi; pi = pi->next)
{
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSEXIT failed.\n");
- }
- if (ioctl (pi->fd, PIOCSENTRY, &pi->saved_entryset) < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSENTRY failed.\n");
- }
- if (ioctl (pi->fd, PIOCSTRACE, &pi->saved_trace) < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSTRACE failed.\n");
- }
- if (ioctl (pi->fd, PIOCSHOLD, &pi->saved_sighold) < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOSCHOLD failed.\n");
- }
- if (ioctl (pi->fd, PIOCSFAULT, &pi->saved_fltset) < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSFAULT failed.\n");
- }
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
- {
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSTATUS failed.\n");
- }
- else
- {
- if (signal || (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
+ if (signal)
{
- if (signal || !pi->was_stopped ||
- query ("Was stopped when attached, make it runnable again? "))
+ set_proc_siginfo (pi, signal);
+ }
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_exitset.cmd = PCSEXIT;
+ if (write (pi->ctl_fd, (char *) &pi->saved_exitset,
+ sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSEXIT, &pi->saved_exitset.sysset) < 0)
+#endif
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("PIOCSEXIT failed.\n");
+ }
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_entryset.cmd = PCSENTRY;
+ if (write (pi->ctl_fd, (char *) &pi->saved_entryset,
+ sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSENTRY, &pi->saved_entryset.sysset) < 0)
+#endif
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("PIOCSENTRY failed.\n");
+ }
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_trace.cmd = PCSTRACE;
+ if (write (pi->ctl_fd, (char *) &pi->saved_trace,
+ sizeof (struct sig_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSTRACE, &pi->saved_trace.sigset) < 0)
+#endif
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("PIOCSTRACE failed.\n");
+ }
+#ifndef UNIXWARE
+ if (ioctl (pi->ctl_fd, PIOCSHOLD, &pi->saved_sighold.sigset) < 0)
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("PIOSCHOLD failed.\n");
+ }
+#endif
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_fltset.cmd = PCSFAULT;
+ if (write (pi->ctl_fd, (char *) &pi->saved_fltset,
+ sizeof (struct flt_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->saved_fltset.fltset) < 0)
+#endif
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("PIOCSFAULT failed.\n");
+ }
+ if (!procfs_read_status (pi))
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("procfs_read_status failed.\n");
+ }
+ else
+ {
+ if (signal
+ || (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)))
{
- /* Clear any pending signal if we want to detach without
- a signal. */
- if (signal == 0)
- set_proc_siginfo (pi, signal);
+ long cmd;
+ struct proc_ctl pctl;
- /* Clear any fault that might have stopped it. */
- if (ioctl (pi->fd, PIOCCFAULT, 0))
+ if (signal || !pi->was_stopped ||
+ query ("Was stopped when attached, make it runnable again? "))
{
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCCFAULT failed.\n");
- }
-
- /* Make it run again when we close it. */
-#if defined (PIOCSET) /* New method */
- {
- long pr_flags;
- pr_flags = PR_RLC;
- result = ioctl (pi->fd, PIOCSET, &pr_flags);
- }
+ /* Clear any pending signal if we want to detach without
+ a signal. */
+ if (signal == 0)
+ set_proc_siginfo (pi, signal);
+
+ /* Clear any fault that might have stopped it. */
+#ifdef PROCFS_USE_READ_WRITE
+ cmd = PCCFAULT;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
#else
-#if defined (PIOCSRLC) /* Original method */
- result = ioctl (pi->fd, PIOCSRLC, 0);
-#endif
+ if (ioctl (pi->ctl_fd, PIOCCFAULT, 0))
#endif
- if (result)
- {
- print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSRLC or PIOCSET failed.\n");
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ printf_unfiltered ("PIOCCFAULT failed.\n");
+ }
+
+ /* Make it run again when we close it. */
+
+ modify_run_on_last_close_flag (pi->ctl_fd, 1);
}
}
}
+ close_proc_file (pi);
}
- close_proc_file (pi);
attach_flag = 0;
}
@@ -2224,7 +3373,6 @@ do_detach (signal)
FIXME: Investigate why wait() seems to have problems with programs
being control by /proc routines. */
-
static int
procfs_wait (pid, ourstatus)
int pid;
@@ -2236,45 +3384,80 @@ procfs_wait (pid, ourstatus)
int checkerr = 0;
int rtnval = -1;
struct procinfo *pi;
+ struct proc_ctl pctl;
- if (pid != -1) /* Non-specific process? */
- pi = NULL;
- else
- for (pi = procinfo_list; pi; pi = pi->next)
- if (pi->had_event)
- break;
+scan_again:
- if (!pi)
+ /* handle all syscall events first, otherwise we might not
+ notice a thread was created until too late. */
+
+ for (pi = procinfo_list; pi; pi = pi->next)
{
- wait_again:
+ if (!pi->had_event)
+ continue;
+
+ if (! (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)) )
+ continue;
- pi = wait_fd ();
+ why = THE_PR_LWP(pi->prstatus).pr_why;
+ what = THE_PR_LWP(pi->prstatus).pr_what;
+ if (why == PR_SYSENTRY || why == PR_SYSEXIT)
+ {
+ int i;
+ int found_handler = 0;
+
+ for (i = 0; i < pi->num_syscall_handlers; i++)
+ if (pi->syscall_handlers[i].syscall_num == what)
+ {
+ found_handler = 1;
+ pi->saved_rtnval = pi->pid;
+ pi->saved_statval = 0;
+ if (!pi->syscall_handlers[i].func
+ (pi, what, why, &pi->saved_rtnval, &pi->saved_statval))
+ pi->had_event = 0;
+ break;
+ }
+
+ if (!found_handler)
+ {
+ if (why == PR_SYSENTRY)
+ error ("PR_SYSENTRY, unhandled system call %d", what);
+ else
+ error ("PR_SYSEXIT, unhandled system call %d", what);
+ }
+ }
}
- if (pid != -1)
- for (pi = procinfo_list; pi; pi = pi->next)
- if (pi->pid == pid && pi->had_event)
- break;
+ /* find a relevant process with an event */
- if (!pi && !checkerr)
- goto wait_again;
+ for (pi = procinfo_list; pi; pi = pi->next)
+ if (pi->had_event && (pid == -1 || pi->pid == pid))
+ break;
- if (!checkerr && !(pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
+ if (!pi)
{
- if (ioctl (pi->fd, PIOCWSTOP, &pi->prstatus) < 0)
+ wait_fd ();
+ goto scan_again;
+ }
+
+ if (!checkerr
+ && !(THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)))
+ {
+ if (!procfs_write_pcwstop (pi))
{
checkerr++;
}
- }
+ }
if (checkerr)
{
if (errno == ENOENT)
{
+ /* XXX Fixme -- what to do if attached? Can't call wait... */
rtnval = wait (&statval);
- if (rtnval != inferior_pid)
+ if ((rtnval) != (PIDGET (inferior_pid)))
{
print_sys_errmsg (pi->pathname, errno);
- error ("PIOCWSTOP, wait failed, returned %d", rtnval);
+ error ("procfs_wait: wait failed, returned %d", rtnval);
/* NOTREACHED */
}
}
@@ -2285,11 +3468,15 @@ procfs_wait (pid, ourstatus)
/* NOTREACHED */
}
}
- else if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
+ else if (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))
{
+#ifdef UNIXWARE
rtnval = pi->prstatus.pr_pid;
- why = pi->prstatus.pr_why;
- what = pi->prstatus.pr_what;
+#else
+ rtnval = pi->pid;
+#endif
+ why = THE_PR_LWP(pi->prstatus).pr_why;
+ what = THE_PR_LWP(pi->prstatus).pr_what;
switch (why)
{
@@ -2297,88 +3484,9 @@ procfs_wait (pid, ourstatus)
statval = (what << 8) | 0177;
break;
case PR_SYSENTRY:
- if (what != SYS_exit)
- error ("PR_SYSENTRY, unknown system call %d", what);
-
- pi->prrun.pr_flags = PRCFAULT;
-
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
- perror_with_name (pi->pathname);
-
- rtnval = wait (&statval);
-
- break;
case PR_SYSEXIT:
- switch (what)
- {
-#ifdef SYS_exec
- case SYS_exec:
-#endif
-#ifdef SYS_execve
- case SYS_execve:
-#endif
-#ifdef SYS_execv
- case SYS_execv:
-#endif
- statval = (SIGTRAP << 8) | 0177;
- break;
-#ifdef SYS_sproc
- case SYS_sproc:
-/* We've just detected the completion of an sproc system call. Now we need to
- setup a procinfo struct for this thread, and notify the thread system of the
- new arrival. */
-
-/* If sproc failed, then nothing interesting happened. Continue the process and
- go back to sleep. */
-
- if (pi->prstatus.pr_errno != 0)
- {
- pi->prrun.pr_flags &= PRSTEP;
- pi->prrun.pr_flags |= PRCFAULT;
-
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
- perror_with_name (pi->pathname);
-
- goto wait_again;
- }
-
-/* At this point, the new thread is stopped at it's first instruction, and
- the parent is stopped at the exit from sproc. */
-
-/* Notify the caller of the arrival of a new thread. */
- create_procinfo (pi->prstatus.pr_rval1);
-
- rtnval = pi->prstatus.pr_rval1;
- statval = (SIGTRAP << 8) | 0177;
-
- break;
- case SYS_fork:
-#ifdef SYS_vfork
- case SYS_vfork:
-#endif
-/* At this point, we've detected the completion of a fork (or vfork) call in
- our child. The grandchild is also stopped because we set inherit-on-fork
- earlier. (Note that nobody has the grandchilds' /proc file open at this
- point.) We will release the grandchild from the debugger by opening it's
- /proc file and then closing it. Since run-on-last-close is set, the
- grandchild continues on its' merry way. */
-
- {
- struct procinfo *pitemp;
-
- pitemp = create_procinfo (pi->prstatus.pr_rval1);
- if (pitemp)
- close_proc_file (pitemp);
-
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
- perror_with_name (pi->pathname);
- }
- goto wait_again;
-#endif /* SYS_sproc */
-
- default:
- error ("PIOCSTATUS (PR_SYSEXIT): Unknown system call %d", what);
- }
+ rtnval = pi->saved_rtnval;
+ statval = pi->saved_statval;
break;
case PR_REQUESTED:
statval = (SIGSTOP << 8) | 0177;
@@ -2409,7 +3517,7 @@ procfs_wait (pid, ourstatus)
case FLTBPT:
case FLTTRACE:
statval = (SIGTRAP << 8) | 0177;
- break;
+ break;
case FLTSTACK:
case FLTACCESS:
case FLTBOUNDS:
@@ -2426,40 +3534,68 @@ procfs_wait (pid, ourstatus)
/* Use the signal which the kernel assigns. This is better than
trying to second-guess it from the fault. In fact, I suspect
that FLTACCESS can be either SIGSEGV or SIGBUS. */
- statval = ((pi->prstatus.pr_info.si_signo) << 8) | 0177;
+ statval =
+ ((THE_PR_LWP(pi->prstatus).pr_info.si_signo) << 8) | 0177;
break;
}
break;
default:
error ("PIOCWSTOP, unknown why %d, what %d", why, what);
}
-/* Stop all the other threads when any of them stops. */
+ /* Stop all the other threads when any of them stops. */
{
- struct procinfo *procinfo;
+ struct procinfo *procinfo, *next_pi;
- for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
+ for (procinfo = procinfo_list; procinfo; procinfo = next_pi)
{
+ next_pi = procinfo->next;
if (!procinfo->had_event)
- if (ioctl (procinfo->fd, PIOCSTOP, &procinfo->prstatus) < 0)
- {
- print_sys_errmsg (procinfo->pathname, errno);
- error ("PIOCSTOP failed");
- }
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ long cmd = PCSTOP;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
+ {
+ print_sys_errmsg (procinfo->pathname, errno);
+ error ("PCSTOP failed");
+ }
+#else
+ /* A bug in Solaris (2.5) causes us to hang when trying to
+ stop a stopped process. So, we have to check first in
+ order to avoid the hang. */
+ if (!procfs_read_status (procinfo))
+ {
+ /* The LWP has apparently terminated. */
+ if (info_verbose)
+ printf_filtered ("LWP %d doesn't respond.\n",
+ (procinfo->pid >> 16) & 0xffff);
+ close_proc_file (procinfo);
+ continue;
+ }
+
+ if (!(procinfo->prstatus.pr_flags & PR_STOPPED))
+ if (ioctl (procinfo->ctl_fd, PIOCSTOP, &procinfo->prstatus)
+ < 0)
+ {
+ print_sys_errmsg (procinfo->pathname, errno);
+ warning ("PIOCSTOP failed");
+ }
+#endif
+ }
}
}
}
else
{
- error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x",
- pi->prstatus.pr_flags);
+ error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x",
+ THE_PR_LWP(pi->prstatus).pr_flags);
}
store_waitstatus (ourstatus, statval);
if (rtnval == -1) /* No more children to wait for */
{
- fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing.\n");
+ warning ("Child process unexpectedly missing");
/* Claim it exited with unknown signal. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
@@ -2515,30 +3651,49 @@ set_proc_siginfo (pip, signo)
{
struct siginfo newsiginfo;
struct siginfo *sip;
+ struct sigi_ctl sictl;
#ifdef PROCFS_DONT_PIOCSSIG_CURSIG
/* With Alpha OSF/1 procfs, the kernel gets really confused if it
receives a PIOCSSIG with a signal identical to the current signal,
it messes up the current signal. Work around the kernel bug. */
- if (signo == pip -> prstatus.pr_cursig)
+ if (signo == THE_PR_LWP(pip->prstatus).pr_cursig)
return;
#endif
- if (signo == pip -> prstatus.pr_info.si_signo)
+#ifdef UNIXWARE
+ if (signo == THE_PR_LWP(pip->prstatus).pr_info.si_signo)
+ {
+ memcpy ((char *) &sictl.siginfo, (char *) &pip->prstatus.pr_lwp.pr_info,
+ sizeof (siginfo_t));
+ }
+#else
+ if (signo == THE_PR_LWP(pip->prstatus).pr_info.si_signo)
{
sip = &pip -> prstatus.pr_info;
}
+#endif
else
{
+#ifdef UNIXWARE
+ siginfo_t *sip = &sictl.siginfo;
+ memset ((char *) sip, 0, sizeof (siginfo_t));
+#else
memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
sip = &newsiginfo;
+#endif
sip -> si_signo = signo;
sip -> si_code = 0;
sip -> si_errno = 0;
sip -> si_pid = getpid ();
sip -> si_uid = getuid ();
}
- if (ioctl (pip -> fd, PIOCSSIG, sip) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ sictl.cmd = PCSSIG;
+ if (write (pip->ctl_fd, (char *) &sictl, sizeof (struct sigi_ctl)) < 0)
+#else
+ if (ioctl (pip->ctl_fd, PIOCSSIG, sip) < 0)
+#endif
{
print_sys_errmsg (pip -> pathname, errno);
warning ("PIOCSSIG failed");
@@ -2556,12 +3711,18 @@ procfs_resume (pid, step, signo)
enum target_signal signo;
{
int signal_to_pass;
- struct procinfo *pi, *procinfo;
+ struct procinfo *pi, *procinfo, *next_pi;
+ struct proc_ctl pctl;
pi = find_procinfo (pid == -1 ? inferior_pid : pid, 0);
errno = 0;
+#ifdef UNIXWARE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+#else
pi->prrun.pr_flags = PRSTRACE | PRSFAULT | PRCFAULT;
+#endif
#if 0
/* It should not be necessary. If the user explicitly changes the value,
@@ -2596,8 +3757,9 @@ procfs_resume (pid, step, signo)
an inferior to continue running at the same time as gdb. (FIXME?) */
signal_to_pass = 0;
else if (signo == TARGET_SIGNAL_TSTP
- && pi->prstatus.pr_cursig == SIGTSTP
- && pi->prstatus.pr_action.sa_handler == SIG_DFL)
+ && THE_PR_LWP(pi->prstatus).pr_cursig == SIGTSTP
+ && THE_PR_LWP(pi->prstatus).pr_action.sa_handler == SIG_DFL
+ )
/* We are about to pass the inferior a SIGTSTP whose action is
SIG_DFL. The SIG_DFL action for a SIGTSTP is to stop
@@ -2623,43 +3785,105 @@ procfs_resume (pid, step, signo)
}
else
{
+#ifdef UNIXWARE
+ pctl.data |= PRCSIG;
+#else
pi->prrun.pr_flags |= PRCSIG;
+#endif
}
pi->nopass_next_sigstop = 0;
if (step)
{
+#ifdef UNIXWARE
+ pctl.data |= PRSTEP;
+#else
pi->prrun.pr_flags |= PRSTEP;
+#endif
}
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ pi->had_event = 0;
+ /* Don't try to start a process unless it's stopped on an
+ `event of interest'. Doing so will cause errors. */
+
+ if (!procfs_read_status (pi))
{
- perror_with_name (pi->pathname);
- /* NOTREACHED */
+ /* The LWP has apparently terminated. */
+ if (info_verbose)
+ printf_filtered ("LWP %d doesn't respond.\n",
+ (pi->pid >> 16) & 0xffff);
+ close_proc_file (pi);
+ }
+ else
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+#else
+ if ((pi->prstatus.pr_flags & PR_ISTOP)
+ && ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif
+ {
+ /* The LWP has apparently terminated. */
+ if (info_verbose)
+ printf_filtered ("LWP %d doesn't respond.\n",
+ (pi->pid >> 16) & 0xffff);
+ close_proc_file (pi);
+ }
}
- pi->had_event = 0;
-
- /* Continue all the other threads that haven't had an event of
- interest. */
+ /* Continue all the other threads that haven't had an event of interest.
+ Also continue them if they have NOPASS_NEXT_SIGSTOP set; this is only
+ set by do_attach, and means this is the first resume after an attach.
+ All threads were CSTOP'd by do_attach, and should be resumed now. */
if (pid == -1)
- for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
+ for (procinfo = procinfo_list; procinfo; procinfo = next_pi)
{
- if (pi != procinfo && !procinfo->had_event)
- {
- procinfo->prrun.pr_flags &= PRSTEP;
- procinfo->prrun.pr_flags |= PRCFAULT | PRCSIG;
- ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus);
- if (ioctl (procinfo->fd, PIOCRUN, &procinfo->prrun) < 0)
- {
- if (ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus) < 0)
- {
- fprintf_unfiltered(gdb_stderr, "PIOCSTATUS failed, errno=%d\n", errno);
- }
- print_sys_errmsg (procinfo->pathname, errno);
- error ("PIOCRUN failed");
- }
- ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus);
- }
+ next_pi = procinfo->next;
+ if (pi != procinfo)
+ if (!procinfo->had_event ||
+ (procinfo->nopass_next_sigstop && signo == TARGET_SIGNAL_STOP))
+ {
+ procinfo->had_event = procinfo->nopass_next_sigstop = 0;
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.data = PRCFAULT | PRCSIG;
+ if (write (procinfo->ctl_fd, (char *) &pctl,
+ sizeof (struct proc_ctl)) < 0)
+ {
+ if (!procfs_read_status (procinfo))
+ fprintf_unfiltered(gdb_stderr,
+ "procfs_read_status failed, errno=%d\n",
+ errno);
+ print_sys_errmsg (procinfo->pathname, errno);
+ error ("PCRUN failed");
+ }
+#else
+ procinfo->prrun.pr_flags &= PRSTEP;
+ procinfo->prrun.pr_flags |= PRCFAULT | PRCSIG;
+ if (!procfs_read_status (procinfo))
+ {
+ /* The LWP has apparently terminated. */
+ if (info_verbose)
+ printf_filtered ("LWP %d doesn't respond.\n",
+ (procinfo->pid >> 16) & 0xffff);
+ close_proc_file (procinfo);
+ continue;
+ }
+
+ /* Don't try to start a process unless it's stopped on an
+ `event of interest'. Doing so will cause errors. */
+
+ if ((procinfo->prstatus.pr_flags & PR_ISTOP)
+ && ioctl (procinfo->ctl_fd, PIOCRUN, &procinfo->prrun) < 0)
+ {
+ if (!procfs_read_status (procinfo))
+ fprintf_unfiltered(gdb_stderr,
+ "procfs_read_status failed, errno=%d\n",
+ errno);
+ print_sys_errmsg (procinfo->pathname, errno);
+ warning ("PIOCRUN failed");
+ }
+#endif
+ }
+ procfs_read_status (procinfo);
}
}
@@ -2689,44 +3913,57 @@ procfs_fetch_registers (regno)
pi = current_procinfo;
- if (ioctl (pi->fd, PIOCGREG, &pi->gregset) != -1)
+#ifdef UNIXWARE
+ if (procfs_read_status (pi))
+ {
+ supply_gregset (&pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs);
+#if defined (FP0_REGNUM)
+ supply_fpregset (&pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs);
+#endif
+ }
+#else /* UNIXWARE */
+ if (ioctl (pi->ctl_fd, PIOCGREG, &pi->gregset.gregset) != -1)
{
- supply_gregset (&pi->gregset);
+ supply_gregset (&pi->gregset.gregset);
}
#if defined (FP0_REGNUM)
- if (ioctl (pi->fd, PIOCGFPREG, &pi->fpregset) != -1)
+ if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset.fpregset) != -1)
{
- supply_fpregset (&pi->fpregset);
+ supply_fpregset (&pi->fpregset.fpregset);
}
#endif
+#endif /* UNIXWARE */
}
/*
LOCAL FUNCTION
- proc_init_failed - called whenever /proc access initialization
+ proc_init_failed - called when /proc access initialization fails
fails
SYNOPSIS
- static void proc_init_failed (struct procinfo *pi, char *why)
+ static void proc_init_failed (struct procinfo *pi,
+ char *why, int kill_p)
DESCRIPTION
This function is called whenever initialization of access to a /proc
entry fails. It prints a suitable error message, does some cleanup,
and then invokes the standard error processing routine which dumps
- us back into the command loop.
+ us back into the command loop. If KILL_P is true, sends SIGKILL.
*/
static void
-proc_init_failed (pi, why)
+proc_init_failed (pi, why, kill_p)
struct procinfo *pi;
char *why;
+ int kill_p;
{
print_sys_errmsg (pi->pathname, errno);
- kill (pi->pid, SIGKILL);
+ if (kill_p)
+ kill (pi->pid, SIGKILL);
close_proc_file (pi);
error (why);
/* NOTREACHED */
@@ -2757,9 +3994,15 @@ close_proc_file (pip)
{
struct procinfo *procinfo;
+ delete_thread (pip->pid); /* remove thread from GDB's thread list */
remove_fd (pip); /* Remove fd from poll/select list */
- close (pip -> fd);
+ close (pip->ctl_fd);
+#ifdef HAVE_MULTIPLE_PROC_FDS
+ close (pip->as_fd);
+ close (pip->status_fd);
+ close (pip->map_fd);
+#endif
free (pip -> pathname);
@@ -2768,11 +4011,17 @@ close_proc_file (pip)
if (procinfo_list == pip)
procinfo_list = pip->next;
else
- for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
- if (procinfo->next == pip)
- procinfo->next = pip->next;
-
- free (pip);
+ {
+ for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
+ {
+ if (procinfo->next == pip)
+ {
+ procinfo->next = pip->next;
+ break;
+ }
+ }
+ free (pip);
+ }
}
/*
@@ -2797,23 +4046,118 @@ DESCRIPTION
Note that the pathname is left intact, even when the open fails,
so that callers can use it to construct meaningful error messages
rather than just "file open failed".
+
+ Note that for Solaris, the process-id also includes an LWP-id, so we
+ actually attempt to open that. If we are handed a pid with a 0 LWP-id,
+ then we will ask the kernel what it is and add it to the pid. Hence,
+ the pid can be changed by us.
*/
static int
-open_proc_file (pid, pip, mode)
+open_proc_file (pid, pip, mode, control)
int pid;
struct procinfo *pip;
int mode;
+ int control;
{
+ int tmp, tmpfd;
+
pip -> next = NULL;
pip -> had_event = 0;
- pip -> pathname = xmalloc (32);
+ pip -> pathname = xmalloc (MAX_PROC_NAME_SIZE);
pip -> pid = pid;
- sprintf (pip -> pathname, PROC_NAME_FMT, pid);
- if ((pip -> fd = open (pip -> pathname, mode)) < 0)
+#ifndef PIOCOPENLWP
+ tmp = pid;
+#else
+ tmp = pid & 0xffff;
+#endif
+
+#ifdef HAVE_MULTIPLE_PROC_FDS
+ sprintf (pip->pathname, STATUS_PROC_NAME_FMT, tmp);
+ if ((pip->status_fd = open (pip->pathname, O_RDONLY)) < 0)
+ {
+ return 0;
+ }
+
+ sprintf (pip->pathname, AS_PROC_NAME_FMT, tmp);
+ if ((pip->as_fd = open (pip->pathname, O_RDWR)) < 0)
+ {
+ close (pip->status_fd);
+ return 0;
+ }
+
+ sprintf (pip->pathname, MAP_PROC_NAME_FMT, tmp);
+ if ((pip->map_fd = open (pip->pathname, O_RDONLY)) < 0)
+ {
+ close (pip->status_fd);
+ close (pip->as_fd);
+ return 0;
+ }
+
+ if (control)
+ {
+ sprintf (pip->pathname, CTL_PROC_NAME_FMT, tmp);
+ if ((pip->ctl_fd = open (pip->pathname, O_WRONLY)) < 0)
+ {
+ close (pip->status_fd);
+ close (pip->as_fd);
+ close (pip->map_fd);
+ return 0;
+ }
+ }
+
+#else /* HAVE_MULTIPLE_PROC_FDS */
+ sprintf (pip -> pathname, CTL_PROC_NAME_FMT, tmp);
+
+ if ((tmpfd = open (pip -> pathname, mode)) < 0)
return 0;
+#ifndef PIOCOPENLWP
+ pip -> ctl_fd = tmpfd;
+ pip -> as_fd = tmpfd;
+ pip -> map_fd = tmpfd;
+ pip -> status_fd = tmpfd;
+#else
+ tmp = (pid >> 16) & 0xffff; /* Extract thread id */
+
+ if (tmp == 0)
+ { /* Don't know thread id yet */
+ if (ioctl (tmpfd, PIOCSTATUS, &pip -> prstatus) < 0)
+ {
+ print_sys_errmsg (pip -> pathname, errno);
+ close (tmpfd);
+ error ("open_proc_file: PIOCSTATUS failed");
+ }
+
+ tmp = pip -> prstatus.pr_who; /* Get thread id from prstatus_t */
+ pip -> pid = (tmp << 16) | pid; /* Update pip */
+ }
+
+ if ((pip -> ctl_fd = ioctl (tmpfd, PIOCOPENLWP, &tmp)) < 0)
+ {
+ close (tmpfd);
+ return 0;
+ }
+
+#ifdef PIOCSET /* New method */
+ {
+ long pr_flags;
+ pr_flags = PR_ASYNC;
+ ioctl (pip -> ctl_fd, PIOCSET, &pr_flags);
+ }
+#endif
+
+ /* keep extra fds in sync */
+ pip->as_fd = pip->ctl_fd;
+ pip->map_fd = pip->ctl_fd;
+ pip->status_fd = pip->ctl_fd;
+
+ close (tmpfd); /* All done with main pid */
+#endif /* PIOCOPENLWP */
+
+#endif /* HAVE_MULTIPLE_PROC_FDS */
+
return 1;
}
@@ -2842,6 +4186,11 @@ info_proc_flags (pip, summary)
int summary;
{
struct trans *transp;
+#ifdef UNIXWARE
+ long flags = pip->prstatus.pr_flags | pip->prstatus.pr_lwp.pr_flags;
+#else
+ long flags = pip->prstatus.pr_flags;
+#endif
printf_filtered ("%-32s", "Process status flags:");
if (!summary)
@@ -2850,7 +4199,7 @@ info_proc_flags (pip, summary)
}
for (transp = pr_flag_table; transp -> name != NULL; transp++)
{
- if (pip -> prstatus.pr_flags & transp -> value)
+ if (flags & transp -> value)
{
if (summary)
{
@@ -2874,10 +4223,10 @@ info_proc_stop (pip, summary)
int why;
int what;
- why = pip -> prstatus.pr_why;
- what = pip -> prstatus.pr_what;
+ why = THE_PR_LWP(pip->prstatus).pr_why;
+ what = THE_PR_LWP(pip->prstatus).pr_what;
- if (pip -> prstatus.pr_flags & PR_STOPPED)
+ if (THE_PR_LWP(pip->prstatus).pr_flags & PR_STOPPED)
{
printf_filtered ("%-32s", "Reason for stopping:");
if (!summary)
@@ -2968,12 +4317,12 @@ info_proc_siginfo (pip, summary)
{
struct siginfo *sip;
- if ((pip -> prstatus.pr_flags & PR_STOPPED) &&
- (pip -> prstatus.pr_why == PR_SIGNALLED ||
- pip -> prstatus.pr_why == PR_FAULTED))
+ if ((THE_PR_LWP(pip->prstatus).pr_flags & PR_STOPPED) &&
+ (THE_PR_LWP(pip->prstatus).pr_why == PR_SIGNALLED ||
+ THE_PR_LWP(pip->prstatus).pr_why == PR_FAULTED))
{
printf_filtered ("%-32s", "Additional signal/fault info:");
- sip = &pip -> prstatus.pr_info;
+ sip = &(THE_PR_LWP(pip->prstatus).pr_info);
if (summary)
{
printf_filtered ("%s ", signalname (sip -> si_signo));
@@ -3091,17 +4440,19 @@ info_proc_syscalls (pip, summary)
}
#endif
- if (ioctl (pip -> fd, PIOCGENTRY, &pip -> entryset) < 0)
+#ifndef UNIXWARE
+ if (ioctl (pip -> ctl_fd, PIOCGENTRY, &pip -> entryset) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGENTRY failed");
}
- if (ioctl (pip -> fd, PIOCGEXIT, &pip -> exitset) < 0)
+ if (ioctl (pip -> ctl_fd, PIOCGEXIT, &pip -> exitset) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGEXIT failed");
}
+#endif
printf_filtered ("System call tracing information:\n\n");
@@ -3113,17 +4464,27 @@ info_proc_syscalls (pip, summary)
{
QUIT;
if (syscall_table[syscallnum] != NULL)
- {
- printf_filtered ("\t%-12s ", syscall_table[syscallnum]);
- printf_filtered ("%-8s ",
- prismember (&pip -> entryset, syscallnum)
- ? "on" : "off");
- printf_filtered ("%-8s ",
- prismember (&pip -> exitset, syscallnum)
- ? "on" : "off");
- printf_filtered ("\n");
- }
- }
+ printf_filtered ("\t%-12s ", syscall_table[syscallnum]);
+ else
+ printf_filtered ("\t%-12d ", syscallnum);
+
+#ifdef UNIXWARE
+ printf_filtered ("%-8s ",
+ prismember (&pip->prstatus.pr_sysentry, syscallnum)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip->prstatus.pr_sysexit, syscallnum)
+ ? "on" : "off");
+#else
+ printf_filtered ("%-8s ",
+ prismember (&pip -> entryset, syscallnum)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip -> exitset, syscallnum)
+ ? "on" : "off");
+#endif
+ printf_filtered ("\n");
+ }
printf_filtered ("\n");
}
}
@@ -3175,11 +4536,13 @@ info_proc_signals (pip, summary)
if (!summary)
{
- if (ioctl (pip -> fd, PIOCGTRACE, &pip -> trace) < 0)
+#ifndef PROCFS_USE_READ_WRITE
+ if (ioctl (pip -> ctl_fd, PIOCGTRACE, &pip -> trace) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGTRACE failed");
}
+#endif
printf_filtered ("Disposition of signals:\n\n");
printf_filtered ("\t%-15s %-8s %-8s %-8s %s\n\n",
@@ -3188,13 +4551,29 @@ info_proc_signals (pip, summary)
{
QUIT;
printf_filtered ("\t%-15s ", signalname (signo));
+#ifdef UNIXWARE
+ printf_filtered ("%-8s ",
+ prismember (&pip -> prstatus.pr_sigtrace, signo)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip -> prstatus.pr_lwp.pr_context.uc_sigmask, signo)
+ ? "on" : "off");
+#else
printf_filtered ("%-8s ",
prismember (&pip -> trace, signo)
? "on" : "off");
printf_filtered ("%-8s ",
prismember (&pip -> prstatus.pr_sighold, signo)
? "on" : "off");
+#endif
+#ifdef UNIXWARE
+ if (prismember (&pip->prstatus.pr_sigpend, signo) ||
+ prismember (&pip->prstatus.pr_lwp.pr_lwppend, signo))
+ printf_filtered("%-8s ", "yes");
+ else
+ printf_filtered("%-8s ", "no");
+#else /* UNIXWARE */
#ifdef PROCFS_SIGPEND_OFFSET
/* Alpha OSF/1 numbers the pending signals from 1. */
printf_filtered ("%-8s ",
@@ -3207,6 +4586,7 @@ info_proc_signals (pip, summary)
prismember (&pip -> prstatus.pr_sigpend, signo)
? "yes" : "no");
#endif
+#endif /* UNIXWARE */
printf_filtered (" %s\n", safe_strsignal (signo));
}
printf_filtered ("\n");
@@ -3222,11 +4602,13 @@ info_proc_faults (pip, summary)
if (!summary)
{
- if (ioctl (pip -> fd, PIOCGFAULT, &pip -> fltset) < 0)
+#ifndef UNIXWARE
+ if (ioctl (pip -> ctl_fd, PIOCGFAULT, &pip->fltset.fltset) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGFAULT failed");
}
+#endif
printf_filtered ("Current traced hardware fault set:\n\n");
printf_filtered ("\t%-12s %-8s\n", "Fault", "Trace");
@@ -3235,8 +4617,13 @@ info_proc_faults (pip, summary)
{
QUIT;
printf_filtered ("\t%-12s ", transp -> name);
- printf_filtered ("%-8s", prismember (&pip -> fltset, transp -> value)
+#ifdef UNIXWARE
+ printf_filtered ("%-8s", prismember (&pip->prstatus.pr_flttrace, transp -> value)
+ ? "on" : "off");
+#else
+ printf_filtered ("%-8s", prismember (&pip->fltset.fltset, transp -> value)
? "on" : "off");
+#endif
printf_filtered ("\n");
}
printf_filtered ("\n");
@@ -3251,6 +4638,7 @@ info_proc_mappings (pip, summary)
int nmap;
struct prmap *prmaps;
struct prmap *prmap;
+ struct stat sbuf;
if (!summary)
{
@@ -3265,12 +4653,25 @@ info_proc_mappings (pip, summary)
" Size",
" Offset",
"Flags");
- if (ioctl (pip -> fd, PIOCNMAP, &nmap) == 0)
+#ifdef PROCFS_USE_READ_WRITE
+ if (fstat (pip->map_fd, &sbuf) == 0)
+ {
+ nmap = sbuf.st_size / sizeof (prmap_t);
+ prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
+ if ((lseek (pip->map_fd, 0, SEEK_SET) == 0) &&
+ (read (pip->map_fd, (char *) prmaps,
+ nmap * sizeof (*prmaps)) == (nmap * sizeof (*prmaps))))
+ {
+ int i = 0;
+ for (prmap = prmaps; i < nmap; ++prmap, ++i)
+#else
+ if (ioctl (pip -> ctl_fd, PIOCNMAP, &nmap) == 0)
{
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pip -> fd, PIOCMAP, prmaps) == 0)
+ if (ioctl (pip -> ctl_fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
+#endif /* PROCFS_USE_READ_WRITE */
{
#ifdef BFD_HOST_64_BIT
printf_filtered (" %#18lx %#18lx %#10x %#10x %7s\n",
@@ -3340,13 +4741,18 @@ info_proc (args, from_tty)
int id = 0;
int status = 0;
int all = 0;
+ int nlwp;
+ int *lwps;
old_chain = make_cleanup (null_cleanup, 0);
/* Default to using the current inferior if no pid specified. Note
that inferior_pid may be 0, hence we set okerr. */
- pip = find_procinfo (inferior_pid, 1);
+ pid = inferior_pid & 0x7fffffff; /* strip off sol-thread bit */
+ if (!(pip = find_procinfo (pid, 1))) /* inferior_pid no good? */
+ pip = procinfo_list; /* take first available */
+ pid = pid & 0xffff; /* extract "real" pid */
if (args != NULL)
{
@@ -3410,11 +4816,12 @@ info_proc (args, from_tty)
memset (pip, 0, sizeof (*pip));
pip->pid = pid;
- if (!open_proc_file (pid, pip, O_RDONLY))
+ if (!open_proc_file (pid, pip, O_RDONLY, 0))
{
perror_with_name (pip -> pathname);
/* NOTREACHED */
}
+ pid = pip->pid;
make_cleanup (close_proc_file, pip);
}
else if (**argv != '\000')
@@ -3433,120 +4840,601 @@ info_proc (args, from_tty)
error ("\
No process. Start debugging a program or specify an explicit process ID.");
}
- if (ioctl (pip -> fd, PIOCSTATUS, &(pip -> prstatus)) < 0)
+
+ if (!procfs_read_status (pip))
{
print_sys_errmsg (pip -> pathname, errno);
- error ("PIOCSTATUS failed");
+ error ("procfs_read_status failed");
}
- /* Print verbose information of the requested type(s), or just a summary
- of the information for all types. */
+#ifndef PROCFS_USE_READ_WRITE
+#ifdef PIOCLWPIDS
+ nlwp = pip->prstatus.pr_nlwp;
+ lwps = alloca ((2 * nlwp + 2) * sizeof (*lwps));
- printf_filtered ("\nInformation for %s:\n\n", pip -> pathname);
- if (summary || all || flags)
- {
- info_proc_flags (pip, summary);
- }
- if (summary || all)
+ if (ioctl (pip->ctl_fd, PIOCLWPIDS, lwps))
{
- info_proc_stop (pip, summary);
+ print_sys_errmsg (pip -> pathname, errno);
+ error ("PIOCLWPIDS failed");
}
- if (summary || all || signals || faults)
+#else /* PIOCLWPIDS */
+ nlwp = 1;
+ lwps = alloca ((2 * nlwp + 2) * sizeof *lwps);
+ lwps[0] = 0;
+#endif /* PIOCLWPIDS */
+
+ for (; nlwp > 0; nlwp--, lwps++)
{
- info_proc_siginfo (pip, summary);
+ pip = find_procinfo ((*lwps << 16) | pid, 1);
+
+ if (!pip)
+ {
+ pip = (struct procinfo *) xmalloc (sizeof (struct procinfo));
+ memset (pip, 0, sizeof (*pip));
+ if (!open_proc_file ((*lwps << 16) | pid, pip, O_RDONLY, 0))
+ continue;
+
+ make_cleanup (close_proc_file, pip);
+
+ if (!procfs_read_status (pip))
+ {
+ print_sys_errmsg (pip -> pathname, errno);
+ error ("procfs_read_status failed");
+ }
+ }
+
+#endif /* PROCFS_USE_READ_WRITE */
+
+ /* Print verbose information of the requested type(s), or just a summary
+ of the information for all types. */
+
+ printf_filtered ("\nInformation for %s.%d:\n\n", pip -> pathname, *lwps);
+ if (summary || all || flags)
+ {
+ info_proc_flags (pip, summary);
+ }
+ if (summary || all)
+ {
+ info_proc_stop (pip, summary);
+#ifdef UNIXWARE
+ supply_gregset (&pip->prstatus.pr_lwp.pr_context.uc_mcontext.gregs);
+#else
+ supply_gregset (&pip->prstatus.pr_reg);
+#endif
+ printf_filtered ("PC: ");
+ print_address (read_pc (), gdb_stdout);
+ printf_filtered ("\n");
+ }
+ if (summary || all || signals || faults)
+ {
+ info_proc_siginfo (pip, summary);
+ }
+ if (summary || all || syscalls)
+ {
+ info_proc_syscalls (pip, summary);
+ }
+ if (summary || all || mappings)
+ {
+ info_proc_mappings (pip, summary);
+ }
+ if (summary || all || signals)
+ {
+ info_proc_signals (pip, summary);
+ }
+ if (summary || all || faults)
+ {
+ info_proc_faults (pip, summary);
+ }
+ printf_filtered ("\n");
+
+ /* All done, deal with closing any temporary process info structure,
+ freeing temporary memory , etc. */
+
+ do_cleanups (old_chain);
+#ifndef PROCFS_USE_READ_WRITE
}
- if (summary || all || syscalls)
+#endif
+}
+
+/*
+
+LOCAL FUNCTION
+
+ modify_inherit_on_fork_flag - Change the inherit-on-fork flag
+
+SYNOPSIS
+
+ void modify_inherit_on_fork_flag (fd, flag)
+
+DESCRIPTION
+
+ Call this routine to modify the inherit-on-fork flag. This routine is
+ just a nice wrapper to hide the #ifdefs needed by various systems to
+ control this flag.
+
+ */
+
+static void
+modify_inherit_on_fork_flag (fd, flag)
+ int fd;
+ int flag;
+{
+#if defined (PIOCSET) || defined (PCSET)
+ long pr_flags;
+#endif
+ int retval = 0;
+ struct proc_ctl pctl;
+
+#if defined (PIOCSET) || defined (PCSET) /* New method */
+ pr_flags = PR_FORK;
+ if (flag)
{
- info_proc_syscalls (pip, summary);
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCSET;
+ pctl.data = PR_FORK;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCSET, &pr_flags);
+#endif
}
- if (summary || all || mappings)
+ else
{
- info_proc_mappings (pip, summary);
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCRESET;
+ pctl.data = PR_FORK;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCRESET, &pr_flags);
+#endif
}
- if (summary || all || signals)
+
+#else
+#ifdef PIOCSFORK /* Original method */
+ if (flag)
{
- info_proc_signals (pip, summary);
+ retval = ioctl (fd, PIOCSFORK, NULL);
}
- if (summary || all || faults)
+ else
{
- info_proc_faults (pip, summary);
+ retval = ioctl (fd, PIOCRFORK, NULL);
}
- printf_filtered ("\n");
+#else
+ Neither PR_FORK nor PIOCSFORK exist!!!
+#endif
+#endif
- /* All done, deal with closing any temporary process info structure,
- freeing temporary memory , etc. */
+ if (!retval)
+ return;
- do_cleanups (old_chain);
+ print_sys_errmsg ("modify_inherit_on_fork_flag", errno);
+ error ("PIOCSFORK or PR_FORK modification failed");
}
/*
LOCAL FUNCTION
- procfs_set_sproc_trap -- arrange for child to stop on sproc().
+ modify_run_on_last_close_flag - Change the run-on-last-close flag
SYNOPSIS
- void procfs_set_sproc_trap (struct procinfo *)
+ void modify_run_on_last_close_flag (fd, flag)
DESCRIPTION
- This function sets up a trap on sproc system call exits so that we can
- detect the arrival of a new thread. We are called with the new thread
- stopped prior to it's first instruction.
+ Call this routine to modify the run-on-last-close flag. This routine
+ is just a nice wrapper to hide the #ifdefs needed by various systems to
+ control this flag.
- Also note that we turn on the inherit-on-fork flag in the child process
- so that any grand-children start with all tracing flags set.
*/
-#ifdef SYS_sproc
+static void
+modify_run_on_last_close_flag (fd, flag)
+ int fd;
+ int flag;
+{
+#if defined (PIOCSET) || defined (PCSET)
+ long pr_flags;
+#endif
+ int retval = 0;
+ struct proc_ctl pctl;
+
+#if defined (PIOCSET) || defined (PCSET) /* New method */
+ pr_flags = PR_RLC;
+ if (flag)
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCSET;
+ pctl.data = PR_RLC;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCSET, &pr_flags);
+#endif
+ }
+ else
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCRESET;
+ pctl.data = PR_RLC;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCRESET, &pr_flags);
+#endif
+ }
+
+#else
+#ifdef PIOCSRLC /* Original method */
+ if (flag)
+ retval = ioctl (fd, PIOCSRLC, NULL);
+ else
+ retval = ioctl (fd, PIOCRRLC, NULL);
+#else
+ Neither PR_RLC nor PIOCSRLC exist!!!
+#endif
+#endif
+
+ if (!retval)
+ return;
+
+ print_sys_errmsg ("modify_run_on_last_close_flag", errno);
+ error ("PIOCSRLC or PR_RLC modification failed");
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_clear_syscall_trap -- Deletes the trap for the specified system call.
+
+SYNOPSIS
+
+ void procfs_clear_syscall_trap (struct procinfo *, int syscall_num, int errok)
+
+DESCRIPTION
+
+ This function function disables traps for the specified system call.
+ errok is non-zero if errors should be ignored.
+ */
static void
-procfs_set_sproc_trap (pi)
+procfs_clear_syscall_trap (pi, syscall_num, errok)
struct procinfo *pi;
+ int syscall_num;
+ int errok;
{
- sysset_t exitset;
-
- if (ioctl (pi->fd, PIOCGEXIT, &exitset) < 0)
+ sysset_t sysset;
+ int goterr, i;
+
+#ifndef UNIXWARE
+ goterr = ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0;
+
+ if (goterr && !errok)
{
print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCGENTRY failed");
+ }
+
+ if (!goterr)
+ {
+ prdelset (&sysset, syscall_num);
+
+ if ((ioctl (pi->ctl_fd, PIOCSENTRY, &sysset) < 0) && !errok)
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCSENTRY failed");
+ }
+ }
+
+ goterr = ioctl (pi->ctl_fd, PIOCGEXIT, &sysset) < 0;
+
+ if (goterr && !errok)
+ {
+ procfs_clear_syscall_trap (pi, syscall_num, 1);
+ print_sys_errmsg (pi->pathname, errno);
error ("PIOCGEXIT failed");
}
- praddset (&exitset, SYS_sproc);
+ if (!goterr)
+ {
+ praddset (&sysset, syscall_num);
- /* We trap on fork() and vfork() in order to disable debugging in our grand-
- children and descendant processes. At this time, GDB can only handle
- threads (multiple processes, one address space). forks (and execs) result
- in the creation of multiple address spaces, which GDB can't handle yet. */
+ if ((ioctl (pi->ctl_fd, PIOCSEXIT, &sysset) < 0) && !errok)
+ {
+ procfs_clear_syscall_trap (pi, syscall_num, 1);
+ print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCSEXIT failed");
+ }
+ }
+#endif
- praddset (&exitset, SYS_fork);
-#ifdef SYS_vfork
- praddset (&exitset, SYS_vfork);
+ if (!pi->syscall_handlers)
+ {
+ if (!errok)
+ error ("procfs_clear_syscall_trap: syscall_handlers is empty");
+ return;
+ }
+
+ /* Remove handler func from the handler list */
+
+ for (i = 0; i < pi->num_syscall_handlers; i++)
+ if (pi->syscall_handlers[i].syscall_num == syscall_num)
+ {
+ if (i + 1 != pi->num_syscall_handlers)
+ { /* Not the last entry.
+ Move subsequent entries fwd. */
+ memcpy (&pi->syscall_handlers[i], &pi->syscall_handlers[i + 1],
+ (pi->num_syscall_handlers - i - 1)
+ * sizeof (struct procfs_syscall_handler));
+ }
+
+ pi->syscall_handlers = xrealloc (pi->syscall_handlers,
+ (pi->num_syscall_handlers - 1)
+ * sizeof (struct procfs_syscall_handler));
+ pi->num_syscall_handlers--;
+ return;
+ }
+
+ if (!errok)
+ error ("procfs_clear_syscall_trap: Couldn't find handler for sys call %d",
+ syscall_num);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_set_syscall_trap -- arrange for a function to be called when the
+ child executes the specified system call.
+
+SYNOPSIS
+
+ void procfs_set_syscall_trap (struct procinfo *, int syscall_num, int flags,
+ syscall_func_t *function)
+
+DESCRIPTION
+
+ This function sets up an entry and/or exit trap for the specified system
+ call. When the child executes the specified system call, your function
+ will be called with the call #, a flag that indicates entry or exit, and
+ pointers to rtnval and statval (which are used by procfs_wait). The
+ function should return non-zero if something interesting happened, zero
+ otherwise.
+ */
+
+static void
+procfs_set_syscall_trap (pi, syscall_num, flags, func)
+ struct procinfo *pi;
+ int syscall_num;
+ int flags;
+ syscall_func_t *func;
+{
+ sysset_t sysset;
+
+#ifndef UNIXWARE
+ if (flags & PROCFS_SYSCALL_ENTRY)
+ {
+ if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0)
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCGENTRY failed");
+ }
+
+ praddset (&sysset, syscall_num);
+
+ if (ioctl (pi->ctl_fd, PIOCSENTRY, &sysset) < 0)
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCSENTRY failed");
+ }
+ }
+
+ if (flags & PROCFS_SYSCALL_EXIT)
+ {
+ if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysset) < 0)
+ {
+ procfs_clear_syscall_trap (pi, syscall_num, 1);
+ print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCGEXIT failed");
+ }
+
+ praddset (&sysset, syscall_num);
+
+ if (ioctl (pi->ctl_fd, PIOCSEXIT, &sysset) < 0)
+ {
+ procfs_clear_syscall_trap (pi, syscall_num, 1);
+ print_sys_errmsg (pi->pathname, errno);
+ error ("PIOCSEXIT failed");
+ }
+ }
#endif
- if (ioctl (pi->fd, PIOCSEXIT, &exitset) < 0)
+ if (!pi->syscall_handlers)
{
- print_sys_errmsg (pi->pathname, errno);
- error ("PIOCSEXIT failed");
+ pi->syscall_handlers = xmalloc (sizeof (struct procfs_syscall_handler));
+ pi->syscall_handlers[0].syscall_num = syscall_num;
+ pi->syscall_handlers[0].func = func;
+ pi->num_syscall_handlers = 1;
}
+ else
+ {
+ int i;
- /* Turn on inherit-on-fork flag so that all grand-children of gdb start with
- tracing flags set. */
+ for (i = 0; i < pi->num_syscall_handlers; i++)
+ if (pi->syscall_handlers[i].syscall_num == syscall_num)
+ {
+ pi->syscall_handlers[i].func = func;
+ return;
+ }
-#ifdef PIOCSET /* New method */
- {
- long pr_flags;
- pr_flags = PR_FORK;
- ioctl (pi->fd, PIOCSET, &pr_flags);
- }
+ pi->syscall_handlers = xrealloc (pi->syscall_handlers, (i + 1)
+ * sizeof (struct procfs_syscall_handler));
+ pi->syscall_handlers[i].syscall_num = syscall_num;
+ pi->syscall_handlers[i].func = func;
+ pi->num_syscall_handlers++;
+ }
+}
+
+#ifdef SYS_lwp_create
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_lwp_creation_handler - handle exit from the _lwp_create syscall
+
+SYNOPSIS
+
+ int procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
+
+DESCRIPTION
+
+ This routine is called both when an inferior process and it's new lwp
+ are about to finish a _lwp_create() system call. This is the system
+ call that Solaris uses to create a lightweight process. When the
+ target process gets this event, we can look at sysarg[2] to find the
+ new childs lwp ID, and create a procinfo struct from that. After that,
+ we pretend that we got a SIGTRAP, and return non-zero to tell
+ procfs_wait to wake up. Subsequently, wait_for_inferior gets woken up,
+ sees the new process and continues it.
+
+ When we see the child exiting from lwp_create, we just contine it,
+ since everything was handled when the parent trapped.
+
+NOTES
+ In effect, we are only paying attention to the parent's completion of
+ the lwp_create syscall. If we only paid attention to the child
+ instead, then we wouldn't detect the creation of a suspended thread.
+ */
+
+static int
+procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
+ struct procinfo *pi;
+ int syscall_num;
+ int why;
+ int *rtnvalp;
+ int *statvalp;
+{
+ int lwp_id;
+ struct procinfo *childpi;
+ struct proc_ctl pctl;
+
+ /* We've just detected the completion of an lwp_create system call. Now we
+ need to setup a procinfo struct for this thread, and notify the thread
+ system of the new arrival. */
+
+ /* If lwp_create failed, then nothing interesting happened. Continue the
+ process and go back to sleep. */
+
+#ifdef UNIXWARE
+ /* Joel ... can you check this logic out please? JKJ */
+ if (pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs[R_EFL] & 1)
+ { /* _lwp_create failed */
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+
+ if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ perror_with_name (pi->pathname);
+
+ return 0;
+ }
+#else /* UNIXWARE */
+ if (PROCFS_GET_CARRY (pi->prstatus.pr_reg))
+ { /* _lwp_create failed */
+ pi->prrun.pr_flags &= PRSTEP;
+ pi->prrun.pr_flags |= PRCFAULT;
+
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+ perror_with_name (pi->pathname);
+
+ return 0;
+ }
+#endif
+
+ /* At this point, the new thread is stopped at it's first instruction, and
+ the parent is stopped at the exit from lwp_create. */
+
+ if (pi->new_child) /* Child? */
+ { /* Yes, just continue it */
+#ifdef UNIXWARE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+
+ if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else /* !UNIXWARE */
+ pi->prrun.pr_flags &= PRSTEP;
+ pi->prrun.pr_flags |= PRCFAULT;
+
+ if ((pi->prstatus.pr_flags & PR_ISTOP)
+ && ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif /* !UNIXWARE */
+ perror_with_name (pi->pathname);
+
+ pi->new_child = 0; /* No longer new */
+
+ return 0;
+ }
+
+ /* We're the proud parent of a new thread. Setup an exit trap for lwp_create
+ in the child and continue the parent. */
+
+ /* Third arg is pointer to new thread id. */
+ lwp_id = read_memory_integer (
+ THE_PR_LWP(pi->prstatus).pr_sysarg[2], sizeof (int));
+
+ lwp_id = (lwp_id << 16) | PIDGET (pi->pid);
+
+ childpi = create_procinfo (lwp_id);
+
+ /* The new process has actually inherited the lwp_create syscall trap from
+ it's parent, but we still have to call this to register handlers for
+ that child. */
+
+ procfs_set_inferior_syscall_traps (childpi);
+ add_thread (lwp_id);
+ printf_filtered ("[New %s]\n", target_pid_to_str (lwp_id));
+
+ /* Continue the parent */
+#ifdef UNIXWARE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+
+ if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
#else
-#ifdef PIOCSFORK /* Original method */
- ioctl (pi->fd, PIOCSFORK, NULL);
+ pi->prrun.pr_flags &= PRSTEP;
+ pi->prrun.pr_flags |= PRCFAULT;
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
#endif
+ perror_with_name (pi->pathname);
+
+ /* The new child may have been created in one of two states:
+ SUSPENDED or RUNNABLE. If runnable, we will simply signal it to run.
+ If suspended, we flag it to be continued later, when it has an event. */
+
+ if (THE_PR_LWP(childpi->prstatus).pr_why == PR_SUSPENDED)
+ childpi->new_child = 1; /* Flag this as an unseen child process */
+ else
+ {
+ /* Continue the child */
+#ifdef UNIXWARE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+
+ if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else
+ childpi->prrun.pr_flags &= PRSTEP;
+ childpi->prrun.pr_flags |= PRCFAULT;
+
+ if (ioctl (childpi->ctl_fd, PIOCRUN, &childpi->prrun) != 0)
#endif
+ perror_with_name (childpi->pathname);
+ }
+ return 0;
}
-#endif /* SYS_sproc */
+#endif /* SYS_lwp_create */
/* Fork an inferior process, and start debugging it with /proc. */
@@ -3626,17 +5514,11 @@ procfs_create_inferior (exec_file, allargs, env)
}
fork_inferior (exec_file, allargs, env,
- proc_set_exec_trap, procfs_init_inferior, shell_file);
+ proc_set_exec_trap, procfs_init_inferior, NULL, shell_file);
/* We are at the first instruction we care about. */
/* Pedal to the metal... */
- /* Setup traps on exit from sproc() */
-
-#ifdef SYS_sproc
- procfs_set_sproc_trap (current_procinfo);
-#endif
-
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}
@@ -3663,9 +5545,14 @@ procfs_mourn_inferior ()
static int
procfs_can_run ()
{
- return(1);
+ /* This variable is controlled by modules that sit atop procfs that may layer
+ their own process structure atop that provided here. sol-thread.c does
+ this because of the Solaris two-level thread model. */
+
+ return !procfs_suppress_run;
}
#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
+#ifndef UNIXWARE
/* Insert a watchpoint */
int
@@ -3682,7 +5569,7 @@ procfs_set_watchpoint(pid, addr, len, rw)
wpt.pr_vaddr = (caddr_t)addr;
wpt.pr_size = len;
wpt.pr_wflags = ((rw & 1) ? MA_READ : 0) | ((rw & 2) ? MA_WRITE : 0);
- if (ioctl (pi->fd, PIOCSWATCH, &wpt) < 0)
+ if (ioctl (pi->ctl_fd, PIOCSWATCH, &wpt) < 0)
{
if (errno == E2BIG)
return -1;
@@ -3725,7 +5612,57 @@ procfs_stopped_by_watchpoint(pid)
}
return 0;
}
-#endif
+#endif /* !UNIXWARE */
+#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
+
+/* Why is this necessary? Shouldn't dead threads just be removed from the
+ thread database? */
+
+static int
+procfs_thread_alive (pid)
+ int pid;
+{
+ struct procinfo *pi, *next_pi;
+
+ for (pi = procinfo_list; pi; pi = next_pi)
+ {
+ next_pi = pi->next;
+ if (pi -> pid == pid)
+ if (procfs_read_status (pi)) /* alive */
+ return 1;
+ else /* defunct (exited) */
+ {
+ close_proc_file (pi);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+int
+procfs_first_available ()
+{
+ struct procinfo *pi;
+
+ for (pi = procinfo_list; pi; pi = pi->next)
+ {
+ if (procfs_read_status (pi))
+ return pi->pid;
+ }
+ return -1;
+}
+
+int
+procfs_get_pid_fd (pid)
+ int pid;
+{
+ struct procinfo *pi = find_procinfo (pid, 1);
+
+ if (pi == NULL)
+ return -1;
+
+ return pi->ctl_fd;
+}
/* Send a SIGINT to the process group. This acts just like the user typed a
^C on the controlling terminal.
@@ -3733,77 +5670,89 @@ procfs_stopped_by_watchpoint(pid)
XXX - This may not be correct for all systems. Some may want to use
killpg() instead of kill (-pgrp). */
-void
+static void
procfs_stop ()
{
extern pid_t inferior_process_group;
kill (-inferior_process_group, SIGINT);
}
+
+/* Convert a pid to printable form. */
+
+#ifdef TIDGET
+char *
+procfs_pid_to_str (pid)
+ int pid;
+{
+ static char buf[100];
+
+ sprintf (buf, "Kernel thread %d", TIDGET (pid));
+
+ return buf;
+}
+#endif /* TIDGET */
-struct target_ops procfs_ops = {
- "procfs", /* to_shortname */
- "Unix /proc child process", /* to_longname */
- "Unix /proc child process (started by the \"run\" command).", /* to_doc */
- procfs_open, /* to_open */
- 0, /* to_close */
- procfs_attach, /* to_attach */
- procfs_detach, /* to_detach */
- procfs_resume, /* to_resume */
- procfs_wait, /* to_wait */
- procfs_fetch_registers, /* to_fetch_registers */
- procfs_store_registers, /* to_store_registers */
- procfs_prepare_to_store, /* to_prepare_to_store */
- procfs_xfer_memory, /* to_xfer_memory */
- procfs_files_info, /* to_files_info */
- memory_insert_breakpoint, /* to_insert_breakpoint */
- memory_remove_breakpoint, /* to_remove_breakpoint */
- terminal_init_inferior, /* to_terminal_init */
- terminal_inferior, /* to_terminal_inferior */
- terminal_ours_for_output, /* to_terminal_ours_for_output */
- terminal_ours, /* to_terminal_ours */
- child_terminal_info, /* to_terminal_info */
- procfs_kill_inferior, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- procfs_create_inferior, /* to_create_inferior */
- procfs_mourn_inferior, /* to_mourn_inferior */
- procfs_can_run, /* to_can_run */
- procfs_notice_signals, /* to_notice_signals */
- 0, /* to_thread_alive */
- procfs_stop, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+static void
+init_procfs_ops ()
+{
+ procfs_ops.to_shortname = "procfs";
+ procfs_ops.to_longname = "Unix /proc child process";
+ procfs_ops.to_doc = "Unix /proc child process (started by the \"run\" command).";
+ procfs_ops.to_open = procfs_open;
+ procfs_ops.to_attach = procfs_attach;
+ procfs_ops.to_detach = procfs_detach;
+ procfs_ops.to_resume = procfs_resume;
+ procfs_ops.to_wait = procfs_wait;
+ procfs_ops.to_fetch_registers = procfs_fetch_registers;
+ procfs_ops.to_store_registers = procfs_store_registers;
+ procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
+ procfs_ops.to_xfer_memory = procfs_xfer_memory;
+ procfs_ops.to_files_info = procfs_files_info;
+ procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ procfs_ops.to_terminal_init = terminal_init_inferior;
+ procfs_ops.to_terminal_inferior = terminal_inferior;
+ procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ procfs_ops.to_terminal_ours = terminal_ours;
+ procfs_ops.to_terminal_info = child_terminal_info;
+ procfs_ops.to_kill = procfs_kill_inferior;
+ procfs_ops.to_create_inferior = procfs_create_inferior;
+ procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
+ procfs_ops.to_can_run = procfs_can_run;
+ procfs_ops.to_notice_signals = procfs_notice_signals;
+ procfs_ops.to_thread_alive = procfs_thread_alive;
+ procfs_ops.to_stop = procfs_stop;
+ procfs_ops.to_stratum = process_stratum;
+ procfs_ops.to_has_all_memory = 1;
+ procfs_ops.to_has_memory = 1;
+ procfs_ops.to_has_stack = 1;
+ procfs_ops.to_has_registers = 1;
+ procfs_ops.to_has_execution = 1;
+ procfs_ops.to_magic = OPS_MAGIC;
+}
void
_initialize_procfs ()
{
#ifdef HAVE_OPTIONAL_PROC_FS
- char procname[32];
+ char procname[MAX_PROC_NAME_SIZE];
int fd;
/* If we have an optional /proc filesystem (e.g. under OSF/1),
don't add procfs support if we cannot access the running
GDB via /proc. */
- sprintf (procname, PROC_NAME_FMT, getpid ());
+ sprintf (procname, STATUS_PROC_NAME_FMT, getpid ());
if ((fd = open (procname, O_RDONLY)) < 0)
return;
close (fd);
#endif
+ init_procfs_ops ();
add_target (&procfs_ops);
- add_info ("proc", info_proc,
+ add_info ("processes", info_proc,
"Show process status information using /proc entry.\n\
Specify process id or use current inferior by default.\n\
Specify keywords for detailed information; default is summary.\n\
diff --git a/contrib/gdb/gdb/pyr-tdep.c b/contrib/gdb/gdb/pyr-tdep.c
index b9abc0f..85e9a07 100644
--- a/contrib/gdb/gdb/pyr-tdep.c
+++ b/contrib/gdb/gdb/pyr-tdep.c
@@ -31,10 +31,10 @@ pyr_print_registers(reg_buf, regnum)
for (regno = 0; regno < 16; regno++) {
printf_unfiltered/*_filtered*/ ("%6.6s: %8x %6.6s: %8x %6s: %8x %6s: %8x\n",
- reg_names[regno], reg_buf[regno],
- reg_names[regno+16], reg_buf[regno+16],
- reg_names[regno+32], reg_buf[regno+32],
- reg_names[regno+48], reg_buf[regno+48]);
+ REGISTER_NAME (regno), reg_buf[regno],
+ REGISTER_NAME (regno+16), reg_buf[regno+16],
+ REGISTER_NAME (regno+32), reg_buf[regno+32],
+ REGISTER_NAME (regno+48), reg_buf[regno+48]);
}
usp = ptrace (3, inferior_pid,
(PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_usp) -
@@ -43,8 +43,8 @@ pyr_print_registers(reg_buf, regnum)
(PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_ksp) -
((char *)&u), 0);
printf_unfiltered/*_filtered*/ ("\n%6.6s: %8x %6.6s: %8x (%08x) %6.6s %8x\n",
- reg_names[CSP_REGNUM],reg_buf[CSP_REGNUM],
- reg_names[KSP_REGNUM], reg_buf[KSP_REGNUM], ksp,
+ REGISTER_NAME (CSP_REGNUM),reg_buf[CSP_REGNUM],
+ REGISTER_NAME (KSP_REGNUM), reg_buf[KSP_REGNUM], ksp,
"usp", usp);
}
@@ -70,9 +70,9 @@ pyr_do_registers_info (regnum, fpregs)
if (i == regnum) {
long val = raw_regs[i];
- fputs_filtered (reg_names[i], stdout);
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
printf_filtered(":");
- print_spaces_filtered (6 - strlen (reg_names[i]), stdout);
+ print_spaces_filtered (6 - strlen (REGISTER_NAME (i)), gdb_stdout);
if (val == 0)
printf_filtered ("0");
else
@@ -89,10 +89,10 @@ CORE_ADDR frame_locals_address (frame)
register int addr = find_saved_register (frame,CFP_REGNUM);
register int result = read_memory_integer (addr, 4);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
- fprintf_unfiltered (stderr,
+ fprintf_unfiltered (gdb_stderr,
"\t[[..frame_locals:%8x, %s= %x @%x fcfp= %x foo= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
frame->frame,
- reg_names[CFP_REGNUM],
+ REGISTER_NAME (CFP_REGNUM),
result, addr,
frame->frame_cfp, (CFP_REGNUM),
@@ -115,10 +115,10 @@ CORE_ADDR frame_args_addr (frame)
register int result = read_memory_integer (addr, 4);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
- fprintf_unfiltered (stderr,
+ fprintf_unfiltered (gdb_stderr,
"\t[[..frame_args:%8x, %s= %x @%x fcfp= %x r_r= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
frame->frame,
- reg_names[CFP_REGNUM],
+ REGISTER_NAME (CFP_REGNUM),
result, addr,
frame->frame_cfp, read_register(CFP_REGNUM),
@@ -184,7 +184,7 @@ CORE_ADDR pyr_saved_pc(frame)
int
pyr_print_insn (memaddr, stream)
CORE_ADDR memaddr;
- FILE *stream;
+ GDB_FILE *stream;
{
unsigned char buffer[MAXLEN];
register int i, nargs, insn_size =4;
@@ -265,14 +265,14 @@ pyr_print_insn (memaddr, stream)
switch (operand_mode) {
case 0:
fprintf_unfiltered (stream, "%s,%s",
- reg_names [op_1_regno],
- reg_names [op_2_regno]);
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno));
break;
case 1:
fprintf_unfiltered (stream, " 0x%0x,%s",
op_1_regno,
- reg_names [op_2_regno]);
+ REGISTER_NAME (op_2_regno));
break;
case 2:
@@ -281,12 +281,12 @@ pyr_print_insn (memaddr, stream)
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream, " $0x%0x,%s",
extra_1,
- reg_names [op_2_regno]);
+ REGISTER_NAME (op_2_regno));
break;
case 3:
fprintf_unfiltered (stream, " (%s),%s",
- reg_names [op_1_regno],
- reg_names [op_2_regno]);
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno));
break;
case 4:
@@ -295,17 +295,17 @@ pyr_print_insn (memaddr, stream)
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream, " 0x%0x(%s),%s",
extra_1,
- reg_names [op_1_regno],
- reg_names [op_2_regno]);
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno));
break;
/* S1 destination mode */
case 5:
fprintf_unfiltered (stream,
((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
- reg_names [op_1_regno],
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
@@ -314,8 +314,8 @@ pyr_print_insn (memaddr, stream)
((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
: " $%#0x,(%s)"),
op_1_regno,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
@@ -327,17 +327,17 @@ pyr_print_insn (memaddr, stream)
((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
: " $%#0x,(%s)"),
extra_1,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 8:
fprintf_unfiltered (stream,
((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
- reg_names [op_1_regno],
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
@@ -350,9 +350,9 @@ pyr_print_insn (memaddr, stream)
? "%#0x(%s),(%s)[%s*%1d]"
: "%#0x(%s),(%s)"),
extra_1,
- reg_names [op_1_regno],
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
@@ -363,10 +363,10 @@ pyr_print_insn (memaddr, stream)
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
- reg_names [op_1_regno],
+ REGISTER_NAME (op_1_regno),
extra_1,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 11:
@@ -378,8 +378,8 @@ pyr_print_insn (memaddr, stream)
" $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
op_1_regno,
extra_1,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 12:
@@ -394,8 +394,8 @@ pyr_print_insn (memaddr, stream)
" $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
extra_1,
extra_2,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
@@ -407,10 +407,10 @@ pyr_print_insn (memaddr, stream)
((index_reg_regno)
? " (%s),%#0x(%s)[%s*%1d]"
: " (%s),%#0x(%s)"),
- reg_names [op_1_regno],
+ REGISTER_NAME (op_1_regno),
extra_1,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 14:
@@ -424,19 +424,19 @@ pyr_print_insn (memaddr, stream)
((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
: "%#0x(%s),%#0x(%s) "),
extra_1,
- reg_names [op_1_regno],
+ REGISTER_NAME (op_1_regno),
extra_2,
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
default:
fprintf_unfiltered (stream,
((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
- reg_names [op_1_regno],
- reg_names [op_2_regno],
- reg_names [index_reg_regno],
+ REGISTER_NAME (op_1_regno),
+ REGISTER_NAME (op_2_regno),
+ REGISTER_NAME (index_reg_regno),
index_multiplier);
fprintf_unfiltered (stream,
"\t\t# unknown mode in %08x",
diff --git a/contrib/gdb/gdb/pyr-xdep.c b/contrib/gdb/gdb/pyr-xdep.c
index e205b50..dd6d9a9 100644
--- a/contrib/gdb/gdb/pyr-xdep.c
+++ b/contrib/gdb/gdb/pyr-xdep.c
@@ -50,13 +50,13 @@ fetch_inferior_registers (regno)
#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
printf_unfiltered ("Fetching register %s, got %0x\n",
- reg_names[regno],
+ REGISTER_NAME (regno),
reg_buf[regno]);
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
if (reg_buf[regno] == -1 && errno == EIO) {
printf_unfiltered("fetch_interior_registers: fetching register %s\n",
- reg_names[regno]);
+ REGISTER_NAME (regno));
errno = 0;
}
supply_register (regno, reg_buf+regno);
@@ -115,7 +115,7 @@ fetch_inferior_registers (regno)
supply_register(CSP_REGNUM, reg_buf+CSP_REGNUM);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
if (skipped_frames) {
- fprintf_unfiltered (stderr,
+ fprintf_unfiltered (gdb_stderr,
"skipped %d frames from %x to %x; cfp was %x, now %x\n",
skipped_frames, reg_buf[CSP_REGNUM]);
}
@@ -321,10 +321,10 @@ core_file_command (filename, from_tty)
if (val < 0
|| (val = myread (corechan, buf, sizeof buf)) < 0)
{
- char * buffer = (char *) alloca (strlen (reg_names[regno])
+ char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno))
+ 30);
strcpy (buffer, "Reading register ");
- strcat (buffer, reg_names[regno]);
+ strcat (buffer, REGISTER_NAME (regno));
perror_with_name (buffer);
}
@@ -333,7 +333,7 @@ core_file_command (filename, from_tty)
perror_with_name (filename);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
printf_unfiltered ("[reg %s(%d), offset in file %s=0x%0x, addr =0x%0x, =%0x]\n",
- reg_names[regno], regno, filename,
+ REGISTER_NAME (regno), regno, filename,
register_addr(regno, reg_offset),
regno * 4 + last_frame_address,
*((int *)buf));
diff --git a/contrib/gdb/gdb/remote-adapt.c b/contrib/gdb/gdb/remote-adapt.c
index 8fcb1f7..b22f180 100644
--- a/contrib/gdb/gdb/remote-adapt.c
+++ b/contrib/gdb/gdb/remote-adapt.c
@@ -29,6 +29,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
o - I can't get 19200 baud rate to work.
7/91 o - Freeze mode tracing can be done on a 29050. */
+
+
#include "defs.h"
#include "gdb_string.h"
#include "inferior.h"
@@ -42,6 +44,40 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "target.h"
#include "gdbcore.h"
+/* This processor is getting rusty but I am trying to keep it
+ up to date at least with data structure changes.
+ Activate this block to compile just this file.
+ */
+#define COMPILE_CHECK 0
+#if COMPILE_CHECK
+#define Q_REGNUM 0
+#define VAB_REGNUM 0
+#define CPS_REGNUM 0
+#define IPA_REGNUM 0
+#define IPB_REGNUM 0
+#define GR1_REGNUM 0
+#define LR0_REGNUM 0
+#define IPC_REGNUM 0
+#define CR_REGNUM 0
+#define BP_REGNUM 0
+#define FC_REGNUM 0
+#define INTE_REGNUM 0
+#define EXO_REGNUM 0
+#define GR96_REGNUM 0
+#define NPC_REGNUM
+#define FPE_REGNUM 0
+#define PC2_REGNUM 0
+#define FPS_REGNUM 0
+#define ALU_REGNUM 0
+#define LRU_REGNUM 0
+#define TERMINAL int
+#define RAW 1
+#define ANYP 1
+extern int a29k_freeze_mode ;
+extern int processor_type ;
+extern char * processor_name ;
+#endif
+
/* External data declarations */
extern int stop_soon_quietly; /* for wait_for_inferior */
@@ -85,6 +121,7 @@ rawmode(desc, turnon)
int desc;
int turnon;
{
+
TERMINAL sg;
if (desc < 0)
@@ -377,7 +414,7 @@ adapt_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote adapt process.");
if (execfile == 0 || exec_bfd == 0)
- error ("No exec file specified");
+ error ("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -511,6 +548,7 @@ the baud rate, and the name of the program to run on the remote system.");
if (adapt_desc < 0)
perror_with_name (dev_name);
ioctl (adapt_desc, TIOCGETP, &sg);
+#if ! defined(COMPILE_CHECK)
#ifdef HAVE_TERMIO
sg.c_cc[VMIN] = 0; /* read with timeout. */
sg.c_cc[VTIME] = timeout * 10;
@@ -525,7 +563,7 @@ the baud rate, and the name of the program to run on the remote system.");
ioctl (adapt_desc, TIOCSETP, &sg);
adapt_stream = fdopen (adapt_desc, "r+");
-
+#endif /* compile_check */
push_target (&adapt_ops);
#ifndef HAVE_TERMIO
@@ -566,7 +604,7 @@ the baud rate, and the name of the program to run on the remote system.");
printf_filtered("Remote debugging using virtual addresses works only\n");
printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n");
if (processor_type != a29k_freeze_mode) {
- fprintf_filtered(stderr,
+ fprintf_filtered(gdb_stderr,
"Freeze-mode debugging not available, and can only be done on an A29050.\n");
}
}
@@ -1200,7 +1238,7 @@ char *save; /* Throw away, let adapt save instructions */
expect_prompt ();
return(0); /* Success */
} else {
- fprintf_filtered(stderr,
+ fprintf_filtered(gdb_stderr,
"Too many break points, break point not installed\n");
return(1); /* Failure */
}
@@ -1325,34 +1363,80 @@ adapt_com (args, fromtty)
/* Define the target subroutine names */
-struct target_ops adapt_ops = {
- "adapt", "Remote AMD `Adapt' target",
- "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232",
- adapt_open, adapt_close,
- adapt_attach, adapt_detach, adapt_resume, adapt_wait,
- adapt_fetch_register, adapt_store_register,
- adapt_prepare_to_store,
- adapt_xfer_inferior_memory,
- adapt_files_info,
- adapt_insert_breakpoint, adapt_remove_breakpoint, /* Breakpoints */
- 0, 0, 0, 0, 0, /* Terminal handling */
- adapt_kill, /* FIXME, kill */
- adapt_load,
- 0, /* lookup_symbol */
- adapt_create_inferior, /* create_inferior */
- adapt_mourn, /* mourn_inferior FIXME */
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_stop */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0,0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
-};
+struct target_ops adapt_ops ;
+
+static void
+init_adapt_ops(void)
+{
+ adapt_ops.to_shortname = "adapt";
+ adapt_ops.to_longname = "Remote AMD `Adapt' target";
+ adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
+ adapt_ops.to_open = adapt_open;
+ adapt_ops.to_close = adapt_close;
+ adapt_ops.to_attach = adapt_attach;
+ adapt_ops.to_post_attach = NULL;
+ adapt_ops.to_require_attach = NULL;
+ adapt_ops.to_detach = adapt_detach;
+ adapt_ops.to_require_detach = NULL;
+ adapt_ops.to_resume = adapt_resume;
+ adapt_ops.to_wait = adapt_wait;
+ adapt_ops.to_post_wait = NULL;
+ adapt_ops.to_fetch_registers = adapt_fetch_register;
+ adapt_ops.to_store_registers = adapt_store_register;
+ adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
+ adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
+ adapt_ops.to_files_info = adapt_files_info;
+ adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
+ adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint;
+ adapt_ops.to_terminal_init = 0;
+ adapt_ops.to_terminal_inferior = 0;
+ adapt_ops.to_terminal_ours_for_output = 0;
+ adapt_ops.to_terminal_ours = 0;
+ adapt_ops.to_terminal_info = 0;
+ adapt_ops.to_kill = adapt_kill;
+ adapt_ops.to_load = adapt_load;
+ adapt_ops.to_lookup_symbol = 0;
+ adapt_ops.to_create_inferior = adapt_create_inferior;
+ adapt_ops.to_post_startup_inferior = NULL;
+ adapt_ops.to_acknowledge_created_inferior = NULL;
+ adapt_ops.to_clone_and_follow_inferior = NULL;
+ adapt_ops.to_post_follow_inferior_by_clone = NULL;
+ adapt_ops.to_insert_fork_catchpoint = NULL;
+ adapt_ops.to_remove_fork_catchpoint = NULL;
+ adapt_ops.to_insert_vfork_catchpoint = NULL;
+ adapt_ops.to_remove_vfork_catchpoint = NULL;
+ adapt_ops.to_has_forked = NULL;
+ adapt_ops.to_has_vforked = NULL;
+ adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ adapt_ops.to_post_follow_vfork = NULL;
+ adapt_ops.to_insert_exec_catchpoint = NULL;
+ adapt_ops.to_remove_exec_catchpoint = NULL;
+ adapt_ops.to_has_execd = NULL;
+ adapt_ops.to_reported_exec_events_per_exec_call = NULL;
+ adapt_ops.to_has_exited = NULL;
+ adapt_ops.to_mourn_inferior = adapt_mourn;
+ adapt_ops.to_can_run = 0;
+ adapt_ops.to_notice_signals = 0;
+ adapt_ops.to_thread_alive = 0;
+ adapt_ops.to_stop = 0 ; /* process_stratum; */
+ adapt_ops.to_pid_to_exec_file = NULL;
+ adapt_ops.to_core_file_to_sym_file = NULL;
+ adapt_ops.to_stratum = 0;
+ adapt_ops.DONT_USE = 0 ;
+ adapt_ops.to_has_all_memory = 1;
+ adapt_ops.to_has_memory = 1;
+ adapt_ops.to_has_stack = 1;
+ adapt_ops.to_has_registers = 1;
+ adapt_ops.to_has_execution = 0;
+ adapt_ops.to_sections = 0;
+ adapt_ops.to_sections_end = 0 ;
+ adapt_ops.to_magic = OPS_MAGIC;
+} /* init_adapt_ops */
void
_initialize_remote_adapt ()
{
+ init_adapt_ops() ;
add_target (&adapt_ops);
add_com ("adapt <command>", class_obscure, adapt_com,
"Send a command to the AMD Adapt remote monitor.");
diff --git a/contrib/gdb/gdb/remote-array.c b/contrib/gdb/gdb/remote-array.c
index 0ed84ca..624871c 100644
--- a/contrib/gdb/gdb/remote-array.c
+++ b/contrib/gdb/gdb/remote-array.c
@@ -1,5 +1,5 @@
/* Remote debugging interface for Array Tech RAID controller..
- Copyright 90, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright 90, 91, 92, 93, 94, 1995, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
This module talks to a debug monitor called 'MONITOR', which
@@ -33,6 +33,7 @@
#else
#include <varargs.h>
#endif
+#include <ctype.h>
#include <signal.h>
#include <sys/types.h>
#include "gdb_string.h"
@@ -89,7 +90,7 @@ static int from_hex();
static int array_send_packet();
static int array_get_packet();
static unsigned long ascii2hexword();
-static char *hexword2ascii();
+static void hexword2ascii();
extern char *version;
@@ -121,50 +122,77 @@ serial_t array_desc = NULL;
extern char *tmp_mips_processor_type;
extern int mips_set_processor_type();
-static struct target_ops array_ops = {
- "array", /* to_shortname */
- /* to_longname */
- "Debug using the standard GDB remote protocol for the Array Tech target.",
- /* to_doc */
- "Debug using the standard GDB remote protocol for the Array Tech target.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
- array_open, /* to_open */
- array_close, /* to_close */
- NULL, /* to_attach */
- array_detach, /* to_detach */
- array_resume, /* to_resume */
- array_wait, /* to_wait */
- array_fetch_registers, /* to_fetch_registers */
- array_store_registers, /* to_store_registers */
- array_prepare_to_store, /* to_prepare_to_store */
- array_xfer_memory, /* to_xfer_memory */
- array_files_info, /* to_files_info */
- array_insert_breakpoint, /* to_insert_breakpoint */
- array_remove_breakpoint, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- array_kill, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- array_create_inferior, /* to_create_inferior */
- array_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC /* to_magic */
+static struct target_ops array_ops ;
+
+static void
+init_array_ops(void)
+{
+ array_ops.to_shortname = "array";
+ array_ops.to_longname =
+ "Debug using the standard GDB remote protocol for the Array Tech target.",
+ array_ops.to_doc =
+ "Debug using the standard GDB remote protocol for the Array Tech target.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya)." ;
+ array_ops.to_open = array_open;
+ array_ops.to_close = array_close;
+ array_ops.to_attach = NULL;
+ array_ops.to_post_attach = NULL;
+ array_ops.to_require_attach = NULL;
+ array_ops.to_detach = array_detach;
+ array_ops.to_require_detach = NULL;
+ array_ops.to_resume = array_resume;
+ array_ops.to_wait = array_wait;
+ array_ops.to_post_wait = NULL;
+ array_ops.to_fetch_registers = array_fetch_registers;
+ array_ops.to_store_registers = array_store_registers;
+ array_ops.to_prepare_to_store = array_prepare_to_store;
+ array_ops.to_xfer_memory = array_xfer_memory;
+ array_ops.to_files_info = array_files_info;
+ array_ops.to_insert_breakpoint = array_insert_breakpoint;
+ array_ops.to_remove_breakpoint = array_remove_breakpoint;
+ array_ops.to_terminal_init = 0;
+ array_ops.to_terminal_inferior = 0;
+ array_ops.to_terminal_ours_for_output = 0;
+ array_ops.to_terminal_ours = 0;
+ array_ops.to_terminal_info = 0;
+ array_ops.to_kill = array_kill;
+ array_ops.to_load = 0;
+ array_ops.to_lookup_symbol = 0;
+ array_ops.to_create_inferior = array_create_inferior;
+ array_ops.to_post_startup_inferior = NULL;
+ array_ops.to_acknowledge_created_inferior = NULL;
+ array_ops.to_clone_and_follow_inferior = NULL;
+ array_ops.to_post_follow_inferior_by_clone = NULL;
+ array_ops.to_insert_fork_catchpoint = NULL;
+ array_ops.to_remove_fork_catchpoint = NULL;
+ array_ops.to_insert_vfork_catchpoint = NULL;
+ array_ops.to_remove_vfork_catchpoint = NULL;
+ array_ops.to_has_forked = NULL;
+ array_ops.to_has_vforked = NULL;
+ array_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ array_ops.to_post_follow_vfork = NULL;
+ array_ops.to_insert_exec_catchpoint = NULL;
+ array_ops.to_remove_exec_catchpoint = NULL;
+ array_ops.to_has_execd = NULL;
+ array_ops.to_reported_exec_events_per_exec_call = NULL;
+ array_ops.to_has_exited = NULL;
+ array_ops.to_mourn_inferior = array_mourn_inferior;
+ array_ops.to_can_run = 0;
+ array_ops.to_notice_signals = 0;
+ array_ops.to_thread_alive = 0;
+ array_ops.to_stop = 0;
+ array_ops.to_pid_to_exec_file = NULL;
+ array_ops.to_core_file_to_sym_file = NULL;
+ array_ops.to_stratum = process_stratum;
+ array_ops.DONT_USE = 0;
+ array_ops.to_has_all_memory = 1;
+ array_ops.to_has_memory = 1;
+ array_ops.to_has_stack = 1;
+ array_ops.to_has_registers = 1;
+ array_ops.to_has_execution = 1;
+ array_ops.to_sections = 0;
+ array_ops.to_sections_end = 0;
+ array_ops.to_magic = OPS_MAGIC;
};
/*
@@ -527,7 +555,7 @@ array_create_inferior (execfile, args, env)
error("Can't pass arguments to remote MONITOR process");
if (execfile == 0 || exec_bfd == 0)
- error("No exec file specified");
+ error("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -599,9 +627,9 @@ array_open(args, name, from_tty)
log_file = fopen (LOG_FILE, "w");
if (log_file == NULL)
perror_with_name (LOG_FILE);
- fprintf_filtered (log_file, "GDB %s (%s", version);
- fprintf_filtered (log_file, " --target %s)\n", array_ops.to_shortname);
- fprintf_filtered (log_file, "Remote target %s connected to %s\n\n", array_ops.to_shortname, dev_name);
+ fprintf (log_file, "GDB %s (%s", version);
+ fprintf (log_file, " --target %s)\n", array_ops.to_shortname);
+ fprintf (log_file, "Remote target %s connected to %s\n\n", array_ops.to_shortname, dev_name);
#endif
/* see if the target is alive. For a ROM monitor, we can just try to force the
@@ -727,7 +755,7 @@ array_wait (pid, status)
timeout = 0; /* Don't time out -- user program is running. */
-#if !defined(__GO32__) && !defined(__MSDOS__) && !defined(__WIN32__)
+#if !defined(__GO32__) && !defined(__MSDOS__) && !defined(_WIN32)
tty_desc = SERIAL_FDOPEN (0);
ttystate = SERIAL_GET_TTY_STATE (tty_desc);
SERIAL_RAW (tty_desc);
@@ -746,7 +774,7 @@ array_wait (pid, status)
i = 0;
}
fputc_unfiltered (c, gdb_stdout);
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
c = SERIAL_READCHAR(tty_desc, timeout);
if (c > 0) {
@@ -756,7 +784,7 @@ array_wait (pid, status)
break;
#if 0
fputc_unfiltered (c, gdb_stdout);
- fflush (stdout);
+ gdb_flush (gdb_stdout);
#endif
}
}
@@ -1047,7 +1075,6 @@ array_mourn_inferior ()
#define MAX_ARRAY_BREAKPOINTS 16
-extern int memory_breakpoint_size;
static CORE_ADDR breakaddr[MAX_ARRAY_BREAKPOINTS] = {0};
/*
@@ -1059,15 +1086,18 @@ array_insert_breakpoint (addr, shadow)
char *shadow;
{
int i;
+ int bp_size = 0;
+ CORE_ADDR bp_addr = addr;
debuglogs (1, "array_insert_breakpoint() addr = 0x%x", addr);
+ BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
for (i = 0; i <= MAX_ARRAY_BREAKPOINTS; i++) {
if (breakaddr[i] == 0) {
breakaddr[i] = addr;
if (sr_get_debug() > 4)
printf ("Breakpoint at %x\n", addr);
- array_read_inferior_memory(addr, shadow, memory_breakpoint_size);
+ array_read_inferior_memory (bp_addr, shadow, bp_size);
printf_monitor("b 0x%x\n", addr);
expect_prompt(1);
return 0;
@@ -1360,6 +1390,7 @@ array_get_packet (packet)
}
}
}
+ return 0; /* exceeded retries */
}
/*
@@ -1393,7 +1424,7 @@ ascii2hexword (mem)
* ascii2hexword -- convert a hex value to an ascii number represented by 8
* digits.
*/
-static char*
+static void
hexword2ascii (mem, num)
unsigned char *mem;
unsigned long num;
@@ -1461,5 +1492,6 @@ _initialize_remote_monitors ()
void
_initialize_array ()
{
+ init_array_ops() ;
add_target (&array_ops);
}
diff --git a/contrib/gdb/gdb/remote-bug.c b/contrib/gdb/gdb/remote-bug.c
index cd3b798..2efd710 100644
--- a/contrib/gdb/gdb/remote-bug.c
+++ b/contrib/gdb/gdb/remote-bug.c
@@ -37,6 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "remote-utils.h"
+
extern int sleep();
/* External data declarations */
@@ -147,7 +148,7 @@ bug_load (args, fromtty)
char *buffer = xmalloc (srec_frame);
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s->_raw_size);
- fflush (stdout);
+ gdb_flush (gdb_stdout);
for (i = 0; i < s->_raw_size; i += srec_frame)
{
if (srec_frame > s->_raw_size - i)
@@ -156,7 +157,7 @@ bug_load (args, fromtty)
bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
bug_write_memory (s->vma + i, buffer, srec_frame);
printf_filtered ("*");
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
printf_filtered ("\n");
free (buffer);
@@ -270,7 +271,7 @@ bug_resume (pid, step, sig)
static char *wait_strings[] = {
"At Breakpoint",
"Exception: Data Access Fault (Local Bus Timeout)",
- "\r8???-Bug>",
+ "\r8??\?-Bug>", /* The '\?' avoids creating a trigraph */
"\r197-Bug>",
NULL,
};
@@ -334,7 +335,7 @@ bug_wait (pid, status)
case -1: /* trouble */
default:
- fprintf_filtered (stderr,
+ fprintf_filtered (gdb_stderr,
"Trouble reading target during wait\n");
break;
}
@@ -921,7 +922,7 @@ bug_insert_breakpoint (addr, save)
}
else
{
- fprintf_filtered (stderr,
+ fprintf_filtered (gdb_stderr,
"Too many break points, break point not installed\n");
return(1);
}
@@ -960,35 +961,80 @@ bug_clear_breakpoints ()
return(0);
}
-struct target_ops bug_ops =
+struct target_ops bug_ops ;
+
+static void
+init_bug_ops(void)
{
- "bug", "Remote BUG monitor",
- "Use the mvme187 board running the BUG monitor connected by a serial line.",
-
- bug_open, gr_close,
- 0, gr_detach, bug_resume, bug_wait, /* attach */
- bug_fetch_register, bug_store_register,
- gr_prepare_to_store,
- bug_xfer_memory,
- gr_files_info,
- bug_insert_breakpoint, bug_remove_breakpoint, /* Breakpoints */
- 0, 0, 0, 0, 0, /* Terminal handling */
- gr_kill, /* FIXME, kill */
- bug_load,
- 0, /* lookup_symbol */
- gr_create_inferior, /* create_inferior */
- gr_mourn, /* mourn_inferior FIXME */
- 0, /* can_run */
- 0, /* notice_signals */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0, 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
-};
+ bug_ops.to_shortname = "bug"; "Remote BUG monitor",
+ bug_ops.to_longname = "Use the mvme187 board running the BUG monitor connected by a serial line.";
+ bug_ops.to_doc = " ";
+ bug_ops.to_open = bug_open;
+ bug_ops.to_close = gr_close;
+ bug_ops.to_attach = 0;
+ bug_ops.to_post_attach = NULL;
+ bug_ops.to_require_attach = NULL;
+ bug_ops.to_detach = gr_detach;
+ bug_ops.to_require_detach = NULL;
+ bug_ops.to_resume = bug_resume;
+ bug_ops.to_wait = bug_wait;
+ bug_ops.to_post_wait = NULL;
+ bug_ops.to_fetch_registers = bug_fetch_register;
+ bug_ops.to_store_registers = bug_store_register;
+ bug_ops.to_prepare_to_store = gr_prepare_to_store;
+ bug_ops.to_xfer_memory = bug_xfer_memory;
+ bug_ops.to_files_info = gr_files_info;
+ bug_ops.to_insert_breakpoint = bug_insert_breakpoint;
+ bug_ops.to_remove_breakpoint = bug_remove_breakpoint;
+ bug_ops.to_terminal_init = 0;
+ bug_ops.to_terminal_inferior = 0;
+ bug_ops.to_terminal_ours_for_output = 0;
+ bug_ops.to_terminal_ours = 0;
+ bug_ops.to_terminal_info = 0;
+ bug_ops.to_kill = gr_kill;
+ bug_ops.to_load = bug_load;
+ bug_ops.to_lookup_symbol = 0;
+ bug_ops.to_create_inferior = gr_create_inferior;
+ bug_ops.to_post_startup_inferior = NULL;
+ bug_ops.to_acknowledge_created_inferior = NULL;
+ bug_ops.to_clone_and_follow_inferior = NULL;
+ bug_ops.to_post_follow_inferior_by_clone = NULL;
+ bug_ops.to_insert_fork_catchpoint = NULL;
+ bug_ops.to_remove_fork_catchpoint = NULL;
+ bug_ops.to_insert_vfork_catchpoint = NULL;
+ bug_ops.to_remove_vfork_catchpoint = NULL;
+ bug_ops.to_has_forked = NULL;
+ bug_ops.to_has_vforked = NULL;
+ bug_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ bug_ops.to_post_follow_vfork = NULL;
+ bug_ops.to_insert_exec_catchpoint = NULL;
+ bug_ops.to_remove_exec_catchpoint = NULL;
+ bug_ops.to_has_execd = NULL;
+ bug_ops.to_reported_exec_events_per_exec_call = NULL;
+ bug_ops.to_has_exited = NULL;
+ bug_ops.to_mourn_inferior = gr_mourn;
+ bug_ops.to_can_run = 0;
+ bug_ops.to_notice_signals = 0;
+ bug_ops.to_thread_alive = 0 ;
+ bug_ops.to_stop = 0;
+ bug_ops.to_pid_to_exec_file = NULL;
+ bug_ops.to_core_file_to_sym_file = NULL;
+ bug_ops.to_stratum = process_stratum ;
+ bug_ops.DONT_USE = 0;
+ bug_ops.to_has_all_memory = 1;
+ bug_ops.to_has_memory = 1;
+ bug_ops.to_has_stack = 1;
+ bug_ops.to_has_registers = 0;
+ bug_ops.to_has_execution = 0;
+ bug_ops.to_sections = 0 ;
+ bug_ops.to_sections_end = 0 ;
+ bug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+} /* init_bug_ops */
void
_initialize_remote_bug ()
{
+ init_bug_ops() ;
add_target (&bug_ops);
add_show_from_set
diff --git a/contrib/gdb/gdb/remote-d10v.c b/contrib/gdb/gdb/remote-d10v.c
new file mode 100644
index 0000000..d529b21
--- /dev/null
+++ b/contrib/gdb/gdb/remote-d10v.c
@@ -0,0 +1,228 @@
+/* Remote target communications for d10v connected via a serial line.
+ Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free
+ Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "wait.h"
+/*#include "terminal.h"*/
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+
+#include "dcache.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <signal.h>
+#include "serial.h"
+
+/* Prototypes for local functions */
+
+static void remote_d10v_open PARAMS ((char *name, int from_tty));
+
+/* Define the target subroutine names */
+static struct target_ops remote_d10v_ops;
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static void
+remote_d10v_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ pop_target ();
+ push_remote_target (name, from_tty);
+}
+
+
+/* Translate a GDB virtual ADDR/LEN into a format the remote target
+ understands. Returns number of bytes that can be transfered
+ starting at taddr, ZERO if no bytes can be transfered. */
+int
+remote_d10v_translate_xfer_address (memaddr, nr_bytes, taddr)
+ CORE_ADDR memaddr;
+ int nr_bytes;
+ CORE_ADDR *taddr;
+{
+ CORE_ADDR phys;
+ CORE_ADDR seg;
+ CORE_ADDR off;
+ char *from = "unknown";
+ char *to = "unknown";
+ unsigned short imap0 = read_register (IMAP0_REGNUM);
+ unsigned short imap1 = read_register (IMAP1_REGNUM);
+ unsigned short dmap = read_register (DMAP_REGNUM);
+
+ /* GDB interprets addresses as:
+
+ 0x00xxxxxx: Logical data address segment (DMAP translated memory)
+ 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
+ 0x10xxxxxx: Physical data memory segment (On-chip data memory)
+ 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
+ 0x12xxxxxx: Phisical unified memory segment (Unified memory)
+
+ The remote d10v board interprets addresses as:
+
+ 0x00xxxxxx: Phisical unified memory segment (Unified memory)
+ 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)
+ 0x02xxxxxx: Physical data memory segment (On-chip data memory)
+
+ Translate according to current IMAP/dmap registers */
+
+ enum {
+ targ_unified = 0x00000000,
+ targ_insn = 0x01000000,
+ targ_data = 0x02000000,
+ };
+
+ seg = (memaddr >> 24);
+ off = (memaddr & 0xffffffL);
+
+ switch (seg)
+ {
+ case 0x00: /* in logical data address segment */
+ {
+ from = "logical-data";
+ if (off <= 0x7fffL)
+ {
+ /* On chip data */
+ phys = targ_data + off;
+ if (off + nr_bytes > 0x7fffL)
+ /* don't cross VM boundary */
+ nr_bytes = 0x7fffL - off + 1;
+ to = "chip-data";
+ }
+ else if (off <= 0xbfffL)
+ {
+ short map = dmap;
+ if (map & 0x1000)
+ {
+ /* Instruction memory */
+ phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff);
+ to = "chip-insn";
+ }
+ else
+ {
+ /* Unified memory */
+ phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff);
+ to = "unified";
+ }
+ if (off + nr_bytes > 0xbfffL)
+ /* don't cross VM boundary */
+ nr_bytes = (0xbfffL - off + 1);
+ }
+ else
+ {
+ /* Logical address out side of data segments, not supported */
+ return (0);
+ }
+ break;
+ }
+
+ case 0x01: /* in logical instruction address segment */
+ {
+ short map;
+ from = "logical-insn";
+ if (off <= 0x1ffffL)
+ {
+ map = imap0;
+ }
+ else if (off <= 0x3ffffL)
+ {
+ map = imap1;
+ }
+ else
+ {
+ /* Logical address outside of IMAP[01] segment, not
+ supported */
+ return (0);
+ }
+ if ((off & 0x1ffff) + nr_bytes > 0x1ffffL)
+ {
+ /* don't cross VM boundary */
+ nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1;
+ }
+ if (map & 0x1000)
+ /* Instruction memory */
+ {
+ phys = targ_insn | off;
+ to = "chip-insn";
+ }
+ else
+ {
+ phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
+ if (phys > 0xffffffL)
+ /* Address outside of unified address segment */
+ return (0);
+ phys |= targ_unified;
+ to = "unified";
+ }
+ break;
+ }
+
+ case 0x10: /* Physical data memory segment */
+ from = "phys-data";
+ phys = targ_data | off;
+ to = "chip-data";
+ break;
+
+ case 0x11: /* Physical instruction memory */
+ from = "phys-insn";
+ phys = targ_insn | off;
+ to = "chip-insn";
+ break;
+
+ case 0x12: /* Physical unified memory */
+ from = "phys-unified";
+ phys = targ_unified | off;
+ to = "unified";
+ break;
+
+ default:
+ return (0);
+ }
+
+
+ *taddr = phys;
+ return nr_bytes;
+}
+
+
+void
+_initialize_remote_d10v ()
+{
+ remote_d10v_ops.to_shortname = "d10v";
+ remote_d10v_ops.to_longname = "Remote d10v serial target in gdb-specific protocol";
+ remote_d10v_ops.to_doc = "Use a remote d10v via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ remote_d10v_ops.to_open = remote_d10v_open;
+
+ add_target (&remote_d10v_ops);
+}
diff --git a/contrib/gdb/gdb/remote-e7000.c b/contrib/gdb/gdb/remote-e7000.c
index d188913..92e69b3 100644
--- a/contrib/gdb/gdb/remote-e7000.c
+++ b/contrib/gdb/gdb/remote-e7000.c
@@ -1,5 +1,5 @@
/* Remote debugging interface for Hitachi E7000 ICE, for GDB
- Copyright 1993, 1994, 1996 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support.
Written by Steve Chamberlain for Cygnus Support.
@@ -33,6 +33,7 @@
#include "defs.h"
#include "gdbcore.h"
+#include "gdbarch.h"
#include "inferior.h"
#include "target.h"
#include "wait.h"
@@ -40,15 +41,18 @@
#include "command.h"
#include <signal.h>
#include "gdb_string.h"
+#include "gdbcmd.h"
#include <sys/types.h>
#include "serial.h"
#include "remote-utils.h"
#include "symfile.h"
-#include <sys/time.h>
+#include <time.h>
+#include <ctype.h>
-#if 0
-#define HARD_BREAKPOINTS
-#define BC_BREAKPOINTS 0
+
+#if 1
+#define HARD_BREAKPOINTS /* Now handled by set option. */
+#define BC_BREAKPOINTS use_hard_breakpoints
#endif
#define CTRLC 0x03
@@ -58,6 +62,11 @@
extern void notice_quit PARAMS ((void));
+extern void report_transfer_performance PARAMS ((unsigned long,
+ time_t, time_t));
+
+extern char *sh_processor_type;
+
/* Local function declarations. */
static void e7000_close PARAMS ((int));
@@ -80,13 +89,20 @@ static void expect_full_prompt PARAMS ((void));
static void expect_prompt PARAMS ((void));
+static int e7000_parse_device PARAMS ((char *args, char *dev_name,
+ int baudrate));
/* Variables. */
static serial_t e7000_desc;
+/* Allow user to chose between using hardware breakpoints or memory. */
+static int use_hard_breakpoints = 0; /* use sw breakpoints by default */
+
/* Nonzero if using the tcp serial driver. */
-static int using_tcp;
+static int using_tcp; /* direct tcp connection to target */
+static int using_tcp_remote; /* indirect connection to target
+ via tcp to controller */
/* Nonzero if using the pc isa card. */
@@ -103,7 +119,7 @@ static int echo;
static int ctrl_c;
-static int timeout = 5;
+static int timeout = 20;
/* Send data to e7000debug. */
@@ -115,10 +131,10 @@ puts_e7000debug (buf)
error ("Use \"target e7000 ...\" first.");
if (remote_debug)
- printf("Sending %s\n", buf);
+ printf_unfiltered ("Sending %s\n", buf);
if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
- fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
+ fprintf_unfiltered (gdb_stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
/* And expect to see it echoed, unless using the pc interface */
#if 0
@@ -154,7 +170,8 @@ normal (x)
}
/* Read a character from the remote system, doing all the fancy timeout
- stuff. */
+ stuff. Handles serial errors and EOF. If TIMEOUT == 0, and no chars,
+ returns -1, else returns next char. Discards chars > 127. */
static int
readchar (timeout)
@@ -175,10 +192,13 @@ readchar (timeout)
echo = 0;
error ("Timeout reading from remote system.");
}
+ else if (c < 0)
+ error ("Serial communication error");
+
if (remote_debug)
{
- putchar (c);
- fflush (stdout);
+ putchar_unfiltered (c);
+ gdb_flush (gdb_stdout);
}
return normal (c);
@@ -222,6 +242,7 @@ expect (string)
while (1)
{
c = readchar (timeout);
+#if 0
notice_quit ();
if (quit_flag == 1)
{
@@ -235,25 +256,22 @@ expect (string)
quit ();
}
}
+#endif
- if (c == SERIAL_ERROR)
- {
- error ("Serial communication error");
- }
- if (echo || remote_debug)
+ if (echo)
{
if (c == '\r' || c == '\n')
{
if (!nl)
- putchar ('\n');
+ putchar_unfiltered ('\n');
nl = 1;
}
else
{
nl = 0;
- putchar (c);
+ putchar_unfiltered (c);
}
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
if (normal (c) == normal (*p++))
{
@@ -365,7 +383,7 @@ e7000_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote E7000DEBUG process");
if (execfile == 0 || exec_bfd == 0)
- error ("No exec file specified");
+ error ("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -442,7 +460,7 @@ e7000_login_command (args, from_tty)
dir = next (&args);
if (from_tty)
{
- printf ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
+ printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
}
}
else
@@ -462,7 +480,7 @@ e7000_ftp_command (args, from_tty)
char buf[200];
int oldtimeout = timeout;
- timeout = 10;
+ timeout = remote_timeout;
sprintf (buf, "ftp %s\r", machine);
puts_e7000debug (buf);
@@ -485,25 +503,31 @@ e7000_ftp_command (args, from_tty)
timeout = oldtimeout;
}
-static void
-e7000_open (args, from_tty)
- char *args;
- int from_tty;
+static int
+e7000_parse_device (args, dev_name, baudrate)
+ char *args;
+ char *dev_name;
+ int baudrate;
{
- int n;
- int loop;
- char junk[100];
- int sync;
- target_preopen (from_tty);
-
- n = 0;
+ char junk[128];
+ int n = 0;
if (args && strcasecmp (args, "pc") == 0)
{
strcpy (dev_name, args);
+ using_pc = 1;
}
else
{
- if (args)
+ /* FIXME! temp hack to allow use with port master -
+ target tcp_remote <device> */
+ if (args && strncmp (args, "tcp", 10) == 0)
+ {
+ char com_type[128];
+ n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
+ using_tcp_remote=1;
+ n--;
+ }
+ else if (args)
{
n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
}
@@ -512,52 +536,67 @@ e7000_open (args, from_tty)
{
error ("Bad arguments. Usage:\ttarget e7000 <device> <speed>\n\
or \t\ttarget e7000 <host>[:<port>]\n\
+or \t\ttarget e7000 tcp_remote <host>[:<port>]\n\
or \t\ttarget e7000 pc\n");
}
-#ifndef __GO32__
+#if !defined(__GO32__) && !defined(_WIN32)
+ /* FIXME! test for ':' is ambiguous */
if (n == 1 && strchr (dev_name, ':') == 0)
{
/* Default to normal telnet port */
+ /* serial_open will use this to determine tcp communication */
strcat (dev_name, ":23");
}
#endif
+ if (!using_tcp_remote && strchr (dev_name, ':'))
+ using_tcp = 1;
}
- push_target (&e7000_ops);
+ return n;
+}
- e7000_desc = SERIAL_OPEN (dev_name);
+/* Stub for catch_errors. */
- if (!e7000_desc)
- perror_with_name (dev_name);
-
- using_tcp = strcmp (e7000_desc->ops->name, "tcp") == 0;
- using_pc = strcmp (e7000_desc->ops->name, "pc") == 0;
+static int
+e7000_start_remote (dummy)
+ char *dummy;
+{
+ int loop;
+ int sync;
+ int try;
+ int quit_trying;
- SERIAL_SETBAUDRATE (e7000_desc, baudrate);
- SERIAL_RAW (e7000_desc);
+ immediate_quit = 1; /* Allow user to interrupt it */
/* Hello? Are you there? */
sync = 0;
loop = 0;
+ try = 0;
+ quit_trying = 20;
putchar_e7000 (CTRLC);
- while (!sync)
+ while (!sync && ++try <= quit_trying)
{
int c;
- if (from_tty)
- printf_unfiltered ("[waiting for e7000...]\n");
+ printf_unfiltered ("[waiting for e7000...]\n");
write_e7000 ("\r");
- c = SERIAL_READCHAR (e7000_desc, 1);
- while (c != SERIAL_TIMEOUT)
+ c = readchar (1);
+
+ /* FIXME! this didn't seem right-> while (c != SERIAL_TIMEOUT)
+ * we get stuck in this loop ...
+ * We may never timeout, and never sync up :-(
+ */
+ while (!sync && c != -1)
{
/* Dont echo cr's */
- if (from_tty && c != '\r')
+ if (c != '\r')
{
- putchar (c);
- fflush (stdout);
+ putchar_unfiltered (c);
+ gdb_flush (gdb_stdout);
}
+ /* Shouldn't we either break here, or check for sync in inner loop? */
if (c == ':')
sync = 1;
@@ -569,30 +608,80 @@ or \t\ttarget e7000 pc\n");
QUIT ;
-
if (quit_flag)
{
putchar_e7000 (CTRLC);
- quit_flag = 0;
+ /* Was-> quit_flag = 0; */
+ c = -1;
+ quit_trying = try+1; /* we don't want to try anymore */
+ }
+ else
+ {
+ c = readchar (1);
}
- c = SERIAL_READCHAR (e7000_desc, 1);
}
}
- puts_e7000debug ("\r");
+ if (!sync)
+ {
+ fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n",try);
+ error ("Unable to syncronize with target.\n");
+ }
+
+ puts_e7000debug ("\r");
+ expect_prompt ();
+ puts_e7000debug ("b -\r"); /* Clear breakpoints */
expect_prompt ();
- puts_e7000debug ("b -\r");
+ immediate_quit = 0;
- expect_prompt ();
+/* This is really the job of start_remote however, that makes an assumption
+ that the target is about to print out a status message of some sort. That
+ doesn't happen here. */
- if (from_tty)
- printf_filtered ("Remote target %s connected to %s\n", target_shortname,
- dev_name);
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame (), 0);
+ print_stack_frame (selected_frame, -1, 1);
+
+ return 1;
+}
+
+static void
+e7000_open (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int n;
+
+ target_preopen (from_tty);
+
+ n = e7000_parse_device (args, dev_name, baudrate);
+
+ push_target (&e7000_ops);
+
+ e7000_desc = SERIAL_OPEN (dev_name);
+
+ if (!e7000_desc)
+ perror_with_name (dev_name);
+
+ SERIAL_SETBAUDRATE (e7000_desc, baudrate);
+ SERIAL_RAW (e7000_desc);
#ifdef GDB_TARGET_IS_H8300
h8300hmode = 1;
#endif
+
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it
+ (we'd be in an inconsistent state otherwise). */
+ if (!catch_errors (e7000_start_remote, (char *)0,
+ "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
+ if (from_tty)
+ printf_filtered ("Remote target %s connected to %s\n", target_shortname,
+ dev_name);
}
/* Close out all files and local state before this target loses control. */
@@ -617,7 +706,7 @@ e7000_detach (from_tty)
{
pop_target (); /* calls e7000_close to do the real work */
if (from_tty)
- printf ("Ending remote %s debugging\n", target_shortname);
+ printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
}
/* Tell the remote machine to resume. */
@@ -646,11 +735,20 @@ e7000_resume (pid, step, sig)
#ifdef GDB_TARGET_IS_H8300
-char *want = "PC=%p CCR=%c\n\
+char *want_h8300h = "PC=%p CCR=%c\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7\n";
+
+char *want_nopc_h8300h = "%p CCR=%c\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7";
+
+char *want_h8300s = "PC=%p CCR=%c\n\
+ MACH=\n\
ER0 - ER3 %0 %1 %2 %3\n\
ER4 - ER7 %4 %5 %6 %7\n";
-char *want_nopc = "%p CCR=%c\n\
+char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\
ER0 - ER3 %0 %1 %2 %3\n\
ER4 - ER7 %4 %5 %6 %7";
@@ -670,21 +768,32 @@ char *want_nopc = "%16 SR=%22\n\
R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
R8-15 %8 %9 %10 %11 %12 %13 %14 %15";
+char *want_sh3 = "PC=%16 SR=%22\n\
+PR=%17 GBR=%18 VBR=%19\n\
+MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\
+R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
+R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
+R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
+R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
+R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
+R4_BANK1-R7_BANK1 %37 %38 %39 %40";
+
+char *want_sh3_nopc = "%16 SR=%22\n\
+ PR=%17 GBR=%18 VBR=%19\n\
+ MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\
+ R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
+ R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
+ R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
+ R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
+ R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
+ R4_BANK1-R7_BANK1 %37 %38 %39 %40";
+
#endif
static int
gch ()
{
- int c = readchar (timeout);
-
- if (remote_debug)
- {
- if (c >= ' ')
- printf ("%c", c);
- else if (c == '\n')
- printf ("\n");
- }
- return c;
+ return readchar (timeout);
}
static unsigned int
@@ -807,9 +916,26 @@ static void
e7000_fetch_registers ()
{
int regno;
+ char *wanted;
puts_e7000debug ("R\r");
- fetch_regs_from_dump (gch, want);
+
+#ifdef GDB_TARGET_IS_SH
+ wanted = want;
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
+ switch (TARGET_ARCHITECTURE->mach)
+ {
+ case bfd_mach_sh3:
+ case bfd_mach_sh3e:
+ wanted = want_sh3;
+ }
+#else
+ if (h8300smode)
+ wanted = want_h8300s;
+ else
+ wanted = want_h8300h;
+#endif
+ fetch_regs_from_dump (gch, wanted);
/* And supply the extra ones the simulator uses */
for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
@@ -939,7 +1065,7 @@ e7000_prepare_to_store ()
static void
e7000_files_info ()
{
- printf ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
+ printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
}
static int
@@ -1064,8 +1190,8 @@ write_large (memaddr, myaddr, len)
compose[where++] = 0;
SERIAL_WRITE (e7000_desc, compose, where);
- j = SERIAL_READCHAR (e7000_desc, 0);
- if (j == SERIAL_TIMEOUT)
+ j = readchar (0);
+ if (j == -1)
{
/* This is ok - nothing there */
}
@@ -1077,10 +1203,10 @@ write_large (memaddr, myaddr, len)
}
else
{
- printf ("@%d}@", j);
- while ((j = SERIAL_READCHAR(e7000_desc,0)) > 0)
+ printf_unfiltered ("@%d}@", j);
+ while ((j = readchar (0)) > 0)
{
- printf ("@{%d}@",j);
+ printf_unfiltered ("@{%d}@",j);
}
}
}
@@ -1153,7 +1279,8 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
c = gch ();
if (c == '*')
{ /* Some kind of error */
- expect_prompt();
+ puts_e7000debug (".\r"); /* Some errors leave us in memory input mode */
+ expect_full_prompt();
return -1;
}
while (c != ' ')
@@ -1182,7 +1309,7 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
}
-#if 0
+
/*
For large transfers we used to send
@@ -1190,10 +1317,10 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
d <addr> <endaddr>\r
and receive
- <ADDR> < D A T A > < ASCII CODE >
- 000000 5F FD FD FF DF 7F DF FF 01 00 01 00 02 00 08 04 "_..............."
- 000010 FF D7 FF 7F D7 F1 7F FF 00 05 00 00 08 00 40 00 "..............@."
- 000020 7F FD FF F7 7F FF FF F7 00 00 00 00 00 00 00 00 "................"
+ <ADDRESS> < D A T A > < ASCII CODE >
+ 00000000 5F FD FD FF DF 7F DF FF 01 00 01 00 02 00 08 04 "_..............."
+ 00000010 FF D7 FF 7F D7 F1 7F FF 00 05 00 00 08 00 40 00 "..............@."
+ 00000020 7F FD FF F7 7F FF FF F7 00 00 00 00 00 00 00 00 "................"
A cost in chars for each transaction of 80 + 5*n-bytes.
@@ -1203,7 +1330,7 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
*/
static int
-e7000_read_inferior_memory (memaddr, myaddr, len)
+e7000_read_inferior_memory_large (memaddr, myaddr, len)
CORE_ADDR memaddr;
unsigned char *myaddr;
int len;
@@ -1225,29 +1352,22 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
count = 0;
c = gch ();
-
- /* First skip the command */
- while (c == '\n')
- c = gch ();
-
- while (c == ' ')
+
+ /* skip down to the first ">" */
+ while( c != '>' )
c = gch ();
- if (c == '*')
- {
- expect ("\r");
- return -1;
- }
-
- /* Skip the title line */
- while (c != '\n')
+ /* now skip to the end of that line */
+ while( c != '\r' )
c = gch ();
c = gch ();
+
while (count < len)
{
- /* Skip the address */
+ /* get rid of any white space before the address */
while (c <= ' ')
c = gch ();
+ /* Skip the address */
get_hex (&c);
/* read in the bytes on the line */
@@ -1260,17 +1380,20 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
myaddr[count++] = get_hex (&c);
}
}
-
- while (c != '\n')
+ /* throw out the rest of the line */
+ while( c != '\r' )
c = gch ();
}
+ /* wait for the ":" prompt */
while (c != ':')
c = gch ();
return len;
}
+#if 0
+
static int
fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
@@ -1371,8 +1494,11 @@ e7000_xfer_inferior_memory (memaddr, myaddr, len, write, target)
{
if (write)
return e7000_write_inferior_memory( memaddr, myaddr, len);
- else
- return e7000_read_inferior_memory( memaddr, myaddr, len);
+ else
+ if( len < 16 )
+ return e7000_read_inferior_memory( memaddr, myaddr, len);
+ else
+ return e7000_read_inferior_memory_large( memaddr, myaddr, len);
}
static void
@@ -1391,7 +1517,6 @@ e7000_load (args, from_tty)
asection *section;
bfd *pbfd;
bfd_vma entry;
- int i;
#define WRITESIZE 0x1000
char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + <addr> + <len> + <data> */
char *filename;
@@ -1399,13 +1524,19 @@ e7000_load (args, from_tty)
int nostart;
time_t start_time, end_time; /* Start and end times of download */
unsigned long data_count; /* Number of bytes transferred to memory */
+ int oldtimeout = timeout;
- if (!strchr (dev_name, ':'))
+ timeout = remote_timeout;
+
+
+ /* FIXME! change test to test for type of download */
+ if (!using_tcp)
{
generic_load (args, from_tty);
return;
}
+ /* for direct tcp connections, we can do a fast binary download */
buf[0] = 'D';
buf[1] = 'T';
quiet = 0;
@@ -1444,7 +1575,7 @@ e7000_load (args, from_tty)
perror_with_name (filename);
return;
}
- old_chain = make_cleanup (bfd_close, pbfd);
+ old_chain = make_cleanup ((make_cleanup_func) bfd_close, pbfd);
if (!bfd_check_format (pbfd, bfd_object))
error ("\"%s\" is not an object file: %s", filename,
@@ -1551,10 +1682,10 @@ e7000_load (args, from_tty)
/* start_routine (entry);*/
}
- printf_filtered ("Transfer rate: %d bits/sec.\n",
- (data_count * 8)/(end_time - start_time));
+ report_transfer_performance (data_count, start_time, end_time);
do_cleanups (old_chain);
+ timeout = oldtimeout;
}
/* Clean up when a program exits.
@@ -1571,15 +1702,16 @@ e7000_mourn_inferior ()
generic_mourn_inferior (); /* Do all the proper things now */
}
+#define MAX_BREAKPOINTS 200
#ifdef HARD_BREAKPOINTS
-#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 : 200)
+#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 : MAX_BREAKPOINTS)
#else
-#define MAX_E7000DEBUG_BREAKPOINTS 200
+#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS
#endif
-extern int memory_breakpoint_size;
-
-static CORE_ADDR breakaddr[MAX_E7000DEBUG_BREAKPOINTS] = {0};
+/* Since we can change to soft breakpoints dynamically, we must define
+ more than enough. Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */
+static CORE_ADDR breakaddr[MAX_BREAKPOINTS] = {0};
static int
e7000_insert_breakpoint (addr, shadow)
@@ -1588,7 +1720,9 @@ e7000_insert_breakpoint (addr, shadow)
{
int i;
char buf[200];
+#if 0
static char nop[2] = NOP;
+#endif
for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
if (breakaddr[i] == 0)
@@ -1714,7 +1848,7 @@ e7000_drain_command (args, fromtty)
puts_e7000debug("end\r");
putchar_e7000 (CTRLC);
- while ((c = SERIAL_READCHAR (e7000_desc, 1) != SERIAL_TIMEOUT))
+ while ((c = readchar (1) != -1))
{
if (quit_flag)
{
@@ -1722,9 +1856,9 @@ e7000_drain_command (args, fromtty)
quit_flag = 0;
}
if (c > ' ' && c < 127)
- printf ("%c", c & 0xff);
+ printf_unfiltered ("%c", c & 0xff);
else
- printf ("<%x>", c & 0xff);
+ printf_unfiltered ("<%x>", c & 0xff);
}
}
@@ -1795,8 +1929,8 @@ char **strings;
int i;
int gotone = 0;
- c = SERIAL_READCHAR (e7000_desc, 1);
- if (c == SERIAL_TIMEOUT)
+ c = readchar (1);
+ if (c == -1)
{
printf_unfiltered ("[waiting for e7000...]\n");
}
@@ -1843,13 +1977,13 @@ char **strings;
if (buffer != saveaway)
{
*buffer++ = 0;
- printf ("%s", buffer);
+ printf_unfiltered ("%s", buffer);
buffer = saveaway;
}
- if (c != SERIAL_TIMEOUT)
+ if (c != -1)
{
- putchar (c);
- fflush (stdout);
+ putchar_unfiltered (c);
+ gdb_flush (gdb_stdout);
}
}
}
@@ -1899,6 +2033,7 @@ e7000_wait (pid, status)
int running_count = 0;
int had_sleep = 0;
int loop = 1;
+ char *wanted_nopc;
/* Then echo chars until PC= string seen */
gch (); /* Drop cr */
@@ -1936,7 +2071,23 @@ e7000_wait (pid, status)
/* Skip till the PC= */
expect ("=");
- fetch_regs_from_dump (gch, want_nopc);
+
+#ifdef GDB_TARGET_IS_SH
+ wanted_nopc = want_nopc;
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
+ switch (TARGET_ARCHITECTURE->mach)
+ {
+ case bfd_mach_sh3:
+ case bfd_mach_sh3e:
+ wanted_nopc = want_sh3_nopc;
+ }
+#else
+ if (h8300smode)
+ wanted_nopc = want_nopc_h8300s;
+ else
+ wanted_nopc = want_nopc_h8300h;
+#endif
+ fetch_regs_from_dump (gch, wanted_nopc);
/* And supply the extra ones the simulator uses */
for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
@@ -1995,72 +2146,113 @@ e7000_wait (pid, status)
return 0;
}
+/* Stop the running program. */
+
+static void
+e7000_stop ()
+{
+ /* Sending a ^C is supposed to stop the running program. */
+ putchar_e7000 (CTRLC);
+}
+
/* Define the target subroutine names. */
-struct target_ops e7000_ops =
+struct target_ops e7000_ops ;
+
+static void
+init_e7000_ops(void)
{
- "e7000",
- "Remote Hitachi e7000 target",
- "Use a remote Hitachi e7000 ICE connected by a serial line,\n\
+ e7000_ops.to_shortname = "e7000";
+ e7000_ops.to_longname = "Remote Hitachi e7000 target";
+ e7000_ops.to_doc = "Use a remote Hitachi e7000 ICE connected by a serial line;\n\
or a network connection.\n\
Arguments are the name of the device for the serial line,\n\
the speed to connect at in bits per second.\n\
eg\n\
target e7000 /dev/ttya 9600\n\
-target e7000 foobar",
- e7000_open, /* to_open */
- e7000_close, /* to_close */
- 0, /* to_attach */
- e7000_detach, /* to_detach */
- e7000_resume, /* to_resume */
- e7000_wait, /* to_wait */
- e7000_fetch_register, /* to_fetch_registers */
- e7000_store_register, /* to_store_registers */
- e7000_prepare_to_store, /* to_prepare_to_store */
- e7000_xfer_inferior_memory, /* to_xfer_memory */
- e7000_files_info, /* to_files_info */
- e7000_insert_breakpoint, /* to_insert_breakpoint */
- e7000_remove_breakpoint, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- e7000_kill, /* to_kill */
- e7000_load, /* to_load */
- 0, /* to_lookup_symbol */
- e7000_create_inferior, /* to_create_inferior */
- e7000_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* next (unused) */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC, /* Always the last thing */
+target e7000 foobar" ;
+ e7000_ops.to_open = e7000_open;
+ e7000_ops.to_close = e7000_close;
+ e7000_ops.to_attach = 0;
+ e7000_ops.to_post_attach = NULL;
+ e7000_ops.to_require_attach = NULL;
+ e7000_ops.to_detach = e7000_detach;
+ e7000_ops.to_require_detach = NULL;
+ e7000_ops.to_resume = e7000_resume;
+ e7000_ops.to_wait = e7000_wait;
+ e7000_ops.to_post_wait = NULL;
+ e7000_ops.to_fetch_registers = e7000_fetch_register;
+ e7000_ops.to_store_registers = e7000_store_register;
+ e7000_ops.to_prepare_to_store = e7000_prepare_to_store;
+ e7000_ops.to_xfer_memory = e7000_xfer_inferior_memory;
+ e7000_ops.to_files_info = e7000_files_info;
+ e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
+ e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
+ e7000_ops.to_terminal_init = 0;
+ e7000_ops.to_terminal_inferior = 0;
+ e7000_ops.to_terminal_ours_for_output = 0;
+ e7000_ops.to_terminal_ours = 0;
+ e7000_ops.to_terminal_info = 0;
+ e7000_ops.to_kill = e7000_kill;
+ e7000_ops.to_load = e7000_load;
+ e7000_ops.to_lookup_symbol = 0;
+ e7000_ops.to_create_inferior = e7000_create_inferior;
+ e7000_ops.to_post_startup_inferior = NULL;
+ e7000_ops.to_acknowledge_created_inferior = NULL;
+ e7000_ops.to_clone_and_follow_inferior = NULL;
+ e7000_ops.to_post_follow_inferior_by_clone = NULL;
+ e7000_ops.to_insert_fork_catchpoint = NULL;
+ e7000_ops.to_remove_fork_catchpoint = NULL;
+ e7000_ops.to_insert_vfork_catchpoint = NULL;
+ e7000_ops.to_remove_vfork_catchpoint = NULL;
+ e7000_ops.to_has_forked = NULL;
+ e7000_ops.to_has_vforked = NULL;
+ e7000_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ e7000_ops.to_post_follow_vfork = NULL;
+ e7000_ops.to_insert_exec_catchpoint = NULL;
+ e7000_ops.to_remove_exec_catchpoint = NULL;
+ e7000_ops.to_has_execd = NULL;
+ e7000_ops.to_reported_exec_events_per_exec_call = NULL;
+ e7000_ops.to_has_exited = NULL;
+ e7000_ops.to_mourn_inferior = e7000_mourn_inferior;
+ e7000_ops.to_can_run = 0;
+ e7000_ops.to_notice_signals = 0;
+ e7000_ops.to_thread_alive = 0;
+ e7000_ops.to_stop = e7000_stop;
+ e7000_ops.to_pid_to_exec_file = NULL;
+ e7000_ops.to_core_file_to_sym_file = NULL;
+ e7000_ops.to_stratum = process_stratum;
+ e7000_ops.DONT_USE = 0;
+ e7000_ops.to_has_all_memory = 1;
+ e7000_ops.to_has_memory = 1;
+ e7000_ops.to_has_stack = 1;
+ e7000_ops.to_has_registers = 1;
+ e7000_ops.to_has_execution = 1;
+ e7000_ops.to_sections = 0;
+ e7000_ops.to_sections_end = 0;
+ e7000_ops.to_magic = OPS_MAGIC;
};
void
_initialize_remote_e7000 ()
{
+ init_e7000_ops() ;
add_target (&e7000_ops);
- add_com ("e7000 <command>", class_obscure, e7000_command,
+ add_com ("e7000", class_obscure, e7000_command,
"Send a command to the e7000 monitor.");
- add_com ("ftplogin <machine> <name> <passwd> <dir>", class_obscure, e7000_login_command,
+ add_com ("ftplogin", class_obscure, e7000_login_command,
"Login to machine and change to directory.");
- add_com ("ftpload <file>", class_obscure, e7000_ftp_command,
+ add_com ("ftpload", class_obscure, e7000_ftp_command,
"Fetch and load a file from previously described place.");
add_com ("drain", class_obscure, e7000_drain_command,
"Drain pending e7000 text buffers.");
+
+ add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class,
+ var_integer, (char *)&use_hard_breakpoints,
+ "Set use of hardware breakpoints for all breakpoints.\n", &setlist),
+ &showlist);
}
diff --git a/contrib/gdb/gdb/remote-eb.c b/contrib/gdb/gdb/remote-eb.c
index baa4d24..d3a3c41 100644
--- a/contrib/gdb/gdb/remote-eb.c
+++ b/contrib/gdb/gdb/remote-eb.c
@@ -248,7 +248,7 @@ eb_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote EBMON process");
if (execfile == 0 || exec_bfd == 0)
- error ("No exec file specified");
+ error ("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -974,36 +974,83 @@ eb_mourn_inferior ()
}
/* Define the target subroutine names */
-struct target_ops eb_ops = {
- "amd-eb", "Remote serial AMD EBMON target",
- "Use a remote computer running EBMON connected by a serial line.\n\
+struct target_ops eb_ops ;
+
+static void
+init_eb_ops(void)
+{
+ eb_ops.to_shortname = "amd-eb";
+ eb_ops.to_longname = "Remote serial AMD EBMON target";
+ eb_ops.to_doc = "Use a remote computer running EBMON connected by a serial line.\n\
Arguments are the name of the device for the serial line,\n\
the speed to connect at in bits per second, and the filename of the\n\
executable as it exists on the remote computer. For example,\n\
- target amd-eb /dev/ttya 9600 demo",
- eb_open, eb_close,
- 0, eb_detach, eb_resume, eb_wait,
- eb_fetch_register, eb_store_register,
- eb_prepare_to_store,
- eb_xfer_inferior_memory, eb_files_info,
- 0, 0, /* Breakpoints */
- 0, 0, 0, 0, 0, /* Terminal handling */
- eb_kill,
- generic_load, /* load */
- 0, /* lookup_symbol */
- eb_create_inferior,
- eb_mourn_inferior,
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_stop */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0, 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
+target amd-eb /dev/ttya 9600 demo",
+ eb_ops.to_open = eb_open;
+ eb_ops.to_close = eb_close;
+ eb_ops.to_attach = 0;
+ eb_ops.to_post_attach = NULL;
+ eb_ops.to_require_attach = NULL;
+ eb_ops.to_detach = eb_detach;
+ eb_ops.to_require_detach = NULL;
+ eb_ops.to_resume = eb_resume;
+ eb_ops.to_wait = eb_wait;
+ eb_ops.to_post_wait = NULL;
+ eb_ops.to_fetch_registers = eb_fetch_register;
+ eb_ops.to_store_registers = eb_store_register;
+ eb_ops.to_prepare_to_store = eb_prepare_to_store;
+ eb_ops.to_xfer_memory = eb_xfer_inferior_memory;
+ eb_ops.to_files_info = eb_files_info;
+ eb_ops.to_insert_breakpoint = 0;
+ eb_ops.to_remove_breakpoint = 0; /* Breakpoints */
+ eb_ops.to_terminal_init = 0;
+ eb_ops.to_terminal_inferior = 0;
+ eb_ops.to_terminal_ours_for_output = 0;
+ eb_ops.to_terminal_ours = 0;
+ eb_ops.to_terminal_info = 0; /* Terminal handling */
+ eb_ops.to_kill = eb_kill;
+ eb_ops.to_load = generic_load; /* load */
+ eb_ops.to_lookup_symbol = 0; /* lookup_symbol */
+ eb_ops.to_create_inferior = eb_create_inferior;
+ eb_ops.to_post_startup_inferior = NULL;
+ eb_ops.to_acknowledge_created_inferior = NULL;
+ eb_ops.to_clone_and_follow_inferior = NULL;
+ eb_ops.to_post_follow_inferior_by_clone = NULL;
+ eb_ops.to_insert_fork_catchpoint = NULL;
+ eb_ops.to_remove_fork_catchpoint = NULL;
+ eb_ops.to_insert_vfork_catchpoint = NULL;
+ eb_ops.to_remove_vfork_catchpoint = NULL;
+ eb_ops.to_has_forked = NULL;
+ eb_ops.to_has_vforked = NULL;
+ eb_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ eb_ops.to_post_follow_vfork = NULL;
+ eb_ops.to_insert_exec_catchpoint = NULL;
+ eb_ops.to_remove_exec_catchpoint = NULL;
+ eb_ops.to_has_execd = NULL;
+ eb_ops.to_reported_exec_events_per_exec_call = NULL;
+ eb_ops.to_has_exited = NULL;
+ eb_ops.to_mourn_inferior = eb_mourn_inferior;
+ eb_ops.to_can_run = 0; /* can_run */
+ eb_ops.to_notice_signals = 0; /* notice_signals */
+ eb_ops.to_thread_alive = 0; /* thread-alive */
+ eb_ops.to_stop = 0; /* to_stop */
+ eb_ops.to_pid_to_exec_file = NULL;
+ eb_ops.to_core_file_to_sym_file = NULL;
+ eb_ops.to_stratum = process_stratum;
+ eb_ops.DONT_USE = 0; /* next */
+ eb_ops.to_has_all_memory = 1;
+ eb_ops.to_has_memory = 1;
+ eb_ops.to_has_stack = 1;
+ eb_ops.to_has_registers = 1;
+ eb_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */
+ eb_ops.to_sections = 0; /* sections */
+ eb_ops.to_sections_end = 0; /* sections end */
+ eb_ops.to_magic = OPS_MAGIC; /* Always the last thing */
};
void
_initialize_remote_eb ()
{
+ init_eb_ops() ;
add_target (&eb_ops);
}
diff --git a/contrib/gdb/gdb/remote-es.c b/contrib/gdb/gdb/remote-es.c
index b4e60ef..d26e85b 100644
--- a/contrib/gdb/gdb/remote-es.c
+++ b/contrib/gdb/gdb/remote-es.c
@@ -96,10 +96,10 @@ STP
#include <sys/file.h>
#include <errno.h>
#include <ctype.h>
-#include "gdb_string.h"
#include <setjmp.h>
#include <fcntl.h>
#include "defs.h"
+#include "gdb_string.h"
#include "frame.h"
#include "inferior.h"
#include "target.h"
@@ -1468,7 +1468,7 @@ es1800_create_inferior (execfile, args, env)
if (execfile == 0 || exec_bfd == 0)
{
- error ("No exec file specified");
+ error ("No executable file specified");
}
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -2042,105 +2042,155 @@ es1800_child_detach (args, from_tty)
/* Define the target subroutine names */
-struct target_ops es1800_ops =
+struct target_ops es1800_ops ;
+
+static void
+init_es1800_ops(void)
{
- "es1800", /* to_shortname */
- /* to_longname */
- "Remote serial target in ES1800-emulator protocol",
- /* to_doc */
- "Remote debugging on the es1800 emulator via a serial line.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
- es1800_open, /* to_open */
- es1800_close, /* to_close */
- es1800_attach, /* to_attach */
- es1800_detach, /* to_detach */
- es1800_resume, /* to_resume */
- NULL, /* to_wait */
- NULL, /* to_fetch_registers */
- NULL, /* to_store_registers */
- es1800_prepare_to_store, /* to_prepare_to_store */
- es1800_xfer_inferior_memory, /* to_xfer_memory */
- es1800_files_info, /* to_files_info */
- es1800_insert_breakpoint, /* to_insert_breakpoint */
- es1800_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- NULL, /* to_kill */
- es1800_load, /* to_load */
- NULL, /* to_lookup_symbol */
- es1800_create_inferior, /* to_create_inferior */
- NULL, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- core_stratum, /* to_stratum */
- 0, /* to_next */
- 0, /* to_has_all_memory */
- 1, /* to_has_memory */
- 0, /* to_has_stack */
- 0, /* to_has_registers */
- 0, /* to_has_execution */
- NULL, /* to_sections */
- NULL, /* to_sections_end */
- OPS_MAGIC /* to_magic (always last) */
-};
+ es1800_ops.to_shortname = "es1800";
+ es1800_ops.to_longname = "Remote serial target in ES1800-emulator protocol";
+ es1800_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya)." ;
+ es1800_ops.to_open = es1800_open;
+ es1800_ops.to_close = es1800_close;
+ es1800_ops.to_attach = es1800_attach;
+ es1800_ops.to_post_attach = NULL;
+ es1800_ops.to_require_attach = NULL;
+ es1800_ops.to_detach = es1800_detach;
+ es1800_ops.to_require_detach = NULL;
+ es1800_ops.to_resume = es1800_resume;
+ es1800_ops.to_wait = NULL;
+ es1800_ops.to_post_wait = NULL;
+ es1800_ops.to_fetch_registers = NULL;
+ es1800_ops.to_store_registers = NULL;
+ es1800_ops.to_prepare_to_store = es1800_prepare_to_store;
+ es1800_ops.to_xfer_memory = es1800_xfer_inferior_memory;
+ es1800_ops.to_files_info = es1800_files_info;
+ es1800_ops.to_insert_breakpoint = es1800_insert_breakpoint;
+ es1800_ops.to_remove_breakpoint = es1800_remove_breakpoint;
+ es1800_ops.to_terminal_init = NULL;
+ es1800_ops.to_terminal_inferior = NULL;
+ es1800_ops.to_terminal_ours_for_output = NULL;
+ es1800_ops.to_terminal_ours = NULL;
+ es1800_ops.to_terminal_info = NULL;
+ es1800_ops.to_kill = NULL;
+ es1800_ops.to_load = es1800_load;
+ es1800_ops.to_lookup_symbol = NULL;
+ es1800_ops.to_create_inferior = es1800_create_inferior;
+ es1800_ops.to_post_startup_inferior = NULL;
+ es1800_ops.to_acknowledge_created_inferior = NULL;
+ es1800_ops.to_clone_and_follow_inferior = NULL;
+ es1800_ops.to_post_follow_inferior_by_clone = NULL;
+ es1800_ops.to_insert_fork_catchpoint = NULL;
+ es1800_ops.to_remove_fork_catchpoint = NULL;
+ es1800_ops.to_insert_vfork_catchpoint = NULL;
+ es1800_ops.to_remove_vfork_catchpoint = NULL;
+ es1800_ops.to_has_forked = NULL;
+ es1800_ops.to_has_vforked = NULL;
+ es1800_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ es1800_ops.to_post_follow_vfork = NULL;
+ es1800_ops.to_insert_exec_catchpoint = NULL;
+ es1800_ops.to_remove_exec_catchpoint = NULL;
+ es1800_ops.to_has_execd = NULL;
+ es1800_ops.to_reported_exec_events_per_exec_call = NULL;
+ es1800_ops.to_has_exited = NULL;
+ es1800_ops.to_mourn_inferior = NULL;
+ es1800_ops.to_can_run = 0;
+ es1800_ops.to_notice_signals = 0;
+ es1800_ops.to_thread_alive = 0;
+ es1800_ops.to_stop = 0;
+ es1800_ops.to_pid_to_exec_file = NULL;
+ es1800_ops.to_core_file_to_sym_file = NULL;
+ es1800_ops.to_stratum = core_stratum;
+ es1800_ops.DONT_USE = 0;
+ es1800_ops.to_has_all_memory = 0;
+ es1800_ops.to_has_memory = 1;
+ es1800_ops.to_has_stack = 0;
+ es1800_ops.to_has_registers = 0;
+ es1800_ops.to_has_execution = 0;
+ es1800_ops.to_sections = NULL;
+ es1800_ops.to_sections_end = NULL;
+ es1800_ops.to_magic = OPS_MAGIC ;
+}
/* Define the target subroutine names */
-struct target_ops es1800_child_ops =
+struct target_ops es1800_child_ops ;
+
+static void
+init_es1800_child_ops(void)
{
- "es1800_process", /* to_shortname */
- /* to_longname */
- "Remote serial target in ES1800-emulator protocol",
- /* to_doc */
- "Remote debugging on the es1800 emulator via a serial line.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
- es1800_child_open, /* to_open */
- NULL, /* to_close */
- es1800_attach, /* to_attach */
- es1800_child_detach, /* to_detach */
- es1800_resume, /* to_resume */
- es1800_wait, /* to_wait */
- es1800_fetch_register, /* to_fetch_registers */
- es1800_store_register, /* to_store_registers */
- es1800_prepare_to_store, /* to_prepare_to_store */
- es1800_xfer_inferior_memory, /* to_xfer_memory */
- es1800_files_info, /* to_files_info */
- es1800_insert_breakpoint, /* to_insert_breakpoint */
- es1800_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- es1800_kill, /* to_kill */
- es1800_load, /* to_load */
- NULL, /* to_lookup_symbol */
- es1800_create_inferior, /* to_create_inferior */
- es1800_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* to_sections */
- NULL, /* to_sections_end */
- OPS_MAGIC /* to_magic (always last) */
-};
+ es1800_child_ops.to_shortname = "es1800_process";
+ es1800_child_ops.to_longname = "Remote serial target in ES1800-emulator protocol";
+ es1800_child_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ es1800_child_ops.to_open = es1800_child_open;
+ es1800_child_ops.to_close = NULL;
+ es1800_child_ops.to_attach = es1800_attach;
+ es1800_child_ops.to_post_attach = NULL;
+ es1800_child_ops.to_require_attach = NULL;
+ es1800_child_ops.to_detach = es1800_child_detach;
+ es1800_child_ops.to_require_detach = NULL;
+ es1800_child_ops.to_resume = es1800_resume;
+ es1800_child_ops.to_wait = es1800_wait;
+ es1800_child_ops.to_post_wait = NULL;
+ es1800_child_ops.to_fetch_registers = es1800_fetch_register;
+ es1800_child_ops.to_store_registers = es1800_store_register;
+ es1800_child_ops.to_prepare_to_store = es1800_prepare_to_store;
+ es1800_child_ops.to_xfer_memory = es1800_xfer_inferior_memory;
+ es1800_child_ops.to_files_info = es1800_files_info;
+ es1800_child_ops.to_insert_breakpoint = es1800_insert_breakpoint;
+ es1800_child_ops.to_remove_breakpoint = es1800_remove_breakpoint;
+ es1800_child_ops.to_terminal_init = NULL;
+ es1800_child_ops.to_terminal_inferior = NULL;
+ es1800_child_ops.to_terminal_ours_for_output = NULL;
+ es1800_child_ops.to_terminal_ours = NULL;
+ es1800_child_ops.to_terminal_info = NULL;
+ es1800_child_ops.to_kill = es1800_kill;
+ es1800_child_ops.to_load = es1800_load;
+ es1800_child_ops.to_lookup_symbol = NULL;
+ es1800_child_ops.to_create_inferior = es1800_create_inferior;
+ es1800_child_ops.to_post_startup_inferior = NULL;
+ es1800_child_ops.to_acknowledge_created_inferior = NULL;
+ es1800_child_ops.to_clone_and_follow_inferior = NULL;
+ es1800_child_ops.to_post_follow_inferior_by_clone = NULL;
+ es1800_child_ops.to_insert_fork_catchpoint = NULL;
+ es1800_child_ops.to_remove_fork_catchpoint = NULL;
+ es1800_child_ops.to_insert_vfork_catchpoint = NULL;
+ es1800_child_ops.to_remove_vfork_catchpoint = NULL;
+ es1800_child_ops.to_has_forked = NULL;
+ es1800_child_ops.to_has_vforked = NULL;
+ es1800_child_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ es1800_child_ops.to_post_follow_vfork = NULL;
+ es1800_child_ops.to_insert_exec_catchpoint = NULL;
+ es1800_child_ops.to_remove_exec_catchpoint = NULL;
+ es1800_child_ops.to_has_execd = NULL;
+ es1800_child_ops.to_reported_exec_events_per_exec_call = NULL;
+ es1800_child_ops.to_has_exited = NULL;
+ es1800_child_ops.to_mourn_inferior = es1800_mourn_inferior;
+ es1800_child_ops.to_can_run = 0;
+ es1800_child_ops.to_notice_signals = 0;
+ es1800_child_ops.to_thread_alive = 0;
+ es1800_child_ops.to_stop = 0;
+ es1800_child_ops.to_pid_to_exec_file = NULL;
+ es1800_child_ops.to_core_file_to_sym_file = NULL;
+ es1800_child_ops.to_stratum = process_stratum;
+ es1800_child_ops.DONT_USE = 0;
+ es1800_child_ops.to_has_all_memory = 1;
+ es1800_child_ops.to_has_memory = 1;
+ es1800_child_ops.to_has_stack = 1;
+ es1800_child_ops.to_has_registers = 1;
+ es1800_child_ops.to_has_execution = 1;
+ es1800_child_ops.to_sections = NULL;
+ es1800_child_ops.to_sections_end = NULL;
+ es1800_child_ops.to_magic = OPS_MAGIC;
+}
void
_initialize_es1800 ()
{
+ init_es1800_ops() ;
+ init_es1800_child_ops() ;
add_target (&es1800_ops);
add_target (&es1800_child_ops);
#ifdef PROVIDE_TRANSPARENT
diff --git a/contrib/gdb/gdb/remote-est.c b/contrib/gdb/gdb/remote-est.c
index cfa9731..27fd8aa 100644
--- a/contrib/gdb/gdb/remote-est.c
+++ b/contrib/gdb/gdb/remote-est.c
@@ -95,61 +95,57 @@ static struct target_ops est_ops;
static char *est_inits[] = {"he\r", /* Resets the prompt, and clears repeated cmds */
NULL};
-static struct monitor_ops est_cmds =
+static struct monitor_ops est_cmds ;
+
+static void
+init_est_cmds(void)
{
- MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT,
- est_inits, /* Init strings */
- "go\r", /* continue command */
- "sidr\r", /* single step */
- "\003", /* ^C interrupts the program */
- "sb %x\r", /* set a breakpoint */
- "rb %x\r", /* clear a breakpoint */
- "rb\r", /* clear all breakpoints */
- "bfb %x %x %x\r", /* fill (start end val) */
- {
- "smb %x %x\r", /* setmem.cmdb (addr, value) */
- "smw %x %x\r", /* setmem.cmdw (addr, value) */
- "sml %x %x\r", /* setmem.cmdl (addr, value) */
- NULL, /* setmem.cmdll (addr, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL, /* setreg.term_cmd */
- },
- {
- "dmb %x %x\r", /* getmem.cmdb (addr, len) */
- "dmw %x %x\r", /* getmem.cmdw (addr, len) */
- "dml %x %x\r", /* getmem.cmdl (addr, len) */
- NULL, /* getmem.cmdll (addr, len) */
- ": ", /* getmem.resp_delim */
- NULL, /* getmem.term */
- NULL, /* getmem.term_cmd */
- },
- {
- "sr %s %x\r", /* setreg.cmd (name, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL /* setreg.term_cmd */
- },
- {
- "dr %s\r", /* getreg.cmd (name) */
- " = ", /* getreg.resp_delim */
- NULL, /* getreg.term */
- NULL /* getreg.term_cmd */
- },
- "dr\r", /* dump_registers */
- "\\(\\w+\\) = \\([0-9a-fA-F]+\\)", /* register_pattern */
- est_supply_register, /* supply_register */
- NULL, /* load_routine (defaults to SRECs) */
- "dl\r", /* download command */
- "+", /* load response */
- ">BKM>", /* monitor command prompt */
- "\r", /* end-of-line terminator */
- NULL, /* optional command terminator */
- &est_ops, /* target operations */
- SERIAL_1_STOPBITS, /* number of stop bits */
- est_regnames, /* registers names */
- MONITOR_OPS_MAGIC /* magic */
- };
+ est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT |
+ MO_SREC_ACK | MO_SREC_ACK_PLUS ;
+ est_cmds.init = est_inits; /* Init strings */
+ est_cmds.cont = "go\r"; /* continue command */
+ est_cmds.step = "sidr\r"; /* single step */
+ est_cmds.stop = "\003"; /* ^C interrupts the program */
+ est_cmds.set_break = "sb %x\r"; /* set a breakpoint */
+ est_cmds.clr_break = "rb %x\r"; /* clear a breakpoint */
+ est_cmds.clr_all_break = "rb\r"; /* clear all breakpoints */
+ est_cmds.fill = "bfb %x %x %x\r"; /* fill (start end val) */
+ est_cmds.setmem.cmdb = "smb %x %x\r"; /* setmem.cmdb (addr, value) */
+ est_cmds.setmem.cmdw = "smw %x %x\r"; /* setmem.cmdw (addr, value) */
+ est_cmds.setmem.cmdl = "sml %x %x\r"; /* setmem.cmdl (addr, value) */
+ est_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ est_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ est_cmds.setmem.term = NULL; /* setreg.term */
+ est_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ est_cmds.getmem.cmdb = "dmb %x %x\r"; /* getmem.cmdb (addr, len) */
+ est_cmds.getmem.cmdw = "dmw %x %x\r"; /* getmem.cmdw (addr, len) */
+ est_cmds.getmem.cmdl = "dml %x %x\r"; /* getmem.cmdl (addr, len) */
+ est_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ est_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ est_cmds.getmem.term = NULL; /* getmem.term */
+ est_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ est_cmds.setreg.cmd = "sr %s %x\r"; /* setreg.cmd (name, value) */
+ est_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ est_cmds.setreg.term = NULL; /* setreg.term */
+ est_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ est_cmds.getreg.cmd = "dr %s\r"; /* getreg.cmd (name) */
+ est_cmds.getreg.resp_delim = " = "; /* getreg.resp_delim */
+ est_cmds.getreg.term = NULL; /* getreg.term */
+ est_cmds.getreg.term_cmd = NULL ; /* getreg.term_cmd */
+ est_cmds.dump_registers = "dr\r"; /* dump_registers */
+ est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)"; /* register_pattern */
+ est_cmds.supply_register = est_supply_register; /* supply_register */
+ est_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ est_cmds.load = "dl\r"; /* download command */
+ est_cmds.loadresp = "+"; /* load response */
+ est_cmds.prompt = ">BKM>"; /* monitor command prompt */
+ est_cmds.line_term = "\r"; /* end-of-line terminator */
+ est_cmds.cmd_end = NULL; /* optional command terminator */
+ est_cmds.target = &est_ops; /* target operations */
+ est_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ est_cmds.regnames = est_regnames; /* registers names */
+ est_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */
+} /* init_est_cmds */
static void
est_open(args, from_tty)
@@ -162,6 +158,7 @@ est_open(args, from_tty)
void
_initialize_est ()
{
+ init_est_cmds() ;
init_monitor_ops (&est_ops);
est_ops.to_shortname = "est";
diff --git a/contrib/gdb/gdb/remote-hms.c b/contrib/gdb/gdb/remote-hms.c
index 2f43e20..3ca8455 100644
--- a/contrib/gdb/gdb/remote-hms.c
+++ b/contrib/gdb/gdb/remote-hms.c
@@ -26,7 +26,6 @@
#include "serial.h"
static void hms_open PARAMS ((char *args, int from_tty));
-
static void
hms_supply_register (regname, regnamelen, val, vallen)
char *regname;
@@ -83,61 +82,56 @@ static char *hms_inits[] =
{"\003", /* Resets the prompt, and clears repeated cmds */
NULL};
-static struct monitor_ops hms_cmds =
+static struct monitor_ops hms_cmds ;
+
+static void
+init_hms_cmds(void)
{
- MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE,
- hms_inits, /* Init strings */
- "g\r", /* continue command */
- "s\r", /* single step */
- "\003", /* ^C interrupts the program */
- "b %x\r", /* set a breakpoint */
- "b - %x\r", /* clear a breakpoint */
- "b -\r", /* clear all breakpoints */
- "f %x %x %x\r", /* fill (start end val) */
- {
- "m.b %x=%x\r", /* setmem.cmdb (addr, value) */
- "m.w %x=%x\r", /* setmem.cmdw (addr, value) */
- NULL, /* setmem.cmdl (addr, value) */
- NULL, /* setmem.cmdll (addr, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL, /* setreg.term_cmd */
- },
- {
- "m.b %x %x\r", /* getmem.cmdb (addr, addr) */
- "m.w %x %x\r", /* getmem.cmdw (addr, addr) */
- NULL, /* getmem.cmdl (addr, addr) */
- NULL, /* getmem.cmdll (addr, addr) */
- ": ", /* getmem.resp_delim */
- ">", /* getmem.term */
- "\003", /* getmem.term_cmd */
- },
- {
- "r %s=%x\r", /* setreg.cmd (name, value) */
- NULL, /* setreg.resp_delim */
- NULL, /* setreg.term */
- NULL /* setreg.term_cmd */
- },
- {
- "r %s\r", /* getreg.cmd (name) */
- " (", /* getreg.resp_delim */
- ":", /* getreg.term */
- "\003", /* getreg.term_cmd */
- },
- "r\r", /* dump_registers */
- "\\(\\w+\\)=\\([0-9a-fA-F]+\\)", /* register_pattern */
- hms_supply_register, /* supply_register */
- NULL, /* load_routine (defaults to SRECs) */
- "tl\r", /* download command */
- NULL, /* load response */
- ">", /* monitor command prompt */
- "\r", /* end-of-command delimitor */
- NULL, /* optional command terminator */
- &hms_ops, /* target operations */
- SERIAL_1_STOPBITS, /* number of stop bits */
- hms_regnames, /* registers names */
- MONITOR_OPS_MAGIC /* magic */
-};
+ hms_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE;
+ hms_cmds.init = hms_inits; /* Init strings */
+ hms_cmds.cont = "g\r"; /* continue command */
+ hms_cmds.step = "s\r"; /* single step */
+ hms_cmds.stop = "\003"; /* ^C interrupts the program */
+ hms_cmds.set_break = "b %x\r"; /* set a breakpoint */
+ hms_cmds.clr_break = "b - %x\r"; /* clear a breakpoint */
+ hms_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
+ hms_cmds.fill = "f %x %x %x\r"; /* fill (start end val) */
+ hms_cmds.setmem.cmdb = "m.b %x=%x\r"; /* setmem.cmdb (addr, value) */
+ hms_cmds.setmem.cmdw = "m.w %x=%x\r"; /* setmem.cmdw (addr, value) */
+ hms_cmds.setmem.cmdl = NULL; /* setmem.cmdl (addr, value) */
+ hms_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ hms_cmds.setmem.resp_delim = NULL;/* setreg.resp_delim */
+ hms_cmds.setmem.term = NULL; /* setreg.term */
+ hms_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ hms_cmds.getmem.cmdb = "m.b %x %x\r"; /* getmem.cmdb (addr, addr) */
+ hms_cmds.getmem.cmdw = "m.w %x %x\r"; /* getmem.cmdw (addr, addr) */
+ hms_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, addr) */
+ hms_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr) */
+ hms_cmds.getmem.resp_delim = ": ";/* getmem.resp_delim */
+ hms_cmds.getmem.term = ">"; /* getmem.term */
+ hms_cmds.getmem.term_cmd = "\003";/* getmem.term_cmd */
+ hms_cmds.setreg.cmd = "r %s=%x\r";/* setreg.cmd (name, value) */
+ hms_cmds.setreg.resp_delim = NULL;/* setreg.resp_delim */
+ hms_cmds.setreg.term = NULL; /* setreg.term */
+ hms_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ hms_cmds.getreg.cmd = "r %s\r"; /* getreg.cmd (name) */
+ hms_cmds.getreg.resp_delim = " (";/* getreg.resp_delim */
+ hms_cmds.getreg.term = ":"; /* getreg.term */
+ hms_cmds.getreg.term_cmd = "\003";/* getreg.term_cmd */
+ hms_cmds.dump_registers = "r\r"; /* dump_registers */
+ hms_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
+ hms_cmds.supply_register = hms_supply_register; /* supply_register */
+ hms_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ hms_cmds.load = "tl\r"; /* download command */
+ hms_cmds.loadresp = NULL; /* load response */
+ hms_cmds.prompt = ">"; /* monitor command prompt */
+ hms_cmds.line_term = "\r"; /* end-of-command delimitor */
+ hms_cmds.cmd_end = NULL; /* optional command terminator */
+ hms_cmds.target = &hms_ops; /* target operations */
+ hms_cmds.stopbits = SERIAL_1_STOPBITS;/* number of stop bits */
+ hms_cmds.regnames = hms_regnames; /* registers names */
+ hms_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_hms-cmds */
static void
hms_open (args, from_tty)
@@ -152,6 +146,7 @@ int write_dos_tick_delay;
void
_initialize_remote_hms ()
{
+ init_hms_cmds() ;
init_monitor_ops (&hms_ops);
hms_ops.to_shortname = "hms";
@@ -164,7 +159,6 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
add_target (&hms_ops);
}
-
#if 0
/* This is kept here because we used to support the H8/500 in this module,
and I haven't done the H8/500 yet */
@@ -419,7 +413,7 @@ hms_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote hms process.");
if (execfile == 0 || exec_bfd == 0)
- error ("No exec file specified");
+ error ("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
check_open ();
@@ -924,7 +918,7 @@ hms_fetch_register (dummy)
int s;
int gottok;
- unsigned LONGEST reg[NUM_REGS];
+ ULONGEST reg[NUM_REGS];
check_open ();
@@ -1327,33 +1321,75 @@ hms_open (name, from_tty)
/* Define the target subroutine names */
-struct target_ops hms_ops =
+struct target_ops hms_ops ;
+
+static void
+init_hms_ops(void)
{
- "hms", "Remote HMS monitor",
- "Use the H8 evaluation board running the HMS monitor connected\n\
-by a serial line.",
-
- hms_open, hms_close,
- 0, hms_detach, hms_resume, hms_wait, /* attach */
- hms_fetch_register, hms_store_register,
- hms_prepare_to_store,
- hms_xfer_inferior_memory,
- hms_files_info,
- hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
- 0, 0, 0, 0, 0, /* Terminal handling */
- hms_kill, /* FIXME, kill */
- generic_load,
- 0, /* lookup_symbol */
- hms_create_inferior, /* create_inferior */
- hms_mourn, /* mourn_inferior FIXME */
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0, 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
+ hms_ops.to_shortname = "hms";
+ hms_ops.to_longname = "Remote HMS monitor";
+ hms_ops.to_doc = "Use the H8 evaluation board running the HMS monitor connected\n\
+by a serial line.";
+ hms_ops.to_open = hms_open;
+ hms_ops.to_close = hms_close;
+ hms_ops.to_attach = 0;
+ hms_ops.to_post_attach = NULL;
+ hms_ops.to_require_attach = NULL;
+ hms_ops.to_detach = hms_detach;
+ hms_ops.to_require_detach = NULL;
+ hms_ops.to_resume = hms_resume;
+ hms_ops.to_wait = hms_wait;
+ hms_ops.to_post_wait = NULL;
+ hms_ops.to_fetch_registers = hms_fetch_register;
+ hms_ops.to_store_registers = hms_store_register;
+ hms_ops.to_prepare_to_store = hms_prepare_to_store;
+ hms_ops.to_xfer_memory = hms_xfer_inferior_memory;
+ hms_ops.to_files_info = hms_files_info;
+ hms_ops.to_insert_breakpoint = hms_insert_breakpoint;
+ hms_ops.to_remove_breakpoint = hms_remove_breakpoint;
+ hms_ops.to_terminal_init = 0;
+ hms_ops.to_terminal_inferior = 0;
+ hms_ops.to_terminal_ours_for_output = 0;
+ hms_ops.to_terminal_ours = 0;
+ hms_ops.to_terminal_info = 0;
+ hms_ops.to_kill = hms_kill;
+ hms_ops.to_load = generic_load;
+ hms_ops.to_lookup_symbol = 0;
+ hms_ops.to_create_inferior = hms_create_inferior;
+ hms_ops.to_post_startup_inferior = NULL;
+ hms_ops.to_acknowledge_created_inferior = NULL;
+ hms_ops.to_clone_and_follow_inferior = NULL;
+ hms_ops.to_post_follow_inferior_by_clone = NULL;
+ hms_ops.to_insert_fork_catchpoint = NULL;
+ hms_ops.to_remove_fork_catchpoint = NULL;
+ hms_ops.to_insert_vfork_catchpoint = NULL;
+ hms_ops.to_remove_vfork_catchpoint = NULL;
+ hms_ops.to_has_forked = NULL;
+ hms_ops.to_has_vforked = NULL;
+ hms_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ hms_ops.to_post_follow_vfork = NULL;
+ hms_ops.to_insert_exec_catchpoint = NULL;
+ hms_ops.to_remove_exec_catchpoint = NULL;
+ hms_ops.to_has_execd = NULL;
+ hms_ops.to_reported_exec_events_per_exec_call = NULL;
+ hms_ops.to_has_exited = NULL;
+ hms_ops.to_mourn_inferior = hms_mourn;
+ hms_ops.to_can_run = 0;
+ hms_ops.to_notice_signals = 0;
+ hms_ops.to_thread_alive = 0;
+ hms_ops.to_stop = 0;
+ hms_ops.to_pid_to_exec_file = NULL;
+ hms_ops.to_core_file_to_sym_file = NULL;
+ hms_ops.to_stratum = process_stratum;
+ hms_ops.DONT_USE = 0;
+ hms_ops.to_has_all_memory = 1;
+ hms_ops.to_has_memory = 1;
+ hms_ops.to_has_stack = 1;
+ hms_ops.to_has_registers = 1;
+ hms_ops.to_has_execution = 1;
+ hms_ops.to_sections = 0;
+ hms_ops.to_sections_end = 0;
+ hms_ops.to_magic = OPS_MAGIC;
};
hms_quiet () /* FIXME - this routine can be removed after Dec '94 */
@@ -1442,6 +1478,7 @@ remove_commands ()
void
_initialize_remote_hms ()
{
+ init_hms_ops() ;
add_target (&hms_ops);
add_com ("hms <command>", class_obscure, hms_com,
diff --git a/contrib/gdb/gdb/remote-mips.c b/contrib/gdb/gdb/remote-mips.c
index 176e1be..c92f8b7 100644
--- a/contrib/gdb/gdb/remote-mips.c
+++ b/contrib/gdb/gdb/remote-mips.c
@@ -29,19 +29,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "serial.h"
#include "target.h"
#include "remote-utils.h"
+#include "gdb_string.h"
#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
#endif
-extern char *mips_read_processor_type PARAMS ((void));
+/* Microsoft C's stat.h doesn't define all the POSIX file modes. */
+#ifndef S_IROTH
+#define S_IROTH S_IREAD
+#endif
extern void mips_set_processor_type_command PARAMS ((char *, int));
+/* Breakpoint types. Values 0, 1, and 2 must agree with the watch
+ types passed by breakpoint.c to target_insert_watchpoint.
+ Value 3 is our own invention, and is used for ordinary instruction
+ breakpoints. Value 4 is used to mark an unused watchpoint in tables. */
+enum break_type {
+ BREAK_WRITE, /* 0 */
+ BREAK_READ, /* 1 */
+ BREAK_ACCESS, /* 2 */
+ BREAK_FETCH, /* 3 */
+ BREAK_UNUSED /* 4 */
+};
+
/* Prototypes for local functions. */
static int mips_readchar PARAMS ((int timeout));
@@ -63,8 +81,8 @@ static void mips_send_command PARAMS ((const char *cmd, int prompt));
static int mips_receive_packet PARAMS ((char *buff, int throw_error,
int timeout));
-static int mips_request PARAMS ((int cmd, unsigned int addr,
- unsigned int data, int *perr, int timeout,
+static CORE_ADDR mips_request PARAMS ((int cmd, CORE_ADDR addr,
+ CORE_ADDR data, int *perr, int timeout,
char *buff));
static void mips_initialize PARAMS ((void));
@@ -73,6 +91,10 @@ static void mips_open PARAMS ((char *name, int from_tty));
static void pmon_open PARAMS ((char *name, int from_tty));
+static void ddb_open PARAMS ((char *name, int from_tty));
+
+static void lsi_open PARAMS ((char *name, int from_tty));
+
static void mips_close PARAMS ((int quitting));
static void mips_detach PARAMS ((char *args, int from_tty));
@@ -82,8 +104,6 @@ static void mips_resume PARAMS ((int pid, int step,
static int mips_wait PARAMS ((int pid, struct target_waitstatus *status));
-static int pmon_wait PARAMS ((int pid, struct target_waitstatus *status));
-
static int mips_map_regno PARAMS ((int regno));
static void mips_fetch_registers PARAMS ((int regno));
@@ -92,9 +112,9 @@ static void mips_prepare_to_store PARAMS ((void));
static void mips_store_registers PARAMS ((int regno));
-static int mips_fetch_word PARAMS ((CORE_ADDR addr));
+static unsigned int mips_fetch_word PARAMS ((CORE_ADDR addr));
-static int mips_store_word PARAMS ((CORE_ADDR addr, int value,
+static int mips_store_word PARAMS ((CORE_ADDR addr, unsigned int value,
char *old_contents));
static int mips_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len,
@@ -118,7 +138,13 @@ static void pmon_make_fastrec PARAMS ((char **outbuf, unsigned char *inbuf,
int *inptr, int inamount, int *recsize,
unsigned int *csum, unsigned int *zerofill));
-static int pmon_check_ack PARAMS ((void));
+static int pmon_check_ack PARAMS ((char *mesg));
+
+static void pmon_start_download PARAMS ((void));
+
+static void pmon_end_download PARAMS ((int final, int bintotal));
+
+static void pmon_download PARAMS ((char *buffer, int length));
static void pmon_load_fast PARAMS ((char *file));
@@ -127,14 +153,19 @@ static void mips_load PARAMS ((char *file, int from_tty));
static int mips_make_srec PARAMS ((char *buffer, int type, CORE_ADDR memaddr,
unsigned char *myaddr, int len));
-static int common_breakpoint PARAMS ((int cmd, CORE_ADDR addr, CORE_ADDR mask,
- char *flags));
+static int set_breakpoint PARAMS ((CORE_ADDR addr, int len,
+ enum break_type type));
+
+static int clear_breakpoint PARAMS ((CORE_ADDR addr, int len,
+ enum break_type type));
+
+static int common_breakpoint PARAMS ((int set, CORE_ADDR addr, int len,
+ enum break_type type));
-static void common_open PARAMS ((struct target_ops *ops, char *name,
- int from_tty));
/* Forward declarations. */
extern struct target_ops mips_ops;
extern struct target_ops pmon_ops;
+extern struct target_ops ddb_ops;
/* The MIPS remote debugging interface is built on top of a simple
packet protocol. Each packet is organized as follows:
@@ -238,7 +269,7 @@ extern struct target_ops pmon_ops;
(((hdr)[HDR_INDX_TYPE_LEN] & TYPE_LEN_DA_BIT) == TYPE_LEN_DATA)
#define HDR_GET_LEN(hdr) \
((((hdr)[HDR_INDX_TYPE_LEN] & 0x1f) << 6) + (((hdr)[HDR_INDX_LEN1] & 0x3f)))
-#define HDR_GET_SEQ(hdr) ((hdr)[HDR_INDX_SEQ] & 0x3f)
+#define HDR_GET_SEQ(hdr) ((unsigned int)(hdr)[HDR_INDX_SEQ] & 0x3f)
/* The maximum data length. */
#define DATA_MAXLEN 1023
@@ -270,27 +301,41 @@ extern struct target_ops pmon_ops;
/* The sequence number modulos. */
#define SEQ_MODULOS (64)
+/* PMON commands to load from the serial port or UDP socket. */
+#define LOAD_CMD "load -b -s tty0\r"
+#define LOAD_CMD_UDP "load -b -s udp\r"
+
+/* The target vectors for the four different remote MIPS targets.
+ These are initialized with code in _initialize_remote_mips instead
+ of static initializers, to make it easier to extend the target_ops
+ vector later. */
+struct target_ops mips_ops, pmon_ops, ddb_ops, lsi_ops;
+
enum mips_monitor_type {
/* IDT/SIM monitor being used: */
MON_IDT,
/* PMON monitor being used: */
- MON_PMON,
+ MON_PMON, /* 3.0.83 [COGENT,EB,FP,NET] Algorithmics Ltd. Nov 9 1995 17:19:50 */
+ MON_DDB, /* 2.7.473 [DDBVR4300,EL,FP,NET] Risq Modular Systems, Thu Jun 6 09:28:40 PDT 1996 */
+ MON_LSI, /* 4.3.12 [EB,FP], LSI LOGIC Corp. Tue Feb 25 13:22:14 1997 */
/* Last and unused value, for sizing vectors, etc. */
MON_LAST
};
static enum mips_monitor_type mips_monitor = MON_LAST;
-/* The default monitor prompt text: */
-static char *mips_monitor_prompt = TARGET_MONITOR_PROMPT;
-/* For the Cogent PMON world this is still not ideal. The default
- prompt is "PMON> ", unfortunately the user can change the prompt
- and the new prompt will survive over a power-cycle (EEPROM). This
- means that the code should really force the monitor prompt to a
- known value as the very first action, and that the
- "mips_monitor_prompt" support is not needed... since the prompt
- could be explicitly set to TARGET_MONITOR_PROMPT (even though it
- may be the prompt for a different monitor). However, this will
- require changing the mips_initialize reset sequence. (TODO) */
+/* The monitor prompt text. If the user sets the PMON prompt
+ to some new value, the GDB `set monitor-prompt' command must also
+ be used to inform GDB about the expected prompt. Otherwise, GDB
+ will not be able to connect to PMON in mips_initialize().
+ If the `set monitor-prompt' command is not used, the expected
+ default prompt will be set according the target:
+ target prompt
+ ----- -----
+ pmon PMON>
+ ddb NEC010>
+ lsi PMON>
+*/
+static char *mips_monitor_prompt;
/* Set to 1 if the target is open. */
static int mips_is_open;
@@ -301,6 +346,9 @@ static struct target_ops *current_ops;
/* Set to 1 while the connection is being initialized. */
static int mips_initializing;
+/* Set to 1 while the connection is being brought down. */
+static int mips_exiting;
+
/* The next sequence number to send. */
static unsigned int mips_send_seq;
@@ -327,6 +375,17 @@ static int mips_need_reply = 0;
/* Handle used to access serial I/O stream. */
static serial_t mips_desc;
+/* UDP handle used to download files to target. */
+static serial_t udp_desc;
+static int udp_in_use;
+
+/* TFTP filename used to download files to DDB board, in the form
+ host:filename. */
+static char *tftp_name; /* host:filename */
+static char *tftp_localname; /* filename portion of above */
+static int tftp_in_use;
+static FILE *tftp_file;
+
/* Counts the number of times the user tried to interrupt the target (usually
via ^C. */
static int interrupt_count;
@@ -339,11 +398,83 @@ static monitor_supports_breakpoints = 0;
/* Data cache header. */
+#if 0 /* not used (yet?) */
static DCACHE *mips_dcache;
+#endif
/* Non-zero means that we've just hit a read or write watchpoint */
static int hit_watchpoint;
+/* Table of breakpoints/watchpoints (used only on LSI PMON target).
+ The table is indexed by a breakpoint number, which is an integer
+ from 0 to 255 returned by the LSI PMON when a breakpoint is set.
+*/
+#define MAX_LSI_BREAKPOINTS 256
+struct lsi_breakpoint_info
+{
+ enum break_type type; /* type of breakpoint */
+ CORE_ADDR addr; /* address of breakpoint */
+ int len; /* length of region being watched */
+ unsigned long value; /* value to watch */
+} lsi_breakpoints [MAX_LSI_BREAKPOINTS];
+
+/* Error/warning codes returned by LSI PMON for breakpoint commands.
+ Warning values may be ORed together; error values may not. */
+#define W_WARN 0x100 /* This bit is set if the error code is a warning */
+#define W_MSK 0x101 /* warning: Range feature is supported via mask */
+#define W_VAL 0x102 /* warning: Value check is not supported in hardware */
+#define W_QAL 0x104 /* warning: Requested qualifiers are not supported in hardware */
+
+#define E_ERR 0x200 /* This bit is set if the error code is an error */
+#define E_BPT 0x200 /* error: No such breakpoint number */
+#define E_RGE 0x201 /* error: Range is not supported */
+#define E_QAL 0x202 /* error: The requested qualifiers can not be used */
+#define E_OUT 0x203 /* error: Out of hardware resources */
+#define E_NON 0x204 /* error: Hardware breakpoint not supported */
+
+struct lsi_error
+{
+ int code; /* error code */
+ char *string; /* string associated with this code */
+};
+
+struct lsi_error lsi_warning_table[] =
+{
+ { W_MSK, "Range feature is supported via mask" },
+ { W_VAL, "Value check is not supported in hardware" },
+ { W_QAL, "Requested qualifiers are not supported in hardware" },
+ { 0, NULL }
+};
+
+struct lsi_error lsi_error_table[] =
+{
+ { E_BPT, "No such breakpoint number" },
+ { E_RGE, "Range is not supported" },
+ { E_QAL, "The requested qualifiers can not be used" },
+ { E_OUT, "Out of hardware resources" },
+ { E_NON, "Hardware breakpoint not supported" },
+ { 0, NULL }
+};
+
+/* Set to 1 with the 'set monitor-warnings' command to enable printing
+ of warnings returned by PMON when hardware breakpoints are used. */
+static int monitor_warnings;
+
+
+static void
+close_ports()
+{
+ mips_is_open = 0;
+ SERIAL_CLOSE (mips_desc);
+
+ if (udp_in_use)
+ {
+ SERIAL_CLOSE (udp_desc);
+ udp_in_use = 0;
+ }
+ tftp_in_use = 0;
+}
+
/* Handle low-level error that we can't recover from. Note that just
error()ing out from target_wait or some such low-level place will cause
all hell to break loose--the rest of GDB will tend to get left in an
@@ -380,8 +511,7 @@ mips_error (va_alist)
/* Clean up in such a way that mips_close won't try to talk to the
board (it almost surely won't work since we weren't able to talk to
it). */
- mips_is_open = 0;
- SERIAL_CLOSE (mips_desc);
+ close_ports ();
printf_unfiltered ("Ending remote MIPS debugging.\n");
target_mourn_inferior ();
@@ -389,15 +519,58 @@ mips_error (va_alist)
return_to_top_level (RETURN_ERROR);
}
+/* putc_readable - print a character, displaying non-printable chars in
+ ^x notation or in hex. */
+
+static void
+putc_readable (ch)
+ int ch;
+{
+ if (ch == '\n')
+ putchar_unfiltered ('\n');
+ else if (ch == '\r')
+ printf_unfiltered ("\\r");
+ else if (ch < 0x20) /* ASCII control character */
+ printf_unfiltered ("^%c", ch + '@');
+ else if (ch >= 0x7f) /* non-ASCII characters (rubout or greater) */
+ printf_unfiltered ("[%02x]", ch & 0xff);
+ else
+ putchar_unfiltered (ch);
+}
+
+
+/* puts_readable - print a string, displaying non-printable chars in
+ ^x notation or in hex. */
+
+static void
+puts_readable (string)
+ char *string;
+{
+ int c;
+
+ while ((c = *string++) != '\0')
+ putc_readable (c);
+}
+
+
/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
- timed out. */
+ timed out. TIMEOUT specifies timeout value in seconds.
+*/
int
-mips_expect (string)
+mips_expect_timeout (string, timeout)
char *string;
+ int timeout;
{
char *p = string;
+ if (remote_debug)
+ {
+ printf_unfiltered ("Expected \"");
+ puts_readable (string);
+ printf_unfiltered ("\", got \"");
+ }
+
immediate_quit = 1;
while (1)
{
@@ -406,16 +579,25 @@ mips_expect (string)
/* Must use SERIAL_READCHAR here cuz mips_readchar would get confused if we
were waiting for the mips_monitor_prompt... */
- c = SERIAL_READCHAR (mips_desc, 2);
+ c = SERIAL_READCHAR (mips_desc, timeout);
if (c == SERIAL_TIMEOUT)
- return 0;
+ {
+ if (remote_debug)
+ printf_unfiltered ("\": FAIL\n");
+ return 0;
+ }
+
+ if (remote_debug)
+ putc_readable (c);
if (c == *p++)
{
if (*p == '\0')
{
immediate_quit = 0;
+ if (remote_debug)
+ printf_unfiltered ("\": OK\n");
return 1;
}
}
@@ -428,6 +610,18 @@ mips_expect (string)
}
}
+/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
+ timed out. The timeout value is hard-coded to 2 seconds. Use
+ mips_expect_timeout if a different timeout value is needed.
+*/
+
+int
+mips_expect (string)
+ char *string;
+{
+ return mips_expect_timeout (string, 2);
+}
+
/* Read the required number of characters into the given buffer (which
is assumed to be large enough). The only failure is a timeout. */
int
@@ -444,7 +638,8 @@ mips_getstring (string, n)
c = SERIAL_READCHAR (mips_desc, 2);
if (c == SERIAL_TIMEOUT) {
- fprintf_unfiltered (stderr, "Failed to read %d characters from target (TIMEOUT)\n", n);
+ fprintf_unfiltered (gdb_stderr,
+ "Failed to read %d characters from target (TIMEOUT)\n", n);
return 0;
}
@@ -475,12 +670,7 @@ mips_readchar (timeout)
{
int ch;
static int state = 0;
- static int mips_monitor_prompt_len = -1;
-
- /* NASTY, since we assume that the prompt does not change after the
- first mips_readchar call: */
- if (mips_monitor_prompt_len = -1)
- mips_monitor_prompt_len = strlen(mips_monitor_prompt);
+ int mips_monitor_prompt_len = strlen (mips_monitor_prompt);
#ifdef MAINTENANCE_CMDS
{
@@ -523,7 +713,8 @@ mips_readchar (timeout)
more than 64 characters long, which ours never are. */
if ((ch == SERIAL_TIMEOUT || ch == '@')
&& state == mips_monitor_prompt_len
- && ! mips_initializing)
+ && ! mips_initializing
+ && ! mips_exiting)
{
if (remote_debug > 0)
/* Don't use _filtered; we can't deal with a QUIT out of
@@ -582,19 +773,7 @@ mips_receive_header (hdr, pgarbage, ch, timeout)
we can't deal with a QUIT out of target_wait. */
if (! mips_initializing || remote_debug > 0)
{
- /* Note that the host's idea of newline may not
- correspond to the target's idea, so recognize
- newline by its actual ASCII code, but write it
- out using the \n notation. */
- if (ch < 0x20 && ch != '\012')
- {
- putchar_unfiltered ('^');
- putchar_unfiltered (ch + 0x40);
- }
- else if (ch == '\012')
- putchar_unfiltered ('\n');
- else
- putchar_unfiltered (ch);
+ putc_readable (ch);
gdb_flush (gdb_stdout);
}
@@ -690,7 +869,7 @@ mips_send_packet (s, get_ack)
const char *s;
int get_ack;
{
- unsigned int len;
+ /* unsigned */ int len;
unsigned char *packet;
register int cksum;
int try;
@@ -747,7 +926,7 @@ mips_send_packet (s, get_ack)
unsigned char hdr[HDR_LENGTH + 1];
unsigned char trlr[TRLR_LENGTH + 1];
int err;
- int seq;
+ unsigned int seq;
/* Get the packet header. If we time out, resend the data
packet. */
@@ -1068,11 +1247,11 @@ mips_receive_packet (buff, throw_error, timeout)
occurs, it sets *PERR to 1 and sets errno according to what the
target board reports. */
-static int
+static CORE_ADDR
mips_request (cmd, addr, data, perr, timeout, buff)
int cmd;
- unsigned int addr;
- unsigned int data;
+ CORE_ADDR addr;
+ CORE_ADDR data;
int *perr;
int timeout;
char *buff;
@@ -1082,7 +1261,7 @@ mips_request (cmd, addr, data, perr, timeout, buff)
int rpid;
char rcmd;
int rerrflg;
- int rresponse;
+ unsigned long rresponse;
if (buff == (char *) NULL)
buff = myBuff;
@@ -1091,7 +1270,7 @@ mips_request (cmd, addr, data, perr, timeout, buff)
{
if (mips_need_reply)
fatal ("mips_request: Trying to send command before reply");
- sprintf (buff, "0x0 %c 0x%x 0x%x", cmd, addr, data);
+ sprintf (buff, "0x0 %c 0x%s 0x%s", cmd, paddr_nz (addr), paddr_nz (data));
mips_send_packet (buff, 1);
mips_need_reply = 1;
}
@@ -1107,7 +1286,7 @@ mips_request (cmd, addr, data, perr, timeout, buff)
len = mips_receive_packet (buff, 1, timeout);
buff[len] = '\0';
- if (sscanf (buff, "0x%x %c 0x%x 0x%x",
+ if (sscanf (buff, "0x%x %c 0x%x 0x%lx",
&rpid, &rcmd, &rerrflg, &rresponse) != 4
|| (cmd != '\0' && rcmd != cmd))
mips_error ("Bad response from remote board");
@@ -1137,13 +1316,20 @@ mips_initialize_cleanups (arg)
}
static void
+mips_exit_cleanups (arg)
+ PTR arg;
+{
+ mips_exiting = 0;
+}
+
+static void
mips_send_command (cmd, prompt)
const char *cmd;
int prompt;
{
SERIAL_WRITE (mips_desc, cmd, strlen(cmd));
mips_expect (cmd);
- mips_expect ("\012");
+ mips_expect ("\n");
if (prompt)
mips_expect (mips_monitor_prompt);
}
@@ -1156,19 +1342,20 @@ mips_enter_debug ()
mips_send_seq = 0;
mips_receive_seq = 0;
- if (mips_monitor == MON_PMON)
- mips_send_command ("debug\015", 0);
+ if (mips_monitor != MON_IDT)
+ mips_send_command ("debug\r", 0);
else /* assume IDT monitor by default */
- mips_send_command ("db tty0\015", 0);
+ mips_send_command ("db tty0\r", 0);
- SERIAL_WRITE (mips_desc, "\015", sizeof "\015" - 1);
+ sleep(1);
+ SERIAL_WRITE (mips_desc, "\r", sizeof "\r" - 1);
/* We don't need to absorb any spurious characters here, since the
mips_receive_header will eat up a reasonable number of characters
whilst looking for the SYN, however this avoids the "garbage"
being displayed to the user. */
- if (mips_monitor == MON_PMON)
- mips_expect ("\015");
+ if (mips_monitor != MON_IDT)
+ mips_expect ("\r");
{
char buff[DATA_MAXLEN + 1];
@@ -1182,19 +1369,29 @@ static int
mips_exit_debug ()
{
int err;
+ struct cleanup *old_cleanups = make_cleanup (mips_exit_cleanups, NULL);
- mips_request ('x', (unsigned int) 0, (unsigned int) 0, &err,
- mips_receive_wait, NULL);
+ mips_exiting = 1;
- if (mips_monitor == MON_PMON && !mips_expect ("Exiting remote debug mode"))
- return -1;
-
- if (!mips_expect ("\015\012"))
- return -1;
+ if (mips_monitor != MON_IDT)
+ {
+ /* The DDB (NEC) and MiniRISC (LSI) versions of PMON exit immediately,
+ so we do not get a reply to this command: */
+ mips_request ('x', (unsigned int) 0, (unsigned int) 0, NULL,
+ mips_receive_wait, NULL);
+ mips_need_reply = 0;
+ if (!mips_expect (" break!"))
+ return -1;
+ }
+ else
+ mips_request ('x', (unsigned int) 0, (unsigned int) 0, &err,
+ mips_receive_wait, NULL);
if (!mips_expect (mips_monitor_prompt))
return -1;
+ do_cleanups (old_cleanups);
+
return 0;
}
@@ -1226,7 +1423,7 @@ mips_initialize ()
/* Force the system into the monitor. After this we *should* be at
the mips_monitor_prompt. */
- if (mips_monitor == MON_PMON)
+ if (mips_monitor != MON_IDT)
j = 0; /* start by checking if we are already at the prompt */
else
j = 1; /* start by sending a break */
@@ -1236,7 +1433,7 @@ mips_initialize ()
{
case 0: /* First, try sending a CR */
SERIAL_FLUSH_INPUT (mips_desc);
- SERIAL_WRITE (mips_desc, "\015", 1);
+ SERIAL_WRITE (mips_desc, "\r", 1);
break;
case 1: /* First, try sending a break */
SERIAL_SEND_BREAK (mips_desc);
@@ -1246,7 +1443,7 @@ mips_initialize ()
break;
case 3: /* Then, try escaping from download */
{
- if (mips_monitor == MON_PMON)
+ if (mips_monitor != MON_IDT)
{
char tbuff[7];
@@ -1257,7 +1454,7 @@ mips_initialize ()
we flush the output buffer before inserting a
termination sequence. */
SERIAL_FLUSH_OUTPUT (mips_desc);
- sprintf (tbuff, "\015/E/E\015");
+ sprintf (tbuff, "\r/E/E\r");
SERIAL_WRITE (mips_desc, tbuff, 6);
}
else
@@ -1295,14 +1492,20 @@ mips_initialize ()
break;
}
- if (mips_monitor == MON_PMON)
+ if (mips_monitor != MON_IDT)
{
+ /* Sometimes PMON ignores the first few characters in the first
+ command sent after a load. Sending a blank command gets
+ around that. */
+ mips_send_command ("\r", -1);
+
/* Ensure the correct target state: */
- mips_send_command ("set regsize 64\015", -1);
- mips_send_command ("set hostport tty0\015", -1);
- mips_send_command ("set brkcmd \"\"\015", -1);
+ if (mips_monitor != MON_LSI)
+ mips_send_command ("set regsize 64\r", -1);
+ mips_send_command ("set hostport tty0\r", -1);
+ mips_send_command ("set brkcmd \"\"\r", -1);
/* Delete all the current breakpoints: */
- mips_send_command ("db *\015", -1);
+ mips_send_command ("db *\r", -1);
/* NOTE: PMON does not have breakpoint support through the
"debug" mode, only at the monitor command-line. */
}
@@ -1310,10 +1513,12 @@ mips_initialize ()
mips_enter_debug ();
/* Clear all breakpoints: */
- if (common_breakpoint ('b', -1, 0, NULL))
- monitor_supports_breakpoints = 0;
+ if ((mips_monitor == MON_IDT
+ && clear_breakpoint (-1, 0, BREAK_UNUSED) == 0)
+ || mips_monitor == MON_LSI)
+ monitor_supports_breakpoints = 1;
else
- monitor_supports_breakpoints = 1;
+ monitor_supports_breakpoints = 0;
do_cleanups (old_cleanups);
@@ -1328,45 +1533,110 @@ mips_initialize ()
/* Open a connection to the remote board. */
static void
-common_open (ops, name, from_tty)
+common_open (ops, name, from_tty, new_monitor, new_monitor_prompt)
struct target_ops *ops;
char *name;
int from_tty;
+ enum mips_monitor_type new_monitor;
+ char *new_monitor_prompt;
{
char *ptype;
+ char *serial_port_name;
+ char *remote_name = 0;
+ char *local_name = 0;
+ char **argv;
if (name == 0)
error (
"To open a MIPS remote debugging connection, you need to specify what serial\n\
-device is attached to the target board (e.g., /dev/ttya).");
+device is attached to the target board (e.g., /dev/ttya).\n"
+"If you want to use TFTP to download to the board, specify the name of a\n"
+"temporary file to be used by GDB for downloads as the second argument.\n"
+"This filename must be in the form host:filename, where host is the name\n"
+"of the host running the TFTP server, and the file must be readable by the\n"
+"world. If the local name of the temporary file differs from the name as\n"
+"seen from the board via TFTP, specify that name as the third parameter.\n");
+
+ /* Parse the serial port name, the optional TFTP name, and the
+ optional local TFTP name. */
+ if ((argv = buildargv (name)) == NULL)
+ nomem(0);
+ make_cleanup ((make_cleanup_func) freeargv, argv);
+
+ serial_port_name = strsave (argv[0]);
+ if (argv[1]) /* remote TFTP name specified? */
+ {
+ remote_name = argv[1];
+ if (argv[2]) /* local TFTP filename specified? */
+ local_name = argv[2];
+ }
target_preopen (from_tty);
if (mips_is_open)
unpush_target (current_ops);
- mips_desc = SERIAL_OPEN (name);
+ /* Open and initialize the serial port. */
+ mips_desc = SERIAL_OPEN (serial_port_name);
if (mips_desc == (serial_t) NULL)
- perror_with_name (name);
+ perror_with_name (serial_port_name);
if (baud_rate != -1)
{
if (SERIAL_SETBAUDRATE (mips_desc, baud_rate))
{
SERIAL_CLOSE (mips_desc);
- perror_with_name (name);
+ perror_with_name (serial_port_name);
}
}
SERIAL_RAW (mips_desc);
+ /* Open and initialize the optional download port. If it is in the form
+ hostname#portnumber, it's a UDP socket. If it is in the form
+ hostname:filename, assume it's the TFTP filename that must be
+ passed to the DDB board to tell it where to get the load file. */
+ if (remote_name)
+ {
+ if (strchr (remote_name, '#'))
+ {
+ udp_desc = SERIAL_OPEN (remote_name);
+ if (!udp_desc)
+ perror_with_name ("Unable to open UDP port");
+ udp_in_use = 1;
+ }
+ else
+ {
+ /* Save the remote and local names of the TFTP temp file. If
+ the user didn't specify a local name, assume it's the same
+ as the part of the remote name after the "host:". */
+ if (tftp_name)
+ free (tftp_name);
+ if (tftp_localname)
+ free (tftp_localname);
+ if (local_name == NULL)
+ if ((local_name = strchr (remote_name, ':')) != NULL)
+ local_name++; /* skip over the colon */
+ if (local_name == NULL)
+ local_name = remote_name; /* local name same as remote name */
+ tftp_name = strsave (remote_name);
+ tftp_localname = strsave (local_name);
+ tftp_in_use = 1;
+ }
+ }
+
current_ops = ops;
mips_is_open = 1;
+ /* Reset the expected monitor prompt if it's never been set before. */
+ if (mips_monitor_prompt == NULL)
+ mips_monitor_prompt = strsave (new_monitor_prompt);
+ mips_monitor = new_monitor;
+
mips_initialize ();
if (from_tty)
- printf_unfiltered ("Remote MIPS debugging using %s\n", name);
+ printf_unfiltered ("Remote MIPS debugging using %s\n", serial_port_name);
/* Switch to using remote target now. */
push_target (ops);
@@ -1389,6 +1659,7 @@ device is attached to the target board (e.g., /dev/ttya).");
set_current_frame (create_new_frame (read_fp (), stop_pc));
select_frame (get_current_frame (), 0);
print_stack_frame (selected_frame, -1, 1);
+ free (serial_port_name);
}
static void
@@ -1396,8 +1667,7 @@ mips_open (name, from_tty)
char *name;
int from_tty;
{
- mips_monitor = MON_IDT;
- common_open (&mips_ops, name, from_tty);
+ common_open (&mips_ops, name, from_tty, MON_IDT, TARGET_MONITOR_PROMPT);
}
static void
@@ -1405,13 +1675,30 @@ pmon_open (name, from_tty)
char *name;
int from_tty;
{
- /* The PMON monitor has a prompt different from the default
- "TARGET_MONITOR_PROMPT": */
- mips_monitor_prompt = "PMON> ";
- mips_monitor = MON_PMON;
- common_open (&pmon_ops, name, from_tty);
+ common_open (&pmon_ops, name, from_tty, MON_PMON, "PMON> ");
}
+static void
+ddb_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ common_open (&ddb_ops, name, from_tty, MON_DDB, "NEC010>");
+}
+
+static void
+lsi_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ int i;
+
+ /* Clear the LSI breakpoint table. */
+ for (i = 0; i < MAX_LSI_BREAKPOINTS; i++)
+ lsi_breakpoints[i].type = BREAK_UNUSED;
+
+ common_open (&lsi_ops, name, from_tty, MON_LSI, "PMON> ");
+}
/* Close a connection to the remote board. */
@@ -1421,14 +1708,10 @@ mips_close (quitting)
{
if (mips_is_open)
{
- int err;
-
- mips_is_open = 0;
-
/* Get the board out of remote debugging mode. */
(void) mips_exit_debug ();
- SERIAL_CLOSE (mips_desc);
+ close_ports ();
}
}
@@ -1451,19 +1734,22 @@ mips_detach (args, from_tty)
}
/* Tell the target board to resume. This does not wait for a reply
- from the board. */
+ from the board, except in the case of single-stepping on LSI boards,
+ where PMON does return a reply. */
static void
mips_resume (pid, step, siggnal)
int pid, step;
enum target_signal siggnal;
{
+ int err;
-
+ /* LSI PMON requires returns a reply packet "0x1 s 0x0 0x57f" after
+ a single step, so we wait for that. */
mips_request (step ? 's' : 'c',
(unsigned int) 1,
(unsigned int) siggnal,
- (int *) NULL,
+ mips_monitor == MON_LSI && step ? &err : (int *) NULL,
mips_receive_wait, NULL);
}
@@ -1500,6 +1786,7 @@ mips_wait (pid, status)
int rpc, rfp, rsp;
char flags[20];
int nfields;
+ int i;
interrupt_count = 0;
hit_watchpoint = 0;
@@ -1522,12 +1809,25 @@ mips_wait (pid, status)
if (err)
mips_error ("Remote failure: %s", safe_strerror (errno));
- nfields = sscanf (buff, "0x%*x %*c 0x%*x 0x%*x 0x%x 0x%x 0x%x 0x%*x %s",
- &rpc, &rfp, &rsp, flags);
+ /* On returning from a continue, the PMON monitor seems to start
+ echoing back the messages we send prior to sending back the
+ ACK. The code can cope with this, but to try and avoid the
+ unnecessary serial traffic, and "spurious" characters displayed
+ to the user, we cheat and reset the debug protocol. The problems
+ seems to be caused by a check on the number of arguments, and the
+ command length, within the monitor causing it to echo the command
+ as a bad packet. */
+ if (mips_monitor == MON_PMON)
+ {
+ mips_exit_debug ();
+ mips_enter_debug ();
+ }
/* See if we got back extended status. If so, pick out the pc, fp, sp, etc... */
- if (nfields == 7 || nfields == 9)
+ nfields = sscanf (buff, "0x%*x %*c 0x%*x 0x%*x 0x%x 0x%x 0x%x 0x%*x %s",
+ &rpc, &rfp, &rsp, flags);
+ if (nfields >= 3)
{
char buf[MAX_REGISTER_RAW_SIZE];
@@ -1555,60 +1855,38 @@ mips_wait (pid, status)
}
}
- /* Translate a MIPS waitstatus. We use constants here rather than WTERMSIG
- and so on, because the constants we want here are determined by the
- MIPS protocol and have nothing to do with what host we are running on. */
- if ((rstatus & 0377) == 0)
- {
- status->kind = TARGET_WAITKIND_EXITED;
- status->value.integer = (((rstatus) >> 8) & 0377);
- }
- else if ((rstatus & 0377) == 0177)
+ if (strcmp (target_shortname, "lsi") == 0)
{
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = mips_signal_from_protocol (((rstatus) >> 8) & 0377);
- }
- else
- {
- status->kind = TARGET_WAITKIND_SIGNALLED;
- status->value.sig = mips_signal_from_protocol (rstatus & 0177);
- }
-
- return 0;
-}
-
-static int
-pmon_wait (pid, status)
- int pid;
- struct target_waitstatus *status;
-{
- int rstatus;
- int err;
- char buff[DATA_MAXLEN];
-
- interrupt_count = 0;
- hit_watchpoint = 0;
+#if 0
+ /* If this is an LSI PMON target, see if we just hit a hardrdware watchpoint.
+ Right now, PMON doesn't give us enough information to determine which
+ breakpoint we hit. So we have to look up the PC in our own table
+ of breakpoints, and if found, assume it's just a normal instruction
+ fetch breakpoint, not a data watchpoint. FIXME when PMON
+ provides some way to tell us what type of breakpoint it is. */
+ int i;
+ CORE_ADDR pc = read_pc();
- /* If we have not sent a single step or continue command, then the
- board is waiting for us to do something. Return a status
- indicating that it is stopped. */
- if (! mips_need_reply)
- {
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = TARGET_SIGNAL_TRAP;
- return 0;
+ hit_watchpoint = 1;
+ for (i = 0; i < MAX_LSI_BREAKPOINTS; i++)
+ {
+ if (lsi_breakpoints[i].addr == pc
+ && lsi_breakpoints[i].type == BREAK_FETCH)
+ {
+ hit_watchpoint = 0;
+ break;
+ }
+ }
+#else
+ /* If a data breakpoint was hit, PMON returns the following packet:
+ 0x1 c 0x0 0x57f 0x1
+ The return packet from an ordinary breakpoint doesn't have the
+ extra 0x01 field tacked onto the end. */
+ if (nfields == 1 && rpc == 1)
+ hit_watchpoint = 1;
+#endif
}
- /* Sit, polling the serial until the target decides to talk to
- us. NOTE: the timeout value we use is used not just for the
- first character, but for all the characters. */
- mips_wait_flag = 1;
- rstatus = mips_request ('\000', (unsigned int) 0, (unsigned int) 0, &err, -1,
- buff);
- mips_wait_flag = 0;
- if (err)
- mips_error ("Remote failure: %s", safe_strerror (errno));
-
/* NOTE: The following (sig) numbers are defined by PMON:
SPP_SIGTRAP 5 breakpoint
SPP_SIGINT 2
@@ -1618,34 +1896,38 @@ pmon_wait (pid, status)
SPP_SIGFPE 8
SPP_SIGTERM 15 */
- /* On returning from a continue, the PMON monitor seems to start
- echoing back the messages we send prior to sending back the
- ACK. The code can cope with this, but to try and avoid the
- unnecessary serial traffic, and "spurious" characters displayed
- to the user, we cheat and reset the debug protocol. The problems
- seems to be caused by a check on the number of arguments, and the
- command length, within the monitor causing it to echo the command
- as a bad packet. */
- mips_exit_debug ();
- mips_enter_debug ();
-
/* Translate a MIPS waitstatus. We use constants here rather than WTERMSIG
and so on, because the constants we want here are determined by the
MIPS protocol and have nothing to do with what host we are running on. */
- if ((rstatus & 0377) == 0)
+ if ((rstatus & 0xff) == 0)
{
status->kind = TARGET_WAITKIND_EXITED;
- status->value.integer = (((rstatus) >> 8) & 0377);
+ status->value.integer = (((rstatus) >> 8) & 0xff);
}
- else if ((rstatus & 0377) == 0177)
+ else if ((rstatus & 0xff) == 0x7f)
{
status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = mips_signal_from_protocol (((rstatus) >> 8) & 0377);
+ status->value.sig = mips_signal_from_protocol (((rstatus) >> 8) & 0xff);
+
+ /* If the stop PC is in the _exit function, assume
+ we hit the 'break 0x3ff' instruction in _exit, so this
+ is not a normal breakpoint. */
+ if (strcmp (target_shortname, "lsi") == 0)
+ {
+ char *func_name;
+ CORE_ADDR func_start;
+ CORE_ADDR pc = read_pc();
+
+ find_pc_partial_function (pc, &func_name, &func_start, NULL);
+ if (func_name != NULL && strcmp (func_name, "_exit") == 0
+ && func_start == pc)
+ status->kind = TARGET_WAITKIND_EXITED;
+ }
}
else
{
status->kind = TARGET_WAITKIND_SIGNALLED;
- status->value.sig = mips_signal_from_protocol (rstatus & 0177);
+ status->value.sig = mips_signal_from_protocol (rstatus & 0x7f);
}
return 0;
@@ -1707,19 +1989,26 @@ mips_fetch_registers (regno)
val = 0;
else
{
-#if 0 /* Unfortunately the PMON version in the Vr4300 board has been
- compiled without the 64bit register access commands. This
- means we cannot get hold of the full register width. */
- if (mips_monitor == MON_PMON)
- val = mips_request ('t', (unsigned int) mips_map_regno (regno),
- (unsigned int) 0, &err, mips_receive_wait, NULL);
+ /* If PMON doesn't support this register, don't waste serial
+ bandwidth trying to read it. */
+ int pmon_reg = mips_map_regno (regno);
+ if (regno != 0 && pmon_reg == 0)
+ val = 0;
else
-#endif
- val = mips_request ('r', (unsigned int) mips_map_regno (regno),
- (unsigned int) 0, &err, mips_receive_wait, NULL);
- if (err)
- mips_error ("Can't read register %d: %s", regno,
- safe_strerror (errno));
+ {
+ /* Unfortunately the PMON version in the Vr4300 board has been
+ compiled without the 64bit register access commands. This
+ means we cannot get hold of the full register width. */
+ if (mips_monitor == MON_DDB)
+ val = (unsigned)mips_request ('t', (unsigned int) pmon_reg,
+ (unsigned int) 0, &err, mips_receive_wait, NULL);
+ else
+ val = mips_request ('r', (unsigned int) pmon_reg,
+ (unsigned int) 0, &err, mips_receive_wait, NULL);
+ if (err)
+ mips_error ("Can't read register %d: %s", regno,
+ safe_strerror (errno));
+ }
}
{
@@ -1756,7 +2045,7 @@ mips_store_registers (regno)
}
mips_request ('R', (unsigned int) mips_map_regno (regno),
- (unsigned int) read_register (regno),
+ read_register (regno),
&err, mips_receive_wait, NULL);
if (err)
mips_error ("Can't write register %d: %s", regno, safe_strerror (errno));
@@ -1764,22 +2053,25 @@ mips_store_registers (regno)
/* Fetch a word from the target board. */
-static int
+static unsigned int
mips_fetch_word (addr)
CORE_ADDR addr;
{
- int val;
+ unsigned int val;
int err;
- val = mips_request ('d', (unsigned int) addr, (unsigned int) 0, &err,
+ /* FIXME! addr was cast to uint! */
+ val = mips_request ('d', addr, (unsigned int) 0, &err,
mips_receive_wait, NULL);
if (err)
{
/* Data space failed; try instruction space. */
- val = mips_request ('i', (unsigned int) addr, (unsigned int) 0, &err,
+ /* FIXME! addr was cast to uint! */
+ val = mips_request ('i', addr, (unsigned int) 0, &err,
mips_receive_wait, NULL);
if (err)
- mips_error ("Can't read address 0x%x: %s", addr, safe_strerror (errno));
+ mips_error ("Can't read address 0x%s: %s",
+ paddr_nz (addr), safe_strerror (errno));
}
return val;
}
@@ -1788,22 +2080,23 @@ mips_fetch_word (addr)
success. If OLD_CONTENTS is non-NULL, put the old contents of that
memory location there. */
+/* FIXME! make sure only 32-bit quantities get stored! */
static int
mips_store_word (addr, val, old_contents)
CORE_ADDR addr;
- int val;
+ unsigned int val;
char *old_contents;
{
int err;
unsigned int oldcontents;
- oldcontents = mips_request ('D', (unsigned int) addr, (unsigned int) val,
+ oldcontents = mips_request ('D', addr, (unsigned int) val,
&err,
mips_receive_wait, NULL);
if (err)
{
/* Data space failed; try instruction space. */
- oldcontents = mips_request ('I', (unsigned int) addr,
+ oldcontents = mips_request ('I', addr,
(unsigned int) val, &err,
mips_receive_wait, NULL);
if (err)
@@ -1871,7 +2164,7 @@ mips_xfer_memory (memaddr, myaddr, len, write, ignore)
if (i % 256 == 255)
{
printf_unfiltered ("*");
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
if (status)
{
@@ -1933,8 +2226,7 @@ Give up (and stop debugging it)? "))
board (it almost surely won't work since we weren't able to talk to
it). */
mips_wait_flag = 0;
- mips_is_open = 0;
- SERIAL_CLOSE (mips_desc);
+ close_ports();
printf_unfiltered ("Ending remote MIPS debugging.\n");
target_mourn_inferior ();
@@ -2007,14 +2299,8 @@ mips_mourn_inferior ()
/* We can write a breakpoint and read the shadow contents in one
operation. */
-/* The IDT board uses an unusual breakpoint value, and sometimes gets
- confused when it sees the usual MIPS breakpoint instruction. */
-
-#define BREAK_INSN (0x00000a0d)
-#define BREAK_INSN_SIZE (4)
-
-/* Insert a breakpoint on targets that don't have any better breakpoint
- support. We read the contents of the target location and stash it,
+/* Insert a breakpoint. On targets that don't have built-in breakpoint
+ support, we read the contents of the target location and stash it,
then overwrite it with a breakpoint instruction. ADDR is the target
location in the target machine. CONTENTS_CACHE is a pointer to
memory allocated for saving the target contents. It is guaranteed
@@ -2026,12 +2312,10 @@ mips_insert_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
- int status;
-
if (monitor_supports_breakpoints)
- return common_breakpoint ('B', addr, 0x3, "f");
-
- return mips_store_word (addr, BREAK_INSN, contents_cache);
+ return set_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH);
+ else
+ return memory_insert_breakpoint (addr, contents_cache);
}
static int
@@ -2040,9 +2324,9 @@ mips_remove_breakpoint (addr, contents_cache)
char *contents_cache;
{
if (monitor_supports_breakpoints)
- return common_breakpoint ('b', addr, 0, NULL);
-
- return target_write_memory (addr, contents_cache, BREAK_INSN_SIZE);
+ return clear_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH);
+ else
+ return memory_remove_breakpoint (addr, contents_cache);
}
#if 0 /* currently not used */
@@ -2073,7 +2357,7 @@ pmon_insert_breakpoint (addr, contents_cache)
if (mips_exit_debug ())
mips_error ("Failed to exit debug mode");
- sprintf (tbuff, "b %08x\015", addr);
+ sprintf (tbuff, "b %08x\r", addr);
mips_send_command (tbuff, 0);
mips_expect ("Bpt ");
@@ -2083,7 +2367,8 @@ pmon_insert_breakpoint (addr, contents_cache)
tbuff[2] = '\0'; /* terminate the string */
if (sscanf (tbuff, "%d", &bpnum) != 1)
{
- fprintf_unfiltered (stderr, "Invalid decimal breakpoint number from target: %s\n", tbuff);
+ fprintf_unfiltered (gdb_stderr,
+ "Invalid decimal breakpoint number from target: %s\n", tbuff);
return 1;
}
@@ -2093,29 +2378,33 @@ pmon_insert_breakpoint (addr, contents_cache)
tbuff[0] = '0';
tbuff[1] = 'x';
+ /* FIXME!! only 8 bytes! need to expand for Bfd64;
+ which targets return 64-bit addresses? PMON returns only 32! */
if (!mips_getstring (&tbuff[2], 8))
return 1;
tbuff[10] = '\0'; /* terminate the string */
if (sscanf (tbuff, "0x%08x", &bpaddr) != 1)
{
- fprintf_unfiltered (stderr, "Invalid hex address from target: %s\n", tbuff);
+ fprintf_unfiltered (gdb_stderr,
+ "Invalid hex address from target: %s\n", tbuff);
return 1;
}
if (bpnum >= PMON_MAX_BP)
{
- fprintf_unfiltered (stderr, "Error: Returned breakpoint number %d outside acceptable range (0..%d)\n",
+ fprintf_unfiltered (gdb_stderr,
+ "Error: Returned breakpoint number %d outside acceptable range (0..%d)\n",
bpnum, PMON_MAX_BP - 1);
return 1;
}
if (bpaddr != addr)
- fprintf_unfiltered (stderr, "Warning: Breakpoint addresses do not match: 0x%x != 0x%x\n", addr, bpaddr);
+ fprintf_unfiltered (gdb_stderr, "Warning: Breakpoint addresses do not match: 0x%x != 0x%x\n", addr, bpaddr);
mips_pmon_bp_info[bpnum] = bpaddr;
- mips_expect ("\015\012");
+ mips_expect ("\r\n");
mips_expect (mips_monitor_prompt);
mips_enter_debug ();
@@ -2142,14 +2431,16 @@ pmon_remove_breakpoint (addr, contents_cache)
if (bpnum >= PMON_MAX_BP)
{
- fprintf_unfiltered (stderr, "pmon_remove_breakpoint: Failed to find breakpoint at address 0x%x\n", addr);
+ fprintf_unfiltered (gdb_stderr,
+ "pmon_remove_breakpoint: Failed to find breakpoint at address 0x%s\n",
+ paddr_nz (addr));
return 1;
}
if (mips_exit_debug ())
mips_error ("Failed to exit debug mode");
- sprintf (tbuff, "db %02d\015", bpnum);
+ sprintf (tbuff, "db %02d\r", bpnum);
mips_send_command (tbuff, -1);
/* NOTE: If the breakpoint does not exist then a "Bpt <dd> not
@@ -2164,6 +2455,19 @@ pmon_remove_breakpoint (addr, contents_cache)
}
#endif
+
+/* Tell whether this target can support a hardware breakpoint. CNT
+ is the number of hardware breakpoints already installed. This
+ implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro. */
+
+int
+remote_mips_can_use_hardware_watchpoint (cnt)
+ int cnt;
+{
+ return cnt < MAX_LSI_BREAKPOINTS && strcmp (target_shortname, "lsi") == 0;
+}
+
+
/* Compute a don't care mask for the region bounding ADDR and ADDR + LEN - 1.
This is used for memory ref breakpoints. */
@@ -2188,39 +2492,47 @@ calculate_mask (addr, len)
return mask;
}
-/* Set a data watchpoint. ADDR and LEN should be obvious. TYPE is either 1
- for a read watchpoint, or 2 for a read/write watchpoint. */
+
+/* Insert a hardware breakpoint. This works only on LSI targets, which
+ implement ordinary breakpoints using hardware facilities. */
int
-remote_mips_set_watchpoint (addr, len, type)
+remote_mips_insert_hw_breakpoint (addr, contents_cache)
CORE_ADDR addr;
- int len;
- int type;
+ char *contents_cache;
{
- CORE_ADDR first_addr;
- unsigned long mask;
- char *flags;
+ if (strcmp (target_shortname, "lsi") == 0)
+ return mips_insert_breakpoint (addr, contents_cache);
+ else
+ return -1;
+}
- mask = calculate_mask (addr, len);
- first_addr = addr & ~mask;
+/* Remove a hardware breakpoint. This works only on LSI targets, which
+ implement ordinary breakpoints using hardware facilities. */
- switch (type)
- {
- case 0: /* write */
- flags = "w";
- break;
- case 1: /* read */
- flags = "r";
- break;
- case 2: /* read/write */
- flags = "rw";
- break;
- default:
- abort ();
- }
+int
+remote_mips_remove_hw_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ if (strcmp (target_shortname, "lsi") == 0)
+ return mips_remove_breakpoint (addr, contents_cache);
+ else
+ return -1;
+}
+
+/* Set a data watchpoint. ADDR and LEN should be obvious. TYPE is 0
+ for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
+ watchpoint. */
- if (common_breakpoint ('B', first_addr, mask, flags))
+int
+remote_mips_set_watchpoint (addr, len, type)
+ CORE_ADDR addr;
+ int len;
+ int type;
+{
+ if (set_breakpoint (addr, len, type))
return -1;
return 0;
@@ -2232,14 +2544,7 @@ remote_mips_remove_watchpoint (addr, len, type)
int len;
int type;
{
- CORE_ADDR first_addr;
- unsigned long mask;
-
- mask = calculate_mask (addr, len);
-
- first_addr = addr & ~mask;
-
- if (common_breakpoint ('b', first_addr, 0, NULL))
+ if (clear_breakpoint (addr, len, type))
return -1;
return 0;
@@ -2251,51 +2556,293 @@ remote_mips_stopped_by_watchpoint ()
return hit_watchpoint;
}
-/* This routine generates the a breakpoint command of the form:
- 0x0 <CMD> <ADDR> <MASK> <FLAGS>
+/* Insert a breakpoint. */
+
+static int
+set_breakpoint (addr, len, type)
+ CORE_ADDR addr;
+ int len;
+ enum break_type type;
+{
+ return common_breakpoint (1, addr, len, type);
+}
+
- Where <CMD> is one of: `B' to set, or `b' to clear a breakpoint. <ADDR> is
- the address of the breakpoint. <MASK> is a don't care mask for addresses.
- <FLAGS> is any combination of `r', `w', or `f' for read/write/or fetch. */
+/* Clear a breakpoint. */
static int
-common_breakpoint (cmd, addr, mask, flags)
- int cmd;
+clear_breakpoint (addr, len, type)
CORE_ADDR addr;
- CORE_ADDR mask;
- char *flags;
+ int len;
+ enum break_type type;
+{
+ return common_breakpoint (0, addr, len, type);
+}
+
+
+/* Check the error code from the return packet for an LSI breakpoint
+ command. If there's no error, just return 0. If it's a warning,
+ print the warning text and return 0. If it's an error, print
+ the error text and return 1. <ADDR> is the address of the breakpoint
+ that was being set. <RERRFLG> is the error code returned by PMON.
+ This is a helper function for common_breakpoint. */
+
+static int
+check_lsi_error (addr, rerrflg)
+ CORE_ADDR addr;
+ int rerrflg;
+{
+ struct lsi_error *err;
+ char *saddr = paddr_nz (addr); /* printable address string */
+
+ if (rerrflg == 0) /* no error */
+ return 0;
+
+ /* Warnings can be ORed together, so check them all. */
+ if (rerrflg & W_WARN)
+ {
+ if (monitor_warnings)
+ {
+ int found = 0;
+ for (err = lsi_warning_table; err->code != 0; err++)
+ {
+ if ((err->code & rerrflg) == err->code)
+ {
+ found = 1;
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Warning: %s\n",
+ saddr,
+ err->string);
+ }
+ }
+ if (!found)
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Unknown warning: 0x%x\n",
+ saddr,
+ rerrflg);
+ }
+ return 0;
+ }
+
+ /* Errors are unique, i.e. can't be ORed together. */
+ for (err = lsi_error_table; err->code != 0; err++)
+ {
+ if ((err->code & rerrflg) == err->code)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Error: %s\n",
+ saddr,
+ err->string);
+ return 1;
+ }
+ }
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Unknown error: 0x%x\n",
+ saddr,
+ rerrflg);
+ return 1;
+}
+
+
+/* This routine sends a breakpoint command to the remote target.
+
+ <SET> is 1 if setting a breakpoint, or 0 if clearing a breakpoint.
+ <ADDR> is the address of the breakpoint.
+ <LEN> the length of the region to break on.
+ <TYPE> is the type of breakpoint:
+ 0 = write (BREAK_WRITE)
+ 1 = read (BREAK_READ)
+ 2 = read/write (BREAK_ACCESS)
+ 3 = instruction fetch (BREAK_FETCH)
+
+ Return 0 if successful; otherwise 1. */
+
+static int
+common_breakpoint (set, addr, len, type)
+ int set;
+ CORE_ADDR addr;
+ int len;
+ enum break_type type;
{
- int len;
char buf[DATA_MAXLEN + 1];
- char rcmd;
- int rpid, rerrflg, rresponse;
+ char cmd, rcmd;
+ int rpid, rerrflg, rresponse, rlen;
int nfields;
- if (flags)
- sprintf (buf, "0x0 %c 0x%x 0x%x %s", cmd, addr, mask, flags);
- else
- sprintf (buf, "0x0 %c 0x%x", cmd, addr);
+ addr = ADDR_BITS_REMOVE (addr);
- mips_send_packet (buf, 1);
+ if (mips_monitor == MON_LSI)
+ {
+ if (set == 0) /* clear breakpoint */
+ {
+ /* The LSI PMON "clear breakpoint" has this form:
+ <pid> 'b' <bptn> 0x0
+ reply:
+ <pid> 'b' 0x0 <code>
- len = mips_receive_packet (buf, 1, mips_receive_wait);
- buf[len] = '\0';
+ <bptn> is a breakpoint number returned by an earlier 'B' command.
+ Possible return codes: OK, E_BPT. */
- nfields = sscanf (buf, "0x%x %c 0x%x 0x%x", &rpid, &rcmd, &rerrflg, &rresponse);
+ int i;
- if (nfields != 4
- || rcmd != cmd)
- mips_error ("common_breakpoint: Bad response from remote board: %s", buf);
+ /* Search for the breakpoint in the table. */
+ for (i = 0; i < MAX_LSI_BREAKPOINTS; i++)
+ if (lsi_breakpoints[i].type == type
+ && lsi_breakpoints[i].addr == addr
+ && lsi_breakpoints[i].len == len)
+ break;
- if (rerrflg != 0)
- {
- if (rresponse != EINVAL)
- fprintf_unfiltered (stderr, "common_breakpoint (0x%x): Got error: 0x%x\n",
- addr, rresponse);
- return 1;
+ /* Clear the table entry and tell PMON to clear the breakpoint. */
+ if (i == MAX_LSI_BREAKPOINTS)
+ {
+ warning ("common_breakpoint: Attempt to clear bogus breakpoint at %s\n",
+ paddr_nz (addr));
+ return 1;
+ }
+
+ lsi_breakpoints[i].type = BREAK_UNUSED;
+ sprintf (buf, "0x0 b 0x%x 0x0", i);
+ mips_send_packet (buf, 1);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+
+ nfields = sscanf (buf, "0x%x b 0x0 0x%x", &rpid, &rerrflg);
+ if (nfields != 2)
+ mips_error ("common_breakpoint: Bad response from remote board: %s", buf);
+
+ return (check_lsi_error (addr, rerrflg));
+ }
+ else /* set a breakpoint */
+ {
+ /* The LSI PMON "set breakpoint" command has this form:
+ <pid> 'B' <addr> 0x0
+ reply:
+ <pid> 'B' <bptn> <code>
+
+ The "set data breakpoint" command has this form:
+
+ <pid> 'A' <addr1> <type> [<addr2> [<value>]]
+
+ where: type= "0x1" = read
+ "0x2" = write
+ "0x3" = access (read or write)
+
+ The reply returns two values:
+ bptn - a breakpoint number, which is a small integer with
+ possible values of zero through 255.
+ code - an error return code, a value of zero indicates a
+ succesful completion, other values indicate various
+ errors and warnings.
+
+ Possible return codes: OK, W_QAL, E_QAL, E_OUT, E_NON.
+
+ */
+
+ if (type == BREAK_FETCH) /* instruction breakpoint */
+ {
+ cmd = 'B';
+ sprintf (buf, "0x0 B 0x%s 0x0", paddr_nz (addr));
+ }
+ else /* watchpoint */
+ {
+ cmd = 'A';
+ sprintf (buf, "0x0 A 0x%s 0x%x 0x%s", paddr_nz (addr),
+ type == BREAK_READ ? 1 : (type == BREAK_WRITE ? 2 : 3),
+ paddr_nz (addr + len - 1));
+ }
+ mips_send_packet (buf, 1);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+
+ nfields = sscanf (buf, "0x%x %c 0x%x 0x%x",
+ &rpid, &rcmd, &rresponse, &rerrflg);
+ if (nfields != 4 || rcmd != cmd || rresponse > 255)
+ mips_error ("common_breakpoint: Bad response from remote board: %s", buf);
+
+ if (rerrflg != 0)
+ if (check_lsi_error (addr, rerrflg))
+ return 1;
+
+ /* rresponse contains PMON's breakpoint number. Record the
+ information for this breakpoint so we can clear it later. */
+ lsi_breakpoints[rresponse].type = type;
+ lsi_breakpoints[rresponse].addr = addr;
+ lsi_breakpoints[rresponse].len = len;
+
+ return 0;
+ }
}
+ else
+ {
+ /* On non-LSI targets, the breakpoint command has this form:
+ 0x0 <CMD> <ADDR> <MASK> <FLAGS>
+ <MASK> is a don't care mask for addresses.
+ <FLAGS> is any combination of `r', `w', or `f' for read/write/fetch.
+ */
+ unsigned long mask;
+
+ mask = calculate_mask (addr, len);
+ addr &= ~mask;
+ if (set) /* set a breakpoint */
+ {
+ char *flags;
+ switch (type)
+ {
+ case BREAK_WRITE: /* write */
+ flags = "w";
+ break;
+ case BREAK_READ: /* read */
+ flags = "r";
+ break;
+ case BREAK_ACCESS: /* read/write */
+ flags = "rw";
+ break;
+ case BREAK_FETCH: /* fetch */
+ flags = "f";
+ break;
+ default:
+ abort ();
+ }
+
+ cmd = 'B';
+ sprintf (buf, "0x0 B 0x%s 0x%s %s", paddr_nz (addr),
+ paddr_nz (mask), flags);
+ }
+ else
+ {
+ cmd = 'b';
+ sprintf (buf, "0x0 b 0x%s", paddr_nz (addr));
+ }
+
+ mips_send_packet (buf, 1);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+
+ nfields = sscanf (buf, "0x%x %c 0x%x 0x%x",
+ &rpid, &rcmd, &rerrflg, &rresponse);
+
+ if (nfields != 4 || rcmd != cmd)
+ mips_error ("common_breakpoint: Bad response from remote board: %s",
+ buf);
+
+ if (rerrflg != 0)
+ {
+ /* Ddb returns "0x0 b 0x16 0x0\000", whereas
+ Cogent returns "0x0 b 0xffffffff 0x16\000": */
+ if (mips_monitor == MON_DDB)
+ rresponse = rerrflg;
+ if (rresponse != 22) /* invalid argument */
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Got error: 0x%x\n",
+ paddr_nz (addr), rresponse);
+ return 1;
+ }
+ }
return 0;
}
@@ -2338,8 +2885,8 @@ mips_load_srec (args)
bfd *abfd;
asection *s;
char *buffer, srec[1024];
- int i;
- int srec_frame = 200;
+ unsigned int i;
+ unsigned int srec_frame = 200;
int reclen;
static int hashmark = 1;
@@ -2359,15 +2906,15 @@ mips_load_srec (args)
}
/* This actually causes a download in the IDT binary format: */
-#define LOAD_CMD "load -b -s tty0\015"
mips_send_command (LOAD_CMD, 0);
for (s = abfd->sections; s; s = s->next)
{
if (s->flags & SEC_LOAD)
{
- int numbytes;
+ unsigned int numbytes;
+ /* FIXME! vma too small?? */
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
s->vma + s->_raw_size);
gdb_flush (gdb_stdout);
@@ -2463,6 +3010,7 @@ mips_make_srec (buf, type, memaddr, myaddr, len)
/* Create the header for the srec. addr_size is the number of bytes in the address,
and 1 is the number of bytes in the count. */
+ /* FIXME!! bigger buf required for 64-bit! */
buf[0] = 'S';
buf[1] = type;
buf[2] = len + 4 + 1; /* len + 4 byte address + 1 byte checksum */
@@ -2514,7 +3062,7 @@ mips_make_srec (buf, type, memaddr, myaddr, len)
The encoding of numbers is done in 6bit fields. The 6bit value is
used to index into this string to get the specific character
encoding for the value: */
-static char encoding[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.";
+static char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.";
/* Convert the number of bits required into an encoded number, 6bits
at a time (range 0..63). Keep a checksum if required (passed
@@ -2530,11 +3078,13 @@ pmon_makeb64 (v, p, n, chksum)
int count = (n / 6);
if ((n % 12) != 0) {
- fprintf_unfiltered(stderr,"Fast encoding bitcount must be a multiple of 12bits: %dbit%s\n",n,(n == 1)?"":"s");
+ fprintf_unfiltered(gdb_stderr,
+ "Fast encoding bitcount must be a multiple of 12bits: %dbit%s\n",n,(n == 1)?"":"s");
return(0);
}
if (n > 36) {
- fprintf_unfiltered(stderr,"Fast encoding cannot process more than 36bits at the moment: %dbits\n",n);
+ fprintf_unfiltered(gdb_stderr,
+ "Fast encoding cannot process more than 36bits at the moment: %dbits\n",n);
return(0);
}
@@ -2585,7 +3135,7 @@ pmon_checkset (recsize, buff, value)
sprintf (*buff, "/C");
count = pmon_makeb64 (*value, (*buff + 2), 12, NULL);
*buff += (count + 2);
- sprintf (*buff, "\015");
+ sprintf (*buff, "\n");
*buff += 2; /* include zero terminator */
/* Forcing a checksum validation clears the sum: */
*value = 0;
@@ -2661,18 +3211,137 @@ pmon_make_fastrec (outbuf, inbuf, inptr, inamount, recsize, csum, zerofill)
return;
}
-#if defined(DOETXACK)
static int
-pmon_check_ack()
+pmon_check_ack(mesg)
+ char *mesg;
{
- int c = SERIAL_READCHAR (mips_desc, 2);
- if ((c == SERIAL_TIMEOUT) || (c != 0x06)) {
- fprintf_unfiltered (gdb_stderr, "Failed to receive valid ACK\n");
- return(-1); /* terminate the download */
- }
+#if defined(DOETXACK)
+ int c;
+
+ if (!tftp_in_use)
+ {
+ c = SERIAL_READCHAR (udp_in_use ? udp_desc : mips_desc, 2);
+ if ((c == SERIAL_TIMEOUT) || (c != 0x06))
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Failed to receive valid ACK for %s\n", mesg);
+ return(-1); /* terminate the download */
+ }
+ }
+#endif /* DOETXACK */
return(0);
}
-#endif /* DOETXACK */
+
+/* pmon_download - Send a sequence of characters to the PMON download port,
+ which is either a serial port or a UDP socket. */
+
+static void
+pmon_start_download ()
+{
+ if (tftp_in_use)
+ {
+ /* Create the temporary download file. */
+ if ((tftp_file = fopen (tftp_localname, "w")) == NULL)
+ perror_with_name (tftp_localname);
+ }
+ else
+ {
+ mips_send_command (udp_in_use ? LOAD_CMD_UDP : LOAD_CMD, 0);
+ mips_expect ("Downloading from ");
+ mips_expect (udp_in_use ? "udp" : "tty0");
+ mips_expect (", ^C to abort\r\n");
+ }
+}
+
+static int
+mips_expect_download (char *string)
+{
+ if (!mips_expect (string))
+ {
+ fprintf_unfiltered (gdb_stderr, "Load did not complete successfully.\n");
+ if (tftp_in_use)
+ remove (tftp_localname); /* Remove temporary file */
+ return 0;
+ }
+ else
+ return 1;
+}
+
+static void
+pmon_end_download (final, bintotal)
+ int final;
+ int bintotal;
+{
+ char hexnumber[9]; /* includes '\0' space */
+
+ if (tftp_in_use)
+ {
+ static char *load_cmd_prefix = "load -b -s ";
+ char *cmd;
+ struct stat stbuf;
+
+ /* Close off the temporary file containing the load data. */
+ fclose (tftp_file);
+ tftp_file = NULL;
+
+ /* Make the temporary file readable by the world. */
+ if (stat (tftp_localname, &stbuf) == 0)
+ chmod (tftp_localname, stbuf.st_mode | S_IROTH);
+
+ /* Must reinitialize the board to prevent PMON from crashing. */
+ mips_send_command ("initEther\r", -1);
+
+ /* Send the load command. */
+ cmd = xmalloc (strlen (load_cmd_prefix) + strlen (tftp_name) + 2);
+ strcpy (cmd, load_cmd_prefix);
+ strcat (cmd, tftp_name);
+ strcat (cmd, "\r");
+ mips_send_command (cmd, 0);
+ free (cmd);
+ if (!mips_expect_download ("Downloading from "))
+ return;
+ if (!mips_expect_download (tftp_name))
+ return;
+ if (!mips_expect_download (", ^C to abort\r\n"))
+ return;
+ }
+
+ /* Wait for the stuff that PMON prints after the load has completed.
+ The timeout value for use in the tftp case (15 seconds) was picked
+ arbitrarily but might be too small for really large downloads. FIXME. */
+ if (mips_monitor == MON_LSI)
+ {
+ pmon_check_ack ("termination");
+ mips_expect_timeout ("Entry address is ", tftp_in_use ? 15 : 2);
+ }
+ else
+ mips_expect_timeout ("Entry Address = ", tftp_in_use ? 15 : 2);
+
+ sprintf (hexnumber,"%x",final);
+ mips_expect (hexnumber);
+ mips_expect ("\r\n");
+ if (mips_monitor != MON_LSI)
+ pmon_check_ack ("termination");
+ mips_expect ("\r\ntotal = 0x");
+ sprintf (hexnumber,"%x",bintotal);
+ mips_expect (hexnumber);
+ if (!mips_expect_download (" bytes\r\n"))
+ return;
+
+ if (tftp_in_use)
+ remove (tftp_localname); /* Remove temporary file */
+}
+
+static void
+pmon_download (buffer, length)
+ char *buffer;
+ int length;
+{
+ if (tftp_in_use)
+ fwrite (buffer, 1, length, tftp_file);
+ else
+ SERIAL_WRITE (udp_in_use ? udp_desc : mips_desc, buffer, length);
+}
static void
pmon_load_fast (file)
@@ -2684,9 +3353,9 @@ pmon_load_fast (file)
char *buffer;
int reclen;
unsigned int csum = 0;
- static int hashmark = 1;
+ int hashmark = !tftp_in_use;
int bintotal = 0;
- int final;
+ int final = 0;
int finished = 0;
buffer = (char *)xmalloc(MAXRECSIZE + 1);
@@ -2706,23 +3375,19 @@ pmon_load_fast (file)
}
/* Setup the required download state: */
- mips_send_command ("set dlproto etxack\015", -1);
- mips_send_command ("set dlecho off\015", -1);
+ mips_send_command ("set dlproto etxack\r", -1);
+ mips_send_command ("set dlecho off\r", -1);
/* NOTE: We get a "cannot set variable" message if the variable is
already defined to have the argument we give. The code doesn't
care, since it just scans to the next prompt anyway. */
/* Start the download: */
- mips_send_command (LOAD_CMD, 0);
- mips_expect ("Downloading from tty0, ^C to abort\015\012");
+ pmon_start_download();
/* Zero the checksum */
- sprintf(buffer,"/Kxx\015");
+ sprintf(buffer,"/Kxx\n");
reclen = strlen(buffer);
- SERIAL_WRITE (mips_desc, buffer, reclen);
-
-#if defined(DOETXACK)
- finished = pmon_check_ack();
-#endif /* DOETXACK */
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack("/Kxx");
for (s = abfd->sections; s && !finished; s = s->next)
if (s->flags & SEC_LOAD) /* only deal with loadable sections */
@@ -2730,27 +3395,25 @@ pmon_load_fast (file)
bintotal += s->_raw_size;
final = (s->vma + s->_raw_size);
- printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
- s->vma + s->_raw_size);
+ printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, (unsigned int)s->vma,
+ (unsigned int)(s->vma + s->_raw_size));
gdb_flush (gdb_stdout);
/* Output the starting address */
sprintf(buffer,"/A");
reclen = pmon_makeb64(s->vma,&buffer[2],36,&csum);
- buffer[2 + reclen] = '\015';
+ buffer[2 + reclen] = '\n';
buffer[3 + reclen] = '\0';
reclen += 3; /* for the initial escape code and carriage return */
- SERIAL_WRITE (mips_desc, buffer, reclen);
-#if defined(DOETXACK)
- finished = pmon_check_ack();
-#endif /* DOETXACK */
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack("/A");
if (!finished)
{
- int binamount;
+ unsigned int binamount;
unsigned int zerofill = 0;
char *bp = buffer;
- int i;
+ unsigned int i;
reclen = 0;
@@ -2767,14 +3430,12 @@ pmon_load_fast (file)
pmon_make_fastrec (&bp, binbuf, &binptr, binamount, &reclen, &csum, &zerofill);
if (reclen >= (MAXRECSIZE - CHECKSIZE)) {
reclen = pmon_checkset (reclen, &bp, &csum);
- SERIAL_WRITE (mips_desc, buffer, reclen);
-#if defined(DOETXACK)
- finished = pmon_check_ack();
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack("data record");
if (finished) {
zerofill = 0; /* do not transmit pending zerofills */
break;
}
-#endif /* DOETXACK */
if (hashmark) {
putchar_unfiltered ('#');
@@ -2796,38 +3457,24 @@ pmon_load_fast (file)
reclen = pmon_checkset (reclen, &bp, &csum);
/* Currently pmon_checkset outputs the line terminator by
default, so we write out the buffer so far: */
- SERIAL_WRITE (mips_desc, buffer, reclen);
-#if defined(DOETXACK)
- finished = pmon_check_ack();
-#endif /* DOETXACK */
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack("record remnant");
}
}
- if (hashmark)
- putchar_unfiltered ('\n');
+ putchar_unfiltered ('\n');
}
/* Terminate the transfer. We know that we have an empty output
buffer at this point. */
- sprintf (buffer, "/E/E\015"); /* include dummy padding characters */
+ sprintf (buffer, "/E/E\n"); /* include dummy padding characters */
reclen = strlen (buffer);
- SERIAL_WRITE (mips_desc, buffer, reclen);
+ pmon_download (buffer, reclen);
if (finished) { /* Ignore the termination message: */
- SERIAL_FLUSH_INPUT (mips_desc);
+ SERIAL_FLUSH_INPUT (udp_in_use ? udp_desc : mips_desc);
} else { /* Deal with termination message: */
- char hexnumber[9]; /* includes '\0' space */
- mips_expect ("Entry Address = ");
- sprintf(hexnumber,"%x",final);
- mips_expect (hexnumber);
-#if defined(DOETXACK)
- mips_expect ("\015\012\006\015\012total = 0x");
-#else /* normal termination */
- mips_expect ("\015\012\015\012total = 0x");
-#endif /* !DOETXACK */
- sprintf(hexnumber,"%x",bintotal);
- mips_expect (hexnumber);
- mips_expect (" bytes\015\012");
+ pmon_end_download (final, bintotal);
}
return;
@@ -2844,15 +3491,21 @@ mips_load (file, from_tty)
if (mips_exit_debug ())
error ("mips_load: Couldn't get into monitor mode.");
- if (mips_monitor == MON_PMON)
+ if (mips_monitor != MON_IDT)
pmon_load_fast (file);
else
mips_load_srec (file);
mips_initialize ();
-/* Finally, make the PC point at the start address */
-
+ /* Finally, make the PC point at the start address */
+ if (mips_monitor != MON_IDT)
+ {
+ /* Work around problem where PMON monitor updates the PC after a load
+ to a different value than GDB thinks it has. The following ensures
+ that the write_pc() WILL update the PC value: */
+ register_valid[PC_REGNUM] = 0;
+ }
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
@@ -2866,109 +3519,95 @@ mips_load (file, from_tty)
clear_symtab_users ();
}
-
-/* The target vector. */
-struct target_ops mips_ops =
-{
- "mips", /* to_shortname */
- "Remote MIPS debugging over serial line", /* to_longname */
- "\
-Debug a board using the MIPS remote debugging protocol over a serial line.\n\
-The argument is the device it is connected to or, if it contains a colon,\n\
-HOST:PORT to access a board over a network", /* to_doc */
- mips_open, /* to_open */
- mips_close, /* to_close */
- NULL, /* to_attach */
- mips_detach, /* to_detach */
- mips_resume, /* to_resume */
- mips_wait, /* to_wait */
- mips_fetch_registers, /* to_fetch_registers */
- mips_store_registers, /* to_store_registers */
- mips_prepare_to_store, /* to_prepare_to_store */
- mips_xfer_memory, /* to_xfer_memory */
- mips_files_info, /* to_files_info */
- mips_insert_breakpoint, /* to_insert_breakpoint */
- mips_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- mips_kill, /* to_kill */
- mips_load, /* to_load */
- NULL, /* to_lookup_symbol */
- mips_create_inferior, /* to_create_inferior */
- mips_mourn_inferior, /* to_mourn_inferior */
- NULL, /* to_can_run */
- NULL, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
-
-/* An alternative target vector: */
-struct target_ops pmon_ops =
+
+/* Pass the command argument as a packet to PMON verbatim. */
+
+static void
+pmon_command (args, from_tty)
+ char *args;
+ int from_tty;
{
- "pmon", /* to_shortname */
- "Remote MIPS debugging over serial line", /* to_longname */
- "\
-Debug a board using the PMON MIPS remote debugging protocol over a serial\n\
-line. The argument is the device it is connected to or, if it contains a\n\
-colon, HOST:PORT to access a board over a network", /* to_doc */
- pmon_open, /* to_open */
- mips_close, /* to_close */
- NULL, /* to_attach */
- mips_detach, /* to_detach */
- mips_resume, /* to_resume */
- pmon_wait, /* to_wait */
- mips_fetch_registers, /* to_fetch_registers */
- mips_store_registers, /* to_store_registers */
- mips_prepare_to_store, /* to_prepare_to_store */
- mips_xfer_memory, /* to_xfer_memory */
- mips_files_info, /* to_files_info */
- mips_insert_breakpoint, /* to_insert_breakpoint */
- mips_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- mips_kill, /* to_kill */
- mips_load, /* to_load */
- NULL, /* to_lookup_symbol */
- mips_create_inferior, /* to_create_inferior */
- mips_mourn_inferior, /* to_mourn_inferior */
- NULL, /* to_can_run */
- NULL, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+ char buf[DATA_MAXLEN + 1];
+ int rlen;
+
+ sprintf (buf, "0x0 %s", args);
+ mips_send_packet (buf, 1);
+ printf_filtered ("Send packet: %s\n", buf);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+ printf_filtered ("Received packet: %s\n", buf);
+}
void
_initialize_remote_mips ()
{
+ /* Initialize the fields in mips_ops that are common to all four targets. */
+ mips_ops.to_longname = "Remote MIPS debugging over serial line";
+ mips_ops.to_close = mips_close;
+ mips_ops.to_detach = mips_detach;
+ mips_ops.to_resume = mips_resume;
+ mips_ops.to_fetch_registers = mips_fetch_registers;
+ mips_ops.to_store_registers = mips_store_registers;
+ mips_ops.to_prepare_to_store = mips_prepare_to_store;
+ mips_ops.to_xfer_memory = mips_xfer_memory;
+ mips_ops.to_files_info = mips_files_info;
+ mips_ops.to_insert_breakpoint = mips_insert_breakpoint;
+ mips_ops.to_remove_breakpoint = mips_remove_breakpoint;
+ mips_ops.to_kill = mips_kill;
+ mips_ops.to_load = mips_load;
+ mips_ops.to_create_inferior = mips_create_inferior;
+ mips_ops.to_mourn_inferior = mips_mourn_inferior;
+ mips_ops.to_stratum = process_stratum;
+ mips_ops.to_has_all_memory = 1;
+ mips_ops.to_has_memory = 1;
+ mips_ops.to_has_stack = 1;
+ mips_ops.to_has_registers = 1;
+ mips_ops.to_has_execution = 1;
+ mips_ops.to_magic = OPS_MAGIC;
+
+ /* Copy the common fields to all four target vectors. */
+ pmon_ops = ddb_ops = lsi_ops = mips_ops;
+
+ /* Initialize target-specific fields in the target vectors. */
+ mips_ops.to_shortname = "mips";
+ mips_ops.to_doc = "\
+Debug a board using the MIPS remote debugging protocol over a serial line.\n\
+The argument is the device it is connected to or, if it contains a colon,\n\
+HOST:PORT to access a board over a network";
+ mips_ops.to_open = mips_open;
+ mips_ops.to_wait = mips_wait;
+
+ pmon_ops.to_shortname = "pmon";
+ pmon_ops.to_doc = "\
+Debug a board using the PMON MIPS remote debugging protocol over a serial\n\
+line. The argument is the device it is connected to or, if it contains a\n\
+colon, HOST:PORT to access a board over a network";
+ pmon_ops.to_open = pmon_open;
+ pmon_ops.to_wait = mips_wait;
+
+ ddb_ops.to_shortname = "ddb";
+ ddb_ops.to_doc = "\
+Debug a board using the PMON MIPS remote debugging protocol over a serial\n\
+line. The first argument is the device it is connected to or, if it contains\n\
+a colon, HOST:PORT to access a board over a network. The optional second\n\
+parameter is the temporary file in the form HOST:FILENAME to be used for\n\
+TFTP downloads to the board. The optional third parameter is the local name\n\
+of the TFTP temporary file, if it differs from the filename seen by the board.";
+ ddb_ops.to_open = ddb_open;
+ ddb_ops.to_wait = mips_wait;
+
+ lsi_ops.to_shortname = "lsi";
+ lsi_ops.to_doc = pmon_ops.to_doc;
+ lsi_ops.to_open = lsi_open;
+ lsi_ops.to_wait = mips_wait;
+
+ /* Add the targets. */
add_target (&mips_ops);
add_target (&pmon_ops);
+ add_target (&ddb_ops);
+ add_target (&lsi_ops);
add_show_from_set (
add_set_cmd ("timeout", no_class, var_zinteger,
@@ -2994,4 +3633,23 @@ synchronize with the remote system. A value of -1 means that there is no limit\
(Note that these characters are printed out even though they are ignored.)",
&setlist),
&showlist);
+
+ add_show_from_set
+ (add_set_cmd ("monitor-prompt", class_obscure, var_string,
+ (char *) &mips_monitor_prompt,
+ "Set the prompt that GDB expects from the monitor.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("monitor-warnings", class_obscure, var_zinteger,
+ (char *)&monitor_warnings,
+ "Set printing of monitor warnings.\n"
+ "When enabled, monitor warnings about hardware breakpoints "
+ "will be displayed.",
+ &setlist),
+ &showlist);
+
+ add_com ("pmon <command>", class_obscure, pmon_command,
+ "Send a packet to PMON (must be in debug mode).");
}
diff --git a/contrib/gdb/gdb/remote-mm.c b/contrib/gdb/gdb/remote-mm.c
index 101d964..19455b4 100644
--- a/contrib/gdb/gdb/remote-mm.c
+++ b/contrib/gdb/gdb/remote-mm.c
@@ -162,7 +162,7 @@ mm_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote mm process (yet).");
if (execfile == 0 /* || exec_bfd == 0 */ )
- error ("No exec file specified");
+ error ("No executable file specified");
if (!mm_stream) {
printf("Minimon not open yet.\n");
@@ -345,7 +345,7 @@ erroid:
printf_filtered("\twhen virtual addresses map 1:1 to physical addresses.\n")
;
if (processor_type != a29k_freeze_mode) {
- fprintf_filtered(stderr,
+ fprintf_filtered(gdb_stderr,
"Freeze-mode debugging not available, and can only be done on an A29050.\n");
}
@@ -542,7 +542,7 @@ mm_wait (status)
i=in_msg_buf->channel1_msg.length;
in_msg_buf->channel1_msg.data[i] = '\0';
printf("%s", in_msg_buf->channel1_msg.data);
- gdb_flush(stdout);
+ gdb_flush(gdb_stdout);
/* Send CHANNEL1_ACK message */
out_msg_buf->channel1_ack_msg.code = CHANNEL1_ACK;
out_msg_buf->channel1_ack_msg.length = 0;
@@ -1015,7 +1015,7 @@ int from_tty;
/* You may need to do an init_target_mm() */
/* init_target_mm(?,?,?,?,?,?,?,?); */
immediate_quit--;
- /* symbol_file_add (arg_string, from_tty, text_addr, 0, 0); */
+ /* symbol_file_add (arg_string, from_tty, text_addr, 0, 0, 0, 0); */
#endif
}
@@ -1585,36 +1585,82 @@ CORE_ADDR *addr;
/****************************************************************************/
/*
- * Define the target subroutine names
+ * Define the target subroutine names
*/
-struct target_ops mm_ops = {
- "minimon", "Remote AMD/Minimon target",
- "Remote debug an AMD 290*0 using the MiniMon dbg core on the target",
- mm_open, mm_close,
- mm_attach, mm_detach, mm_resume, mm_wait,
- mm_fetch_registers, mm_store_registers,
- mm_prepare_to_store,
- mm_xfer_inferior_memory,
- mm_files_info,
- mm_insert_breakpoint, mm_remove_breakpoint, /* Breakpoints */
- 0, 0, 0, 0, 0, /* Terminal handling */
- mm_kill, /* FIXME, kill */
- mm_load,
- 0, /* lookup_symbol */
- mm_create_inferior, /* create_inferior */
- mm_mourn, /* mourn_inferior FIXME */
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_stop */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0,0, /* sections, sections_end */
- OPS_MAGIC, /* Always the last thing */
+struct target_ops mm_ops ;
+
+static void
+init_mm_ops(void)
+{
+ mm_ops.to_shortname = "minimon";
+ mm_ops.to_longname = "Remote AMD/Minimon target";
+ mm_ops.to_doc = "Remote debug an AMD 290*0 using the MiniMon dbg core on the target";
+ mm_ops.to_open = mm_open;
+ mm_ops.to_close = mm_close;
+ mm_ops.to_attach = mm_attach;
+ mm_ops.to_post_attach = NULL;
+ mm_ops.to_require_attach = NULL;
+ mm_ops.to_detach = mm_detach;
+ mm_ops.to_require_detach = NULL;
+ mm_ops.to_resume = mm_resume;
+ mm_ops.to_wait = mm_wait;
+ mm_ops.to_post_wait = NULL;
+ mm_ops.to_fetch_registers = mm_fetch_registers;
+ mm_ops.to_store_registers = mm_store_registers;
+ mm_ops.to_prepare_to_store = mm_prepare_to_store;
+ mm_ops.to_xfer_memory = mm_xfer_inferior_memory;
+ mm_ops.to_files_info = mm_files_info;
+ mm_ops.to_insert_breakpoint = mm_insert_breakpoint;
+ mm_ops.to_remove_breakpoint = mm_remove_breakpoint;
+ mm_ops.to_terminal_init = 0;
+ mm_ops.to_terminal_inferior = 0;
+ mm_ops.to_terminal_ours_for_output = 0;
+ mm_ops.to_terminal_ours = 0;
+ mm_ops.to_terminal_info = 0;
+ mm_ops.to_kill = mm_kill;
+ mm_ops.to_load = mm_load;
+ mm_ops.to_lookup_symbol = 0;
+ mm_ops.to_create_inferior = mm_create_inferior;
+ mm_ops.to_post_startup_inferior = NULL;
+ mm_ops.to_acknowledge_created_inferior = NULL;
+ mm_ops.to_clone_and_follow_inferior = NULL;
+ mm_ops.to_post_follow_inferior_by_clone = NULL;
+ mm_ops.to_insert_fork_catchpoint = NULL;
+ mm_ops.to_remove_fork_catchpoint = NULL;
+ mm_ops.to_insert_vfork_catchpoint = NULL;
+ mm_ops.to_remove_vfork_catchpoint = NULL;
+ mm_ops.to_has_forked = NULL;
+ mm_ops.to_has_vforked = NULL;
+ mm_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ mm_ops.to_post_follow_vfork = NULL;
+ mm_ops.to_insert_exec_catchpoint = NULL;
+ mm_ops.to_remove_exec_catchpoint = NULL;
+ mm_ops.to_has_execd = NULL;
+ mm_ops.to_reported_exec_events_per_exec_call = NULL;
+ mm_ops.to_has_exited = NULL;
+ mm_ops.to_mourn_inferior = mm_mourn;
+ mm_ops.to_can_run = 0;
+ mm_ops.to_notice_signals = 0;
+ mm_ops.to_thread_alive = 0;
+ mm_ops.to_stop = 0;
+ mm_ops.to_pid_to_exec_file = NULL;
+ mm_ops.to_core_file_to_sym_file = NULL;
+ mm_ops.to_stratum = process_stratum;
+ mm_ops.DONT_USE = 0;
+ mm_ops.to_has_all_memory = 1;
+ mm_ops.to_has_memory = 1;
+ mm_ops.to_has_stack = 1;
+ mm_ops.to_has_registers = 1;
+ mm_ops.to_has_execution = 1;
+ mm_ops.to_sections = 0;
+ mm_ops.to_sections_end = 0;
+ mm_ops.to_magic = OPS_MAGIC;
};
void
_initialize_remote_mm()
{
+ init_mm_ops() ;
add_target (&mm_ops);
}
diff --git a/contrib/gdb/gdb/remote-nindy.c b/contrib/gdb/gdb/remote-nindy.c
index a3417f0..58e89b8 100644
--- a/contrib/gdb/gdb/remote-nindy.c
+++ b/contrib/gdb/gdb/remote-nindy.c
@@ -128,7 +128,7 @@ extern char *mktemp();
extern void generic_mourn_inferior ();
extern struct target_ops nindy_ops;
-extern GDB_FILE *instream;
+extern FILE *instream;
extern char ninStopWhy ();
extern int ninMemGet ();
@@ -211,7 +211,13 @@ nindy_open (name, from_tty)
savename = savestring (name, strlen (name));
push_target (&nindy_ops);
+
target_fetch_registers(-1);
+
+ init_thread_list ();
+ init_wait_for_inferior ();
+ clear_proceed_status ();
+ normal_stop ();
}
/* User-initiated quit of nindy operations. */
@@ -437,8 +443,7 @@ nindy_fetch_registers(regno)
int regno;
{
struct nindy_regs nindy_regs;
- int regnum, inv;
- double dub;
+ int regnum;
immediate_quit++;
ninRegsGet( (char *) &nindy_regs );
@@ -449,14 +454,7 @@ nindy_fetch_registers(regno)
memcpy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2*4);
memcpy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1*4);
memcpy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1*4);
- for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
- dub = unpack_double (builtin_type_double,
- &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
- &inv);
- /* dub now in host byte order */
- floatformat_from_double (&floatformat_i960_ext, &dub,
- &registers[REGISTER_BYTE (regnum)]);
- }
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], nindy_regs.fp_as_double, 4 * 8);
registers_fetched ();
}
@@ -474,21 +472,13 @@ nindy_store_registers(regno)
{
struct nindy_regs nindy_regs;
int regnum;
- double dub;
memcpy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16*4);
memcpy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16*4);
memcpy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2*4);
memcpy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1*4);
memcpy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1*4);
- for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++)
- {
- floatformat_to_double (&floatformat_i960_ext,
- &registers[REGISTER_BYTE (regnum)], &dub);
- store_floating (&nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
- REGISTER_VIRTUAL_SIZE (regnum),
- dub);
- }
+ memcpy (nindy_regs.fp_as_double, &registers[REGISTER_BYTE (FP0_REGNUM)], 8*4);
immediate_quit++;
ninRegsPut( (char *) &nindy_regs );
@@ -525,11 +515,11 @@ nindy_store_word (addr, word)
FIXME, rewrite this to not use the word-oriented routines. */
int
-nindy_xfer_inferior_memory(memaddr, myaddr, len, write, target)
+nindy_xfer_inferior_memory(memaddr, myaddr, len, should_write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
- int write;
+ int should_write;
struct target_ops *target; /* ignored */
{
register int i;
@@ -541,7 +531,7 @@ nindy_xfer_inferior_memory(memaddr, myaddr, len, write, target)
/* Allocate buffer of that many longwords. */
register int *buffer = (int *) alloca (count * sizeof (int));
- if (write)
+ if (should_write)
{
/* Fill start and end extra bytes of buffer with existing memory data. */
@@ -601,7 +591,7 @@ nindy_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote NINDY process");
if (execfile == 0 || exec_bfd == 0)
- error ("No exec file specified");
+ error ("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -776,42 +766,84 @@ nindy_before_main_loop ()
/* Define the target subroutine names */
-struct target_ops nindy_ops = {
- "nindy", "Remote serial target in i960 NINDY-specific protocol",
- "Use a remote i960 system running NINDY connected by a serial line.\n\
+struct target_ops nindy_ops ;
+
+static void
+init_nindy_ops(void)
+{
+ nindy_ops.to_shortname = "nindy"; "Remote serial target in i960 NINDY-specific protocol",
+ nindy_ops.to_longname = "Use a remote i960 system running NINDY connected by a serial line.\n\
Specify the name of the device the serial line is connected to.\n\
The speed (baud rate), whether to use the old NINDY protocol,\n\
and whether to send a break on startup, are controlled by options\n\
-specified when you started GDB.",
- nindy_open, nindy_close,
- 0,
- nindy_detach,
- nindy_resume,
- nindy_wait,
- nindy_fetch_registers, nindy_store_registers,
- nindy_prepare_to_store,
- nindy_xfer_inferior_memory, nindy_files_info,
- memory_insert_breakpoint,
- memory_remove_breakpoint,
- 0, 0, 0, 0, 0, /* Terminal crud */
- nindy_kill,
- nindy_load,
- 0, /* lookup_symbol */
- nindy_create_inferior,
- nindy_mourn_inferior,
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0, 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
-};
+specified when you started GDB." ;
+ nindy_ops.to_doc = "";
+ nindy_ops.to_open = nindy_open;
+ nindy_ops.to_close = nindy_close;
+ nindy_ops.to_attach = 0;
+ nindy_ops.to_post_attach = NULL;
+ nindy_ops.to_require_attach = NULL;
+ nindy_ops.to_detach = nindy_detach;
+ nindy_ops.to_require_detach = NULL;
+ nindy_ops.to_resume = nindy_resume;
+ nindy_ops.to_wait = nindy_wait;
+ nindy_ops.to_post_wait = NULL;
+ nindy_ops.to_fetch_registers = nindy_fetch_registers;
+ nindy_ops.to_store_registers = nindy_store_registers;
+ nindy_ops.to_prepare_to_store = nindy_prepare_to_store;
+ nindy_ops.to_xfer_memory = nindy_xfer_inferior_memory;
+ nindy_ops.to_files_info = nindy_files_info;
+ nindy_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ nindy_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ nindy_ops.to_terminal_init = 0;
+ nindy_ops.to_terminal_inferior = 0;
+ nindy_ops.to_terminal_ours_for_output = 0;
+ nindy_ops.to_terminal_ours = 0;
+ nindy_ops.to_terminal_info = 0; /* Terminal crud */
+ nindy_ops.to_kill = nindy_kill;
+ nindy_ops.to_load = nindy_load;
+ nindy_ops.to_lookup_symbol = 0; /* lookup_symbol */
+ nindy_ops.to_create_inferior = nindy_create_inferior;
+ nindy_ops.to_post_startup_inferior = NULL;
+ nindy_ops.to_acknowledge_created_inferior = NULL;
+ nindy_ops.to_clone_and_follow_inferior = NULL;
+ nindy_ops.to_post_follow_inferior_by_clone = NULL;
+ nindy_ops.to_insert_fork_catchpoint = NULL;
+ nindy_ops.to_remove_fork_catchpoint = NULL;
+ nindy_ops.to_insert_vfork_catchpoint = NULL;
+ nindy_ops.to_remove_vfork_catchpoint = NULL;
+ nindy_ops.to_has_forked = NULL;
+ nindy_ops.to_has_vforked = NULL;
+ nindy_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ nindy_ops.to_post_follow_vfork = NULL;
+ nindy_ops.to_insert_exec_catchpoint = NULL;
+ nindy_ops.to_remove_exec_catchpoint = NULL;
+ nindy_ops.to_has_execd = NULL;
+ nindy_ops.to_reported_exec_events_per_exec_call = NULL;
+ nindy_ops.to_has_exited = NULL;
+ nindy_ops.to_mourn_inferior = nindy_mourn_inferior;
+ nindy_ops.to_can_run = 0; /* can_run */
+ nindy_ops.to_notice_signals = 0; /* notice_signals */
+ nindy_ops.to_thread_alive = 0; /* to_thread_alive */
+ nindy_ops.to_stop = 0; /* to_stop */
+ nindy_ops.to_pid_to_exec_file = NULL;
+ nindy_ops.to_core_file_to_sym_file = NULL;
+ nindy_ops.to_stratum = process_stratum;
+ nindy_ops.DONT_USE = 0; /* next */
+ nindy_ops.to_has_all_memory = 1;
+ nindy_ops.to_has_memory = 1;
+ nindy_ops.to_has_stack = 1;
+ nindy_ops.to_has_registers = 1;
+ nindy_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */
+ nindy_ops.to_sections = 0;
+ nindy_ops.to_sections_end = 0; /* Section pointers */
+ nindy_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+}
void
_initialize_nindy ()
{
+ init_nindy_ops() ;
add_target (&nindy_ops);
add_com ("reset", class_obscure, reset_command,
"Send a 'break' to the remote target system.\n\
diff --git a/contrib/gdb/gdb/remote-nrom.c b/contrib/gdb/gdb/remote-nrom.c
index d67791b..4999a68 100644
--- a/contrib/gdb/gdb/remote-nrom.c
+++ b/contrib/gdb/gdb/remote-nrom.c
@@ -268,52 +268,80 @@ nrom_mourn()
/* Define the target vector. */
-struct target_ops nrom_ops = {
- "nrom", /* to_shortname */
- "Remote XDI `NetROM' target", /* to_longname */
- "Remote debug using a NetROM over Ethernet", /* to_doc */
- nrom_open, /* to_open */
- nrom_close, /* to_close */
- NULL, /* to_attach */
- NULL, /* to_detach */
- NULL, /* to_resume */
- NULL, /* to_wait */
- NULL, /* to_fetch_registers */
- NULL, /* to_store_registers */
- NULL, /* to_prepare_to_store */
- NULL, /* to_xfer_memory */
- NULL, /* to_files_info */
- NULL, /* to_insert_breakpoint */
- NULL, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- nrom_kill, /* to_kill */
- nrom_load, /* to_load */
- NULL, /* to_lookup_symbol */
- NULL, /* to_create_inferior */
- nrom_mourn, /* to_mourn_inferior */
- NULL, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- download_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 0, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
+struct target_ops nrom_ops ;
+
+static void
+init_nrom_ops(void)
+{
+ nrom_ops.to_shortname = "nrom";
+ nrom_ops.to_longname = "Remote XDI `NetROM' target";
+ nrom_ops.to_doc = "Remote debug using a NetROM over Ethernet";
+ nrom_ops.to_open = nrom_open;
+ nrom_ops.to_close = nrom_close;
+ nrom_ops.to_attach = NULL;
+ nrom_ops.to_post_attach = NULL;
+ nrom_ops.to_require_attach = NULL;
+ nrom_ops.to_detach = NULL;
+ nrom_ops.to_require_detach = NULL;
+ nrom_ops.to_resume = NULL;
+ nrom_ops.to_wait = NULL;
+ nrom_ops.to_post_wait = NULL;
+ nrom_ops.to_fetch_registers = NULL;
+ nrom_ops.to_store_registers = NULL;
+ nrom_ops.to_prepare_to_store = NULL;
+ nrom_ops.to_xfer_memory = NULL;
+ nrom_ops.to_files_info = NULL;
+ nrom_ops.to_insert_breakpoint = NULL;
+ nrom_ops.to_remove_breakpoint = NULL;
+ nrom_ops.to_terminal_init = NULL;
+ nrom_ops.to_terminal_inferior = NULL;
+ nrom_ops.to_terminal_ours_for_output = NULL;
+ nrom_ops.to_terminal_ours = NULL;
+ nrom_ops.to_terminal_info = NULL;
+ nrom_ops.to_kill = nrom_kill;
+ nrom_ops.to_load = nrom_load;
+ nrom_ops.to_lookup_symbol = NULL;
+ nrom_ops.to_create_inferior = NULL;
+ nrom_ops.to_post_startup_inferior = NULL;
+ nrom_ops.to_acknowledge_created_inferior = NULL;
+ nrom_ops.to_clone_and_follow_inferior = NULL;
+ nrom_ops.to_post_follow_inferior_by_clone = NULL;
+ nrom_ops.to_insert_fork_catchpoint = NULL;
+ nrom_ops.to_remove_fork_catchpoint = NULL;
+ nrom_ops.to_insert_vfork_catchpoint = NULL;
+ nrom_ops.to_remove_vfork_catchpoint = NULL;
+ nrom_ops.to_has_forked = NULL;
+ nrom_ops.to_has_vforked = NULL;
+ nrom_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ nrom_ops.to_post_follow_vfork = NULL;
+ nrom_ops.to_insert_exec_catchpoint = NULL;
+ nrom_ops.to_remove_exec_catchpoint = NULL;
+ nrom_ops.to_has_execd = NULL;
+ nrom_ops.to_reported_exec_events_per_exec_call = NULL;
+ nrom_ops.to_has_exited = NULL;
+ nrom_ops.to_mourn_inferior = nrom_mourn;
+ nrom_ops.to_can_run = NULL;
+ nrom_ops.to_notice_signals = 0;
+ nrom_ops.to_thread_alive = 0;
+ nrom_ops.to_stop = 0;
+ nrom_ops.to_pid_to_exec_file = NULL;
+ nrom_ops.to_core_file_to_sym_file = NULL;
+ nrom_ops.to_stratum = download_stratum;
+ nrom_ops.DONT_USE = NULL;
+ nrom_ops.to_has_all_memory = 1;
+ nrom_ops.to_has_memory = 1;
+ nrom_ops.to_has_stack = 1;
+ nrom_ops.to_has_registers = 1;
+ nrom_ops.to_has_execution = 0;
+ nrom_ops.to_sections = NULL;
+ nrom_ops.to_sections_end = NULL;
+ nrom_ops.to_magic = OPS_MAGIC ;
};
void
_initialize_remote_nrom ()
{
+ init_nrom_ops() ;
add_target (&nrom_ops);
add_show_from_set (
diff --git a/contrib/gdb/gdb/remote-os9k.c b/contrib/gdb/gdb/remote-os9k.c
index fda5272..2abfa83 100644
--- a/contrib/gdb/gdb/remote-os9k.c
+++ b/contrib/gdb/gdb/remote-os9k.c
@@ -33,6 +33,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
of ROMBUG is not available yet.
*/
+/* FIXME This file needs to be rewritten if it's to work again, either
+ to self-contained or to use the new monitor interface. */
+
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
@@ -54,7 +57,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "objfiles.h"
#include "gdb-stabs.h"
-struct monitor_ops *current_monitor;
struct cmd_list_element *showlist;
extern struct target_ops rombug_ops; /* Forward declaration */
extern struct monitor_ops rombug_cmds; /* Forward declaration */
@@ -299,7 +301,7 @@ rombug_create_inferior (execfile, args, env)
error("Can't pass arguments to remote ROMBUG process");
if (execfile == 0 || exec_bfd == 0)
- error("No exec file specified");
+ error("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -545,11 +547,11 @@ get_reg_name (regno)
if (regno < 0)
return ("");
/*
- for (p = reg_names[regno]; *p; p++)
+ for (p = REGISTER_NAME (regno); *p; p++)
*b++ = toupper(*p);
*b = '\000';
*/
- p = (char *)reg_names[regno];
+ p = (char *)REGISTER_NAME (regno);
return p;
/*
return buf;
@@ -884,7 +886,6 @@ rombug_mourn_inferior ()
#define MAX_MONITOR_BREAKPOINTS 16
-extern int memory_breakpoint_size;
static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
static int
@@ -893,9 +894,12 @@ rombug_insert_breakpoint (addr, shadow)
char *shadow;
{
int i;
+ CORE_ADDR bp_addr = addr;
+ int bp_size = 0;
if (monitor_log)
fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
+ BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
if (breakaddr[i] == 0)
@@ -903,7 +907,7 @@ rombug_insert_breakpoint (addr, shadow)
breakaddr[i] = addr;
if (sr_get_debug())
printf ("Breakpoint at %x\n", addr);
- rombug_read_inferior_memory(addr, shadow, memory_breakpoint_size);
+ rombug_read_inferior_memory (bp_addr, shadow, bp_size);
printf_monitor(SET_BREAK_CMD, addr);
is_trace_mode = 0;
expect_prompt(1);
@@ -1121,6 +1125,7 @@ connect_command (args, fromtty)
* through to a printf style function, we need can include formatting
* strings. We also need a CR or LF on the end.
*/
+#warning FIXME: monitor interface pattern strings, stale struct decl
struct monitor_ops rombug_cmds = {
"g \r", /* execute or usually GO command */
"g \r", /* continue command */
@@ -1139,52 +1144,81 @@ struct monitor_ops rombug_cmds = {
".\r" /* optional command terminator */
};
-struct target_ops rombug_ops = {
- "rombug",
- "Microware's ROMBUG debug monitor",
- "Use a remote computer running the ROMBUG debug monitor.\n\
+struct target_ops rombug_ops ;
+
+static void
+init_rombug_ops(void)
+{
+ rombug_ops.to_shortname = "rombug";
+ rombug_ops.to_longname = "Microware's ROMBUG debug monitor";
+ rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).",
- rombug_open,
- rombug_close,
- 0,
- rombug_detach,
- rombug_resume,
- rombug_wait,
- rombug_fetch_register,
- rombug_store_register,
- rombug_prepare_to_store,
- rombug_xfer_inferior_memory,
- rombug_files_info,
- rombug_insert_breakpoint,
- rombug_remove_breakpoint, /* Breakpoints */
- 0,
- 0,
- 0,
- 0,
- 0, /* Terminal handling */
- rombug_kill,
- rombug_load, /* load */
- rombug_link, /* lookup_symbol */
- rombug_create_inferior,
- rombug_mourn_inferior,
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_stop */
- process_stratum,
- 0, /* next */
- 1,
- 1,
- 1,
- 1,
- 1, /* has execution */
- 0,
- 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
-};
+ rombug_ops.to_open = rombug_open;
+ rombug_ops.to_close = rombug_close;
+ rombug_ops.to_attach = 0;
+ rombug_ops.to_post_attach = NULL;
+ rombug_ops.to_require_attach = NULL;
+ rombug_ops.to_detach = rombug_detach;
+ rombug_ops.to_require_detach = NULL;
+ rombug_ops.to_resume = rombug_resume;
+ rombug_ops.to_wait = rombug_wait;
+ rombug_ops.to_post_wait = NULL;
+ rombug_ops.to_fetch_registers = rombug_fetch_register;
+ rombug_ops.to_store_registers = rombug_store_register;
+ rombug_ops.to_prepare_to_store = rombug_prepare_to_store;
+ rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory;
+ rombug_ops.to_files_info = rombug_files_info;
+ rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint;
+ rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */
+ rombug_ops.to_terminal_init = 0;
+ rombug_ops.to_terminal_inferior = 0;
+ rombug_ops.to_terminal_ours_for_output = 0;
+ rombug_ops.to_terminal_ours = 0;
+ rombug_ops.to_terminal_info = 0; /* Terminal handling */
+ rombug_ops.to_kill = rombug_kill;
+ rombug_ops.to_load = rombug_load; /* load */
+ rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */
+ rombug_ops.to_create_inferior = rombug_create_inferior;
+ rombug_ops.to_post_startup_inferior = NULL;
+ rombug_ops.to_acknowledge_created_inferior = NULL;
+ rombug_ops.to_clone_and_follow_inferior = NULL;
+ rombug_ops.to_post_follow_inferior_by_clone = NULL;
+ rombug_ops.to_insert_fork_catchpoint = NULL;
+ rombug_ops.to_remove_fork_catchpoint = NULL;
+ rombug_ops.to_insert_vfork_catchpoint = NULL;
+ rombug_ops.to_remove_vfork_catchpoint = NULL;
+ rombug_ops.to_has_forked = NULL;
+ rombug_ops.to_has_vforked = NULL;
+ rombug_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ rombug_ops.to_post_follow_vfork = NULL;
+ rombug_ops.to_insert_exec_catchpoint = NULL;
+ rombug_ops.to_remove_exec_catchpoint = NULL;
+ rombug_ops.to_has_execd = NULL;
+ rombug_ops.to_reported_exec_events_per_exec_call = NULL;
+ rombug_ops.to_has_exited = NULL;
+ rombug_ops.to_mourn_inferior = rombug_mourn_inferior;
+ rombug_ops.to_can_run = 0; /* can_run */
+ rombug_ops.to_notice_signals = 0; /* notice_signals */
+ rombug_ops.to_thread_alive = 0;
+ rombug_ops.to_stop = 0; /* to_stop */
+ rombug_ops.to_pid_to_exec_file = NULL;
+ rombug_ops.to_core_file_to_sym_file = NULL;
+ rombug_ops.to_stratum = process_stratum;
+ rombug_ops.DONT_USE = 0; /* next */
+ rombug_ops.to_has_all_memory = 1;
+ rombug_ops.to_has_memory = 1;
+ rombug_ops.to_has_stack = 1;
+ rombug_ops.to_has_registers = 1;
+ rombug_ops.to_has_execution = 1; /* has execution */
+ rombug_ops.to_sections = 0;
+ rombug_ops.to_sections_end = 0; /* Section pointers */
+ rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+}
void
_initialize_remote_os9k ()
{
+ init_rombug_ops() ;
add_target (&rombug_ops);
add_show_from_set (
diff --git a/contrib/gdb/gdb/remote-rdi.c b/contrib/gdb/gdb/remote-rdi.c
new file mode 100644
index 0000000..dba920e
--- /dev/null
+++ b/contrib/gdb/gdb/remote-rdi.c
@@ -0,0 +1,973 @@
+/* GDB interface to ARM RDI library.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "wait.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+#include "gdbcore.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <signal.h>
+
+#include "rdi-share/ardi.h"
+#include "rdi-share/adp.h"
+#include "rdi-share/hsys.h"
+
+extern int isascii PARAMS ((int));
+
+/* Prototypes for local functions */
+
+static void arm_rdi_files_info PARAMS ((struct target_ops *ignore));
+
+static int arm_rdi_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct target_ops *target));
+
+static void arm_rdi_prepare_to_store PARAMS ((void));
+
+static void arm_rdi_fetch_registers PARAMS ((int regno));
+
+static void arm_rdi_resume PARAMS ((int pid, int step,
+ enum target_signal siggnal));
+
+static int arm_rdi_start_remote PARAMS ((char *dummy));
+
+static void arm_rdi_open PARAMS ((char *name, int from_tty));
+
+static void arm_rdi_create_inferior PARAMS ((char *exec_file, char *args,
+ char **env));
+
+static void arm_rdi_close PARAMS ((int quitting));
+
+static void arm_rdi_store_registers PARAMS ((int regno));
+
+static void arm_rdi_mourn PARAMS ((void));
+
+static void arm_rdi_send PARAMS ((char *buf));
+
+static int arm_rdi_wait PARAMS ((int pid, struct target_waitstatus *status));
+
+static void arm_rdi_kill PARAMS ((void));
+
+static void arm_rdi_detach PARAMS ((char *args, int from_tty));
+
+static void arm_rdi_interrupt PARAMS ((int signo));
+
+static void arm_rdi_interrupt_twice PARAMS ((int signo));
+
+static void interrupt_query PARAMS ((void));
+
+static int arm_rdi_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int arm_rdi_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static char *rdi_error_message PARAMS ((int err));
+
+static enum target_signal rdi_error_signal PARAMS ((int err));
+
+/* Global variables. */
+
+struct target_ops arm_rdi_ops;
+
+static struct Dbg_ConfigBlock gdb_config;
+
+static struct Dbg_HostosInterface gdb_hostif;
+
+static int max_load_size;
+
+static int execute_status;
+
+/* A little list of breakpoints that have been set. */
+
+static struct local_bp_list_entry {
+ CORE_ADDR addr;
+ PointHandle point;
+ struct local_bp_list_entry *next;
+} *local_bp_list;
+
+
+/* Stub for catch_errors. */
+
+static int
+arm_rdi_start_remote (dummy)
+ char *dummy;
+{
+ return 1;
+}
+
+/* Helper callbacks for the "host interface" structure. RDI functions call
+ these to forward output from the target system and so forth. */
+
+void
+voiddummy ()
+{
+ fprintf_unfiltered (gdb_stdout, "void dummy\n");
+}
+
+static void
+myprint (arg, format, ap)
+ PTR arg;
+ const char *format;
+ va_list ap;
+{
+ vfprintf_unfiltered (gdb_stdout, format, ap);
+}
+
+static void
+mywritec (arg, c)
+ PTR arg;
+ int c;
+{
+ if (isascii (c))
+ fputc_unfiltered (c, gdb_stdout);
+}
+
+static int
+mywrite (arg, buffer, len)
+ PTR arg;
+ char const *buffer;
+ int len;
+{
+ int i;
+ char *e;
+
+ e = (char *) buffer;
+ for (i = 0; i < len; i++)
+{
+ if (isascii ((int) *e))
+ {
+ fputc_unfiltered ((int) *e, gdb_stdout);
+ e++;
+ }
+}
+
+ return len;
+}
+
+static void
+mypause (arg)
+ PTR arg;
+{
+}
+
+/* These last two are tricky as we have to handle the special case of
+ being interrupted more carefully */
+
+static int
+myreadc (arg)
+ PTR arg;
+{
+ return fgetc (stdin);
+}
+
+static char *
+mygets (arg, buffer, len)
+ PTR arg;
+ char *buffer;
+ int len;
+{
+ return fgets(buffer, len, stdin);
+}
+
+/* Prevent multiple calls to angel_RDI_close(). */
+static int closed_already = 1;
+
+/* Open a connection to a remote debugger. NAME is the filename used
+ for communication. */
+
+static void
+arm_rdi_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ int rslt, i;
+ unsigned long arg1, arg2;
+
+ if (name == NULL)
+ error ("To open an RDI connection, you need to specify what serial\n\
+device is attached to the remote system (e.g. /dev/ttya).");
+
+ /* Make the basic low-level connection. */
+
+ rslt = Adp_OpenDevice (name, NULL, 1);
+
+ if (rslt != adp_ok)
+ error ("Could not open device \"%s\"", name);
+
+ gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BIG_ENDIAN ? 1 : 0);
+ gdb_config.fpe = 1;
+ gdb_config.rditype = 2;
+ gdb_config.heartbeat_on = 1;
+ gdb_config.flags = 2;
+
+ gdb_hostif.dbgprint = myprint;
+ gdb_hostif.dbgpause = mypause;
+ gdb_hostif.dbgarg = NULL;
+ gdb_hostif.writec = mywritec;
+ gdb_hostif.readc = myreadc;
+ gdb_hostif.write = mywrite;
+ gdb_hostif.gets = mygets;
+ gdb_hostif.hostosarg = NULL;
+ gdb_hostif.reset = voiddummy;
+
+ rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
+ if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
+ ; /* do nothing, this is the expected return */
+ else if (rslt)
+ {
+ printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
+ }
+
+ rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ max_load_size = arg1;
+
+ push_target (&arm_rdi_ops);
+
+ target_fetch_registers (-1);
+
+ rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
+ if (rslt)
+ {
+ printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
+ }
+
+ arg1 = 0x13b;
+ rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ arg1 = (unsigned long) "";
+ rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ /* Clear out any existing records of breakpoints. */
+ {
+ struct local_bp_list_entry *entry, *preventry = NULL;
+
+ for (entry = local_bp_list; entry != NULL; entry = entry->next)
+ {
+ if (preventry)
+ free (preventry);
+ }
+ }
+
+ printf_filtered ("Connected to ARM RDI target.\n");
+ closed_already = 0;
+ inferior_pid = 42;
+}
+
+/* Start an inferior process and set inferior_pid to its pid.
+ EXEC_FILE is the file to run.
+ ARGS is a string containing the arguments to the program.
+ ENV is the environment vector to pass. Errors reported with error().
+ On VxWorks and various standalone systems, we ignore exec_file. */
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+
+static void
+arm_rdi_create_inferior (exec_file, args, env)
+ char *exec_file;
+ char *args;
+ char **env;
+{
+ int len, rslt;
+ unsigned long arg1, arg2;
+ char *arg_buf;
+ CORE_ADDR entry_point;
+
+ if (exec_file == 0 || exec_bfd == 0)
+ error ("No executable file specified.");
+
+ entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
+
+ arm_rdi_kill ();
+ remove_breakpoints ();
+ init_wait_for_inferior ();
+
+ len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
+ arg_buf = (char *) alloca (len);
+ arg_buf[0] = '\0';
+ strcat (arg_buf, exec_file);
+ strcat (arg_buf, " ");
+ strcat (arg_buf, args);
+
+ inferior_pid = 42;
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+
+ if (env != NULL)
+ {
+ while (*env)
+ {
+ if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
+ {
+ unsigned long top_of_memory;
+ char *end_of_num;
+
+ /* Set up memory limit */
+ top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
+ &end_of_num, 0);
+ printf_filtered ("Setting top-of-memory to 0x%x\n",
+ top_of_memory);
+
+ rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ }
+ env++;
+ }
+ }
+
+ arg1 = (unsigned long) arg_buf;
+ rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *)arg_buf, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+static void
+arm_rdi_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ pop_target ();
+}
+
+/* Clean up connection to a remote debugger. */
+
+static void
+arm_rdi_close (quitting)
+ int quitting;
+{
+ int rslt;
+
+ if (! closed_already)
+ {
+ rslt = angel_RDI_close ();
+ if (rslt)
+ {
+ printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
+ }
+ closed_already = 1;
+ inferior_pid = 0;
+ }
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+arm_rdi_resume (pid, step, siggnal)
+ int pid, step;
+ enum target_signal siggnal;
+{
+ int rslt;
+ PointHandle point;
+
+ if (0 /* turn on when hardware supports single-stepping */)
+ {
+ rslt = angel_RDI_step (1, &point);
+ if (rslt)
+ {
+ printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
+ }
+ }
+ else
+ {
+ char handle[4];
+ CORE_ADDR pc;
+
+ if (step)
+ {
+ pc = read_register (PC_REGNUM);
+ pc = arm_get_next_pc (pc);
+ arm_rdi_insert_breakpoint (pc, handle);
+ }
+ execute_status = rslt = angel_RDI_execute (&point);
+ if (rslt == RDIError_BreakpointReached)
+ ;
+ else if (rslt)
+ {
+ printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
+ }
+ if (step)
+ {
+ arm_rdi_remove_breakpoint (pc, handle);
+ }
+ }
+}
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+static void
+arm_rdi_interrupt (signo)
+ int signo;
+{
+}
+
+static void (*ofunc)();
+
+/* The user typed ^C twice. */
+static void
+arm_rdi_interrupt_twice (signo)
+ int signo;
+{
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query ()
+{
+}
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. Returns "pid" (though it's not clear
+ what, if anything, that means in the case of this target). */
+
+static int
+arm_rdi_wait (pid, status)
+ int pid;
+ struct target_waitstatus *status;
+{
+ status->kind = (execute_status == RDIError_NoError ?
+ TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED);
+
+ /* convert stopped code from target into right signal */
+ status->value.sig = rdi_error_signal (execute_status);
+
+ return inferior_pid;
+}
+
+/* Read the remote registers into the block REGS. */
+
+/* ARGSUSED */
+static void
+arm_rdi_fetch_registers (regno)
+ int regno;
+{
+ int rslt, rdi_regmask;
+ unsigned long rawreg, rawregs[32];
+ char cookedreg[4];
+
+ if (regno == -1)
+ {
+ rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
+ if (rslt)
+ {
+ printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
+ }
+
+ for (regno = 0; regno < 15; regno++)
+ {
+ store_unsigned_integer (cookedreg, 4, rawregs[regno]);
+ supply_register (regno, (char *) cookedreg);
+ }
+ store_unsigned_integer (cookedreg, 4, rawregs[15]);
+ supply_register (PS_REGNUM, (char *) cookedreg);
+ arm_rdi_fetch_registers (PC_REGNUM);
+ }
+ else
+ {
+ if (regno == PC_REGNUM)
+ rdi_regmask = RDIReg_PC;
+ else if (regno == PS_REGNUM)
+ rdi_regmask = RDIReg_CPSR;
+ else if (regno < 0 || regno > 15)
+ {
+ rawreg = 0;
+ supply_register (regno, (char *) &rawreg);
+ return;
+ }
+ else
+ rdi_regmask = 1 << regno;
+
+ rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
+ if (rslt)
+ {
+ printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
+ }
+ store_unsigned_integer (cookedreg, 4, rawreg);
+ supply_register (regno, (char *) cookedreg);
+ }
+}
+
+static void
+arm_rdi_prepare_to_store ()
+{
+ /* Nothing to do. */
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. FIXME: ignores errors. */
+
+static void
+arm_rdi_store_registers (regno)
+ int regno;
+{
+ int rslt, rdi_regmask;
+
+ /* These need to be able to take 'floating point register' contents */
+ unsigned long rawreg[3], rawerreg[3];
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ arm_rdi_store_registers (regno);
+ }
+ else
+ {
+ read_register_gen (regno, (char *) rawreg);
+ /* RDI manipulates data in host byte order, so convert now. */
+ store_unsigned_integer (rawerreg, 4, rawreg[0]);
+
+ if (regno == PC_REGNUM)
+ rdi_regmask = RDIReg_PC;
+ else if (regno == PS_REGNUM)
+ rdi_regmask = RDIReg_CPSR;
+ else if (regno < 0 || regno > 15)
+ return;
+ else
+ rdi_regmask = 1 << regno;
+
+ rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
+ if (rslt)
+ {
+ printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
+ }
+ }
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. */
+
+/* ARGSUSED */
+static int
+arm_rdi_xfer_memory(memaddr, myaddr, len, should_write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int should_write;
+ struct target_ops *target; /* ignored */
+{
+ int rslt, i;
+
+ if (should_write)
+ {
+ rslt = angel_RDI_write (myaddr, memaddr, &len);
+ if (rslt)
+ {
+ printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
+ }
+ }
+ else
+ {
+ rslt = angel_RDI_read (memaddr, myaddr, &len);
+ if (rslt)
+ {
+ printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
+ len = 0;
+ }
+ }
+ return len;
+}
+
+/* Display random info collected from the target. */
+
+static void
+arm_rdi_files_info (ignore)
+ struct target_ops *ignore;
+{
+ char *file = "nothing";
+ int rslt;
+ unsigned long arg1, arg2;
+
+ rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ if (arg1 & (1 << 15))
+ printf_filtered ("Target supports Thumb code.\n");
+ if (arg1 & (1 << 14))
+ printf_filtered ("Target can do profiling.\n");
+ if (arg1 & (1 << 4))
+ printf_filtered ("Target is real hardware.\n");
+
+ rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
+
+ rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
+ if (rslt)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ else
+ printf_filtered ("Target includes an EmbeddedICE.\n");
+}
+
+static void
+arm_rdi_kill ()
+{
+ int rslt;
+
+ rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
+ if (rslt)
+ {
+ printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
+ }
+}
+
+static void
+arm_rdi_mourn_inferior ()
+{
+ unpush_target (&arm_rdi_ops);
+ generic_mourn_inferior ();
+}
+
+/* While the RDI library keeps track of its own breakpoints, we need
+ to remember "handles" so that we can delete them later. Since
+ breakpoints get used for stepping, be careful not to leak memory
+ here. */
+
+static int
+arm_rdi_insert_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ int rslt;
+ PointHandle point;
+ struct local_bp_list_entry *entry;
+ int type = RDIPoint_EQ;
+
+ if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
+ type |= RDIPoint_16Bit;
+ rslt = angel_RDI_setbreak (addr, type, 0, &point);
+ if (rslt)
+ {
+ printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
+ }
+ entry =
+ (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
+ entry->addr = addr;
+ entry->point = point;
+ entry->next = local_bp_list;
+ local_bp_list = entry;
+ return rslt;
+}
+
+static int
+arm_rdi_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ int rslt;
+ PointHandle point;
+ struct local_bp_list_entry *entry, *preventry;
+
+ for (entry = local_bp_list; entry != NULL; entry = entry->next)
+ {
+ if (entry->addr == addr)
+ {
+ break;
+ }
+ preventry = entry;
+ }
+ if (entry)
+ {
+ rslt = angel_RDI_clearbreak (entry->point);
+ if (rslt)
+ {
+ printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
+ }
+ /* Delete the breakpoint entry locally. */
+ if (entry == local_bp_list)
+ {
+ local_bp_list = entry->next;
+ }
+ else
+ {
+ preventry->next = entry->next;
+ }
+ free (entry);
+ }
+ return 0;
+}
+
+static char *
+rdi_error_message (err)
+ int err;
+{
+ switch (err)
+ {
+ case RDIError_NoError:
+ return "no error";
+ case RDIError_Reset:
+ return "debuggee reset";
+ case RDIError_UndefinedInstruction:
+ return "undefined instruction";
+ case RDIError_SoftwareInterrupt:
+ return "SWI trapped";
+ case RDIError_PrefetchAbort:
+ return "prefetch abort, execution ran into unmapped memory?";
+ case RDIError_DataAbort:
+ return "data abort, no memory at specified address?";
+ case RDIError_AddressException:
+ return "address exception, access >26bit in 26bit mode";
+ case RDIError_IRQ:
+ return "IRQ, interrupt trapped";
+ case RDIError_FIQ:
+ return "FIQ, fast interrupt trapped";
+ case RDIError_Error:
+ return "a miscellaneous type of error";
+ case RDIError_BranchThrough0:
+ return "branch through location 0";
+ case RDIError_NotInitialised:
+ return "internal error, RDI_open not called first";
+ case RDIError_UnableToInitialise:
+ return "internal error, target world is broken";
+ case RDIError_WrongByteSex:
+ return "See Operator: WrongByteSex";
+ case RDIError_UnableToTerminate:
+ return "See Operator: Unable to Terminate";
+ case RDIError_BadInstruction:
+ return "bad instruction, illegal to execute this instruction";
+ case RDIError_IllegalInstruction:
+ return "illegal instruction, the effect of executing it is undefined";
+ case RDIError_BadCPUStateSetting:
+ return "internal error, tried to set SPSR of user mode";
+ case RDIError_UnknownCoPro:
+ return "unknown co-processor";
+ case RDIError_UnknownCoProState:
+ return "cannot execute co-processor request";
+ case RDIError_BadCoProState:
+ return "recognizably broken co-processor request";
+ case RDIError_BadPointType:
+ return "internal error, bad point yype";
+ case RDIError_UnimplementedType:
+ return "internal error, unimplemented type";
+ case RDIError_BadPointSize:
+ return "internal error, bad point size";
+ case RDIError_UnimplementedSize:
+ return "internal error, unimplemented size";
+ case RDIError_NoMorePoints:
+ return "last break/watch point was used";
+ case RDIError_BreakpointReached:
+ return "breakpoint reached";
+ case RDIError_WatchpointAccessed:
+ return "watchpoint accessed";
+ case RDIError_NoSuchPoint:
+ return "attempted to clear non-existent break/watch point";
+ case RDIError_ProgramFinishedInStep:
+ return "end of the program reached while stepping";
+ case RDIError_UserInterrupt:
+ return "you pressed Escape";
+ case RDIError_CantSetPoint:
+ return "no more break/watch points available";
+ case RDIError_IncompatibleRDILevels:
+ return "incompatible RDI levels";
+ case RDIError_LittleEndian:
+ return "debuggee is little endian";
+ case RDIError_BigEndian:
+ return "debuggee is big endian";
+ case RDIError_SoftInitialiseError:
+ return "recoverable error in RDI initialization";
+ case RDIError_InsufficientPrivilege:
+ return "internal error, supervisor state not accessible to monitor";
+ case RDIError_UnimplementedMessage:
+ return "internal error, unimplemented message";
+ case RDIError_UndefinedMessage:
+ return "internal error, undefined message";
+ default:
+ return "undefined error message, should reset target";
+ }
+}
+
+/* Convert the ARM error messages to signals that GDB knows about. */
+
+static enum target_signal
+rdi_error_signal (err)
+ int err;
+{
+ switch (err)
+ {
+ case RDIError_NoError:
+ return 0;
+ case RDIError_Reset:
+ return TARGET_SIGNAL_TERM; /* ??? */
+ case RDIError_UndefinedInstruction:
+ return TARGET_SIGNAL_ILL;
+ case RDIError_SoftwareInterrupt:
+ case RDIError_PrefetchAbort:
+ case RDIError_DataAbort:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_AddressException:
+ return TARGET_SIGNAL_SEGV;
+ case RDIError_IRQ:
+ case RDIError_FIQ:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_Error:
+ return TARGET_SIGNAL_TERM;
+ case RDIError_BranchThrough0:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_NotInitialised:
+ case RDIError_UnableToInitialise:
+ case RDIError_WrongByteSex:
+ case RDIError_UnableToTerminate:
+ return TARGET_SIGNAL_UNKNOWN;
+ case RDIError_BadInstruction:
+ case RDIError_IllegalInstruction:
+ return TARGET_SIGNAL_ILL;
+ case RDIError_BadCPUStateSetting:
+ case RDIError_UnknownCoPro:
+ case RDIError_UnknownCoProState:
+ case RDIError_BadCoProState:
+ case RDIError_BadPointType:
+ case RDIError_UnimplementedType:
+ case RDIError_BadPointSize:
+ case RDIError_UnimplementedSize:
+ case RDIError_NoMorePoints:
+ return TARGET_SIGNAL_UNKNOWN;
+ case RDIError_BreakpointReached:
+ case RDIError_WatchpointAccessed:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_NoSuchPoint:
+ case RDIError_ProgramFinishedInStep:
+ return TARGET_SIGNAL_UNKNOWN;
+ case RDIError_UserInterrupt:
+ return TARGET_SIGNAL_INT;
+ case RDIError_IncompatibleRDILevels:
+ case RDIError_LittleEndian:
+ case RDIError_BigEndian:
+ case RDIError_SoftInitialiseError:
+ case RDIError_InsufficientPrivilege:
+ case RDIError_UnimplementedMessage:
+ case RDIError_UndefinedMessage:
+ default:
+ return TARGET_SIGNAL_UNKNOWN;
+ }
+}
+
+/* Define the target operations structure. */
+
+static void
+init_rdi_ops ()
+{
+ arm_rdi_ops.to_shortname = "rdi";
+ arm_rdi_ops.to_longname = "ARM RDI";
+ arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya)." ;
+ arm_rdi_ops.to_open = arm_rdi_open;
+ arm_rdi_ops.to_close = arm_rdi_close;
+ arm_rdi_ops.to_detach = arm_rdi_detach;
+ arm_rdi_ops.to_resume = arm_rdi_resume;
+ arm_rdi_ops.to_wait = arm_rdi_wait;
+ arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
+ arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
+ arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
+ arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory;
+ arm_rdi_ops.to_files_info = arm_rdi_files_info;
+ arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
+ arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
+ arm_rdi_ops.to_kill = arm_rdi_kill;
+ arm_rdi_ops.to_load = generic_load;
+ arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
+ arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
+ arm_rdi_ops.to_stratum = process_stratum;
+ arm_rdi_ops.to_has_all_memory = 1;
+ arm_rdi_ops.to_has_memory = 1;
+ arm_rdi_ops.to_has_stack = 1;
+ arm_rdi_ops.to_has_registers = 1;
+ arm_rdi_ops.to_has_execution = 1;
+ arm_rdi_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_remote_rdi ()
+{
+ init_rdi_ops () ;
+ add_target (&arm_rdi_ops);
+}
+
+/* A little dummy to make linking with the library succeed. */
+
+int Fail() { return 0; }
diff --git a/contrib/gdb/gdb/remote-rdp.c b/contrib/gdb/gdb/remote-rdp.c
index 3cc4c4e..1d596a4 100644
--- a/contrib/gdb/gdb/remote-rdp.c
+++ b/contrib/gdb/gdb/remote-rdp.c
@@ -54,6 +54,7 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#include "gdbcore.h"
extern struct target_ops remote_rdp_ops;
@@ -138,6 +139,16 @@ ds;
#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9)
#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10)
#define RDP_INFO_ABOUT_BREAK_COND (1<<11)
+#define RDP_INFO_VECTOR_CATCH (0x180)
+#define RDP_INFO_ICEBREAKER (7)
+#define RDP_INFO_SET_CMDLINE (0x300)
+
+#define RDP_SELECT_CONFIG (0x16)
+#define RDI_ConfigCPU 0
+#define RDI_ConfigSystem 1
+#define RDI_MatchAny 0
+#define RDI_MatchExactly 1
+#define RDI_MatchNoEarlier 2
#define RDP_RESET 0x7f
@@ -157,6 +168,8 @@ ds;
static int timeout = 2;
+static char * commandline = NULL;
+
static int
remote_rdp_xfer_inferior_memory PARAMS ((CORE_ADDR memaddr,
char *myaddr,
@@ -263,9 +276,39 @@ rdp_init (cold, tty)
if (tty)
printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);
+
+ /*
+ ** It seems necessary to reset an EmbeddedICE to get it going.
+ ** This has the side benefit of displaying the startup banner.
+ */
+ if (cold)
+ {
+ put_byte (RDP_RESET);
+ while ((restype = SERIAL_READCHAR (io, 1)) > 0)
+ {
+ switch (restype)
+ {
+ case SERIAL_TIMEOUT:
+ break;
+ case RDP_RESET:
+ /* Sent at start of reset process: ignore */
+ break;
+ default:
+ printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
+ break;
+ }
+ }
+
+ if (restype == 0)
+ {
+ /* Got end-of-banner mark */
+ printf_filtered ("\n");
+ }
+ }
+
put_byte (RDP_OPEN);
- put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
+ put_byte (type | RDP_OPEN_TYPE_RETURN_SEX );
put_word (0);
while (!sync && (restype = SERIAL_READCHAR (io, 1)) > 0)
@@ -277,15 +320,16 @@ rdp_init (cold, tty)
{
case SERIAL_TIMEOUT:
break;
+
case RDP_RESET:
while ((restype = SERIAL_READCHAR (io, 1)) == RDP_RESET)
;
- while ((restype = SERIAL_READCHAR (io, 1)) > 0)
+ do
{
printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
}
- while ((restype = SERIAL_READCHAR (io, 1)) > 0)
- ;
+ while ((restype = SERIAL_READCHAR (io, 1)) > 0);
+
if (tty)
{
printf_unfiltered ("\nThe board has sent notification that it was reset.\n");
@@ -294,12 +338,19 @@ rdp_init (cold, tty)
sleep (3);
if (tty)
printf_unfiltered ("\nTrying again.\n");
+ cold = 0;
break;
+
default:
break;
+
case RDP_RES_VALUE:
{
int resval = SERIAL_READCHAR (io, 1);
+
+ if (remote_debug)
+ printf_unfiltered ("[%02x]\n", resval);
+
switch (resval)
{
case SERIAL_TIMEOUT:
@@ -384,9 +435,27 @@ send_rdp (char *template, va_alist)
}
break;
case 'Z':
- /* Check the result code, error if not zero */
- if (get_byte ())
- error ("Command garbled");
+ /* Check the result code */
+ switch (get_byte ())
+ {
+ case 0:
+ /* Success */
+ break;
+ case 253:
+ /* Target can't do it; never mind */
+ printf_unfiltered ("RDP: Insufficient privilege\n");
+ return;
+ case 254:
+ /* Target can't do it; never mind */
+ printf_unfiltered ("RDP: Unimplemented message\n");
+ return;
+ case 255:
+ error ("Command garbled");
+ break;
+ default:
+ error ("Corrupt reply from target");
+ break;
+ }
break;
case 'W':
/* Read a word from the target */
@@ -652,6 +721,50 @@ rdp_execute_start ()
}
+static void
+rdp_set_command_line (command, args)
+ char * command;
+ char * args;
+{
+ /*
+ ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems
+ ** don't implement that, and get all confused at the unexpected text.
+ ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv
+ */
+
+ if (commandline != NULL)
+ free (commandline);
+
+ commandline = malloc (strlen (command) + strlen (args) + 2);
+ if (commandline != NULL)
+ {
+ strcpy (commandline, command);
+ strcat (commandline, " ");
+ strcat (commandline, args);
+ }
+}
+
+static void
+rdp_catch_vectors ()
+{
+ /*
+ ** We want the target monitor to intercept the abort vectors
+ ** i.e. stop the program if any of these are used.
+ */
+ send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH,
+ /*
+ ** Specify a bitmask including
+ ** the reset vector
+ ** the undefined instruction vector
+ ** the prefetch abort vector
+ ** the data abort vector
+ ** the address exception vector
+ */
+ (1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<5)
+ );
+}
+
+
#define a_byte 1
#define a_word 2
@@ -698,6 +811,26 @@ argsin;
#define SWI_GenerateError 0x71
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+static int translate_open_mode[] =
+{
+ O_RDONLY, /* "r" */
+ O_RDONLY+O_BINARY, /* "rb" */
+ O_RDWR, /* "r+" */
+ O_RDWR +O_BINARY, /* "r+b" */
+ O_WRONLY +O_CREAT+O_TRUNC, /* "w" */
+ O_WRONLY+O_BINARY+O_CREAT+O_TRUNC, /* "wb" */
+ O_RDWR +O_CREAT+O_TRUNC, /* "w+" */
+ O_RDWR +O_BINARY+O_CREAT+O_TRUNC, /* "w+b" */
+ O_WRONLY +O_APPEND+O_CREAT,/* "a" */
+ O_WRONLY+O_BINARY+O_APPEND+O_CREAT,/* "ab" */
+ O_RDWR +O_APPEND+O_CREAT,/* "a+" */
+ O_RDWR +O_BINARY+O_APPEND+O_CREAT /* "a+b" */
+};
+
static int
exec_swi (swi, args)
int swi;
@@ -727,31 +860,41 @@ exec_swi (swi, args)
case SWI_Time:
args->n = callback->time (callback, NULL);
return 1;
+
+ case SWI_Clock :
+ /* return number of centi-seconds... */
+ args->n =
+#ifdef CLOCKS_PER_SEC
+ (CLOCKS_PER_SEC >= 100)
+ ? (clock() / (CLOCKS_PER_SEC / 100))
+ : ((clock() * 100) / CLOCKS_PER_SEC) ;
+#else
+ /* presume unix... clock() returns microseconds */
+ clock() / 10000 ;
+#endif
+ return 1 ;
+
case SWI_Remove:
args->n = callback->unlink (callback, args->s);
return 1;
case SWI_Rename:
args->n = callback->rename (callback, args[0].s, args[1].s);
return 1;
- case SWI_Open:
- i = 0;
-
-#ifdef O_BINARY
- if (args[1].n & 1)
- i |= O_BINARY;
-#endif
- if (args[1].n & 2)
- i |= O_RDWR;
-
- if (args[1].n & 4)
- {
- i |= O_CREAT;
- }
-
- if (args[1].n & 8)
- i |= O_APPEND;
- args->n = callback->open (callback, args->s, i);
+ case SWI_Open:
+ /* Now we need to decode the Demon open mode */
+ i = translate_open_mode[args[1].n];
+
+ /* Filename ":tt" is special: it denotes stdin/out */
+ if (strcmp(args->s,":tt")==0)
+ {
+ if (i == O_RDONLY ) /* opening tty "r" */
+ args->n = 0 /* stdin */ ;
+ else
+ args->n = 1 /* stdout */ ;
+ }
+ else
+ args->n = callback->open (callback, args->s, i);
return 1;
case SWI_Close:
@@ -759,25 +902,30 @@ exec_swi (swi, args)
return 1;
case SWI_Write:
- args->n = callback->write (callback, args[0].n, args[1].s, args[1].n);
+ /* Return the number of bytes *not* written */
+ args->n = args[1].n -
+ callback->write (callback, args[0].n, args[1].s, args[1].n);
return 1;
+
case SWI_Read:
{
char *copy = alloca (args[2].n);
int done = callback->read (callback, args[0].n, copy, args[2].n);
if (done > 0)
- remote_rdp_xfer_inferior_memory (args[0].n, copy, done, 1, 0);
- args->n -= done;
+ remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0);
+ args->n = args[2].n-done;
return 1;
}
case SWI_Seek:
- args->n = callback->lseek (callback, args[0].n, args[1].n, 0) >= 0;
+ /* Return non-zero on failure */
+ args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0;
return 1;
+
case SWI_Flen:
{
- long old = callback->lseek (callback, args->n, 1, 1);
- args->n = callback->lseek (callback, args->n, 2, 0);
+ long old = callback->lseek (callback, args->n, 0, SEEK_CUR);
+ args->n = callback->lseek (callback, args->n, 0, SEEK_END);
callback->lseek (callback, args->n, old, 0);
return 1;
}
@@ -786,6 +934,22 @@ exec_swi (swi, args)
args->n = callback->isatty (callback, args->n);
return 1;
+ case SWI_GetEnv:
+ if (commandline != NULL)
+ {
+ int len = strlen (commandline);
+ if (len > 255)
+ {
+ len = 255;
+ commandline [255]='\0';
+ }
+ remote_rdp_xfer_inferior_memory (args[0].n,
+ commandline, len+1, 1, 0);
+ }
+ else
+ remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0);
+ return 1;
+
default:
return 0;
}
@@ -986,6 +1150,8 @@ remote_rdp_open (args, from_tty)
char *args;
int from_tty;
{
+ int not_icebreaker;
+
if (!args)
error_no_arg ("serial port device name");
@@ -1010,7 +1176,33 @@ remote_rdp_open (args, from_tty)
rdp_info ();
- push_target (&remote_rdp_ops);
+ /* Need to set up the vector interception state */
+ rdp_catch_vectors();
+
+ /*
+ ** If it's an EmbeddedICE, we need to set the processor config.
+ ** Assume we can always have ARM7TDI...
+ */
+ send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, & not_icebreaker);
+ if (!not_icebreaker)
+ {
+ const char * CPU = "ARM7TDI";
+ int ICEversion;
+ int len = strlen (CPU);
+
+ send_rdp ("bbbbw-p-SWZ",
+ RDP_SELECT_CONFIG,
+ RDI_ConfigCPU, /* Aspect: set the CPU */
+ len, /* The number of bytes in the name */
+ RDI_MatchAny, /* We'll take whatever we get */
+ 0, /* We'll take whatever version's there */
+ CPU,len,
+ & ICEversion);
+ }
+
+ /* command line initialised on 'run'*/
+
+ push_target (& remote_rdp_ops);
callback->init (callback);
flush_cached_frames ();
@@ -1192,56 +1384,129 @@ remote_rdp_files_info (target)
}
+static void
+remote_rdp_create_inferior (exec_file, allargs, env)
+ char * exec_file;
+ char * allargs;
+ char ** env;
+{
+ CORE_ADDR entry_point;
+
+ if (exec_file == 0 || exec_bfd == 0)
+ error ("No executable file specified.");
+
+ entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
+
+ remote_rdp_kill ();
+ remove_breakpoints ();
+ init_wait_for_inferior ();
+
+ /* This gives us a chance to set up the command line */
+ rdp_set_command_line (exec_file, allargs);
+
+ inferior_pid = 42;
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+
+ /*
+ ** RDP targets don't provide any facility to set the top of memory,
+ ** so we don't bother to look for MEMSIZE in the environment.
+ */
+
+ /* Let's go! */
+ proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Accept any stray run/attach commands */
+static int
+remote_rdp_can_run()
+{
+ return 1;
+}
+
+/* Attach doesn't need to do anything */
+static void
+remote_rdp_attach(args, from_tty)
+ char * args;
+ int from_tty;
+{
+ return;
+}
+
/* Define the target subroutine names */
-struct target_ops remote_rdp_ops =
+struct target_ops remote_rdp_ops ;
+
+static void
+init_remote_rdp_ops(void)
{
- "rdp", /* to_shortname */
- /* to_longname */
- "Remote Target using the RDProtocol",
- /* to_doc */
- "Use a remote ARM system which uses the ARM Remote Debugging Protocol",
- remote_rdp_open, /* to_open */
- remote_rdp_close, /* to_close */
- NULL, /* to_attach */
- NULL, /* to_detach */
- remote_rdp_resume, /* to_resume */
- remote_rdp_wait, /* to_wait */
- remote_rdp_fetch_register, /* to_fetch_registers */
- remote_rdp_store_register, /* to_store_registers */
- remote_rdp_prepare_to_store, /* to_prepare_to_store */
- remote_rdp_xfer_inferior_memory, /* to_xfer_memory */
- remote_rdp_files_info, /* to_files_info */
- remote_rdp_insert_breakpoint, /* to_insert_breakpoint */
- remote_rdp_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- remote_rdp_kill, /* to_kill */
- generic_load, /* to_load */
- NULL, /* to_lookup_symbol */
- NULL, /* to_create_inferior */
- generic_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC, /* to_magic */
-};
+ remote_rdp_ops.to_shortname = "rdp";
+ remote_rdp_ops.to_longname = "Remote Target using the RDProtocol";
+ remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol";
+ remote_rdp_ops.to_open = remote_rdp_open;
+ remote_rdp_ops.to_close = remote_rdp_close;
+ remote_rdp_ops.to_attach = remote_rdp_attach;
+ remote_rdp_ops.to_post_attach = NULL;
+ remote_rdp_ops.to_require_attach = NULL;
+ remote_rdp_ops.to_detach = NULL;
+ remote_rdp_ops.to_require_detach = NULL;
+ remote_rdp_ops.to_resume = remote_rdp_resume;
+ remote_rdp_ops.to_wait = remote_rdp_wait;
+ remote_rdp_ops.to_post_wait = NULL;
+ remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register;
+ remote_rdp_ops.to_store_registers = remote_rdp_store_register;
+ remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store;
+ remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory;
+ remote_rdp_ops.to_files_info = remote_rdp_files_info;
+ remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
+ remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
+ remote_rdp_ops.to_terminal_init = NULL;
+ remote_rdp_ops.to_terminal_inferior = NULL;
+ remote_rdp_ops.to_terminal_ours_for_output = NULL;
+ remote_rdp_ops.to_terminal_ours = NULL;
+ remote_rdp_ops.to_terminal_info = NULL;
+ remote_rdp_ops.to_kill = remote_rdp_kill;
+ remote_rdp_ops.to_load = generic_load;
+ remote_rdp_ops.to_lookup_symbol = NULL;
+ remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
+ remote_rdp_ops.to_post_startup_inferior = NULL;
+ remote_rdp_ops.to_acknowledge_created_inferior = NULL;
+ remote_rdp_ops.to_clone_and_follow_inferior = NULL;
+ remote_rdp_ops.to_post_follow_inferior_by_clone = NULL;
+ remote_rdp_ops.to_insert_fork_catchpoint = NULL;
+ remote_rdp_ops.to_remove_fork_catchpoint = NULL;
+ remote_rdp_ops.to_insert_vfork_catchpoint = NULL;
+ remote_rdp_ops.to_remove_vfork_catchpoint = NULL;
+ remote_rdp_ops.to_has_forked = NULL;
+ remote_rdp_ops.to_has_vforked = NULL;
+ remote_rdp_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ remote_rdp_ops.to_post_follow_vfork = NULL;
+ remote_rdp_ops.to_insert_exec_catchpoint = NULL;
+ remote_rdp_ops.to_remove_exec_catchpoint = NULL;
+ remote_rdp_ops.to_has_execd = NULL;
+ remote_rdp_ops.to_reported_exec_events_per_exec_call = NULL;
+ remote_rdp_ops.to_has_exited = NULL;
+ remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior;
+ remote_rdp_ops.to_can_run = remote_rdp_can_run;
+ remote_rdp_ops.to_notice_signals = 0;
+ remote_rdp_ops.to_thread_alive = 0;
+ remote_rdp_ops.to_stop = 0;
+ remote_rdp_ops.to_pid_to_exec_file = NULL;
+ remote_rdp_ops.to_core_file_to_sym_file = NULL;
+ remote_rdp_ops.to_stratum = process_stratum;
+ remote_rdp_ops.DONT_USE = NULL;
+ remote_rdp_ops.to_has_all_memory = 1;
+ remote_rdp_ops.to_has_memory = 1;
+ remote_rdp_ops.to_has_stack = 1;
+ remote_rdp_ops.to_has_registers = 1;
+ remote_rdp_ops.to_has_execution = 1;
+ remote_rdp_ops.to_sections = NULL;
+ remote_rdp_ops.to_sections_end = NULL;
+ remote_rdp_ops.to_magic = OPS_MAGIC;
+}
void
_initialize_remote_rdp ()
{
+ init_remote_rdp_ops() ;
add_target (&remote_rdp_ops);
}
diff --git a/contrib/gdb/gdb/remote-sds.c b/contrib/gdb/gdb/remote-sds.c
new file mode 100644
index 0000000..3ab5f44
--- /dev/null
+++ b/contrib/gdb/gdb/remote-sds.c
@@ -0,0 +1,1206 @@
+/* Remote target communications for serial-line targets using SDS' protocol.
+ Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This interface was written by studying the behavior of the SDS
+ monitor on an ADS 821/860 board, and by consulting the
+ documentation of the monitor that is available on Motorola's web
+ site. -sts 8/13/97 */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "wait.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+#include "gdbcore.h"
+#include "dcache.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <signal.h>
+#include "serial.h"
+
+extern void _initialize_remote_sds PARAMS ((void));
+
+/* Declarations of local functions. */
+
+static int sds_write_bytes PARAMS ((CORE_ADDR, char *, int));
+
+static int sds_read_bytes PARAMS ((CORE_ADDR, char *, int));
+
+static void sds_files_info PARAMS ((struct target_ops *ignore));
+
+static int sds_xfer_memory PARAMS ((CORE_ADDR, char *,
+ int, int, struct target_ops *));
+
+static void sds_prepare_to_store PARAMS ((void));
+
+static void sds_fetch_registers PARAMS ((int));
+
+static void sds_resume PARAMS ((int, int, enum target_signal));
+
+static int sds_start_remote PARAMS ((PTR));
+
+static void sds_open PARAMS ((char *, int));
+
+static void sds_close PARAMS ((int));
+
+static void sds_store_registers PARAMS ((int));
+
+static void sds_mourn PARAMS ((void));
+
+static void sds_create_inferior PARAMS ((char *, char *, char **));
+
+static void sds_load PARAMS ((char *, int));
+
+static int getmessage PARAMS ((unsigned char *, int));
+
+static int putmessage PARAMS ((unsigned char *, int));
+
+static int sds_send PARAMS ((unsigned char *, int));
+
+static int readchar PARAMS ((int));
+
+static int sds_wait PARAMS ((int, struct target_waitstatus *));
+
+static void sds_kill PARAMS ((void));
+
+static int tohex PARAMS ((int));
+
+static int fromhex PARAMS ((int));
+
+static void sds_detach PARAMS ((char *, int));
+
+static void sds_interrupt PARAMS ((int));
+
+static void sds_interrupt_twice PARAMS ((int));
+
+static void interrupt_query PARAMS ((void));
+
+static int read_frame PARAMS ((char *));
+
+static int sds_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int sds_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static void init_sds_ops PARAMS ((void));
+
+static void sds_command PARAMS ((char *args, int from_tty));
+
+/* Define the target operations vector. */
+
+static struct target_ops sds_ops;
+
+/* This was 5 seconds, which is a long time to sit and wait.
+ Unless this is going though some terminal server or multiplexer or
+ other form of hairy serial connection, I would think 2 seconds would
+ be plenty. */
+
+static int sds_timeout = 2;
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so
+ that sds_open knows that we don't have a file open when the program
+ starts. */
+
+static serial_t sds_desc = NULL;
+
+/* This limit comes from the monitor. */
+
+#define PBUFSIZ 250
+
+/* Maximum number of bytes to read/write at once. The value here
+ is chosen to fill up a packet (the headers account for the 32). */
+#define MAXBUFBYTES ((PBUFSIZ-32)/2)
+
+static int next_msg_id;
+
+static int just_started;
+
+static int message_pending;
+
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+static void
+sds_close (quitting)
+ int quitting;
+{
+ if (sds_desc)
+ SERIAL_CLOSE (sds_desc);
+ sds_desc = NULL;
+}
+
+/* Stub for catch_errors. */
+
+static int
+sds_start_remote (dummy)
+ PTR dummy;
+{
+ char c;
+ unsigned char buf[200];
+
+ immediate_quit = 1; /* Allow user to interrupt it */
+
+ /* Ack any packet which the remote side has already sent. */
+ SERIAL_WRITE (sds_desc, "{#*\r\n", 5);
+ SERIAL_WRITE (sds_desc, "{#}\r\n", 5);
+
+ while ((c = readchar (1)) >= 0)
+ printf_unfiltered ("%c", c);
+ printf_unfiltered ("\n");
+
+ next_msg_id = 251;
+
+ buf[0] = 26;
+ sds_send (buf, 1);
+
+ buf[0] = 0;
+ sds_send (buf, 1);
+
+ immediate_quit = 0;
+
+ start_remote (); /* Initialize gdb process mechanisms */
+ return 1;
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static DCACHE *sds_dcache;
+
+static void
+sds_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ if (name == 0)
+ error ("To open a remote debug connection, you need to specify what serial\n\
+device is attached to the remote system (e.g. /dev/ttya).");
+
+ target_preopen (from_tty);
+
+ unpush_target (&sds_ops);
+
+ sds_dcache = dcache_init (sds_read_bytes, sds_write_bytes);
+
+ sds_desc = SERIAL_OPEN (name);
+ if (!sds_desc)
+ perror_with_name (name);
+
+ if (baud_rate != -1)
+ {
+ if (SERIAL_SETBAUDRATE (sds_desc, baud_rate))
+ {
+ SERIAL_CLOSE (sds_desc);
+ perror_with_name (name);
+ }
+ }
+
+
+ SERIAL_RAW (sds_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ SERIAL_FLUSH_INPUT (sds_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote debugging using ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+ push_target (&sds_ops); /* Switch to using remote target now */
+
+ just_started = 1;
+
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it (we'd be
+ in an inconsistent state otherwise). */
+ if (!catch_errors (sds_start_remote, NULL,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ pop_target ();
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+static void
+sds_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char buf[PBUFSIZ];
+
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+#if 0
+ /* Tell the remote target to detach. */
+ strcpy (buf, "D");
+ sds_send (buf, 1);
+#endif
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+}
+
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (a)
+ int a;
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else
+ error ("Reply contains invalid hex digit %d", a);
+}
+
+/* Convert number NIB to a hex digit. */
+
+static int
+tohex (nib)
+ int nib;
+{
+ if (nib < 10)
+ return '0'+nib;
+ else
+ return 'a'+nib-10;
+}
+
+static int
+tob64 (inbuf, outbuf, len)
+ unsigned char *inbuf;
+ char *outbuf;
+ int len;
+{
+ int i, sum;
+ char *p;
+
+ if (len % 3 != 0)
+ error ("bad length");
+
+ p = outbuf;
+ for (i = 0; i < len; i += 3)
+ {
+ /* Collect the next three bytes into a number. */
+ sum = ((long) *inbuf++) << 16;
+ sum |= ((long) *inbuf++) << 8;
+ sum |= ((long) *inbuf++);
+
+ /* Spit out 4 6-bit encodings. */
+ *p++ = ((sum >> 18) & 0x3f) + '0';
+ *p++ = ((sum >> 12) & 0x3f) + '0';
+ *p++ = ((sum >> 6) & 0x3f) + '0';
+ *p++ = (sum & 0x3f) + '0';
+ }
+ return (p - outbuf);
+}
+
+static int
+fromb64 (inbuf, outbuf, len)
+ char *inbuf, *outbuf;
+ int len;
+{
+ int i, sum;
+
+ if (len % 4 != 0)
+ error ("bad length");
+
+ for (i = 0; i < len; i += 4)
+ {
+ /* Collect 4 6-bit digits. */
+ sum = (*inbuf++ - '0') << 18;
+ sum |= (*inbuf++ - '0') << 12;
+ sum |= (*inbuf++ - '0') << 6;
+ sum |= (*inbuf++ - '0');
+
+ /* Now take the resulting 24-bit number and get three bytes out
+ of it. */
+ *outbuf++ = (sum >> 16) & 0xff;
+ *outbuf++ = (sum >> 8) & 0xff;
+ *outbuf++ = sum & 0xff;
+ }
+
+ return (len / 4) * 3;
+}
+
+
+/* Tell the remote machine to resume. */
+
+static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+int last_sent_step;
+
+static void
+sds_resume (pid, step, siggnal)
+ int pid, step;
+ enum target_signal siggnal;
+{
+ unsigned char buf[PBUFSIZ];
+
+ dcache_flush (sds_dcache);
+
+ last_sent_signal = siggnal;
+ last_sent_step = step;
+
+ buf[0] = (step ? 21 : 20);
+ buf[1] = 0; /* (should be signal?) */
+
+ sds_send (buf, 2);
+}
+
+/* Send a message to target to halt it. Target will respond, and send
+ us a message pending notice. */
+
+static void
+sds_interrupt (signo)
+ int signo;
+{
+ unsigned char buf[PBUFSIZ];
+
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, sds_interrupt_twice);
+
+ if (remote_debug)
+ printf_unfiltered ("sds_interrupt called\n");
+
+ buf[0] = 25;
+ sds_send (buf, 1);
+}
+
+static void (*ofunc)();
+
+/* The user typed ^C twice. */
+
+static void
+sds_interrupt_twice (signo)
+ int signo;
+{
+ signal (signo, ofunc);
+
+ interrupt_query ();
+
+ signal (signo, sds_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query ()
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ return_to_top_level (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+/* If nonzero, ignore the next kill. */
+int kill_kludge;
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. Returns "pid" (though it's not clear
+ what, if anything, that means in the case of this target). */
+
+static int
+sds_wait (pid, status)
+ int pid;
+ struct target_waitstatus *status;
+{
+ unsigned char buf[PBUFSIZ];
+ int retlen;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ ofunc = (void (*)()) signal (SIGINT, sds_interrupt);
+
+ signal (SIGINT, ofunc);
+
+ if (just_started)
+ {
+ just_started = 0;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ return inferior_pid;
+ }
+
+ while (1)
+ {
+ getmessage (buf, 1);
+
+ if (message_pending)
+ {
+ buf[0] = 26;
+ retlen = sds_send (buf, 1);
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stderr, "Signals: %04x %02x %02x\n",
+ ((int) buf[0]) << 8 + buf[1],
+ buf[2], buf[3]);
+ }
+ message_pending = 0;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ goto got_status;
+ }
+ }
+ got_status:
+ return inferior_pid;
+}
+
+static unsigned char sprs[16];
+
+/* Read the remote registers into the block REGS. */
+/* Currently we just read all the registers, so we don't use regno. */
+
+/* ARGSUSED */
+static void
+sds_fetch_registers (regno)
+ int regno;
+{
+ unsigned char buf[PBUFSIZ];
+ int i, retlen;
+ char *p;
+ char regs[REGISTER_BYTES];
+
+ /* Unimplemented registers read as all bits zero. */
+ memset (regs, 0, REGISTER_BYTES);
+
+ buf[0] = 18;
+ buf[1] = 1;
+ buf[2] = 0;
+ retlen = sds_send (buf, 3);
+
+ for (i = 0; i < 4 * 6; ++i)
+ regs[i + 4 * 32 + 8 * 32] = buf[i];
+ for (i = 0; i < 4 * 4; ++i)
+ sprs[i] = buf[i + 4 * 7];
+
+ buf[0] = 18;
+ buf[1] = 2;
+ buf[2] = 0;
+ retlen = sds_send (buf, 3);
+
+ for (i = 0; i < retlen; i++)
+ regs[i] = buf[i];
+
+ /* (should warn about reply too short) */
+
+ for (i = 0; i < NUM_REGS; i++)
+ supply_register (i, &regs[REGISTER_BYTE(i)]);
+}
+
+/* Prepare to store registers. Since we may send them all, we have to
+ read out the ones we don't want to change first. */
+
+static void
+sds_prepare_to_store ()
+{
+ /* Make sure the entire registers array is valid. */
+ read_register_bytes (0, (char *)NULL, REGISTER_BYTES);
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. FIXME: ignores errors. */
+
+static void
+sds_store_registers (regno)
+ int regno;
+{
+ unsigned char *p, buf[PBUFSIZ];
+ int i;
+
+ /* Store all the special-purpose registers. */
+ p = buf;
+ *p++ = 19;
+ *p++ = 1;
+ *p++ = 0;
+ *p++ = 0;
+ for (i = 0; i < 4 * 6; i++)
+ *p++ = registers[i + 4 * 32 + 8 * 32];
+ for (i = 0; i < 4 * 1; i++)
+ *p++ = 0;
+ for (i = 0; i < 4 * 4; i++)
+ *p++ = sprs[i];
+
+ sds_send (buf, p - buf);
+
+ /* Store all the general-purpose registers. */
+ p = buf;
+ *p++ = 19;
+ *p++ = 2;
+ *p++ = 0;
+ *p++ = 0;
+ for (i = 0; i < 4 * 32; i++)
+ *p++ = registers[i];
+
+ sds_send (buf, p - buf);
+
+}
+
+/* Write memory data directly to the remote machine. This does not
+ inform the data cache; the data cache uses this. MEMADDR is the
+ address in the remote memory space. MYADDR is the address of the
+ buffer in our space. LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int
+sds_write_bytes (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
+ unsigned char buf[PBUFSIZ];
+ int todo;
+ int i;
+
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = 150;
+
+ origlen = len;
+ while (len > 0)
+ {
+ todo = min (len, max_buf_size);
+
+ buf[0] = 13;
+ buf[1] = 0;
+ buf[2] = (int) (memaddr >> 24) & 0xff;
+ buf[3] = (int) (memaddr >> 16) & 0xff;
+ buf[4] = (int) (memaddr >> 8) & 0xff;
+ buf[5] = (int) (memaddr ) & 0xff;
+ buf[6] = 1;
+ buf[7] = 0;
+
+ for (i = 0; i < todo; i++)
+ buf[i + 8] = myaddr[i];
+
+ sds_send (buf, 8 + todo);
+
+ /* (should look at result) */
+
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
+ }
+ return origlen;
+}
+
+/* Read memory data directly from the remote machine. This does not
+ use the data cache; the data cache uses this. MEMADDR is the
+ address in the remote memory space. MYADDR is the address of the
+ buffer in our space. LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int
+sds_read_bytes (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+{
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen, retlen;
+ unsigned char buf[PBUFSIZ];
+ int todo;
+ int i;
+
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = 150;
+
+ origlen = len;
+ while (len > 0)
+ {
+ todo = min (len, max_buf_size);
+
+ buf[0] = 12;
+ buf[1] = 0;
+ buf[2] = (int) (memaddr >> 24) & 0xff;
+ buf[3] = (int) (memaddr >> 16) & 0xff;
+ buf[4] = (int) (memaddr >> 8) & 0xff;
+ buf[5] = (int) (memaddr ) & 0xff;
+ buf[6] = (int) (todo >> 8) & 0xff;
+ buf[7] = (int) (todo ) & 0xff;
+ buf[8] = 1;
+
+ retlen = sds_send (buf, 9);
+
+ if (retlen - 2 != todo)
+ {
+ return 0;
+ }
+
+ /* Reply describes memory byte by byte. */
+
+ for (i = 0; i < todo; i++)
+ myaddr[i] = buf[i + 2];
+
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
+ }
+
+ return origlen;
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. */
+
+/* ARGSUSED */
+static int
+sds_xfer_memory(memaddr, myaddr, len, should_write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int should_write;
+ struct target_ops *target; /* ignored */
+{
+ return dcache_xfer_memory (sds_dcache, memaddr, myaddr, len, should_write);
+}
+
+
+static void
+sds_files_info (ignore)
+ struct target_ops *ignore;
+{
+ puts_filtered ("Debugging over a serial connection, using SDS protocol.\n");
+}
+
+/* Stuff for dealing with the packets which are part of this protocol.
+ See comment at top of file for details. */
+
+/* Read a single character from the remote end, masking it down to 7 bits. */
+
+static int
+readchar (timeout)
+ int timeout;
+{
+ int ch;
+
+ ch = SERIAL_READCHAR (sds_desc, timeout);
+
+ if (remote_debug > 1 && ch >= 0)
+ printf_unfiltered("%c(%x)", ch, ch);
+
+ switch (ch)
+ {
+ case SERIAL_EOF:
+ error ("Remote connection closed");
+ case SERIAL_ERROR:
+ perror_with_name ("Remote communication error");
+ case SERIAL_TIMEOUT:
+ return ch;
+ default:
+ return ch & 0x7f;
+ }
+}
+
+/* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably
+ because 253, 254, and 255 are special flags in the protocol.) */
+
+static int
+compute_checksum (csum, buf, len)
+ int csum, len;
+ char *buf;
+{
+ int i;
+
+ for (i = 0; i < len; ++i)
+ csum += (unsigned char) buf[i];
+
+ csum %= 253;
+ return csum;
+}
+
+/* Send the command in BUF to the remote machine, and read the reply
+ into BUF also. */
+
+static int
+sds_send (buf, len)
+ unsigned char *buf;
+ int len;
+{
+ putmessage (buf, len);
+
+ return getmessage (buf, 0);
+}
+
+/* Send a message to the remote machine. */
+
+static int
+putmessage (buf, len)
+ unsigned char *buf;
+ int len;
+{
+ int i, enclen;
+ unsigned char csum = 0;
+ char buf2[PBUFSIZ], buf3[PBUFSIZ];
+ unsigned char header[3];
+ int ch;
+ int tcount = 0;
+ char *p;
+
+ /* Copy the packet into buffer BUF2, encapsulating it
+ and giving it a checksum. */
+
+ if (len > 170) /* Prosanity check */
+ abort();
+
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stderr, "Message to send: \"");
+ for (i = 0; i < len; ++i)
+ fprintf_unfiltered (gdb_stderr, "%02x", buf[i]);
+ fprintf_unfiltered (gdb_stderr, "\"\n");
+ }
+
+ p = buf2;
+ *p++ = '$';
+
+ if (len % 3 != 0)
+ {
+ buf[len] = '\0';
+ buf[len+1] = '\0';
+ }
+
+ header[1] = next_msg_id;
+
+ header[2] = len;
+
+ csum = compute_checksum (csum, buf, len);
+ csum = compute_checksum (csum, header + 1, 2);
+
+ header[0] = csum;
+
+ tob64 (header, p, 3);
+ p += 4;
+ enclen = tob64 (buf, buf3, ((len + 2) / 3) * 3);
+
+ for (i = 0; i < enclen; ++i)
+ *p++ = buf3[i];
+ *p++ = '\r';
+ *p++ = '\n';
+
+ next_msg_id = (next_msg_id + 3) % 245;
+
+ /* Send it over and over until we get a positive ack. */
+
+ while (1)
+ {
+ int started_error_output = 0;
+
+ if (remote_debug)
+ {
+ *p = '\0';
+ printf_unfiltered ("Sending encoded: \"%s\"", buf2);
+ printf_unfiltered (" (Checksum %d, id %d, length %d)\n",
+ header[0], header[1], header[2]);
+ gdb_flush (gdb_stdout);
+ }
+ if (SERIAL_WRITE (sds_desc, buf2, p - buf2))
+ perror_with_name ("putmessage: write failed");
+
+ return 1;
+
+ }
+
+}
+
+/* Come here after finding the start of the frame. Collect the rest
+ into BUF. Returns 0 on any error, 1 on success. */
+
+static int
+read_frame (buf)
+ char *buf;
+{
+ char *bp;
+ int c;
+
+ bp = buf;
+
+ while (1)
+ {
+ c = readchar (sds_timeout);
+
+ switch (c)
+ {
+ case SERIAL_TIMEOUT:
+ if (remote_debug)
+ puts_filtered ("Timeout in mid-message, retrying\n");
+ return 0;
+ case '$':
+ if (remote_debug)
+ puts_filtered ("Saw new packet start in middle of old one\n");
+ return 0; /* Start a new packet, count retries */
+ case '\r':
+ break;
+
+ case '\n':
+ {
+ *bp = '\000';
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stderr, "Received encoded: \"%s\"\n",
+ buf);
+ return 1;
+ }
+
+ default:
+ if (bp < buf + PBUFSIZ - 1)
+ {
+ *bp++ = c;
+ continue;
+ }
+
+ *bp = '\0';
+ puts_filtered ("Message too long: ");
+ puts_filtered (buf);
+ puts_filtered ("\n");
+
+ return 0;
+ }
+ }
+}
+
+/* Read a packet from the remote machine, with error checking,
+ and store it in BUF. BUF is expected to be of size PBUFSIZ.
+ If FOREVER, wait forever rather than timing out; this is used
+ while the target is executing user code. */
+
+static int
+getmessage (buf, forever)
+ unsigned char *buf;
+ int forever;
+{
+ int c, c2, c3;
+ int tries;
+ int timeout;
+ int val, i, len, csum;
+ unsigned char header[3];
+ unsigned char inbuf[500];
+
+ strcpy (buf, "timeout");
+
+ if (forever)
+ {
+#ifdef MAINTENANCE_CMDS
+ timeout = watchdog > 0 ? watchdog : -1;
+#else
+ timeout = -1;
+#endif
+ }
+
+ else
+ timeout = sds_timeout;
+
+#define MAX_TRIES 3
+
+ for (tries = 1; tries <= MAX_TRIES; tries++)
+ {
+ /* This can loop forever if the remote side sends us characters
+ continuously, but if it pauses, we'll get a zero from readchar
+ because of timeout. Then we'll count that as a retry. */
+
+ /* Note that we will only wait forever prior to the start of a packet.
+ After that, we expect characters to arrive at a brisk pace. They
+ should show up within sds_timeout intervals. */
+
+ do
+ {
+ c = readchar (timeout);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+#ifdef MAINTENANCE_CMDS
+ if (forever) /* Watchdog went off. Kill the target. */
+ {
+ target_mourn_inferior ();
+ error ("Watchdog has expired. Target detached.\n");
+ }
+#endif
+ if (remote_debug)
+ puts_filtered ("Timed out.\n");
+ goto retry;
+ }
+ }
+ while (c != '$' && c != '{');
+
+ /* We might have seen a "trigraph", a sequence of three characters
+ that indicate various sorts of communication state. */
+
+ if (c == '{')
+ {
+ /* Read the other two chars of the trigraph. */
+ c2 = readchar (timeout);
+ c3 = readchar (timeout);
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stderr, "Trigraph %c%c%c received\n",
+ c, c2, c3);
+ if (c3 == '+')
+ {
+ message_pending = 1;
+ return 0; /*????*/
+ }
+ continue;
+ }
+
+ val = read_frame (inbuf);
+
+ if (val == 1)
+ {
+ fromb64 (inbuf, header, 4);
+ /* (should check out other bits) */
+ fromb64 (inbuf + 4, buf, strlen (inbuf) - 4);
+
+ len = header[2];
+
+ csum = 0;
+ csum = compute_checksum (csum, buf, len);
+ csum = compute_checksum (csum, header + 1, 2);
+
+ if (csum != header[0])
+ fprintf_unfiltered (gdb_stderr,
+ "Checksum mismatch: computed %d, received %d\n",
+ csum, header[0]);
+
+ if (header[2] == 0xff)
+ fprintf_unfiltered (gdb_stderr, "Requesting resend...\n");
+
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "... (Got checksum %d, id %d, length %d)\n",
+ header[0], header[1], header[2]);
+ fprintf_unfiltered (gdb_stderr, "Message received: \"");
+ for (i = 0; i < len; ++i)
+ {
+ fprintf_unfiltered (gdb_stderr, "%02x", (unsigned char) buf[i]);
+ }
+ fprintf_unfiltered (gdb_stderr, "\"\n");
+ }
+
+ /* no ack required? */
+ return len;
+ }
+
+ /* Try the whole thing again. */
+ retry:
+ /* need to do something here */
+ }
+
+ /* We have tried hard enough, and just can't receive the packet. Give up. */
+
+ printf_unfiltered ("Ignoring packet error, continuing...\n");
+ return 0;
+}
+
+static void
+sds_kill ()
+{
+ /* Don't try to do anything to the target. */
+}
+
+static void
+sds_mourn ()
+{
+ unpush_target (&sds_ops);
+ generic_mourn_inferior ();
+}
+
+static void
+sds_create_inferior (exec_file, args, env)
+ char *exec_file;
+ char *args;
+ char **env;
+{
+ inferior_pid = 42000;
+
+ /* Clean up from the last time we were running. */
+ clear_proceed_status ();
+
+ /* Let the remote process run. */
+ proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
+static void
+sds_load (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ generic_load (filename, from_tty);
+
+ inferior_pid = 0;
+}
+
+/* The SDS monitor has commands for breakpoint insertion, although it
+ it doesn't actually manage the breakpoints, it just returns the
+ replaced instruction back to the debugger. */
+
+static int
+sds_insert_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ int i, retlen;
+ unsigned char *p, buf[PBUFSIZ];
+
+ p = buf;
+ *p++ = 16;
+ *p++ = 0;
+ *p++ = (int) (addr >> 24) & 0xff;
+ *p++ = (int) (addr >> 16) & 0xff;
+ *p++ = (int) (addr >> 8) & 0xff;
+ *p++ = (int) (addr ) & 0xff;
+
+ retlen = sds_send (buf, p - buf);
+
+ for (i = 0; i < 4; ++i)
+ contents_cache[i] = buf[i + 2];
+
+ return 0;
+}
+
+static int
+sds_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ int i, retlen;
+ unsigned char *p, buf[PBUFSIZ];
+
+ p = buf;
+ *p++ = 17;
+ *p++ = 0;
+ *p++ = (int) (addr >> 24) & 0xff;
+ *p++ = (int) (addr >> 16) & 0xff;
+ *p++ = (int) (addr >> 8) & 0xff;
+ *p++ = (int) (addr ) & 0xff;
+ for (i = 0; i < 4; ++i)
+ *p++ = contents_cache[i];
+
+ retlen = sds_send (buf, p - buf);
+
+ return 0;
+}
+
+static void
+init_sds_ops ()
+{
+ sds_ops.to_shortname = "sds";
+ sds_ops.to_longname = "Remote serial target with SDS protocol";
+ sds_ops.to_doc = "Use a remote computer via a serial line; using the SDS protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ sds_ops.to_open = sds_open;
+ sds_ops.to_close = sds_close;
+ sds_ops.to_detach = sds_detach;
+ sds_ops.to_resume = sds_resume;
+ sds_ops.to_wait = sds_wait;
+ sds_ops.to_fetch_registers = sds_fetch_registers;
+ sds_ops.to_store_registers = sds_store_registers;
+ sds_ops.to_prepare_to_store = sds_prepare_to_store;
+ sds_ops.to_xfer_memory = sds_xfer_memory;
+ sds_ops.to_files_info = sds_files_info;
+ sds_ops.to_insert_breakpoint = sds_insert_breakpoint;
+ sds_ops.to_remove_breakpoint = sds_remove_breakpoint;
+ sds_ops.to_kill = sds_kill;
+ sds_ops.to_load = sds_load;
+ sds_ops.to_create_inferior = sds_create_inferior;
+ sds_ops.to_mourn_inferior = sds_mourn;
+ sds_ops.to_stratum = process_stratum;
+ sds_ops.to_has_all_memory = 1;
+ sds_ops.to_has_memory = 1;
+ sds_ops.to_has_stack = 1;
+ sds_ops.to_has_registers = 1;
+ sds_ops.to_has_execution = 1;
+ sds_ops.to_magic = OPS_MAGIC;
+}
+
+/* Put a command string, in args, out to the monitor and display the
+ reply message. */
+
+static void
+sds_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char *p;
+ int i, len, retlen;
+ unsigned char buf[1000];
+
+ /* Convert hexadecimal chars into a byte buffer. */
+ p = args;
+ len = 0;
+ while (*p != '\0')
+ {
+ buf[len++] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ if (p[1] == '\0')
+ break;
+ p += 2;
+ }
+
+ retlen = sds_send (buf, len);
+
+ printf_filtered ("Reply is ");
+ for (i = 0; i < retlen; ++i)
+ {
+ printf_filtered ("%02x", buf[i]);
+ }
+ printf_filtered ("\n");
+}
+
+void
+_initialize_remote_sds ()
+{
+ init_sds_ops ();
+ add_target (&sds_ops);
+
+ add_show_from_set (add_set_cmd ("sdstimeout", no_class,
+ var_integer, (char *)&sds_timeout,
+ "Set timeout value for sds read.\n", &setlist),
+ &showlist);
+
+ add_com ("sds", class_obscure, sds_command,
+ "Send a command to the SDS monitor.");
+}
diff --git a/contrib/gdb/gdb/remote-sim.c b/contrib/gdb/gdb/remote-sim.c
index d0f0f50..e10fced 100644
--- a/contrib/gdb/gdb/remote-sim.c
+++ b/contrib/gdb/gdb/remote-sim.c
@@ -1,5 +1,5 @@
/* Generic remote debugging interface for simulators.
- Copyright 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
Contributed by Cygnus Support.
Steve Chamberlain (sac@cygnus.com).
@@ -32,14 +32,76 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "terminal.h"
#include "target.h"
#include "gdbcore.h"
+#include "callback.h"
#include "remote-sim.h"
#include "remote-utils.h"
-#include "callback.h"
+#include "command.h"
+
+/* Prototypes */
+
+static void dump_mem PARAMS ((char *buf, int len));
+
+static void init_callbacks PARAMS ((void));
+
+static void end_callbacks PARAMS ((void));
+
+static int gdb_os_write_stdout PARAMS ((host_callback *, const char *, int));
+
+static void gdb_os_flush_stdout PARAMS ((host_callback *));
+
+static int gdb_os_write_stderr PARAMS ((host_callback *, const char *, int));
+
+static void gdb_os_flush_stderr PARAMS ((host_callback *));
+
+static int gdb_os_poll_quit PARAMS ((host_callback *));
+
+/* printf_filtered is depreciated */
+static void gdb_os_printf_filtered PARAMS ((host_callback *, const char *, ...));
+
+static void gdb_os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
+
+static void gdb_os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
+
+static void gdb_os_error PARAMS ((host_callback *, const char *, ...));
+
+static void gdbsim_fetch_register PARAMS ((int regno));
+
+static void gdbsim_store_register PARAMS ((int regno));
+
+static void gdbsim_kill PARAMS ((void));
+
+static void gdbsim_load PARAMS ((char *prog, int fromtty));
+
+static void gdbsim_create_inferior PARAMS ((char *exec_file, char *args, char **env));
+
+static void gdbsim_open PARAMS ((char *args, int from_tty));
+
+static void gdbsim_close PARAMS ((int quitting));
+
+static void gdbsim_detach PARAMS ((char *args, int from_tty));
+
+static void gdbsim_resume PARAMS ((int pid, int step, enum target_signal siggnal));
+
+static int gdbsim_wait PARAMS ((int pid, struct target_waitstatus *status));
+
+static void gdbsim_prepare_to_store PARAMS ((void));
+
+static int gdbsim_xfer_inferior_memory PARAMS ((CORE_ADDR memaddr,
+ char *myaddr, int len,
+ int write,
+ struct target_ops *target));
+
+static void gdbsim_files_info PARAMS ((struct target_ops *target));
+
+static void gdbsim_mourn_inferior PARAMS ((void));
+
+static void gdbsim_stop PARAMS ((void));
+
+void simulator_command PARAMS ((char *args, int from_tty));
/* Naming convention:
sim_* are the interface to the simulator (see remote-sim.h).
- sim_callback_* are the stuff which the simulator can see inside GDB.
gdbsim_* are stuff which is internal to gdb. */
/* Forward data declarations */
@@ -47,6 +109,12 @@ extern struct target_ops gdbsim_ops;
static int program_loaded = 0;
+/* We must keep track of whether the simulator has been opened or not because
+ GDB can call a target's close routine twice, but sim_close doesn't allow
+ this. We also need to record the result of sim_open so we can pass it
+ back to the other sim_foo routines. */
+static SIM_DESC gdbsim_desc = 0;
+
static void
dump_mem (buf, len)
char *buf;
@@ -72,20 +140,226 @@ dump_mem (buf, len)
}
}
+static host_callback gdb_callback;
+static int callbacks_initialized = 0;
+
+/* Initialize gdb_callback. */
+
+static void
+init_callbacks ()
+{
+ if (! callbacks_initialized)
+ {
+ gdb_callback = default_callback;
+ gdb_callback.init (&gdb_callback);
+ gdb_callback.write_stdout = gdb_os_write_stdout;
+ gdb_callback.flush_stdout = gdb_os_flush_stdout;
+ gdb_callback.write_stderr = gdb_os_write_stderr;
+ gdb_callback.flush_stderr = gdb_os_flush_stderr;
+ gdb_callback.printf_filtered = gdb_os_printf_filtered;
+ gdb_callback.vprintf_filtered = gdb_os_vprintf_filtered;
+ gdb_callback.evprintf_filtered = gdb_os_evprintf_filtered;
+ gdb_callback.error = gdb_os_error;
+ gdb_callback.poll_quit = gdb_os_poll_quit;
+ gdb_callback.magic = HOST_CALLBACK_MAGIC;
+ callbacks_initialized = 1;
+ }
+}
+
+/* Release callbacks (free resources used by them). */
+
+static void
+end_callbacks ()
+{
+ if (callbacks_initialized)
+ {
+ gdb_callback.shutdown (&gdb_callback);
+ callbacks_initialized = 0;
+ }
+}
+
+/* GDB version of os_write_stdout callback. */
+
+static int
+gdb_os_write_stdout (p, buf, len)
+ host_callback *p;
+ const char *buf;
+ int len;
+{
+ int i;
+ char b[2];
+
+ for (i = 0; i < len; i++)
+ {
+ b[0] = buf[i];
+ b[1] = 0;
+ if (target_output_hook)
+ target_output_hook (b);
+ else
+ fputs_filtered (b, gdb_stdout);
+ }
+ return len;
+}
+
+/* GDB version of os_flush_stdout callback. */
+
+static void
+gdb_os_flush_stdout (p)
+ host_callback *p;
+{
+ gdb_flush (gdb_stdout);
+}
+
+/* GDB version of os_write_stderr callback. */
+
+static int
+gdb_os_write_stderr (p, buf, len)
+ host_callback *p;
+ const char *buf;
+ int len;
+{
+ int i;
+ char b[2];
+
+ for (i = 0; i < len; i++)
+ {
+ b[0] = buf[i];
+ b[1] = 0;
+ if (target_output_hook)
+ target_output_hook (b);
+ else
+ fputs_filtered (b, gdb_stderr);
+ }
+ return len;
+}
+
+/* GDB version of os_flush_stderr callback. */
+
+static void
+gdb_os_flush_stderr (p)
+ host_callback *p;
+{
+ gdb_flush (gdb_stderr);
+}
+
+/* GDB version of printf_filtered callback. */
+
+/* VARARGS */
+static void
+#ifdef ANSI_PROTOTYPES
+gdb_os_printf_filtered (host_callback *p, const char *format, ...)
+#else
+gdb_os_printf_filtered (p, va_alist)
+ host_callback *p;
+ va_dcl
+#endif
+{
+ va_list args;
+#ifdef ANSI_PROTOTYPES
+ va_start (args, format);
+#else
+ char *format;
+
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+
+ vfprintf_filtered (gdb_stdout, format, args);
+
+ va_end (args);
+}
+
+/* GDB version of error vprintf_filtered. */
+
+/* VARARGS */
+static void
+#ifdef ANSI_PROTOTYPES
+gdb_os_vprintf_filtered (host_callback *p, const char *format, va_list ap)
+#else
+gdb_os_vprintf_filtered (p, format, ap)
+ host_callback *p;
+ char *format;
+ va_list ap;
+#endif
+{
+ vfprintf_filtered (gdb_stdout, format, ap);
+}
+
+/* GDB version of error evprintf_filtered. */
+
+/* VARARGS */
+static void
+#ifdef ANSI_PROTOTYPES
+gdb_os_evprintf_filtered (host_callback *p, const char *format, va_list ap)
+#else
+gdb_os_evprintf_filtered (p, format, ap)
+ host_callback *p;
+ char *format;
+ va_list ap;
+#endif
+{
+ vfprintf_filtered (gdb_stderr, format, ap);
+}
+
+/* GDB version of error callback. */
+
+/* VARARGS */
+static void
+#ifdef ANSI_PROTOTYPES
+gdb_os_error (host_callback *p, const char *format, ...)
+#else
+gdb_os_error (p, va_alist)
+ host_callback *p;
+ va_dcl
+#endif
+{
+ if (error_hook)
+ (*error_hook) ();
+ else
+ {
+ va_list args;
+#ifdef ANSI_PROTOTYPES
+ va_start (args, format);
+#else
+ char *format;
+
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+
+ error_begin ();
+ vfprintf_filtered (gdb_stderr, format, args);
+ fprintf_filtered (gdb_stderr, "\n");
+ va_end (args);
+ return_to_top_level (RETURN_ERROR);
+ }
+}
+
static void
gdbsim_fetch_register (regno)
-int regno;
+ int regno;
{
+ static int warn_user = 1;
if (regno == -1)
{
for (regno = 0; regno < NUM_REGS; regno++)
gdbsim_fetch_register (regno);
}
- else
+ else if (REGISTER_NAME (regno) != NULL && *REGISTER_NAME (regno) != '\0')
{
char buf[MAX_REGISTER_RAW_SIZE];
-
- sim_fetch_register (regno, buf);
+ int nr_bytes = sim_fetch_register (gdbsim_desc, regno, buf, REGISTER_RAW_SIZE (regno));
+ if (nr_bytes == 0)
+ /* register not applicable, supply zero's */
+ memset (buf, 0, MAX_REGISTER_RAW_SIZE);
+ else if (nr_bytes > 0 && nr_bytes != REGISTER_RAW_SIZE (regno)
+ && warn_user)
+ {
+ printf_unfiltered ("Size of register %s (%d) incorrect (%d instead of %d))",
+ REGISTER_NAME (regno), regno,
+ nr_bytes, REGISTER_RAW_SIZE (regno));
+ warn_user = 0;
+ }
supply_register (regno, buf);
if (sr_get_debug ())
{
@@ -99,19 +373,21 @@ int regno;
static void
gdbsim_store_register (regno)
-int regno;
+ int regno;
{
if (regno == -1)
{
for (regno = 0; regno < NUM_REGS; regno++)
gdbsim_store_register (regno);
}
- else
+ else if (REGISTER_NAME (regno) != NULL && *REGISTER_NAME (regno) != '\0')
{
- /* FIXME: Until read_register() returns LONGEST, we have this. */
char tmp[MAX_REGISTER_RAW_SIZE];
+ int nr_bytes;
read_register_gen (regno, tmp);
- sim_store_register (regno, tmp);
+ nr_bytes = sim_store_register (gdbsim_desc, regno, tmp, REGISTER_RAW_SIZE (regno));
+ if (nr_bytes > 0 && nr_bytes != REGISTER_RAW_SIZE (regno))
+ fatal ("Register size different to expected");
if (sr_get_debug ())
{
printf_filtered ("gdbsim_store_register: %d", regno);
@@ -130,7 +406,8 @@ gdbsim_kill ()
if (sr_get_debug ())
printf_filtered ("gdbsim_kill\n");
- sim_kill (); /* close fd's, remove mappings */
+ /* There is no need to `kill' running simulator - the simulator is
+ not running */
inferior_pid = 0;
}
@@ -148,17 +425,22 @@ gdbsim_load (prog, fromtty)
inferior_pid = 0;
- /* This must be done before calling gr_load_image. */
- program_loaded = 1;
+ /* FIXME: We will print two messages on error.
+ Need error to either not print anything if passed NULL or need
+ another routine that doesn't take any arguments. */
+ if (sim_load (gdbsim_desc, prog, NULL, fromtty) == SIM_RC_FAIL)
+ error ("unable to load program");
- if (sim_load (prog, fromtty) != 0)
- generic_load (prog, fromtty);
+ /* FIXME: If a load command should reset the targets registers then
+ a call to sim_create_inferior() should go here. */
+
+ program_loaded = 1;
}
/* Start an inferior process and set inferior_pid to its pid.
EXEC_FILE is the file to run.
- ALLARGS is a string containing the arguments to the program.
+ ARGS is a string containing the arguments to the program.
ENV is the environment vector to pass. Errors reported with error().
On VxWorks and various standalone systems, we ignore exec_file. */
/* This is called not only when we first attach, but also when the
@@ -172,37 +454,43 @@ gdbsim_create_inferior (exec_file, args, env)
{
int len;
char *arg_buf,**argv;
- CORE_ADDR entry_pt;
+ if (exec_file == 0 || exec_bfd == 0)
+ warning ("No executable file specified.");
if (! program_loaded)
- error ("No program loaded.");
+ warning ("No program loaded.");
if (sr_get_debug ())
printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n",
- exec_file, args);
-
- if (exec_file == 0 || exec_bfd == 0)
- error ("No exec file specified.");
+ (exec_file ? exec_file: "(NULL)"),
+ args);
- entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd);
-
- gdbsim_kill (NULL, NULL);
+ gdbsim_kill ();
remove_breakpoints ();
init_wait_for_inferior ();
- len = 5 + strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
- arg_buf = (char *) alloca (len);
- arg_buf[0] = '\0';
- strcat (arg_buf, exec_file);
- strcat (arg_buf, " ");
- strcat (arg_buf, args);
- argv = buildargv (arg_buf);
- make_cleanup (freeargv, (char *) argv);
- sim_create_inferior (entry_pt, argv, env);
+ if (exec_file != NULL)
+ {
+ len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
+ arg_buf = (char *) alloca (len);
+ arg_buf[0] = '\0';
+ strcat (arg_buf, exec_file);
+ strcat (arg_buf, " ");
+ strcat (arg_buf, args);
+ argv = buildargv (arg_buf);
+ make_cleanup ((make_cleanup_func) freeargv, argv);
+ }
+ else
+ argv = NULL;
+ sim_create_inferior (gdbsim_desc, exec_bfd, argv, env);
inferior_pid = 42;
- insert_breakpoints (); /* Needed to get correct instruction in cache */
- proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+
+ clear_proceed_status ();
+
+ /* NB: Entry point already set by sim_create_inferior. */
+ proceed ((CORE_ADDR)-1, TARGET_SIGNAL_DEFAULT, 0);
}
/* The open routine takes the rest of the parameters from the command,
@@ -215,13 +503,69 @@ gdbsim_open (args, from_tty)
char *args;
int from_tty;
{
+ int len;
+ char *arg_buf;
+ char **argv;
+
if (sr_get_debug ())
printf_filtered ("gdbsim_open: args \"%s\"\n", args ? args : "(null)");
- sim_set_callbacks (&default_callback);
- default_callback.init (&default_callback);
+ /* Remove current simulator if one exists. Only do this if the simulator
+ has been opened because sim_close requires it.
+ This is important because the call to push_target below will cause
+ sim_close to be called if the simulator is already open, but push_target
+ is called after sim_open! We can't move the call to push_target before
+ the call to sim_open because sim_open may invoke `error'. */
+ if (gdbsim_desc != NULL)
+ unpush_target (&gdbsim_ops);
+
+ len = (7 + 1 /* gdbsim */
+ + strlen (" -E little")
+ + strlen (" --architecture=xxxxxxxxxx")
+ + (args ? strlen (args) : 0)
+ + 50) /* slack */;
+ arg_buf = (char *) alloca (len);
+ strcpy (arg_buf, "gdbsim"); /* 7 */
+ /* Specify the byte order for the target when it is both selectable
+ and explicitly specified by the user (not auto detected). */
+ if (TARGET_BYTE_ORDER_SELECTABLE_P
+ && !TARGET_BYTE_ORDER_AUTO)
+ {
+ switch (TARGET_BYTE_ORDER)
+ {
+ case BIG_ENDIAN:
+ strcat (arg_buf, " -E big");
+ break;
+ case LITTLE_ENDIAN:
+ strcat (arg_buf, " -E little");
+ break;
+ default:
+ fatal ("Value of TARGET_BYTE_ORDER unknown");
+ }
+ }
+ /* Specify the architecture of the target when it has been
+ explicitly specified */
+ if (!TARGET_ARCHITECTURE_AUTO)
+ {
+ strcat (arg_buf, " --architecture=");
+ strcat (arg_buf, TARGET_ARCHITECTURE->printable_name);
+ }
+ /* finally, any explicit args */
+ if (args)
+ {
+ strcat (arg_buf, " "); /* 1 */
+ strcat (arg_buf, args);
+ }
+ argv = buildargv (arg_buf);
+ if (argv == NULL)
+ error ("Insufficient memory available to allocate simulator arg list.");
+ make_cleanup ((make_cleanup_func) freeargv, argv);
+
+ init_callbacks ();
+ gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, argv);
- sim_open (args);
+ if (gdbsim_desc == 0)
+ error ("unable to create simulator instance");
push_target (&gdbsim_ops);
target_fetch_registers (-1);
@@ -246,7 +590,13 @@ gdbsim_close (quitting)
program_loaded = 0;
- sim_close (quitting);
+ if (gdbsim_desc != NULL)
+ {
+ sim_close (gdbsim_desc, quitting);
+ gdbsim_desc = NULL;
+ }
+
+ end_callbacks ();
}
/* Takes a program previously attached to and detaches it.
@@ -275,33 +625,104 @@ gdbsim_detach (args,from_tty)
or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
to the target, or zero for no signal. */
+static enum target_signal resume_siggnal;
+static int resume_step;
+
static void
gdbsim_resume (pid, step, siggnal)
int pid, step;
enum target_signal siggnal;
{
+ if (inferior_pid != 42)
+ error ("The program is not being run.");
+
if (sr_get_debug ())
printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal);
- sim_resume (step, target_signal_to_host (siggnal));
+ resume_siggnal = siggnal;
+ resume_step = step;
+}
+
+/* Notify the simulator of an asynchronous request to stop.
+
+ The simulator shall ensure that the stop request is eventually
+ delivered to the simulator. If the call is made while the
+ simulator is not running then the stop request is processed when
+ the simulator is next resumed.
+
+ For simulators that do not support this operation, just abort */
+
+static void
+gdbsim_stop ()
+{
+ if (! sim_stop (gdbsim_desc))
+ {
+ quit ();
+ }
+}
+
+/* GDB version of os_poll_quit callback.
+ Taken from gdb/util.c - should be in a library */
+
+static int
+gdb_os_poll_quit (p)
+ host_callback *p;
+{
+ notice_quit ();
+ if (quit_flag) /* gdb's idea of quit */
+ {
+ quit_flag = 0; /* we've stolen it */
+ return 1;
+ }
+ else if (immediate_quit)
+ {
+ return 1;
+ }
+ return 0;
}
/* Wait for inferior process to do something. Return pid of child,
or -1 in case of error; store status through argument pointer STATUS,
- just as `wait' would. */
+ just as `wait' would. */
+
+static void
+gdbsim_cntrl_c (signo)
+ int signo;
+{
+ gdbsim_stop ();
+}
static int
gdbsim_wait (pid, status)
int pid;
struct target_waitstatus *status;
{
- int sigrc;
- enum sim_stop reason;
+ static RETSIGTYPE (*prev_sigint) ();
+ int sigrc = 0;
+ enum sim_stop reason = sim_running;
if (sr_get_debug ())
printf_filtered ("gdbsim_wait\n");
- sim_stop_reason (&reason, &sigrc);
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+ {
+ struct sigaction sa, osa;
+ sa.sa_handler = gdbsim_cntrl_c;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction (SIGINT, &sa, &osa);
+ prev_sigint = osa.sa_handler;
+ }
+#else
+ prev_sigint = signal (SIGINT, gdbsim_cntrl_c);
+#endif
+ sim_resume (gdbsim_desc, resume_step,
+ target_signal_to_host (resume_siggnal));
+ signal (SIGINT, prev_sigint);
+ resume_step = 0;
+
+ sim_stop_reason (gdbsim_desc, &reason, &sigrc);
+
switch (reason)
{
case sim_exited:
@@ -309,10 +730,20 @@ gdbsim_wait (pid, status)
status->value.integer = sigrc;
break;
case sim_stopped:
- status->kind = TARGET_WAITKIND_STOPPED;
- /* The signal in sigrc is a host signal. That probably
- should be fixed. */
- status->value.sig = target_signal_from_host (sigrc);
+ switch (sigrc)
+ {
+ case SIGABRT:
+ quit ();
+ break;
+ case SIGINT:
+ case SIGTRAP:
+ default:
+ status->kind = TARGET_WAITKIND_STOPPED;
+ /* The signal in sigrc is a host signal. That probably
+ should be fixed. */
+ status->value.sig = target_signal_from_host (sigrc);
+ break;
+ }
break;
case sim_signalled:
status->kind = TARGET_WAITKIND_SIGNALLED;
@@ -320,6 +751,10 @@ gdbsim_wait (pid, status)
should be fixed. */
status->value.sig = target_signal_from_host (sigrc);
break;
+ case sim_running:
+ case sim_polling:
+ /* FIXME: Is this correct? */
+ break;
}
return inferior_pid;
@@ -358,11 +793,11 @@ gdbsim_xfer_inferior_memory (memaddr, myaddr, len, write, target)
if (write)
{
- len = sim_write (memaddr, myaddr, len);
+ len = sim_write (gdbsim_desc, memaddr, myaddr, len);
}
else
{
- len = sim_read (memaddr, myaddr, len);
+ len = sim_read (gdbsim_desc, memaddr, myaddr, len);
if (sr_get_debug () && len > 0)
dump_mem(myaddr, len);
}
@@ -385,7 +820,7 @@ gdbsim_files_info (target)
{
printf_filtered ("\tAttached to %s running program %s\n",
target_shortname, file);
- sim_info (0);
+ sim_info (gdbsim_desc, 0);
}
}
@@ -401,66 +836,166 @@ gdbsim_mourn_inferior ()
generic_mourn_inferior ();
}
-/* Put a command string, in args, out to MONITOR. Output from MONITOR
- is placed on the users terminal until the prompt is seen. FIXME: We
- read the characters ourseleves here cause of a nasty echo. */
+static int
+gdbsim_insert_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+#ifdef SIM_HAS_BREAKPOINTS
+ SIM_RC retcode;
+
+ retcode = sim_set_breakpoint (gdbsim_desc, addr);
-static void
+ switch (retcode)
+ {
+ case SIM_RC_OK:
+ return 0;
+ case SIM_RC_INSUFFICIENT_RESOURCES:
+ return ENOMEM;
+ default:
+ return EIO;
+ }
+#else
+ return memory_insert_breakpoint (addr, contents_cache);
+#endif
+}
+
+static int
+gdbsim_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+#ifdef SIM_HAS_BREAKPOINTS
+ SIM_RC retcode;
+
+ retcode = sim_clear_breakpoint (gdbsim_desc, addr);
+
+ switch (retcode)
+ {
+ case SIM_RC_OK:
+ case SIM_RC_UNKNOWN_BREAKPOINT:
+ return 0;
+ case SIM_RC_INSUFFICIENT_RESOURCES:
+ return ENOMEM;
+ default:
+ return EIO;
+ }
+#else
+ return memory_remove_breakpoint (addr, contents_cache);
+#endif
+}
+
+/* Pass the command argument through to the simulator verbatim. The
+ simulator must do any command interpretation work. */
+
+void
simulator_command (args, from_tty)
char *args;
int from_tty;
{
- sim_do_command (args);
+ if (gdbsim_desc == NULL)
+ {
+
+ /* PREVIOUSLY: The user may give a command before the simulator
+ is opened. [...] (??? assuming of course one wishes to
+ continue to allow commands to be sent to unopened simulators,
+ which isn't entirely unreasonable). */
+
+ /* The simulator is a builtin abstraction of a remote target.
+ Consistent with that model, access to the simulator, via sim
+ commands, is restricted to the period when the channel to the
+ simulator is open. */
+
+ error ("Not connected to the simulator target");
+ }
+
+ sim_do_command (gdbsim_desc, args);
+
+ /* Invalidate the register cache, in case the simulator command does
+ something funny. */
+ registers_changed ();
}
/* Define the target subroutine names */
-struct target_ops gdbsim_ops = {
- "sim", /* to_shortname */
- "simulator", /* to_longname */
- "Use the compiled-in simulator.", /* to_doc */
- gdbsim_open, /* to_open */
- gdbsim_close, /* to_close */
- NULL, /* to_attach */
- gdbsim_detach, /* to_detach */
- gdbsim_resume, /* to_resume */
- gdbsim_wait, /* to_wait */
- gdbsim_fetch_register, /* to_fetch_registers */
- gdbsim_store_register, /* to_store_registers */
- gdbsim_prepare_to_store, /* to_prepare_to_store */
- gdbsim_xfer_inferior_memory, /* to_xfer_memory */
- gdbsim_files_info, /* to_files_info */
- memory_insert_breakpoint, /* to_insert_breakpoint */
- memory_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- gdbsim_kill, /* to_kill */
- gdbsim_load, /* to_load */
- NULL, /* to_lookup_symbol */
- gdbsim_create_inferior, /* to_create_inferior */
- gdbsim_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC, /* to_magic */
-};
+struct target_ops gdbsim_ops ;
+
+static void
+init_gdbsim_ops(void)
+{
+ gdbsim_ops.to_shortname = "sim";
+ gdbsim_ops.to_longname = "simulator";
+ gdbsim_ops.to_doc = "Use the compiled-in simulator.";
+ gdbsim_ops.to_open = gdbsim_open;
+ gdbsim_ops.to_close = gdbsim_close;
+ gdbsim_ops.to_attach = NULL;
+ gdbsim_ops.to_post_attach = NULL;
+ gdbsim_ops.to_require_attach = NULL;
+ gdbsim_ops.to_detach = gdbsim_detach;
+ gdbsim_ops.to_require_detach = NULL;
+ gdbsim_ops.to_resume = gdbsim_resume;
+ gdbsim_ops.to_wait = gdbsim_wait;
+ gdbsim_ops.to_post_wait = NULL;
+ gdbsim_ops.to_fetch_registers = gdbsim_fetch_register;
+ gdbsim_ops.to_store_registers = gdbsim_store_register;
+ gdbsim_ops.to_prepare_to_store = gdbsim_prepare_to_store;
+ gdbsim_ops.to_xfer_memory = gdbsim_xfer_inferior_memory;
+ gdbsim_ops.to_files_info = gdbsim_files_info;
+ gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint;
+ gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint;
+ gdbsim_ops.to_terminal_init = NULL;
+ gdbsim_ops.to_terminal_inferior = NULL;
+ gdbsim_ops.to_terminal_ours_for_output = NULL;
+ gdbsim_ops.to_terminal_ours = NULL;
+ gdbsim_ops.to_terminal_info = NULL;
+ gdbsim_ops.to_kill = gdbsim_kill;
+ gdbsim_ops.to_load = gdbsim_load;
+ gdbsim_ops.to_lookup_symbol = NULL;
+ gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
+ gdbsim_ops.to_post_startup_inferior = NULL;
+ gdbsim_ops.to_acknowledge_created_inferior = NULL;
+ gdbsim_ops.to_clone_and_follow_inferior = NULL;
+ gdbsim_ops.to_post_follow_inferior_by_clone = NULL;
+ gdbsim_ops.to_insert_fork_catchpoint = NULL;
+ gdbsim_ops.to_remove_fork_catchpoint = NULL;
+ gdbsim_ops.to_insert_vfork_catchpoint = NULL;
+ gdbsim_ops.to_remove_vfork_catchpoint = NULL;
+ gdbsim_ops.to_has_forked = NULL;
+ gdbsim_ops.to_has_vforked = NULL;
+ gdbsim_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ gdbsim_ops.to_post_follow_vfork = NULL;
+ gdbsim_ops.to_insert_exec_catchpoint = NULL;
+ gdbsim_ops.to_remove_exec_catchpoint = NULL;
+ gdbsim_ops.to_has_execd = NULL;
+ gdbsim_ops.to_reported_exec_events_per_exec_call = NULL;
+ gdbsim_ops.to_has_exited = NULL;
+ gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior;
+ gdbsim_ops.to_can_run = 0;
+ gdbsim_ops.to_notice_signals = 0;
+ gdbsim_ops.to_thread_alive = 0;
+ gdbsim_ops.to_stop = gdbsim_stop;
+ gdbsim_ops.to_pid_to_exec_file = NULL;
+ gdbsim_ops.to_core_file_to_sym_file = NULL;
+ gdbsim_ops.to_stratum = process_stratum;
+ gdbsim_ops.DONT_USE = NULL;
+ gdbsim_ops.to_has_all_memory = 1;
+ gdbsim_ops.to_has_memory = 1;
+ gdbsim_ops.to_has_stack = 1;
+ gdbsim_ops.to_has_registers = 1;
+ gdbsim_ops.to_has_execution = 1;
+ gdbsim_ops.to_sections = NULL;
+ gdbsim_ops.to_sections_end = NULL;
+ gdbsim_ops.to_magic = OPS_MAGIC;
+
+#ifdef TARGET_REDEFINE_DEFAULT_OPS
+ TARGET_REDEFINE_DEFAULT_OPS (&gdbsim_ops);
+#endif
+}
void
_initialize_remote_sim ()
{
+ init_gdbsim_ops() ;
add_target (&gdbsim_ops);
add_com ("sim <command>", class_obscure, simulator_command,
diff --git a/contrib/gdb/gdb/remote-st.c b/contrib/gdb/gdb/remote-st.c
index 117501d..1efdbfa 100644
--- a/contrib/gdb/gdb/remote-st.c
+++ b/contrib/gdb/gdb/remote-st.c
@@ -260,7 +260,7 @@ st2000_create_inferior (execfile, args, env)
error("Can't pass arguments to remote STDEBUG process");
if (execfile == 0 || exec_bfd == 0)
- error("No exec file specified");
+ error("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
@@ -424,7 +424,7 @@ get_reg_name (regno)
b = buf;
- for (p = reg_names[regno]; *p; p++)
+ for (p = REGISTER_NAME (regno); *p; p++)
*b++ = toupper(*p);
*b = '\000';
@@ -627,7 +627,6 @@ st2000_mourn_inferior ()
#define MAX_STDEBUG_BREAKPOINTS 16
-extern int memory_breakpoint_size;
static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] = {0};
static int
@@ -636,13 +635,17 @@ st2000_insert_breakpoint (addr, shadow)
char *shadow;
{
int i;
+ CORE_ADDR bp_addr = addr;
+ int bp_size = 0;
+
+ BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++)
if (breakaddr[i] == 0)
{
breakaddr[i] = addr;
- st2000_read_inferior_memory(addr, shadow, memory_breakpoint_size);
+ st2000_read_inferior_memory (bp_addr, shadow, bp_size);
printf_stdebug("BR %x H\r", addr);
expect_prompt(1);
return 0;
@@ -790,54 +793,83 @@ connect_command (args, fromtty)
/* Define the target subroutine names */
-struct target_ops st2000_ops = {
- "st2000",
- "Remote serial Tandem ST2000 target",
- "Use a remote computer running STDEBUG connected by a serial line,\n\
+struct target_ops st2000_ops ;
+
+static void
+init_st2000_ops(void)
+{
+ st2000_ops.to_shortname = "st2000";
+ st2000_ops.to_longname = "Remote serial Tandem ST2000 target";
+ st2000_ops.to_doc = "Use a remote computer running STDEBUG connected by a serial line;\n\
or a network connection.\n\
Arguments are the name of the device for the serial line,\n\
-the speed to connect at in bits per second.",
- st2000_open,
- st2000_close,
- 0,
- st2000_detach,
- st2000_resume,
- st2000_wait,
- st2000_fetch_register,
- st2000_store_register,
- st2000_prepare_to_store,
- st2000_xfer_inferior_memory,
- st2000_files_info,
- st2000_insert_breakpoint,
- st2000_remove_breakpoint, /* Breakpoints */
- 0,
- 0,
- 0,
- 0,
- 0, /* Terminal handling */
- st2000_kill,
- 0, /* load */
- 0, /* lookup_symbol */
- st2000_create_inferior,
- st2000_mourn_inferior,
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_stop */
- process_stratum,
- 0, /* next */
- 1,
- 1,
- 1,
- 1,
- 1, /* all mem, mem, stack, regs, exec */
- 0,
- 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
-};
+the speed to connect at in bits per second." ;
+ st2000_ops.to_open = st2000_open;
+ st2000_ops.to_close = st2000_close;
+ st2000_ops.to_attach = 0;
+ st2000_run_ops.to_post_attach = NULL;
+ st2000_ops.to_require_attach = NULL;
+ st2000_ops.to_detach = st2000_detach;
+ st2000_ops.to_require_detach = NULL;
+ st2000_ops.to_resume = st2000_resume;
+ st2000_ops.to_wait = st2000_wait;
+ st2000_ops.to_post_wait = NULL;
+ st2000_ops.to_fetch_registers = st2000_fetch_register;
+ st2000_ops.to_store_registers = st2000_store_register;
+ st2000_ops.to_prepare_to_store = st2000_prepare_to_store;
+ st2000_ops.to_xfer_memory = st2000_xfer_inferior_memory;
+ st2000_ops.to_files_info = st2000_files_info;
+ st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint;
+ st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint; /* Breakpoints */
+ st2000_ops.to_terminal_init = 0;
+ st2000_ops.to_terminal_inferior = 0;
+ st2000_ops.to_terminal_ours_for_output = 0;
+ st2000_ops.to_terminal_ours = 0;
+ st2000_ops.to_terminal_info = 0; /* Terminal handling */
+ st2000_ops.to_kill = st2000_kill;
+ st2000_ops.to_load = 0; /* load */
+ st2000_ops.to_lookup_symbol = 0; /* lookup_symbol */
+ st2000_ops.to_create_inferior = st2000_create_inferior;
+ st2000_ops.to_post_startup_inferior = NULL;
+ st2000_ops.to_acknowledge_created_inferior = NULL;
+ st2000_ops.to_clone_and_follow_inferior = NULL;
+ st2000_ops.to_post_follow_inferior_by_clone = NULL;
+ st2000_run_ops.to_insert_fork_catchpoint = NULL;
+ st2000_run_ops.to_remove_fork_catchpoint = NULL;
+ st2000_run_ops.to_insert_vfork_catchpoint = NULL;
+ st2000_run_ops.to_remove_vfork_catchpoint = NULL;
+ st2000_ops.to_has_forked = NULL;
+ st2000_ops.to_has_vforked = NULL;
+ st2000_run_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ st2000_ops.to_post_follow_vfork = NULL;
+ st2000_run_ops.to_insert_exec_catchpoint = NULL;
+ st2000_run_ops.to_remove_exec_catchpoint = NULL;
+ st2000_run_ops.to_has_execd = NULL;
+ st2000_run_ops.to_reported_exec_events_per_exec_call = NULL;
+ st2000_run_ops.to_has_exited = NULL;
+ st2000_ops.to_mourn_inferior = st2000_mourn_inferior;
+ st2000_ops.to_can_run = 0; /* can_run */
+ st2000_ops.to_notice_signals = 0; /* notice_signals */
+ st2000_ops.to_thread_alive = 0; /* thread alive */
+ st2000_ops.to_stop = 0; /* to_stop */
+ st2000_ops.to_pid_to_exec_file = NULL;
+ st2000_run_ops.to_core_file_to_sym_file = NULL;
+ st2000_ops.to_stratum = process_stratum;
+ st2000_ops.DONT_USE = 0; /* next */
+ st2000_ops.to_has_all_memory = 1;
+ st2000_ops.to_has_memory = 1;
+ st2000_ops.to_has_stack = 1;
+ st2000_ops.to_has_registers = 1;
+ st2000_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */
+ st2000_ops.to_sections = 0;
+ st2000_ops.to_sections_end = 0; /* Section pointers */
+ st2000_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+} ;
void
_initialize_remote_st2000 ()
{
+ init_st2000_ops() ;
add_target (&st2000_ops);
add_com ("st2000 <command>", class_obscure, st2000_command,
"Send a command to the STDBUG monitor.");
diff --git a/contrib/gdb/gdb/remote-udi.c b/contrib/gdb/gdb/remote-udi.c
index 9512023..6397bca 100644
--- a/contrib/gdb/gdb/remote-udi.c
+++ b/contrib/gdb/gdb/remote-udi.c
@@ -453,13 +453,13 @@ udi_wait (pid, status)
a whole bunch of output (more than SBUF_MAX, I would
guess). It doesn't seem to happen with the simulator. */
warning ("UDIGetStdout() failed in udi_wait");
- fwrite (sbuf, 1, CountDone, gdb_stdout);
+ fwrite (sbuf, 1, CountDone, stdout);
gdb_flush(gdb_stdout);
continue;
case UDIStderrReady:
UDIGetStderr (sbuf, (UDISizeT)SBUF_MAX, &CountDone);
- fwrite (sbuf, 1, CountDone, gdb_stderr);
+ fwrite (sbuf, 1, CountDone, stderr);
gdb_flush(gdb_stderr);
continue;
@@ -1092,7 +1092,7 @@ download(load_arg_string, from_tty)
error ("Must specify at least a file name with the load command");
filename = tilde_expand (filename);
- make_cleanup (free, filename);
+ make_cleanup ((make_cleanup_func) free, filename);
while (token = strtok (NULL, " \t"))
{
@@ -1146,7 +1146,7 @@ download(load_arg_string, from_tty)
/* FIXME: should be checking for errors from bfd_close (for one thing,
on error it does not free all the storage associated with the
bfd). */
- make_cleanup (bfd_close, pbfd);
+ make_cleanup ((make_cleanup_func) bfd_close, pbfd);
QUIT;
immediate_quit++;
@@ -1299,7 +1299,7 @@ udi_load (args, from_tty)
/* As a convenience, pick up any symbol info that is in the program
being loaded. Note that we assume that the program is the``mainline'';
if this is not always true, then this code will need to be augmented. */
- symbol_file_add (strtok (args, " \t"), from_tty, 0, 1, 0, 0);
+ symbol_file_add (strtok (args, " \t"), from_tty, 0, 1, 0, 0, 0, 0);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1450,7 +1450,7 @@ fetch_register (regno)
supply_register(regno, (char *) &To);
if (remote_debug)
- printf_unfiltered("Fetching register %s = 0x%x\n", reg_names[regno], To);
+ printf_unfiltered("Fetching register %s = 0x%x\n", REGISTER_NAME (regno), To);
}
/*****************************************************************************/
/* Store a single register indicated by 'regno'.
@@ -1471,7 +1471,7 @@ store_register (regno)
From = read_register (regno); /* get data value */
if (remote_debug)
- printf_unfiltered("Storing register %s = 0x%x\n", reg_names[regno], From);
+ printf_unfiltered("Storing register %s = 0x%x\n", REGISTER_NAME (regno), From);
if (regno == GR1_REGNUM)
{
@@ -1621,18 +1621,22 @@ service_HIF(msg)
The RS/6000 doesn't like "extern" followed by "static"; SunOS
/bin/cc doesn't like "static" twice. */
-struct target_ops udi_ops = {
- "udi",
- "Remote UDI connected TIP",
- "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
+struct target_ops udi_ops;
+
+static void
+init_udi_ops(void)
+{
+ udi_ops.to_shortname = "udi";
+ udi_ops.to_longname = "Remote UDI connected TIP";
+ udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
Arguments are\n\
`configuration-id AF_INET hostname port-number'\n\
- To connect via the network, where hostname and port-number specify the\n\
- host and port where you can connect via UDI.\n\
- configuration-id is unused.\n\
+To connect via the network, where hostname and port-number specify the\n\
+host and port where you can connect via UDI.\n\
+configuration-id is unused.\n\
\n\
`configuration-id AF_UNIX socket-name tip-program'\n\
- To connect using a local connection to the \"tip.exe\" program which is\n\
+To connect using a local connection to the \"tip.exe\" program which is\n\
supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
tip program must already be started; connect to it using that socket.\n\
If not, start up tip-program, which should be the name of the tip\n\
@@ -1642,48 +1646,49 @@ Arguments are\n\
`configuration-id'\n\
Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
are files containing lines in the above formats. configuration-id is\n\
- used to pick which line of the file to use.",
- udi_open,
- udi_close,
- udi_attach,
- udi_detach,
- udi_resume,
- udi_wait,
- udi_fetch_registers,
- udi_store_registers,
- udi_prepare_to_store,
- udi_xfer_inferior_memory,
- udi_files_info,
- udi_insert_breakpoint,
- udi_remove_breakpoint,
- 0, /* termial_init */
- 0, /* terminal_inferior */
- 0, /* terminal_ours_for_output */
- 0, /* terminal_ours */
- 0, /* terminal_info */
- udi_kill, /* FIXME, kill */
- udi_load, /* to_load */
- 0, /* lookup_symbol */
- udi_create_inferior,
- udi_mourn, /* mourn_inferior FIXME */
- 0, /* can_run */
- 0, /* notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum,
- 0, /* next */
- 1, /* has_all_memory */
- 1, /* has_memory */
- 1, /* has_stack */
- 1, /* has_registers */
- 1, /* has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC, /* Always the last thing */
+ used to pick which line of the file to use." ;
+ udi_ops.to_open = udi_open;
+ udi_ops.to_close = udi_close;
+ udi_ops.to_attach = udi_attach;
+ udi_ops.to_detach = udi_detach;
+ udi_ops.to_resume = udi_resume;
+ udi_ops.to_wait = udi_wait;
+ udi_ops.to_fetch_registers = udi_fetch_registers;
+ udi_ops.to_store_registers = udi_store_registers;
+ udi_ops.to_prepare_to_store = udi_prepare_to_store;
+ udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
+ udi_ops.to_files_info = udi_files_info;
+ udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
+ udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
+ udi_ops.to_terminal_init = 0;
+ udi_ops.to_terminal_inferior = 0;
+ udi_ops.to_terminal_ours_for_output = 0;
+ udi_ops.to_terminal_ours = 0;
+ udi_ops.to_terminal_info = 0;
+ udi_ops.to_kill = udi_kill;
+ udi_ops.to_load = udi_load;
+ udi_ops.to_lookup_symbol = 0;
+ udi_ops.to_create_inferior = udi_create_inferior;
+ udi_ops.to_mourn_inferior = udi_mourn;
+ udi_ops.to_can_run = 0;
+ udi_ops.to_notice_signals = 0;
+ udi_ops.to_thread_alive = 0;
+ udi_ops.to_stop = 0;
+ udi_ops.to_stratum = process_stratum;
+ udi_ops.DONT_USE = 0;
+ udi_ops.to_has_all_memory = 1;
+ udi_ops.to_has_memory = 1;
+ udi_ops.to_has_stack = 1;
+ udi_ops.to_has_registers = 1;
+ udi_ops.to_has_execution = 1;
+ udi_ops.to_sections = 0;
+ udi_ops.to_sections_end = 0;
+ udi_ops.to_magic = OPS_MAGIC;
};
void
_initialize_remote_udi ()
{
+ init_udi_ops() ;
add_target (&udi_ops);
}
diff --git a/contrib/gdb/gdb/remote-utils.c b/contrib/gdb/gdb/remote-utils.c
index cbbdeaf..7219255 100644
--- a/contrib/gdb/gdb/remote-utils.c
+++ b/contrib/gdb/gdb/remote-utils.c
@@ -1,6 +1,6 @@
/* Generic support for remote debugging interfaces.
- Copyright 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -50,6 +50,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "inferior.h" /* for generic_mourn_inferior */
#include "remote-utils.h"
+
+void _initialize_sr_support PARAMS ((void));
+
struct _sr_settings sr_settings = {
4, /* timeout:
remote-hms.c had 2
@@ -69,6 +72,9 @@ struct _sr_settings sr_settings = {
struct gr_settings *gr_settings = NULL;
+static void usage PARAMS ((char *, char *));
+static void sr_com PARAMS ((char *, int));
+
static void
usage(proto, junk)
char *proto;
@@ -241,10 +247,12 @@ sr_pollchar()
if (buf == SERIAL_TIMEOUT)
buf = 0;
if (sr_get_debug() > 0)
- if (buf)
- printf_unfiltered ("%c", buf);
- else
- printf_unfiltered ("<empty character poll>");
+ {
+ if (buf)
+ printf_unfiltered ("%c", buf);
+ else
+ printf_unfiltered ("<empty character poll>");
+ }
return buf & 0x7f;
}
@@ -380,7 +388,7 @@ sr_get_hex_word ()
prompt from the remote is seen.
FIXME: Can't handle commands that take input. */
-void
+static void
sr_com (args, fromtty)
char *args;
int fromtty;
@@ -488,7 +496,7 @@ gr_create_inferior (execfile, args, env)
error ("Can't pass arguments to remote process.");
if (execfile == 0 || exec_bfd == 0)
- error ("No exec file specified");
+ error ("No executable file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
sr_check_open ();
diff --git a/contrib/gdb/gdb/remote-vx.c b/contrib/gdb/gdb/remote-vx.c
index 13b6c29..9ad86d4 100644
--- a/contrib/gdb/gdb/remote-vx.c
+++ b/contrib/gdb/gdb/remote-vx.c
@@ -1,5 +1,5 @@
/* Memory-access and commands for remote VxWorks processes, for GDB.
- Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1990-95, 1997-98, 1999 Free Software Foundation, Inc.
Contributed by Wind River Systems and Cygnus Support.
This file is part of GDB.
@@ -68,7 +68,14 @@ extern int stop_soon_quietly; /* for wait_for_inferior */
static int net_step ();
static int net_ptrace_clnt_call (); /* Forward decl */
static enum clnt_stat net_clnt_call (); /* Forward decl */
-extern struct target_ops vx_ops, vx_run_ops; /* Forward declaration */
+
+/* Target ops structure for accessing memory and such over the net */
+
+static struct target_ops vx_ops;
+
+/* Target ops structure for accessing VxWorks child processes over the net */
+
+static struct target_ops vx_run_ops;
/* Saved name of target host and called function for "info files".
Both malloc'd. */
@@ -414,7 +421,7 @@ net_read_registers (reg_buf, len, procnum)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS)
? "general-purpose"
: "floating-point");
@@ -460,7 +467,7 @@ net_write_registers (reg_buf, len, procnum)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS)
? "general-purpose"
: "floating-point");
@@ -557,7 +564,7 @@ vx_xfer_memory (memaddr, myaddr, len, write, target)
code chosen by the target so that a later perror () will
say something meaningful. */
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
}
}
@@ -629,7 +636,7 @@ vx_resume (pid, step, siggnal)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
perror_with_name ("Resuming remote process");
}
}
@@ -691,7 +698,7 @@ vx_add_symbols (name, from_tty, text_addr, data_addr, bss_addr)
/* It might be nice to suppress the breakpoint_re_set which happens here
because we are going to do one again after the objfile_relocate. */
- objfile = symbol_file_add (name, from_tty, 0, 0, 0, 0);
+ objfile = symbol_file_add (name, from_tty, 0, 0, 0, 0, 0, 0);
/* This is a (slightly cheesy) way of superceding the old symbols. A less
cheesy way would be to find the objfile with the same name and
@@ -715,9 +722,6 @@ vx_add_symbols (name, from_tty, text_addr, data_addr, bss_addr)
ANOFFSET (offs, SECT_OFF_DATA) = data_addr - ss.data_start;
ANOFFSET (offs, SECT_OFF_BSS) = bss_addr - ss.bss_start;
objfile_relocate (objfile, offs);
-
- /* Need to do this *after* things are relocated. */
- breakpoint_re_set ();
}
/* This function allows the addition of incrementally linked object files. */
@@ -1247,43 +1251,20 @@ vx_attach (args, from_tty)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
perror_with_name ("Attaching remote process");
}
/* It worked... */
- push_target (&vx_run_ops);
- /* The unsigned long pid will get turned into a signed int here,
- but it doesn't seem to matter. inferior_pid must be signed
- in order for other parts of GDB to work correctly. */
- inferior_pid = pid;
- vx_running = 0;
-#if defined (START_INFERIOR_HOOK)
- START_INFERIOR_HOOK ();
-#endif
-
- mark_breakpoints_out ();
- /* Set up the "saved terminal modes" of the inferior
- based on what modes we are starting it with. */
-
- target_terminal_init ();
-
- /* Install inferior's terminal modes. */
-
- target_terminal_inferior ();
-
- /* We will get a task spawn event immediately. */
+ inferior_pid = pid;
+ push_target (&vx_run_ops);
- init_wait_for_inferior ();
- clear_proceed_status ();
- stop_soon_quietly = 1;
- wait_for_inferior ();
- stop_soon_quietly = 0;
- normal_stop ();
+ if (vx_running)
+ free (vx_running);
+ vx_running = 0;
}
-
/* detach_command --
takes a program previously attached to and detaches it.
The program resumes execution and will no longer stop
@@ -1322,7 +1303,7 @@ vx_detach (args, from_tty)
error (rpcerr);
if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
perror_with_name ("Detaching VxWorks process");
}
@@ -1350,7 +1331,7 @@ vx_kill ()
warning (rpcerr);
else if (ptrace_out.status == -1)
{
- errno = ptrace_out.errno;
+ errno = ptrace_out.errno_num;
perror_with_name ("Killing VxWorks process");
}
@@ -1418,71 +1399,69 @@ vx_proc_open (name, from_tty)
error ("Use the \"run\" command to start a VxWorks process.");
}
-/* 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\
-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 */
- 0, /* thread_alive */
- 0, /* to_stop */
- 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 */
+static void
+init_vx_ops ()
+{
+ vx_ops.to_shortname = "vxworks";
+ vx_ops.to_longname = "VxWorks target memory via RPC over TCP/IP";
+ vx_ops.to_doc = "Use VxWorks target memory. \n\
+Specify the name of the machine to connect to.";
+ vx_ops.to_open = vx_open;
+ vx_ops.to_close = vx_close;
+ vx_ops.to_attach = vx_attach;
+ vx_ops.to_xfer_memory = vx_xfer_memory;
+ vx_ops.to_files_info = vx_files_info;
+ vx_ops.to_load = vx_load_command;
+ vx_ops.to_lookup_symbol = vx_lookup_symbol;
+ vx_ops.to_create_inferior = vx_create_inferior;
+ vx_ops.to_stratum = core_stratum;
+ vx_ops.to_has_all_memory = 1;
+ vx_ops.to_has_memory = 1;
+ vx_ops.to_magic = 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 */
- 0, /* thread_alive */
- 0, /* to_stop */
- 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. */
+static void
+init_vx_run_ops ()
+{
+ vx_run_ops.to_shortname = "vxprocess";
+ vx_run_ops.to_longname = "VxWorks process";
+ vx_run_ops.to_doc = "VxWorks process; started by the \"run\" command.";
+ vx_run_ops.to_open = vx_proc_open;
+ vx_run_ops.to_close = vx_proc_close;
+ vx_run_ops.to_detach = vx_detach;
+ vx_run_ops.to_resume = vx_resume;
+ vx_run_ops.to_wait = vx_wait;
+ vx_run_ops.to_fetch_registers = vx_read_register;
+ vx_run_ops.to_store_registers = vx_write_register;
+ vx_run_ops.to_prepare_to_store = vx_prepare_to_store;
+ vx_run_ops.to_xfer_memory = vx_xfer_memory;
+ vx_run_ops.to_files_info = vx_run_files_info;
+ vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint;
+ vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint;
+ vx_run_ops.to_kill = vx_kill;
+ vx_run_ops.to_load = vx_load_command;
+ vx_run_ops.to_lookup_symbol = vx_lookup_symbol;
+ vx_run_ops.to_mourn_inferior = vx_mourn_inferior ;
+ vx_run_ops.to_stratum = process_stratum;
+ vx_run_ops.to_has_memory = 1;
+ vx_run_ops.to_has_stack = 1;
+ vx_run_ops.to_has_registers = 1;
+ vx_run_ops.to_has_execution = 1;
+ vx_run_ops.to_magic = OPS_MAGIC;
+}
void
_initialize_vx ()
{
+ init_vx_ops ();
+ add_target (&vx_ops);
+ init_vx_run_ops ();
+ add_target (&vx_run_ops);
+
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_run_ops);
}
diff --git a/contrib/gdb/gdb/remote-vx29k.c b/contrib/gdb/gdb/remote-vx29k.c
index 02554aa..e6fc2c7 100644
--- a/contrib/gdb/gdb/remote-vx29k.c
+++ b/contrib/gdb/gdb/remote-vx29k.c
@@ -176,7 +176,7 @@ vx_write_register (regno)
contents when FRAME_CHAIN_VALID is invoked. */
int
-get_fp_contents (chain, thisframe)
+vx29k_frame_chain_valid (chain, thisframe)
CORE_ADDR chain;
struct frame_info *thisframe; /* not used here */
{
diff --git a/contrib/gdb/gdb/remote.c b/contrib/gdb/gdb/remote.c
index 5356e5e..f5b6f7c 100644
--- a/contrib/gdb/gdb/remote.c
+++ b/contrib/gdb/gdb/remote.c
@@ -1,5 +1,6 @@
/* Remote target communications for serial-line targets in custom GDB protocol
- Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -89,6 +90,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
where only part of the data was
written).
+ write mem XAA..AA,LLLL:XX..XX
+ (binary) AA..AA is address,
+ LLLL is number of bytes,
+ XX..XX is binary data
+ reply OK for success
+ ENN for an error
+
continue cAA..AA AA..AA is address to resume
If AA..AA is omitted,
resume at same address.
@@ -97,10 +105,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
If AA..AA is omitted,
resume at same address.
- continue with Csig;AA Continue with signal sig (hex signal
- signal number).
+ continue with Csig;AA..AA Continue with signal sig (hex signal
+ signal number). If ;AA..AA is omitted,
+ resume at same address.
- step with Ssig;AA Like 'C' but step not continue.
+ step with Ssig;AA..AA Like 'C' but step not continue.
signal
last signal ? Reply the current reason for stopping.
@@ -133,9 +142,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
or... XAA The process terminated with signal
AA.
or... OXX..XX XX..XX is hex encoding of ASCII data. This
- can happen at any time while the program is
- running and the debugger should
- continue to wait for 'W', 'T', etc.
+ can happen at any time while the
+ program is running and the debugger
+ should continue to wait for
+ 'W', 'T', etc.
thread alive TXX Find out if the thread XX is alive.
reply OK thread is still alive
@@ -177,6 +187,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdb_string.h"
+#include <ctype.h>
#include <fcntl.h>
#include "frame.h"
#include "inferior.h"
@@ -188,7 +199,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcmd.h"
#include "objfiles.h"
#include "gdb-stabs.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "dcache.h"
@@ -209,9 +220,9 @@ static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
static void remote_files_info PARAMS ((struct target_ops *ignore));
-static int remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+static int remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char * myaddr,
int len, int should_write,
- struct target_ops *target));
+ struct target_ops * target));
static void remote_prepare_to_store PARAMS ((void));
@@ -220,13 +231,14 @@ static void remote_fetch_registers PARAMS ((int regno));
static void remote_resume PARAMS ((int pid, int step,
enum target_signal siggnal));
-static int remote_start_remote PARAMS ((char *dummy));
+static int remote_start_remote PARAMS ((PTR));
static void remote_open PARAMS ((char *name, int from_tty));
static void extended_remote_open PARAMS ((char *name, int from_tty));
-static void remote_open_1 PARAMS ((char *, int, struct target_ops *));
+static void remote_open_1 PARAMS ((char *, int, struct target_ops *,
+ int extended_p));
static void remote_close PARAMS ((int quitting));
@@ -242,39 +254,174 @@ static void extended_remote_create_inferior PARAMS ((char *, char *, char **));
static void remote_mourn_1 PARAMS ((struct target_ops *));
-static void getpkt PARAMS ((char *buf, int forever));
-
-static int putpkt PARAMS ((char *buf));
-
static void remote_send PARAMS ((char *buf));
static int readchar PARAMS ((int timeout));
-static int remote_wait PARAMS ((int pid, struct target_waitstatus *status));
+static int remote_wait PARAMS ((int pid, struct target_waitstatus * status));
static void remote_kill PARAMS ((void));
static int tohex PARAMS ((int nib));
-static int fromhex PARAMS ((int a));
-
static void remote_detach PARAMS ((char *args, int from_tty));
static void remote_interrupt PARAMS ((int signo));
-static void remote_interrupt_twice PARAMS ((int signo));
-
static void interrupt_query PARAMS ((void));
-extern struct target_ops remote_ops; /* Forward decl */
-extern struct target_ops extended_remote_ops; /* Forward decl */
+static void set_thread PARAMS ((int, int));
+
+static int remote_thread_alive PARAMS ((int));
+
+static void get_offsets PARAMS ((void));
+
+static int read_frame PARAMS ((char *));
+
+static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int remote_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int hexnumlen PARAMS ((ULONGEST num));
+
+static void init_remote_ops PARAMS ((void));
+
+static void init_extended_remote_ops PARAMS ((void));
+
+static void remote_stop PARAMS ((void));
+
+static int ishex PARAMS ((int ch, int *val));
+
+static int stubhex PARAMS ((int ch));
+
+static int remote_query PARAMS ((int/*char*/, char *, char *, int *));
+
+static int hexnumstr PARAMS ((char *, ULONGEST));
+
+static CORE_ADDR remote_address_masked PARAMS ((CORE_ADDR));
+
+static void print_packet PARAMS ((char *));
+
+static unsigned long crc32 PARAMS ((unsigned char *, int, unsigned int));
+
+static void compare_sections_command PARAMS ((char *, int));
+
+static void packet_command PARAMS ((char *, int));
+
+static int stub_unpack_int PARAMS ((char *buff, int fieldlength));
+
+char *unpack_varlen_hex PARAMS ((char *buff, int *result));
+
+static char *unpack_nibble PARAMS ((char *buf, int *val));
+
+static char *pack_nibble PARAMS ((char *buf, int nibble));
+
+static char *pack_hex_byte PARAMS ((char *pkt, int/*unsigned char*/ byte));
+
+static char *unpack_byte PARAMS ((char *buf, int *value));
+
+static char *pack_int PARAMS ((char *buf, int value));
+
+static char *unpack_int PARAMS ((char *buf, int *value));
+
+static char *unpack_string PARAMS ((char *src, char *dest, int length));
+
+static char *pack_threadid PARAMS ((char *pkt, threadref *id));
+
+static char *unpack_threadid PARAMS ((char *inbuf, threadref *id));
+
+void int_to_threadref PARAMS ((threadref *id, int value));
+
+static int threadref_to_int PARAMS ((threadref *ref));
+
+static void copy_threadref PARAMS ((threadref *dest, threadref *src));
+
+static int threadmatch PARAMS ((threadref *dest, threadref *src));
+
+static char *pack_threadinfo_request PARAMS ((char *pkt, int mode,
+ threadref *id));
+
+static int remote_unpack_thread_info_response PARAMS ((char *pkt,
+ threadref *expectedref,
+ struct gdb_ext_thread_info *info));
+
+
+static int remote_get_threadinfo PARAMS ((threadref *threadid,
+ int fieldset, /*TAG mask */
+ struct gdb_ext_thread_info *info));
+
+static int adapt_remote_get_threadinfo PARAMS ((gdb_threadref *ref,
+ int selection,
+ struct gdb_ext_thread_info *info));
+
+static char *pack_threadlist_request PARAMS ((char *pkt, int startflag,
+ int threadcount,
+ threadref *nextthread));
+
+static int parse_threadlist_response PARAMS ((char *pkt,
+ int result_limit,
+ threadref *original_echo,
+ threadref *resultlist,
+ int *doneflag));
+
+static int remote_get_threadlist PARAMS ((int startflag,
+ threadref *nextthread,
+ int result_limit,
+ int *done,
+ int *result_count,
+ threadref *threadlist));
+
+typedef int (*rmt_thread_action) (threadref *ref, void *context);
+
+static int remote_threadlist_iterator PARAMS ((rmt_thread_action stepfunction,
+ void *context, int looplimit));
+
+static int remote_newthread_step PARAMS ((threadref *ref, void *context));
+
+static int remote_current_thread PARAMS ((int oldpid));
+
+int remote_find_new_threads PARAMS ((void));
+
+static void record_currthread PARAMS ((int currthread));
+
+static void init_remote_threads PARAMS ((void));
+
+/* exported functions */
+
+extern int fromhex PARAMS ((int a));
+
+extern void getpkt PARAMS ((char *buf, int forever));
+
+extern int putpkt PARAMS ((char *buf));
+
+static int putpkt_binary PARAMS ((char *buf, int cnt));
+
+void remote_console_output PARAMS ((char *));
+
+static void check_binary_download PARAMS ((CORE_ADDR addr));
+
+/* Define the target subroutine names */
+
+void open_remote_target PARAMS ((char *, int, struct target_ops *, int));
+
+void _initialize_remote PARAMS ((void));
+
+/* */
+
+static struct target_ops remote_ops;
+
+static struct target_ops extended_remote_ops;
+
+static struct target_thread_vector remote_thread_vec;
/* This was 5 seconds, which is a long time to sit and wait.
Unless this is going though some terminal server or multiplexer or
other form of hairy serial connection, I would think 2 seconds would
be plenty. */
-static int remote_timeout = 2;
+/* Changed to allow option to set timeout value.
+ was static int remote_timeout = 2; */
+extern int remote_timeout;
/* This variable chooses whether to send a ^C or a break when the user
requests program interruption. Although ^C is usually what remote
@@ -283,10 +430,26 @@ static int remote_timeout = 2;
static int remote_break;
+/* Has the user attempted to interrupt the target? If so, then offer
+ the user the opportunity to bail out completely if he interrupts
+ again. */
+static int interrupted_already = 0;
+
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
remote_open knows that we don't have a file open when the program
starts. */
-serial_t remote_desc = NULL;
+static serial_t remote_desc = NULL;
+
+/* This variable (available to the user via "set remotebinarydownload")
+ dictates whether downloads are sent in binary (via the 'X' packet).
+ We assume that the stub can, and attempt to do it. This will be cleared if
+ the stub does not understand it. This switch is still needed, though
+ in cases when the packet is supported in the stub, but the connection
+ does not allow it (i.e., 7-bit serial connection only). */
+static int remote_binary_download = 1;
+
+/* Have we already checked whether binary downloads work? */
+static int remote_binary_checked;
/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
and i386-stub.c. Normally, no one would notice because it only matters
@@ -308,15 +471,76 @@ serial_t remote_desc = NULL;
#define PBUFSIZ (REGISTER_BYTES * 2 + 32)
#endif
+
+/* This variable sets the number of bytes to be written to the target
+ in a single packet. Normally PBUFSIZ is satisfactory, but some
+ targets need smaller values (perhaps because the receiving end
+ is slow). */
+
+static int remote_write_size = PBUFSIZ;
+
+/* This variable sets the number of bits in an address that are to be
+ sent in a memory ("M" or "m") packet. Normally, after stripping
+ leading zeros, the entire address would be sent. This variable
+ restricts the address to REMOTE_ADDRESS_SIZE bits. HISTORY: The
+ initial implementation of remote.c restricted the address sent in
+ memory packets to ``host::sizeof long'' bytes - (typically 32
+ bits). Consequently, for 64 bit targets, the upper 32 bits of an
+ address was never sent. Since fixing this bug may cause a break in
+ some remote targets this variable is principly provided to
+ facilitate backward compatibility. */
+
+static int remote_address_size;
+
+/* This is the size (in chars) of the first response to the `g' command. This
+ is used to limit the size of the memory read and write commands to prevent
+ stub buffers from overflowing. The size does not include headers and
+ trailers, it is only the payload size. */
+
+static int remote_register_buf_size = 0;
+
/* Should we try the 'P' request? If this is set to one when the stub
doesn't support 'P', the only consequence is some unnecessary traffic. */
static int stub_supports_P = 1;
+/* These are pointers to hook functions that may be set in order to
+ modify resume/wait behavior for a particular architecture. */
+
+void (*target_resume_hook) PARAMS ((void));
+void (*target_wait_loop_hook) PARAMS ((void));
+
-/* These are the threads which we last sent to the remote system. -1 for all
- or -2 for not sent yet. */
-int general_thread;
-int cont_thread;
+
+/* These are the threads which we last sent to the remote system.
+ -1 for all or -2 for not sent yet. */
+static int general_thread;
+static int cont_thread;
+
+/* Call this function as a result of
+ 1) A halt indication (T packet) containing a thread id
+ 2) A direct query of currthread
+ 3) Successful execution of set thread
+ */
+
+static void
+record_currthread (currthread)
+ int currthread;
+{
+#if 0 /* target_wait must not modify inferior_pid! */
+ inferior_pid = currthread;
+#endif
+ general_thread = currthread;
+#if 0 /* setting cont_thread has a different meaning
+ from having the target report its thread id. */
+ cont_thread = currthread;
+#endif
+ /* If this is a new thread, add it to GDB's thread list.
+ If we leave it up to WFI to do this, bad things will happen. */
+ if (!in_thread_list (currthread))
+ add_thread (currthread);
+}
+
+#define MAGIC_NULL_PID 42000
static void
set_thread (th, gen)
@@ -325,11 +549,13 @@ set_thread (th, gen)
{
char buf[PBUFSIZ];
int state = gen ? general_thread : cont_thread;
+
if (state == th)
return;
+
buf[0] = 'H';
buf[1] = gen ? 'g' : 'c';
- if (th == 42000)
+ if (th == MAGIC_NULL_PID)
{
buf[2] = '0';
buf[3] = '\0';
@@ -356,14 +582,681 @@ remote_thread_alive (th)
buf[0] = 'T';
if (th < 0)
- sprintf (&buf[1], "-%x", -th);
+ sprintf (&buf[1], "-%08x", -th);
else
- sprintf (&buf[1], "%x", th);
+ sprintf (&buf[1], "%08x", th);
putpkt (buf);
getpkt (buf, 0);
return (buf[0] == 'O' && buf[1] == 'K');
}
+/* About these extended threadlist and threadinfo packets. They are
+ variable length packets but, the fields within them are often fixed
+ length. They are redundent enough to send over UDP as is the
+ remote protocol in general. There is a matching unit test module
+ in libstub. */
+
+#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
+
+/* encode 64 bits in 16 chars of hex */
+
+static const char hexchars[] = "0123456789abcdef";
+
+static int
+ishex (ch, val)
+ int ch;
+ int *val;
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ {
+ *val = ch - 'a' + 10;
+ return 1;
+ }
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ *val = ch - 'A' + 10;
+ return 1;
+ }
+ if ((ch >= '0') && (ch <= '9'))
+ {
+ *val = ch - '0';
+ return 1;
+ }
+ return 0;
+}
+
+static int
+stubhex (ch)
+ int ch;
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ return -1;
+}
+
+static int
+stub_unpack_int (buff, fieldlength)
+ char *buff;
+ int fieldlength;
+{
+ int nibble;
+ int retval = 0;
+
+ while (fieldlength)
+ {
+ nibble = stubhex (*buff++);
+ retval |= nibble;
+ fieldlength--;
+ if (fieldlength)
+ retval = retval << 4;
+ }
+ return retval;
+}
+
+char *
+unpack_varlen_hex (buff, result)
+ char *buff; /* packet to parse */
+ int *result;
+{
+ int nibble;
+ int retval = 0;
+
+ while (ishex (*buff, &nibble))
+ {
+ buff++;
+ retval = retval << 4;
+ retval |= nibble & 0x0f;
+ }
+ *result = retval;
+ return buff;
+}
+
+static char *
+unpack_nibble (buf, val)
+ char *buf;
+ int *val;
+{
+ ishex (*buf++, val);
+ return buf;
+}
+
+static char *
+pack_nibble (buf, nibble)
+ char *buf;
+ int nibble;
+{
+ *buf++ = hexchars[(nibble & 0x0f)];
+ return buf;
+}
+
+static char *
+pack_hex_byte (pkt, byte)
+ char *pkt;
+ int byte;
+{
+ *pkt++ = hexchars[(byte >> 4) & 0xf];
+ *pkt++ = hexchars[(byte & 0xf)];
+ return pkt;
+}
+
+static char *
+unpack_byte (buf, value)
+ char *buf;
+ int *value;
+{
+ *value = stub_unpack_int (buf, 2);
+ return buf + 2;
+}
+
+static char *
+pack_int (buf, value)
+ char *buf;
+ int value;
+{
+ buf = pack_hex_byte (buf, (value >> 24) & 0xff);
+ buf = pack_hex_byte (buf, (value >> 16) & 0xff);
+ buf = pack_hex_byte (buf, (value >> 8) & 0x0ff);
+ buf = pack_hex_byte (buf, (value & 0xff));
+ return buf;
+}
+
+static char *
+unpack_int (buf, value)
+ char *buf;
+ int *value;
+{
+ *value = stub_unpack_int (buf, 8);
+ return buf + 8;
+}
+
+#if 0 /* currently unused, uncomment when needed */
+static char *pack_string PARAMS ((char *pkt, char *string));
+
+static char *
+pack_string (pkt, string)
+ char *pkt;
+ char *string;
+{
+ char ch;
+ int len;
+
+ len = strlen (string);
+ if (len > 200)
+ len = 200; /* Bigger than most GDB packets, junk??? */
+ pkt = pack_hex_byte (pkt, len);
+ while (len-- > 0)
+ {
+ ch = *string++;
+ if ((ch == '\0') || (ch == '#'))
+ ch = '*'; /* Protect encapsulation */
+ *pkt++ = ch;
+ }
+ return pkt;
+}
+#endif /* 0 (unused) */
+
+static char *
+unpack_string (src, dest, length)
+ char *src;
+ char *dest;
+ int length;
+{
+ while (length--)
+ *dest++ = *src++;
+ *dest = '\0';
+ return src;
+}
+
+static char *
+pack_threadid (pkt, id)
+ char *pkt;
+ threadref *id;
+{
+ char *limit;
+ unsigned char *altid;
+
+ altid = (unsigned char *) id;
+ limit = pkt + BUF_THREAD_ID_SIZE;
+ while (pkt < limit)
+ pkt = pack_hex_byte (pkt, *altid++);
+ return pkt;
+}
+
+
+static char *
+unpack_threadid (inbuf, id)
+ char *inbuf;
+ threadref *id;
+{
+ char *altref;
+ char *limit = inbuf + BUF_THREAD_ID_SIZE;
+ int x, y;
+
+ altref = (char *) id;
+
+ while (inbuf < limit)
+ {
+ x = stubhex (*inbuf++);
+ y = stubhex (*inbuf++);
+ *altref++ = (x << 4) | y;
+ }
+ return inbuf;
+}
+
+/* Externally, threadrefs are 64 bits but internally, they are still
+ ints. This is due to a mismatch of specifications. We would like
+ to use 64bit thread references internally. This is an adapter
+ function. */
+
+void
+int_to_threadref (id, value)
+ threadref *id;
+ int value;
+{
+ unsigned char *scan;
+
+ scan = (unsigned char *) id;
+ {
+ int i = 4;
+ while (i--)
+ *scan++ = 0;
+ }
+ *scan++ = (value >> 24) & 0xff;
+ *scan++ = (value >> 16) & 0xff;
+ *scan++ = (value >> 8) & 0xff;
+ *scan++ = (value & 0xff);
+}
+
+static int
+threadref_to_int (ref)
+ threadref *ref;
+{
+ int i, value = 0;
+ unsigned char *scan;
+
+ scan = (char *) ref;
+ scan += 4;
+ i = 4;
+ while (i-- > 0)
+ value = (value << 8) | ((*scan++) & 0xff);
+ return value;
+}
+
+static void
+copy_threadref (dest, src)
+ threadref *dest;
+ threadref *src;
+{
+ int i;
+ unsigned char *csrc, *cdest;
+
+ csrc = (unsigned char *) src;
+ cdest = (unsigned char *) dest;
+ i = 8;
+ while (i--)
+ *cdest++ = *csrc++;
+}
+
+static int
+threadmatch (dest, src)
+ threadref *dest;
+ threadref *src;
+{
+ /* things are broken right now, so just assume we got a match */
+#if 0
+ unsigned char *srcp, *destp;
+ int i, result;
+ srcp = (char *) src;
+ destp = (char *) dest;
+
+ result = 1;
+ while (i-- > 0)
+ result &= (*srcp++ == *destp++) ? 1 : 0;
+ return result;
+#endif
+ return 1;
+}
+
+/*
+ threadid:1, # always request threadid
+ context_exists:2,
+ display:4,
+ unique_name:8,
+ more_display:16
+*/
+
+/* Encoding: 'Q':8,'P':8,mask:32,threadid:64 */
+
+static char *
+pack_threadinfo_request (pkt, mode, id)
+ char *pkt;
+ int mode;
+ threadref *id;
+{
+ *pkt++ = 'q'; /* Info Query */
+ *pkt++ = 'P'; /* process or thread info */
+ pkt = pack_int (pkt, mode); /* mode */
+ pkt = pack_threadid (pkt, id); /* threadid */
+ *pkt = '\0'; /* terminate */
+ return pkt;
+}
+
+/* These values tag the fields in a thread info response packet */
+/* Tagging the fields allows us to request specific fields and to
+ add more fields as time goes by */
+
+#define TAG_THREADID 1 /* Echo the thread identifier */
+#define TAG_EXISTS 2 /* Is this process defined enough to
+ fetch registers and its stack */
+#define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
+#define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
+#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
+ the process*/
+
+static int
+remote_unpack_thread_info_response (pkt, expectedref, info)
+ char *pkt;
+ threadref *expectedref;
+ struct gdb_ext_thread_info *info;
+{
+ int mask, length;
+ unsigned int tag;
+ threadref ref;
+ char *limit = pkt + PBUFSIZ; /* plausable parsing limit */
+ int retval = 1;
+
+ /* info->threadid = 0; FIXME: implement zero_threadref */
+ info->active = 0;
+ info->display[0] = '\0';
+ info->shortname[0] = '\0';
+ info->more_display[0] = '\0';
+
+ /* Assume the characters indicating the packet type have been stripped */
+ pkt = unpack_int (pkt, &mask); /* arg mask */
+ pkt = unpack_threadid (pkt, &ref);
+
+ if (mask == 0)
+ warning ("Incomplete response to threadinfo request\n");
+ if (!threadmatch (&ref, expectedref))
+ { /* This is an answer to a different request */
+ warning ("ERROR RMT Thread info mismatch\n");
+ return 0;
+ }
+ copy_threadref (&info->threadid, &ref);
+
+ /* Loop on tagged fields , try to bail if somthing goes wrong */
+
+ while ((pkt < limit) && mask && *pkt) /* packets are terminated with nulls */
+ {
+ pkt = unpack_int (pkt, &tag); /* tag */
+ pkt = unpack_byte (pkt, &length); /* length */
+ if (!(tag & mask)) /* tags out of synch with mask */
+ {
+ warning ("ERROR RMT: threadinfo tag mismatch\n");
+ retval = 0;
+ break;
+ }
+ if (tag == TAG_THREADID)
+ {
+ if (length != 16)
+ {
+ warning ("ERROR RMT: length of threadid is not 16\n");
+ retval = 0;
+ break;
+ }
+ pkt = unpack_threadid (pkt, &ref);
+ mask = mask & ~TAG_THREADID;
+ continue;
+ }
+ if (tag == TAG_EXISTS)
+ {
+ info->active = stub_unpack_int (pkt, length);
+ pkt += length;
+ mask = mask & ~(TAG_EXISTS);
+ if (length > 8)
+ {
+ warning ("ERROR RMT: 'exists' length too long\n");
+ retval = 0;
+ break;
+ }
+ continue;
+ }
+ if (tag == TAG_THREADNAME)
+ {
+ pkt = unpack_string (pkt, &info->shortname[0], length);
+ mask = mask & ~TAG_THREADNAME;
+ continue;
+ }
+ if (tag == TAG_DISPLAY)
+ {
+ pkt = unpack_string (pkt, &info->display[0], length);
+ mask = mask & ~TAG_DISPLAY;
+ continue;
+ }
+ if (tag == TAG_MOREDISPLAY)
+ {
+ pkt = unpack_string (pkt, &info->more_display[0], length);
+ mask = mask & ~TAG_MOREDISPLAY;
+ continue;
+ }
+ warning ("ERROR RMT: unknown thread info tag\n");
+ break; /* Not a tag we know about */
+ }
+ return retval;
+}
+
+static int
+remote_get_threadinfo (threadid, fieldset, info)
+ threadref *threadid;
+ int fieldset; /* TAG mask */
+ struct gdb_ext_thread_info *info;
+{
+ int result;
+ char threadinfo_pkt[PBUFSIZ];
+
+ pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
+ putpkt (threadinfo_pkt);
+ getpkt (threadinfo_pkt, 0);
+ result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid,
+ info);
+ return result;
+}
+
+/* Unfortunately, 61 bit thread-ids are bigger than the internal
+ representation of a threadid. */
+
+static int
+adapt_remote_get_threadinfo (ref, selection, info)
+ gdb_threadref *ref;
+ int selection;
+ struct gdb_ext_thread_info *info;
+{
+ threadref lclref;
+
+ int_to_threadref (&lclref, *ref);
+ return remote_get_threadinfo (&lclref, selection, info);
+}
+
+/* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */
+
+static char *
+pack_threadlist_request (pkt, startflag, threadcount, nextthread)
+ char *pkt;
+ int startflag;
+ int threadcount;
+ threadref *nextthread;
+{
+ *pkt++ = 'q'; /* info query packet */
+ *pkt++ = 'L'; /* Process LIST or threadLIST request */
+ pkt = pack_nibble (pkt, startflag); /* initflag 1 bytes */
+ pkt = pack_hex_byte (pkt, threadcount); /* threadcount 2 bytes */
+ pkt = pack_threadid (pkt, nextthread); /* 64 bit thread identifier */
+ *pkt = '\0';
+ return pkt;
+}
+
+/* Encoding: 'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
+
+static int
+parse_threadlist_response (pkt, result_limit, original_echo, resultlist,
+ doneflag)
+ char *pkt;
+ int result_limit;
+ threadref *original_echo;
+ threadref *resultlist;
+ int *doneflag;
+{
+ char *limit;
+ int count, resultcount, done;
+
+ resultcount = 0;
+ /* Assume the 'q' and 'M chars have been stripped. */
+ limit = pkt + (PBUFSIZ - BUF_THREAD_ID_SIZE); /* done parse past here */
+ pkt = unpack_byte (pkt, &count); /* count field */
+ pkt = unpack_nibble (pkt, &done);
+ /* The first threadid is the argument threadid. */
+ pkt = unpack_threadid (pkt, original_echo); /* should match query packet */
+ while ((count-- > 0) && (pkt < limit))
+ {
+ pkt = unpack_threadid (pkt, resultlist++);
+ if (resultcount++ >= result_limit)
+ break;
+ }
+ if (doneflag)
+ *doneflag = done;
+ return resultcount;
+}
+
+static int
+remote_get_threadlist (startflag, nextthread, result_limit,
+ done, result_count, threadlist)
+ int startflag;
+ threadref *nextthread;
+ int result_limit;
+ int *done;
+ int *result_count;
+ threadref *threadlist;
+
+{
+ static threadref echo_nextthread;
+ char threadlist_packet[PBUFSIZ];
+ char t_response[PBUFSIZ];
+ int result = 1;
+
+ /* Trancate result limit to be smaller than the packet size */
+ if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= PBUFSIZ)
+ result_limit = (PBUFSIZ / BUF_THREAD_ID_SIZE) - 2;
+
+ pack_threadlist_request (threadlist_packet,
+ startflag, result_limit, nextthread);
+ putpkt (threadlist_packet);
+ getpkt (t_response, 0);
+
+ *result_count =
+ parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
+ threadlist, done);
+
+ if (!threadmatch (&echo_nextthread, nextthread))
+ {
+ /* FIXME: This is a good reason to drop the packet */
+ /* Possably, there is a duplicate response */
+ /* Possabilities :
+ retransmit immediatly - race conditions
+ retransmit after timeout - yes
+ exit
+ wait for packet, then exit
+ */
+ warning ("HMM: threadlist did not echo arg thread, dropping it\n");
+ return 0; /* I choose simply exiting */
+ }
+ if (*result_count <= 0)
+ {
+ if (*done != 1)
+ {
+ warning ("RMT ERROR : failed to get remote thread list\n");
+ result = 0;
+ }
+ return result; /* break; */
+ }
+ if (*result_count > result_limit)
+ {
+ *result_count = 0;
+ warning ("RMT ERROR: threadlist response longer than requested\n");
+ return 0;
+ }
+ return result;
+}
+
+/* This is the interface between remote and threads, remotes upper interface */
+
+/* remote_find_new_threads retrieves the thread list and for each
+ thread in the list, looks up the thread in GDB's internal list,
+ ading the thread if it does not already exist. This involves
+ getting partial thread lists from the remote target so, polling the
+ quit_flag is required. */
+
+
+/* About this many threadisds fit in a packet. */
+
+#define MAXTHREADLISTRESULTS 32
+
+static int
+remote_threadlist_iterator (stepfunction, context, looplimit)
+ rmt_thread_action stepfunction;
+ void *context;
+ int looplimit;
+{
+ int done, i, result_count;
+ int startflag = 1;
+ int result = 1;
+ int loopcount = 0;
+ static threadref nextthread;
+ static threadref resultthreadlist[MAXTHREADLISTRESULTS];
+
+ done = 0;
+ while (!done)
+ {
+ if (loopcount++ > looplimit)
+ {
+ result = 0;
+ warning ("Remote fetch threadlist -infinite loop-\n");
+ break;
+ }
+ if (!remote_get_threadlist (startflag, &nextthread, MAXTHREADLISTRESULTS,
+ &done, &result_count, resultthreadlist))
+ {
+ result = 0;
+ break;
+ }
+ /* clear for later iterations */
+ startflag = 0;
+ /* Setup to resume next batch of thread references, set nextthread. */
+ if (result_count >= 1)
+ copy_threadref (&nextthread, &resultthreadlist[result_count - 1]);
+ i = 0;
+ while (result_count--)
+ if (!(result = (*stepfunction) (&resultthreadlist[i++], context)))
+ break;
+ }
+ return result;
+}
+
+static int
+remote_newthread_step (ref, context)
+ threadref *ref;
+ void *context;
+{
+ int pid;
+
+ pid = threadref_to_int (ref);
+ if (!in_thread_list (pid))
+ add_thread (pid);
+ return 1; /* continue iterator */
+}
+
+#define CRAZY_MAX_THREADS 1000
+
+static int
+remote_current_thread (oldpid)
+ int oldpid;
+{
+ char buf[PBUFSIZ];
+
+ putpkt ("qC");
+ getpkt (buf, 0);
+ if (buf[0] == 'Q' && buf[1] == 'C')
+ return strtol (&buf[2], NULL, 16);
+ else
+ return oldpid;
+}
+
+int
+remote_find_new_threads ()
+{
+ int ret;
+
+ ret = remote_threadlist_iterator (remote_newthread_step, 0,
+ CRAZY_MAX_THREADS);
+ if (inferior_pid == MAGIC_NULL_PID) /* ack ack ack */
+ inferior_pid = remote_current_thread (inferior_pid);
+ return ret;
+}
+
+/* Initialize the thread vector which is used by threads.c */
+/* The thread stub is a package, it has an initializer */
+
+static void
+init_remote_threads ()
+{
+ remote_thread_vec.find_new_threads = remote_find_new_threads;
+ remote_thread_vec.get_thread_info = adapt_remote_get_threadinfo;
+}
+
+
/* Restart the remote side; this is an extended protocol operation. */
static void
@@ -400,8 +1293,8 @@ remote_close (quitting)
static void
get_offsets ()
{
- char buf[PBUFSIZ];
- int nvals;
+ char buf[PBUFSIZ], *ptr;
+ int lose;
CORE_ADDR text_addr, data_addr, bss_addr;
struct section_offsets *offs;
@@ -410,17 +1303,51 @@ get_offsets ()
getpkt (buf, 0);
if (buf[0] == '\000')
- return; /* Return silently. Stub doesn't support this
- command. */
+ return; /* Return silently. Stub doesn't support
+ this command. */
if (buf[0] == 'E')
{
warning ("Remote failure reply: %s", buf);
return;
}
- nvals = sscanf (buf, "Text=%lx;Data=%lx;Bss=%lx", &text_addr, &data_addr,
- &bss_addr);
- if (nvals != 3)
+ /* Pick up each field in turn. This used to be done with scanf, but
+ scanf will make trouble if CORE_ADDR size doesn't match
+ conversion directives correctly. The following code will work
+ with any size of CORE_ADDR. */
+ text_addr = data_addr = bss_addr = 0;
+ ptr = buf;
+ lose = 0;
+
+ if (strncmp (ptr, "Text=", 5) == 0)
+ {
+ ptr += 5;
+ /* Don't use strtol, could lose on big values. */
+ while (*ptr && *ptr != ';')
+ text_addr = (text_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (!lose && strncmp (ptr, ";Data=", 6) == 0)
+ {
+ ptr += 6;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (lose)
error ("Malformed response to offset query, %s", buf);
if (symfile_objfile == NULL)
@@ -450,7 +1377,7 @@ get_offsets ()
static int
remote_start_remote (dummy)
- char *dummy;
+ PTR dummy;
{
immediate_quit = 1; /* Allow user to interrupt it */
@@ -460,6 +1387,8 @@ remote_start_remote (dummy)
/* Let the stub know that we want it to return the thread. */
set_thread (-1, 0);
+ inferior_pid = remote_current_thread (inferior_pid);
+
get_offsets (); /* Get text, data & bss offsets */
putpkt ("?"); /* initiate a query from remote machine */
@@ -477,7 +1406,7 @@ remote_open (name, from_tty)
char *name;
int from_tty;
{
- remote_open_1 (name, from_tty, &remote_ops);
+ remote_open_1 (name, from_tty, &remote_ops, 0);
}
/* Open a connection to a remote debugger using the extended
@@ -488,29 +1417,23 @@ extended_remote_open (name, from_tty)
char *name;
int from_tty;
{
- char buf[PBUFSIZ];
-
- /* Do the basic remote open stuff. */
- remote_open_1 (name, from_tty, &extended_remote_ops);
-
- /* Now tell the remote that we're using the extended protocol. */
- putpkt ("!");
- getpkt (buf, 0);
-
+ remote_open_1 (name, from_tty, &extended_remote_ops, 1/*extended_p*/);
}
/* Generic code for opening a connection to a remote target. */
+
static DCACHE *remote_dcache;
static void
-remote_open_1 (name, from_tty, target)
+remote_open_1 (name, from_tty, target, extended_p)
char *name;
int from_tty;
struct target_ops *target;
+ int extended_p;
{
if (name == 0)
- error ("To open a remote debug connection, you need to specify what serial\n\
-device is attached to the remote system (e.g. /dev/ttya).");
+ error ("To open a remote debug connection, you need to specify what\n\
+serial device is attached to the remote system (e.g. /dev/ttya).");
target_preopen (from_tty);
@@ -546,28 +1469,50 @@ device is attached to the remote system (e.g. /dev/ttya).");
}
push_target (target); /* Switch to using remote target now */
- /* Start out by trying the 'P' request to set registers. We set this each
- time that we open a new target so that if the user switches from one
- stub to another, we can (if the target is closed and reopened) cope. */
+ /* The target vector does not have the thread functions in it yet,
+ so we use this function to call back into the thread module and
+ register the thread vector and its contained functions. */
+ bind_target_thread_vector (&remote_thread_vec);
+
+ /* Start out by trying the 'P' request to set registers. We set
+ this each time that we open a new target so that if the user
+ switches from one stub to another, we can (if the target is
+ closed and reopened) cope. */
stub_supports_P = 1;
general_thread = -2;
cont_thread = -2;
- /* Without this, some commands which require an active target (such as kill)
- won't work. This variable serves (at least) double duty as both the pid
- of the target process (if it has such), and as a flag indicating that a
- target is active. These functions should be split out into seperate
- variables, especially since GDB will someday have a notion of debugging
- several processes. */
+ /* Force remote_write_bytes to check whether target supports
+ binary downloading. */
+ remote_binary_checked = 0;
+
+ /* Without this, some commands which require an active target (such
+ as kill) won't work. This variable serves (at least) double duty
+ as both the pid of the target process (if it has such), and as a
+ flag indicating that a target is active. These functions should
+ be split out into seperate variables, especially since GDB will
+ someday have a notion of debugging several processes. */
- inferior_pid = 42000;
+ inferior_pid = MAGIC_NULL_PID;
/* Start the remote connection; if error (0), discard this target.
In particular, if the user quits, be sure to discard it
(we'd be in an inconsistent state otherwise). */
- if (!catch_errors (remote_start_remote, (char *)0,
- "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
- pop_target();
+ if (!catch_errors (remote_start_remote, NULL,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ pop_target ();
+ return;
+ }
+
+ if (extended_p)
+ {
+ /* tell the remote that we're using the extended protocol. */
+ char buf[PBUFSIZ];
+ putpkt ("!");
+ getpkt (buf, 0);
+ }
}
/* This takes a program previously attached to and detaches it. After
@@ -596,7 +1541,7 @@ remote_detach (args, from_tty)
/* Convert hex digit A to a number. */
-static int
+int
fromhex (a)
int a;
{
@@ -604,6 +1549,8 @@ fromhex (a)
return a - '0';
else if (a >= 'a' && a <= 'f')
return a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
else
error ("Reply contains invalid hex digit %d", a);
}
@@ -623,7 +1570,8 @@ tohex (nib)
/* Tell the remote machine to resume. */
static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
-int last_sent_step;
+
+static int last_sent_step;
static void
remote_resume (pid, step, siggnal)
@@ -633,15 +1581,20 @@ remote_resume (pid, step, siggnal)
char buf[PBUFSIZ];
if (pid == -1)
- set_thread (inferior_pid, 0);
+ set_thread (0, 0); /* run any thread */
else
- set_thread (pid, 0);
+ set_thread (pid, 0); /* run this thread */
dcache_flush (remote_dcache);
last_sent_signal = siggnal;
last_sent_step = step;
+ /* A hook for when we need to do something at the last moment before
+ resumption. */
+ if (target_resume_hook)
+ (*target_resume_hook) ();
+
if (siggnal != TARGET_SIGNAL_0)
{
buf[0] = step ? 'S' : 'C';
@@ -658,35 +1611,39 @@ remote_resume (pid, step, siggnal)
/* Send ^C to target to halt it. Target will respond, and send us a
packet. */
+static void (*ofunc) PARAMS ((int));
+
static void
remote_interrupt (signo)
int signo;
{
- /* If this doesn't work, try more severe steps. */
- signal (signo, remote_interrupt_twice);
-
- if (remote_debug)
- printf_unfiltered ("remote_interrupt called\n");
-
- /* Send a break or a ^C, depending on user preference. */
- if (remote_break)
- SERIAL_SEND_BREAK (remote_desc);
- else
- SERIAL_WRITE (remote_desc, "\003", 1);
+ remote_stop ();
+ signal (signo, remote_interrupt);
}
-
-static void (*ofunc)();
-
-/* The user typed ^C twice. */
+
static void
-remote_interrupt_twice (signo)
- int signo;
+remote_stop ()
{
- signal (signo, ofunc);
-
- interrupt_query ();
+ if (!interrupted_already)
+ {
+ /* Send a break or a ^C, depending on user preference. */
+ interrupted_already = 1;
- signal (signo, remote_interrupt);
+ if (remote_debug)
+ printf_unfiltered ("remote_stop called\n");
+
+ if (remote_break)
+ SERIAL_SEND_BREAK (remote_desc);
+ else
+ SERIAL_WRITE (remote_desc, "\003", 1);
+ }
+ else
+ {
+ signal (SIGINT, ofunc);
+ interrupt_query ();
+ signal (SIGINT, remote_interrupt);
+ interrupted_already = 0;
+ }
}
/* Ask the user what to do when an interrupt is received. */
@@ -707,12 +1664,31 @@ Give up (and stop debugging it)? "))
}
/* If nonzero, ignore the next kill. */
+
int kill_kludge;
-/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would.
- Returns "pid" (though it's not clear what, if anything, that
- means in the case of this target). */
+void
+remote_console_output (msg)
+ char *msg;
+{
+ char *p;
+
+ for (p = msg; *p; p +=2)
+ {
+ char tb[2];
+ char c = fromhex (p[0]) * 16 + fromhex (p[1]);
+ tb[0] = c;
+ tb[1] = 0;
+ if (target_output_hook)
+ target_output_hook (tb);
+ else
+ fputs_filtered (tb, gdb_stdout);
+ }
+}
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. Returns "pid" (though it's not clear
+ what, if anything, that means in the case of this target). */
static int
remote_wait (pid, status)
@@ -729,10 +1705,16 @@ remote_wait (pid, status)
{
unsigned char *p;
- ofunc = (void (*)()) signal (SIGINT, remote_interrupt);
+ interrupted_already = 0;
+ ofunc = signal (SIGINT, remote_interrupt);
getpkt ((char *) buf, 1);
signal (SIGINT, ofunc);
+ /* This is a hook for when we need to do something (perhaps the
+ collection of trace data) every time the target stops. */
+ if (target_wait_loop_hook)
+ (*target_wait_loop_hook) ();
+
switch (buf[0])
{
case 'E': /* Error of some sort */
@@ -750,7 +1732,6 @@ remote_wait (pid, status)
n... = register number
r... = register contents
*/
-
p = &buf[3]; /* after Txx */
while (*p)
@@ -758,20 +1739,22 @@ remote_wait (pid, status)
unsigned char *p1;
char *p_temp;
- regno = strtol ((const char *) p, &p_temp, 16); /* Read the register number */
+ /* Read the register number */
+ regno = strtol ((const char *) p, &p_temp, 16);
p1 = (unsigned char *)p_temp;
- if (p1 == p)
+ if (p1 == p) /* No register number present here */
{
p1 = (unsigned char *) strchr ((const char *) p, ':');
if (p1 == NULL)
- warning ("Malformed packet (missing colon): %s\n\
+ warning ("Malformed packet(a) (missing colon): %s\n\
Packet: '%s'\n",
p, buf);
if (strncmp ((const char *) p, "thread", p1 - p) == 0)
{
- thread_num = strtol ((const char *) ++p1, &p_temp, 16);
- p = (unsigned char *)p_temp;
+ p_temp = unpack_varlen_hex (++p1, &thread_num);
+ record_currthread (thread_num);
+ p = (unsigned char *) p_temp;
}
}
else
@@ -779,7 +1762,7 @@ Packet: '%s'\n",
p = p1;
if (*p++ != ':')
- warning ("Malformed packet (missing colon): %s\n\
+ warning ("Malformed packet(b) (missing colon): %s\n\
Packet: '%s'\n",
p, buf);
@@ -799,7 +1782,10 @@ Packet: '%s'\n",
}
if (*p++ != ';')
- warning ("Remote register badly formatted: %s", buf);
+ {
+ warning ("Remote register badly formatted: %s", buf);
+ warning (" here: %s",p);
+ }
}
}
/* fall through */
@@ -824,17 +1810,7 @@ Packet: '%s'\n",
goto got_status;
case 'O': /* Console output */
- for (p = buf + 1; *p; p +=2)
- {
- char tb[2];
- char c = fromhex (p[0]) * 16 + fromhex (p[1]);
- tb[0] = c;
- tb[1] = 0;
- if (target_output_hook)
- target_output_hook (tb);
- else
- fputs_filtered (tb, gdb_stdout);
- }
+ remote_console_output (buf + 1);
continue;
case '\0':
if (last_sent_signal != TARGET_SIGNAL_0)
@@ -864,10 +1840,11 @@ Packet: '%s'\n",
/* Initial thread value can only be acquired via wait, so deal with
this marker which is used before the first thread value is
acquired. */
- if (inferior_pid == 42000)
+ if (inferior_pid == MAGIC_NULL_PID)
{
inferior_pid = thread_num;
- add_thread (inferior_pid);
+ if (!in_thread_list (inferior_pid))
+ add_thread (inferior_pid);
}
return thread_num;
}
@@ -875,10 +1852,12 @@ Packet: '%s'\n",
}
/* Number of bytes of registers this stub implements. */
+
static int register_bytes_found;
/* Read the remote registers into the block REGS. */
/* Currently we just read all the registers, so we don't use regno. */
+
/* ARGSUSED */
static void
remote_fetch_registers (regno)
@@ -894,6 +1873,9 @@ remote_fetch_registers (regno)
sprintf (buf, "g");
remote_send (buf);
+ if (remote_register_buf_size == 0)
+ remote_register_buf_size = strlen (buf);
+
/* Unimplemented registers read as all bits zero. */
memset (regs, 0, REGISTER_BYTES);
@@ -901,7 +1883,8 @@ remote_fetch_registers (regno)
in the buffer is not a hex character, assume that has happened
and try to fetch another packet to read. */
while ((buf[0] < '0' || buf[0] > '9')
- && (buf[0] < 'a' || buf[0] > 'f'))
+ && (buf[0] < 'a' || buf[0] > 'f')
+ && buf[0] != 'x') /* New: unavailable register value */
{
if (remote_debug)
printf_unfiltered ("Bad register packet; fetching a new packet\n");
@@ -924,7 +1907,10 @@ remote_fetch_registers (regno)
print a second warning. */
goto supply_them;
}
- regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ if (p[0] == 'x' && p[1] == 'x')
+ regs[i] = 0; /* 'x' */
+ else
+ regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
p += 2;
}
@@ -936,10 +1922,14 @@ remote_fetch_registers (regno)
warning ("Remote reply is too short: %s", buf);
#endif
}
-
- supply_them:
+
+ supply_them:
for (i = 0; i < NUM_REGS; i++)
+ {
supply_register (i, &regs[REGISTER_BYTE(i)]);
+ if (buf[REGISTER_BYTE(i) * 2] == 'x')
+ register_valid[i] = -1; /* register value not available */
+ }
}
/* Prepare to store registers. Since we may send them all (using a
@@ -1010,9 +2000,8 @@ remote_store_registers (regno)
remote_send (buf);
}
-/*
- Use of the data cache *used* to be disabled because it loses for looking at
- and changing hardware I/O ports and the like. Accepting `volatile'
+/* Use of the data cache *used* to be disabled because it loses for looking
+ at and changing hardware I/O ports and the like. Accepting `volatile'
would perhaps be one way to fix it. Another idea would be to use the
executable file for the text segment (for all SEC_CODE sections?
For all SEC_READONLY sections?). This has problems if you want to
@@ -1020,8 +2009,7 @@ remote_store_registers (regno)
clobbered memory, user downloaded the wrong thing).
Because it speeds so much up, it's now enabled, if you're playing
- with registers you turn it of (set remotecache 0)
-*/
+ with registers you turn it of (set remotecache 0). */
/* Read a word from remote address ADDR and return it.
This goes through the data cache. */
@@ -1047,6 +2035,98 @@ remote_store_word (addr, word)
#endif /* 0 (unused?) */
+
+/* Return the number of hex digits in num. */
+
+static int
+hexnumlen (num)
+ ULONGEST num;
+{
+ int i;
+
+ for (i = 0; num != 0; i++)
+ num >>= 4;
+
+ return max (i, 1);
+}
+
+/* Set BUF to the hex digits representing NUM. */
+
+static int
+hexnumstr (buf, num)
+ char *buf;
+ ULONGEST num;
+{
+ int i;
+ int len = hexnumlen (num);
+
+ buf[len] = '\0';
+
+ for (i = len - 1; i >= 0; i--)
+ {
+ buf[i] = "0123456789abcdef" [(num & 0xf)];
+ num >>= 4;
+ }
+
+ return len;
+}
+
+/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
+
+static CORE_ADDR
+remote_address_masked (addr)
+ CORE_ADDR addr;
+{
+ if (remote_address_size > 0
+ && remote_address_size < (sizeof (ULONGEST) * 8))
+ {
+ /* Only create a mask when that mask can safely be constructed
+ in a ULONGEST variable. */
+ ULONGEST mask = 1;
+ mask = (mask << remote_address_size) - 1;
+ addr &= mask;
+ }
+ return addr;
+}
+
+/* Determine whether the remote target supports binary downloading.
+ This is accomplished by sending a no-op memory write of zero length
+ to the target at the specified address. It does not suffice to send
+ the whole packet, since many stubs strip the eighth bit and subsequently
+ compute a wrong checksum, which causes real havoc with remote_write_bytes. */
+static void
+check_binary_download (addr)
+ CORE_ADDR addr;
+{
+ if (remote_binary_download && !remote_binary_checked)
+ {
+ char buf[PBUFSIZ], *p;
+ remote_binary_checked = 1;
+
+ p = buf;
+ *p++ = 'X';
+ p += hexnumstr (p, (ULONGEST) addr);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) 0);
+ *p++ = ':';
+ *p = '\0';
+
+ putpkt_binary (buf, (int) (p - buf));
+ getpkt (buf, 0);
+
+ if (buf[0] == '\0')
+ remote_binary_download = 0;
+ }
+
+ if (remote_debug)
+ {
+ if (remote_binary_download)
+ printf_unfiltered ("binary downloading suppported by target\n");
+ else
+ printf_unfiltered ("binary downloading NOT suppported by target\n");
+ }
+}
+
/* Write memory data directly to the remote machine.
This does not inform the data cache; the data cache uses this.
MEMADDR is the address in the remote memory space.
@@ -1061,36 +2141,102 @@ remote_write_bytes (memaddr, myaddr, len)
char *myaddr;
int len;
{
- char buf[PBUFSIZ];
- int i;
- char *p;
- int done;
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
+
+ /* Verify that the target can support a binary download */
+ check_binary_download (memaddr);
+
/* Chop the transfer down if necessary */
- done = 0;
- while (done < len)
+ max_buf_size = min (remote_write_size, PBUFSIZ);
+ if (remote_register_buf_size != 0)
+ max_buf_size = min (max_buf_size, remote_register_buf_size);
+
+ /* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
+ max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
+
+ origlen = len;
+ while (len > 0)
{
- int todo = len - done;
- int cando = PBUFSIZ /2 - 32; /* number of bytes that will fit. */
- if (todo > cando)
- todo = cando;
+ unsigned char buf[PBUFSIZ];
+ unsigned char *p, *plen;
+ int todo;
+ int i;
+
+ /* construct "M"<memaddr>","<len>":" */
+ /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
+ memaddr = remote_address_masked (memaddr);
+ p = buf;
+ if (remote_binary_download)
+ {
+ *p++ = 'X';
+ todo = min (len, max_buf_size);
+ }
+ else
+ {
+ *p++ = 'M';
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
+ }
- /* FIXME-32x64: Need a version of print_address_numeric which puts the
- result in a buffer like sprintf. */
- sprintf (buf, "M%lx,%x:", (unsigned long) memaddr + done, todo);
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
- /* We send target system values byte by byte, in increasing byte addresses,
- each byte encoded as two hex characters. */
+ plen = p; /* remember where len field goes */
+ p += hexnumstr (p, (ULONGEST) todo);
+ *p++ = ':';
+ *p = '\0';
- p = buf + strlen (buf);
- for (i = 0; i < todo; i++)
+ /* We send target system values byte by byte, in increasing byte
+ addresses, each byte encoded as two hex characters (or one
+ binary character). */
+ if (remote_binary_download)
+ {
+ int escaped = 0;
+ for (i = 0;
+ (i < todo) && (i + escaped) < (max_buf_size - 2);
+ i++)
+ {
+ switch (myaddr[i] & 0xff)
+ {
+ case '$':
+ case '#':
+ case 0x7d:
+ /* These must be escaped */
+ escaped++;
+ *p++ = 0x7d;
+ *p++ = (myaddr[i] & 0xff) ^ 0x20;
+ break;
+ default:
+ *p++ = myaddr[i] & 0xff;
+ break;
+ }
+ }
+
+ if (i < todo)
+ {
+ /* Escape chars have filled up the buffer prematurely,
+ and we have actually sent fewer bytes than planned.
+ Fix-up the length field of the packet. */
+
+ /* FIXME: will fail if new len is a shorter string than
+ old len. */
+
+ plen += hexnumstr (plen, (ULONGEST) i);
+ *plen++ = ':';
+ }
+ }
+ else
{
- *p++ = tohex ((myaddr[i + done] >> 4) & 0xf);
- *p++ = tohex (myaddr[i + done] & 0xf);
+ for (i = 0; i < todo; i++)
+ {
+ *p++ = tohex ((myaddr[i] >> 4) & 0xf);
+ *p++ = tohex (myaddr[i] & 0xf);
+ }
+ *p = '\0';
}
- *p = '\0';
- putpkt (buf);
+ putpkt_binary (buf, (int) (p - buf));
getpkt (buf, 0);
if (buf[0] == 'E')
@@ -1102,9 +2248,14 @@ remote_write_bytes (memaddr, myaddr, len)
errno = EIO;
return 0;
}
- done += todo;
+
+ /* Increment by i, not by todo, in case escape chars
+ caused us to send fewer bytes than we'd planned. */
+ myaddr += i;
+ memaddr += i;
+ len -= i;
}
- return len;
+ return origlen;
}
/* Read memory data directly from the remote machine.
@@ -1121,28 +2272,35 @@ remote_read_bytes (memaddr, myaddr, len)
char *myaddr;
int len;
{
- char buf[PBUFSIZ];
- int i;
- char *p;
- int done;
- /* Chop transfer down if neccessary */
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
-#if 0
- /* FIXME: This is wrong for larger packets */
- if (len > PBUFSIZ / 2 - 1)
- abort ();
-#endif
- done = 0;
- while (done < len)
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = min (remote_write_size, PBUFSIZ);
+ if (remote_register_buf_size != 0)
+ max_buf_size = min (max_buf_size, remote_register_buf_size);
+
+ origlen = len;
+ while (len > 0)
{
- int todo = len - done;
- int cando = PBUFSIZ / 2 - 32; /* number of bytes that will fit. */
- if (todo > cando)
- todo = cando;
-
- /* FIXME-32x64: Need a version of print_address_numeric which puts the
- result in a buffer like sprintf. */
- sprintf (buf, "m%lx,%x", (unsigned long) memaddr + done, todo);
+ char buf[PBUFSIZ];
+ char *p;
+ int todo;
+ int i;
+
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
+
+ /* construct "m"<memaddr>","<len>" */
+ /* sprintf (buf, "m%lx,%x", (unsigned long) memaddr, todo); */
+ memaddr = remote_address_masked (memaddr);
+ p = buf;
+ *p++ = 'm';
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) todo);
+ *p = '\0';
+
putpkt (buf);
getpkt (buf, 0);
@@ -1163,31 +2321,45 @@ remote_read_bytes (memaddr, myaddr, len)
for (i = 0; i < todo; i++)
{
if (p[0] == 0 || p[1] == 0)
- /* Reply is short. This means that we were able to read only part
- of what we wanted to. */
- return i + done;
- myaddr[i + done] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ /* Reply is short. This means that we were able to read
+ only part of what we wanted to. */
+ return i + (origlen - len);
+ myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
p += 2;
}
- done += todo;
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
}
- return len;
+ return origlen;
}
-/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
- to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
- nonzero. Returns length of data written or read; 0 for error. */
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. */
/* ARGSUSED */
static int
-remote_xfer_memory(memaddr, myaddr, len, should_write, target)
+remote_xfer_memory (memaddr, myaddr, len, should_write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int should_write;
struct target_ops *target; /* ignored */
{
- return dcache_xfer_memory (remote_dcache, memaddr, myaddr, len, should_write);
+#ifdef REMOTE_TRANSLATE_XFER_ADDRESS
+ CORE_ADDR targaddr;
+ int targlen;
+ REMOTE_TRANSLATE_XFER_ADDRESS (memaddr, len, targaddr, targlen);
+ if (targlen == 0)
+ return 0;
+ memaddr = targaddr;
+ len = targlen;
+#endif
+
+ return dcache_xfer_memory (remote_dcache, memaddr, myaddr,
+ len, should_write);
}
@@ -1298,9 +2470,8 @@ readchar (timeout)
}
}
-/* Send the command in BUF to the remote machine,
- and read the reply into BUF.
- Report an error if we get an error reply. */
+/* Send the command in BUF to the remote machine, and read the reply
+ into BUF. Report an error if we get an error reply. */
static void
remote_send (buf)
@@ -1313,17 +2484,39 @@ remote_send (buf)
error ("Remote failure reply: %s", buf);
}
-/* Send a packet to the remote machine, with error checking.
- The data of the packet is in BUF. */
+/* Display a null-terminated packet on stdout, for debugging, using C
+ string notation. */
-static int
+static void
+print_packet (buf)
+ char *buf;
+{
+ puts_filtered ("\"");
+ while (*buf)
+ gdb_printchar (*buf++, gdb_stdout, '"');
+ puts_filtered ("\"");
+}
+
+int
putpkt (buf)
char *buf;
{
+ return putpkt_binary (buf, strlen (buf));
+}
+
+/* Send a packet to the remote machine, with error checking. The data
+ of the packet is in BUF. The string in BUF can be at most PBUFSIZ - 5
+ to account for the $, # and checksum, and for a possible /0 if we are
+ debugging (remote_debug) and want to print the sent packet as a string */
+
+static int
+putpkt_binary (buf, cnt)
+ char *buf;
+ int cnt;
+{
int i;
unsigned char csum = 0;
char buf2[PBUFSIZ];
- int cnt = strlen (buf);
int ch;
int tcount = 0;
char *p;
@@ -1332,7 +2525,7 @@ putpkt (buf)
and giving it a checksum. */
if (cnt > (int) sizeof (buf2) - 5) /* Prosanity check */
- abort();
+ abort ();
p = buf2;
*p++ = '$';
@@ -1356,7 +2549,7 @@ putpkt (buf)
{
*p = '\0';
printf_unfiltered ("Sending packet: %s...", buf2);
- gdb_flush(gdb_stdout);
+ gdb_flush (gdb_stdout);
}
if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
perror_with_name ("putpkt: write failed");
@@ -1385,7 +2578,7 @@ putpkt (buf)
{
case '+':
if (remote_debug)
- printf_unfiltered("Ack\n");
+ printf_unfiltered ("Ack\n");
return 1;
case SERIAL_TIMEOUT:
tcount ++;
@@ -1396,8 +2589,8 @@ putpkt (buf)
{
char junkbuf[PBUFSIZ];
- /* It's probably an old response, and we're out of sync. Just
- gobble up the packet and ignore it. */
+ /* It's probably an old response, and we're out of sync.
+ Just gobble up the packet and ignore it. */
getpkt (junkbuf, 0);
continue; /* Now, go look for + */
}
@@ -1418,10 +2611,10 @@ putpkt (buf)
#if 0
/* This is wrong. If doing a long backtrace, the user should be
- able to get out next time we call QUIT, without anything as violent
- as interrupt_query. If we want to provide a way out of here
- without getting to the next QUIT, it should be based on hitting
- ^C twice as in remote_wait. */
+ able to get out next time we call QUIT, without anything as
+ violent as interrupt_query. If we want to provide a way out of
+ here without getting to the next QUIT, it should be based on
+ hitting ^C twice as in remote_wait. */
if (quit_flag)
{
quit_flag = 0;
@@ -1431,9 +2624,9 @@ putpkt (buf)
}
}
-/* Come here after finding the start of the frame. Collect the rest into BUF,
- verifying the checksum, length, and handling run-length compression.
- Returns 0 on any error, 1 on success. */
+/* Come here after finding the start of the frame. Collect the rest
+ into BUF, verifying the checksum, length, and handling run-length
+ compression. Returns 0 on any error, 1 on success. */
static int
read_frame (buf)
@@ -1519,12 +2712,12 @@ read_frame (buf)
}
}
-/* Read a packet from the remote machine, with error checking,
- and store it in BUF. BUF is expected to be of size PBUFSIZ.
- If FOREVER, wait forever rather than timing out; this is used
- while the target is executing user code. */
+/* Read a packet from the remote machine, with error checking, and
+ store it in BUF. BUF is expected to be of size PBUFSIZ. If
+ FOREVER, wait forever rather than timing out; this is used while
+ the target is executing user code. */
-static void
+void
getpkt (buf, forever)
char *buf;
int forever;
@@ -1587,7 +2780,7 @@ getpkt (buf, forever)
if (val == 1)
{
if (remote_debug)
- fprintf_unfiltered (gdb_stderr, "Packet received: %s\n", buf);
+ fprintf_unfiltered (gdb_stdout, "Packet received: %s\n", buf);
SERIAL_WRITE (remote_desc, "+", 1);
return;
}
@@ -1617,7 +2810,7 @@ remote_kill ()
/* Use catch_errors so the user can quit from gdb even when we aren't on
speaking terms with the remote system. */
- catch_errors (putpkt, "k", "", RETURN_MASK_ERROR);
+ catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
/* Don't wait for it to die. I'm not really sure it matters whether
we do or not. For the existing stubs, kill is a noop. */
@@ -1684,19 +2877,33 @@ extended_remote_create_inferior (exec_file, args, env)
}
-#ifdef REMOTE_BREAKPOINT
-
/* On some machines, e.g. 68k, we may use a different breakpoint instruction
- than other targets. */
-static unsigned char break_insn[] = REMOTE_BREAKPOINT;
+ than other targets; in those use REMOTE_BREAKPOINT instead of just
+ BREAKPOINT. Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT
+ and BIG_REMOTE_BREAKPOINT. If none of these are defined, we just call
+ the standard routines that are in mem-break.c. */
+
+/* FIXME, these ought to be done in a more dynamic fashion. For instance,
+ the choice of breakpoint instruction affects target program design and
+ vice versa, and by making it user-tweakable, the special code here
+ goes away and we need fewer special GDB configurations. */
+
+#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT)
+#define REMOTE_BREAKPOINT
+#endif
-#else /* No REMOTE_BREAKPOINT. */
+#ifdef REMOTE_BREAKPOINT
-/* Same old breakpoint instruction. This code does nothing different
- than mem-break.c. */
-static unsigned char break_insn[] = BREAKPOINT;
+/* If the target isn't bi-endian, just pretend it is. */
+#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT)
+#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#endif
-#endif /* No REMOTE_BREAKPOINT. */
+static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT;
+static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT;
+
+#endif /* REMOTE_BREAKPOINT */
/* Insert a breakpoint on targets that don't have any better breakpoint
support. We read the contents of the target location and stash it,
@@ -1711,14 +2918,25 @@ remote_insert_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
+#ifdef REMOTE_BREAKPOINT
int val;
- val = target_read_memory (addr, contents_cache, sizeof break_insn);
+ val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
if (val == 0)
- val = target_write_memory (addr, (char *)break_insn, sizeof break_insn);
+ {
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ val = target_write_memory (addr, (char *) big_break_insn,
+ sizeof big_break_insn);
+ else
+ val = target_write_memory (addr, (char *) little_break_insn,
+ sizeof little_break_insn);
+ }
return val;
+#else
+ return memory_insert_breakpoint (addr, contents_cache);
+#endif /* REMOTE_BREAKPOINT */
}
static int
@@ -1726,114 +2944,530 @@ remote_remove_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
- return target_write_memory (addr, contents_cache, sizeof break_insn);
+#ifdef REMOTE_BREAKPOINT
+ return target_write_memory (addr, contents_cache, sizeof big_break_insn);
+#else
+ return memory_remove_breakpoint (addr, contents_cache);
+#endif /* REMOTE_BREAKPOINT */
}
-
-/* Define the target subroutine names */
-struct target_ops remote_ops = {
- "remote", /* to_shortname */
- "Remote serial target in gdb-specific protocol", /* to_longname */
- "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
- remote_open, /* to_open */
- remote_close, /* to_close */
- NULL, /* to_attach */
- remote_detach, /* to_detach */
- remote_resume, /* to_resume */
- remote_wait, /* to_wait */
- remote_fetch_registers, /* to_fetch_registers */
- remote_store_registers, /* to_store_registers */
- remote_prepare_to_store, /* to_prepare_to_store */
- remote_xfer_memory, /* to_xfer_memory */
- remote_files_info, /* to_files_info */
- remote_insert_breakpoint, /* to_insert_breakpoint */
- remote_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- remote_kill, /* to_kill */
- generic_load, /* to_load */
- NULL, /* to_lookup_symbol */
- NULL, /* to_create_inferior */
- remote_mourn, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- remote_thread_alive, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
-
-struct target_ops extended_remote_ops = {
- "extended-remote", /* to_shortname */
- "Extended remote serial target in gdb-specific protocol",/* to_longname */
- "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
- extended_remote_open, /* to_open */
- remote_close, /* to_close */
- NULL, /* to_attach */
- remote_detach, /* to_detach */
- remote_resume, /* to_resume */
- remote_wait, /* to_wait */
- remote_fetch_registers, /* to_fetch_registers */
- remote_store_registers, /* to_store_registers */
- remote_prepare_to_store, /* to_prepare_to_store */
- remote_xfer_memory, /* to_xfer_memory */
- remote_files_info, /* to_files_info */
-
- remote_insert_breakpoint, /* to_insert_breakpoint */
- remote_remove_breakpoint, /* to_remove_breakpoint */
-
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- remote_kill, /* to_kill */
- generic_load, /* to_load */
- NULL, /* to_lookup_symbol */
- extended_remote_create_inferior,/* to_create_inferior */
- extended_remote_mourn, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- remote_thread_alive, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+/* Some targets are only capable of doing downloads, and afterwards
+ they switch to the remote serial protocol. This function provides
+ a clean way to get from the download target to the remote target.
+ It's basically just a wrapper so that we don't have to expose any
+ of the internal workings of remote.c.
+
+ Prior to calling this routine, you should shutdown the current
+ target code, else you will get the "A program is being debugged
+ already..." message. Usually a call to pop_target() suffices. */
+
+void
+push_remote_target (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ printf_filtered ("Switching to remote protocol\n");
+ remote_open (name, from_tty);
+}
+
+/* Other targets want to use the entire remote serial module but with
+ certain remote_ops overridden. */
+
+void
+open_remote_target (name, from_tty, target, extended_p)
+ char *name;
+ int from_tty;
+ struct target_ops *target;
+ int extended_p;
+{
+ printf_filtered ("Selecting the %sremote protocol\n",
+ (extended_p ? "extended-" : ""));
+ remote_open_1 (name, from_tty, target, extended_p);
+}
+
+/* Table used by the crc32 function to calcuate the checksum. */
+
+static unsigned long crc32_table[256] = {0, 0};
+
+static unsigned long
+crc32 (buf, len, crc)
+ unsigned char *buf;
+ int len;
+ unsigned int crc;
+{
+ if (! crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned int c;
+
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (len--)
+ {
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+ buf++;
+ }
+ return crc;
+}
+
+/* compare-sections command
+
+ With no arguments, compares each loadable section in the exec bfd
+ with the same memory range on the target, and reports mismatches.
+ Useful for verifying the image on the target against the exec file.
+ Depends on the target understanding the new "qCRC:" request. */
+
+static void
+compare_sections_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ asection *s;
+ unsigned long host_crc, target_crc;
+ extern bfd *exec_bfd;
+ struct cleanup *old_chain;
+ char *tmp, *sectdata, *sectname, buf[PBUFSIZ];
+ bfd_size_type size;
+ bfd_vma lma;
+ int matched = 0;
+ int mismatched = 0;
+
+ if (!exec_bfd)
+ error ("command cannot be used without an exec file");
+ if (!current_target.to_shortname ||
+ strcmp (current_target.to_shortname, "remote") != 0)
+ error ("command can only be used with remote target");
+
+ for (s = exec_bfd->sections; s; s = s->next)
+ {
+ if (!(s->flags & SEC_LOAD))
+ continue; /* skip non-loadable section */
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size == 0)
+ continue; /* skip zero-length section */
+
+ sectname = (char *) bfd_get_section_name (exec_bfd, s);
+ if (args && strcmp (args, sectname) != 0)
+ continue; /* not the section selected by user */
+
+ matched = 1; /* do this section */
+ lma = s->lma;
+ /* FIXME: assumes lma can fit into long */
+ sprintf (buf, "qCRC:%lx,%lx", (long) lma, (long) size);
+ putpkt (buf);
+
+ /* be clever; compute the host_crc before waiting for target reply */
+ sectdata = xmalloc (size);
+ old_chain = make_cleanup (free, sectdata);
+ bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
+ host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
+
+ getpkt (buf, 0);
+ if (buf[0] == 'E')
+ error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
+ sectname, lma, lma + size);
+ if (buf[0] != 'C')
+ error ("remote target does not support this operation");
+
+ for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
+ target_crc = target_crc * 16 + fromhex (*tmp);
+
+ printf_filtered ("Section %s, range 0x%08x -- 0x%08x: ",
+ sectname, lma, lma + size);
+ if (host_crc == target_crc)
+ printf_filtered ("matched.\n");
+ else
+ {
+ printf_filtered ("MIS-MATCHED!\n");
+ mismatched++;
+ }
+
+ do_cleanups (old_chain);
+ }
+ if (mismatched > 0)
+ warning ("One or more sections of the remote executable does not match\n\
+the loaded file\n");
+ if (args && !matched)
+ printf_filtered ("No loaded section named '%s'.\n", args);
+}
+
+static int
+remote_query (query_type, buf, outbuf, bufsiz)
+ int query_type;
+ char *buf;
+ char *outbuf;
+ int *bufsiz;
+{
+ int i;
+ char buf2[PBUFSIZ];
+ char *p2 = &buf2[0];
+ char *p = buf;
+
+ if (! bufsiz)
+ error ("null pointer to remote bufer size specified");
+
+ /* minimum outbuf size is PBUFSIZE - if bufsiz is not large enough let
+ the caller know and return what the minimum size is */
+ /* Note: a zero bufsiz can be used to query the minimum buffer size */
+ if ( *bufsiz < PBUFSIZ )
+ {
+ *bufsiz = PBUFSIZ;
+ return -1;
+ }
+
+ /* except for querying the minimum buffer size, target must be open */
+ if (! remote_desc)
+ error ("remote query is only available after target open");
+
+ /* we only take uppercase letters as query types, at least for now */
+ if ( (query_type < 'A') || (query_type > 'Z') )
+ error ("invalid remote query type");
+
+ if (! buf)
+ error ("null remote query specified");
+
+ if (! outbuf)
+ error ("remote query requires a buffer to receive data");
+
+ outbuf[0] = '\0';
+
+ *p2++ = 'q';
+ *p2++ = query_type;
+
+ /* we used one buffer char for the remote protocol q command and another
+ for the query type. As the remote protocol encapsulation uses 4 chars
+ plus one extra in case we are debugging (remote_debug),
+ we have PBUFZIZ - 7 left to pack the query string */
+ i = 0;
+ while ( buf[i] && (i < (PBUFSIZ - 8)) )
+ {
+ /* bad caller may have sent forbidden characters */
+ if ( (!isprint(buf[i])) || (buf[i] == '$') || (buf[i] == '#') )
+ error ("illegal characters in query string");
+
+ *p2++ = buf[i];
+ i++;
+ }
+ *p2 = buf[i];
+
+ if ( buf[i] )
+ error ("query larger than available buffer");
+
+ i = putpkt (buf2);
+ if ( i < 0 ) return i;
+
+ getpkt (outbuf, 0);
+
+ return 0;
+}
+
+static void
+packet_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char buf[PBUFSIZ];
+
+ if (! remote_desc)
+ error ("command can only be used with remote target");
+
+ if (! args)
+ error ("remote-packet command requires packet text as argument");
+
+ puts_filtered ("sending: ");
+ print_packet (args);
+ puts_filtered ("\n");
+ putpkt (args);
+
+ getpkt (buf, 0);
+ puts_filtered ("received: ");
+ print_packet (buf);
+ puts_filtered ("\n");
+}
+
+#if 0
+/* --------- UNIT_TEST for THREAD oriented PACKETS ------------------------- */
+
+static void display_thread_info PARAMS ((struct gdb_ext_thread_info *info));
+
+static void threadset_test_cmd PARAMS ((char *cmd, int tty));
+
+static void threadalive_test PARAMS ((char *cmd, int tty));
+
+static void threadlist_test_cmd PARAMS ((char *cmd, int tty));
+
+int get_and_display_threadinfo PARAMS ((threadref *ref));
+
+static void threadinfo_test_cmd PARAMS ((char *cmd, int tty));
+
+static int thread_display_step PARAMS ((threadref *ref, void *context));
+
+static void threadlist_update_test_cmd PARAMS ((char *cmd, int tty));
+
+static void init_remote_threadtests PARAMS ((void));
+
+#define SAMPLE_THREAD 0x05060708 /* Truncated 64 bit threadid */
+
+static void
+threadset_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int sample_thread = SAMPLE_THREAD;
+
+ printf_filtered ("Remote threadset test\n");
+ set_thread (sample_thread, 1);
+}
+
+
+static void
+threadalive_test (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int sample_thread = SAMPLE_THREAD;
+
+ if (remote_thread_alive (sample_thread))
+ printf_filtered ("PASS: Thread alive test\n");
+ else
+ printf_filtered ("FAIL: Thread alive test\n");
+}
+
+void output_threadid PARAMS ((char *title, threadref * ref));
+
+void
+output_threadid (title, ref)
+ char *title;
+ threadref *ref;
+{
+ char hexid[20];
+
+ pack_threadid (&hexid[0], ref); /* Convert threead id into hex */
+ hexid[16] = 0;
+ printf_filtered ("%s %s\n", title, (&hexid[0]));
+}
+
+static void
+threadlist_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int startflag = 1;
+ threadref nextthread;
+ int done, result_count;
+ threadref threadlist[3];
+
+ printf_filtered ("Remote Threadlist test\n");
+ if (!remote_get_threadlist (startflag, &nextthread, 3, &done,
+ &result_count, &threadlist[0]))
+ printf_filtered ("FAIL: threadlist test\n");
+ else
+ {
+ threadref *scan = threadlist;
+ threadref *limit = scan + result_count;
+
+ while (scan < limit)
+ output_threadid (" thread ", scan++);
+ }
+}
+
+void
+display_thread_info (info)
+ struct gdb_ext_thread_info *info;
+{
+ output_threadid ("Threadid: ", &info->threadid);
+ printf_filtered ("Name: %s\n ", info->shortname);
+ printf_filtered ("State: %s\n", info->display);
+ printf_filtered ("other: %s\n\n", info->more_display);
+}
+
+int
+get_and_display_threadinfo (ref)
+ threadref *ref;
+{
+ int result;
+ int set;
+ struct gdb_ext_thread_info threadinfo;
+
+ set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+ | TAG_MOREDISPLAY | TAG_DISPLAY;
+ if (0 != (result = remote_get_threadinfo (ref, set, &threadinfo)))
+ display_thread_info (&threadinfo);
+ return result;
+}
+
+static void
+threadinfo_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int athread = SAMPLE_THREAD;
+ threadref thread;
+ int set;
+
+ int_to_threadref (&thread, athread);
+ printf_filtered ("Remote Threadinfo test\n");
+ if (!get_and_display_threadinfo (&thread))
+ printf_filtered ("FAIL cannot get thread info\n");
+}
+
+static int
+thread_display_step (ref, context)
+ threadref *ref;
+ void *context;
+{
+ /* output_threadid(" threadstep ",ref); *//* simple test */
+ return get_and_display_threadinfo (ref);
+}
+
+static void
+threadlist_update_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ printf_filtered ("Remote Threadlist update test\n");
+ remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
+}
+
+static void
+init_remote_threadtests (void)
+{
+ add_com ("tlist", class_obscure, threadlist_test_cmd,
+ "Fetch and print the remote list of thread identifiers, one pkt only");
+ add_com ("tinfo", class_obscure, threadinfo_test_cmd,
+ "Fetch and display info about one thread");
+ add_com ("tset", class_obscure, threadset_test_cmd,
+ "Test setting to a different thread");
+ add_com ("tupd", class_obscure, threadlist_update_test_cmd,
+ "Iterate through updating all remote thread info");
+ add_com ("talive", class_obscure, threadalive_test,
+ " Remote thread alive test ");
+}
+
+#endif /* 0 */
+
+static void
+init_remote_ops ()
+{
+ remote_ops.to_shortname = "remote";
+ remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
+ remote_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ remote_ops.to_open = remote_open;
+ remote_ops.to_close = remote_close;
+ remote_ops.to_detach = remote_detach;
+ remote_ops.to_resume = remote_resume;
+ remote_ops.to_wait = remote_wait;
+ remote_ops.to_fetch_registers = remote_fetch_registers;
+ remote_ops.to_store_registers = remote_store_registers;
+ remote_ops.to_prepare_to_store = remote_prepare_to_store;
+ remote_ops.to_xfer_memory = remote_xfer_memory;
+ remote_ops.to_files_info = remote_files_info;
+ remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
+ remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_ops.to_kill = remote_kill;
+ remote_ops.to_load = generic_load;
+ remote_ops.to_mourn_inferior = remote_mourn;
+ remote_ops.to_thread_alive = remote_thread_alive;
+ remote_ops.to_stop = remote_stop;
+ remote_ops.to_query = remote_query;
+ remote_ops.to_stratum = process_stratum;
+ remote_ops.to_has_all_memory = 1;
+ remote_ops.to_has_memory = 1;
+ remote_ops.to_has_stack = 1;
+ remote_ops.to_has_registers = 1;
+ remote_ops.to_has_execution = 1;
+ remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
+ remote_ops.to_magic = OPS_MAGIC;
+}
+
+/* Set up the extended remote vector by making a copy of the standard
+ remote vector and adding to it. */
+
+static void
+init_extended_remote_ops ()
+{
+ extended_remote_ops = remote_ops;
+
+ extended_remote_ops.to_shortname = "extended-remote";
+ extended_remote_ops.to_longname =
+ "Extended remote serial target in gdb-specific protocol";
+ extended_remote_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+ extended_remote_ops.to_open = extended_remote_open;
+ extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
+ extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
+}
void
_initialize_remote ()
{
+ init_remote_ops ();
add_target (&remote_ops);
- add_target (&extended_remote_ops);
- add_show_from_set (add_set_cmd ("remotetimeout", no_class,
- var_integer, (char *)&remote_timeout,
- "Set timeout value for remote read.\n", &setlist),
- &showlist);
+ init_extended_remote_ops ();
+ add_target (&extended_remote_ops);
+ init_remote_threads ();
+#if 0
+ init_remote_threadtests ();
+#endif
- add_show_from_set (add_set_cmd ("remotebreak", no_class,
- var_integer, (char *)&remote_break,
- "Set whether to send break if interrupted.\n", &setlist),
+ add_cmd ("compare-sections", class_obscure, compare_sections_command,
+ "Compare section data on target to the exec file.\n\
+Argument is a single section name (default: all loaded sections).",
+ &cmdlist);
+
+ add_cmd ("packet", class_maintenance, packet_command,
+ "Send an arbitrary packet to a remote target.\n\
+ maintenance packet TEXT\n\
+If GDB is talking to an inferior via the GDB serial protocol, then\n\
+this command sends the string TEXT to the inferior, and displays the\n\
+response packet. GDB supplies the initial `$' character, and the\n\
+terminating `#' character and checksum.",
+ &maintenancelist);
+
+ add_show_from_set
+ (add_set_cmd ("remotetimeout", no_class,
+ var_integer, (char *)&remote_timeout,
+ "Set timeout value for remote read.\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("remotebreak", no_class,
+ var_integer, (char *)&remote_break,
+ "Set whether to send break if interrupted.\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("remotewritesize", no_class,
+ var_integer, (char *)&remote_write_size,
+ "Set the maximum number of bytes per memory write packet.\n",
+ &setlist),
+ &showlist);
+
+ remote_address_size = TARGET_PTR_BIT;
+ add_show_from_set
+ (add_set_cmd ("remoteaddresssize", class_obscure,
+ var_integer, (char *)&remote_address_size,
+ "Set the maximum size of the address (in bits) \
+in a memory packet.\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (add_set_cmd ("remotebinarydownload", no_class,
+ var_boolean, (char *) &remote_binary_download,
+ "Set binary downloads.\n", &setlist),
&showlist);
}
diff --git a/contrib/gdb/gdb/scm-exp.c b/contrib/gdb/gdb/scm-exp.c
index 8df6803..6399563 100644
--- a/contrib/gdb/gdb/scm-exp.c
+++ b/contrib/gdb/gdb/scm-exp.c
@@ -30,15 +30,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define USE_EXPRSTRING 0
+static void scm_lreadparen PARAMS ((int));
+static int scm_skip_ws PARAMS ((void));
+static void scm_read_token PARAMS ((int, int));
+static LONGEST scm_istring2number PARAMS ((char *, int, int));
+static LONGEST scm_istr2int PARAMS ((char *, int, int));
static void scm_lreadr PARAMS ((int));
-LONGEST
+static LONGEST
scm_istr2int(str, len, radix)
char *str;
int len;
int radix;
{
- int j;
int i = 0;
LONGEST inum = 0;
int c;
@@ -78,7 +82,7 @@ scm_istr2int(str, len, radix)
return SCM_MAKINUM (inum);
}
-LONGEST
+static LONGEST
scm_istring2number(str, len, radix)
char *str;
int len;
@@ -87,7 +91,9 @@ scm_istring2number(str, len, radix)
int i = 0;
char ex = 0;
char ex_p = 0, rx_p = 0; /* Only allow 1 exactness and 1 radix prefix */
+#if 0
SCM res;
+#endif
if (len==1)
if (*str=='+' || *str=='-') /* Catches lone `+' and `-' for speed */
return SCM_BOOL_F;
@@ -224,7 +230,7 @@ scm_lreadr (skipping)
{
int c, j;
struct stoken str;
- LONGEST svalue;
+ LONGEST svalue = 0;
tryagain:
c = *lexptr++;
switch (c)
@@ -319,7 +325,9 @@ scm_lreadr (skipping)
goto tryagain;
case '.':
default:
+#if 0
callshrp:
+#endif
scm_lreadr (skipping);
return;
}
@@ -365,7 +373,9 @@ scm_lreadr (skipping)
case ':':
scm_read_token ('-', 0);
return;
+#if 0
do_symbol:
+#endif
default:
str.ptr = lexptr-1;
scm_read_token (c, 0);
@@ -398,7 +408,6 @@ int
scm_parse ()
{
char* start;
- struct stoken str;
while (*lexptr == ' ')
lexptr++;
start = lexptr;
diff --git a/contrib/gdb/gdb/scm-lang.c b/contrib/gdb/gdb/scm-lang.c
index b054dcf..7f31ba4 100644
--- a/contrib/gdb/gdb/scm-lang.c
+++ b/contrib/gdb/gdb/scm-lang.c
@@ -28,10 +28,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "scm-lang.h"
#include "scm-tags.h"
#include "gdb_string.h"
+#include "gdbcore.h"
-extern struct type ** const (c_builtin_types[]);
-extern value_ptr value_allocate_space_in_inferior PARAMS ((int));
-extern value_ptr find_function_in_inferior PARAMS ((char*));
+static value_ptr evaluate_subexp_scm PARAMS ((struct type *, struct expression *,
+ int *, enum noside));
+static value_ptr scm_lookup_name PARAMS ((char *));
+static int in_eval_c PARAMS ((void));
+static void scm_printstr PARAMS ((GDB_FILE *stream, char *string, unsigned int length, int width, int force_ellipses));
+
+extern struct type ** CONST_PTR (c_builtin_types[]);
struct type *builtin_type_scm;
@@ -44,10 +49,11 @@ scm_printchar (c, stream)
}
static void
-scm_printstr (stream, string, length, force_ellipses)
+scm_printstr (stream, string, length, width, force_ellipses)
GDB_FILE *stream;
char *string;
unsigned int length;
+ int width;
int force_ellipses;
{
fprintf_filtered (stream, "\"%s\"", string);
@@ -73,7 +79,6 @@ scm_get_field (svalue, index)
LONGEST svalue;
int index;
{
- value_ptr val;
char buffer[20];
read_memory (SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm),
buffer, TYPE_LENGTH (builtin_type_scm));
@@ -100,7 +105,7 @@ scm_unpack (type, valaddr, context)
else
return 1;
}
- switch (7 & svalue)
+ switch (7 & (int) svalue)
{
case 2: case 6: /* fixnum */
return svalue >> 2;
@@ -109,7 +114,7 @@ scm_unpack (type, valaddr, context)
return SCM_ICHR (svalue);
else if (SCM_IFLAGP (svalue))
{
- switch (svalue)
+ switch ((int) svalue)
{
#ifndef SICP
case SCM_EOL:
@@ -148,13 +153,13 @@ in_eval_c ()
First lookup in Scheme context (using the scm_lookup_cstr inferior
function), then try lookup_symbol for compiled variables. */
-value_ptr
+static value_ptr
scm_lookup_name (str)
char *str;
{
value_ptr args[3];
int len = strlen (str);
- value_ptr symval, func, val;
+ value_ptr func, val;
struct symbol *sym;
args[0] = value_allocate_space_in_inferior (len);
args[1] = value_from_longest (builtin_type_int, len);
@@ -241,9 +246,10 @@ const struct language_defn scm_language_defn = {
scm_parse,
c_error,
evaluate_subexp_scm,
- scm_printchar, /* Print a character constant */
+ scm_printchar, /* Print a character constant */
scm_printstr, /* Function to print string constant */
- NULL, /* Create fundamental type in this language */
+ NULL, /* Function to print a single character */
+ NULL, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
scm_val_print, /* Print a value using appropriate syntax */
scm_value_print, /* Print a top-level value */
diff --git a/contrib/gdb/gdb/scm-lang.h b/contrib/gdb/gdb/scm-lang.h
index f990d77..878a2ab 100644
--- a/contrib/gdb/gdb/scm-lang.h
+++ b/contrib/gdb/gdb/scm-lang.h
@@ -29,12 +29,12 @@ struct value;
extern int scm_value_print PARAMS ((struct value *, GDB_FILE*,
int, enum val_prettyprint));
-extern int scm_val_print PARAMS ((struct type*, char*, CORE_ADDR, GDB_FILE*,
+extern int scm_val_print PARAMS ((struct type*, char*, int, CORE_ADDR, GDB_FILE*,
int, int, int, enum val_prettyprint));
extern LONGEST scm_get_field PARAMS ((LONGEST, int));
-extern int scm_scmval_print PARAMS ((LONGEST, GDB_FILE *,
+extern void scm_scmval_print PARAMS ((LONGEST, GDB_FILE *,
int, int, int, enum val_prettyprint));
extern int is_scmvalue_type PARAMS ((struct type*));
@@ -45,6 +45,6 @@ extern struct value * scm_evaluate_string PARAMS ((char*, int));
extern struct type *builtin_type_scm;
-extern int scm_parse ();
+extern int scm_parse PARAMS ((void));
extern LONGEST scm_unpack PARAMS ((struct type *, char *, enum type_code));
diff --git a/contrib/gdb/gdb/scm-tags.h b/contrib/gdb/gdb/scm-tags.h
index a3b736b..fbe45cc 100644
--- a/contrib/gdb/gdb/scm-tags.h
+++ b/contrib/gdb/gdb/scm-tags.h
@@ -16,8 +16,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* As a special exception, the Free Software Foundation gives permission
* for additional uses of the text contained in its release of GUILE.
diff --git a/contrib/gdb/gdb/scm-valprint.c b/contrib/gdb/gdb/scm-valprint.c
index 8544870..71acc69 100644
--- a/contrib/gdb/gdb/scm-valprint.c
+++ b/contrib/gdb/gdb/scm-valprint.c
@@ -26,12 +26,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "value.h"
#include "scm-lang.h"
#include "valprint.h"
+#include "gdbcore.h"
+
+/* FIXME: Should be in a header file that we import. */
+extern int
+c_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *, int, int,
+ int, enum val_prettyprint));
+
+static void scm_ipruk PARAMS ((char *, LONGEST, GDB_FILE *));
+static void scm_scmlist_print PARAMS ((LONGEST, GDB_FILE *, int, int,
+ int, enum val_prettyprint));
+static int scm_inferior_print PARAMS ((LONGEST, GDB_FILE *, int, int,
+ int, enum val_prettyprint));
/* Prints the SCM value VALUE by invoking the inferior, if appropraite.
Returns >= 0 on succes; retunr -1 if the inferior cannot/should not
print VALUE. */
-int
+static int
scm_inferior_print (value, stream, format, deref_ref, recurse, pretty)
LONGEST value;
GDB_FILE *stream;
@@ -82,7 +94,7 @@ static char *scm_isymnames[] =
"#<unspecified>"
};
-static int
+static void
scm_scmlist_print (svalue, stream, format, deref_ref, recurse, pretty)
LONGEST svalue;
GDB_FILE *stream;
@@ -95,7 +107,7 @@ scm_scmlist_print (svalue, stream, format, deref_ref, recurse, pretty)
if (recurse > 6)
{
fputs_filtered ("...", stream);
- return 0;
+ return;
}
scm_scmval_print (SCM_CAR (svalue), stream, format,
deref_ref, recurse + 1, pretty);
@@ -135,7 +147,7 @@ scm_ipruk (hdr, ptr, stream)
fprintf_filtered (stream, " 0x%x>", ptr);
}
-int
+void
scm_scmval_print (svalue, stream, format, deref_ref, recurse, pretty)
LONGEST svalue;
GDB_FILE *stream;
@@ -145,7 +157,7 @@ scm_scmval_print (svalue, stream, format, deref_ref, recurse, pretty)
enum val_prettyprint pretty;
{
taloop:
- switch (7 & svalue)
+ switch (7 & (int) svalue)
{
case 2:
case 6:
@@ -191,7 +203,9 @@ scm_scmval_print (svalue, stream, format, deref_ref, recurse, pretty)
case scm_tcs_cons_gloc:
if (SCM_CDR (SCM_CAR (svalue) - 1L) == 0)
{
+#if 0
SCM name;
+#endif
fputs_filtered ("#<latte ", stream);
#if 1
fputs_filtered ("???", stream);
@@ -351,17 +365,21 @@ scm_scmval_print (svalue, stream, format, deref_ref, recurse, pretty)
goto punk;
#endif
default:
- punk:scm_ipruk ("type", svalue, stream);
+#if 0
+ punk:
+#endif
+ scm_ipruk ("type", svalue, stream);
}
break;
}
}
int
-scm_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
- pretty)
+scm_val_print (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -387,7 +405,7 @@ scm_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
else
{
- return c_val_print (type, valaddr, address, stream, format,
+ return c_val_print (type, valaddr, 0, address, stream, format,
deref_ref, recurse, pretty);
}
}
@@ -399,6 +417,6 @@ scm_value_print (val, stream, format, pretty)
int format;
enum val_prettyprint pretty;
{
- return (val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
+ return (val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
}
diff --git a/contrib/gdb/gdb/ser-e7kpc.c b/contrib/gdb/gdb/ser-e7kpc.c
index 9faf7dd..8be5db9 100644
--- a/contrib/gdb/gdb/ser-e7kpc.c
+++ b/contrib/gdb/gdb/ser-e7kpc.c
@@ -1,29 +1,40 @@
/* Remote serial interface using Hitachi E7000 PC ISA card in a PC
+ Copyright 1994, 1999 Free Software Foundation, Inc.
- Copyright 1994 Free Software Foundation, Inc.
+This file is part of GDB.
- This file is part of GDB.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifdef __GO32__
+#if defined __GO32__ || defined _WIN32
#include "defs.h"
#include "serial.h"
-#include <sys/dos.h>
+#include "gdb_string.h"
+
+/* MSVC uses strnicmp instead of strncasecmp */
+#ifdef _MSC_VER
+#define strncasecmp strnicmp
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#ifdef __GO32__
+#include <sys/dos.h>
+#endif
static int e7000pc_open PARAMS ((serial_t scb, const char *name));
static void e7000pc_raw PARAMS ((serial_t scb));
@@ -33,13 +44,6 @@ static int e7000pc_write PARAMS ((serial_t scb, const char *str, int len));
static void e7000pc_close PARAMS ((serial_t scb));
static serial_ttystate e7000pc_get_tty_state PARAMS ((serial_t scb));
static int e7000pc_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
-static char *aptr PARAMS ((short p));
-
-static int dos_async_init PARAMS ((int port));
-static void dos_async_tx PARAMS ((const char c));
-static int dos_async_rx PARAMS (());
-
-
#define OFF_DPD 0x0000
#define OFF_DDP 0x1000
@@ -78,14 +82,24 @@ static unsigned long pon;
static unsigned long irqtop;
static unsigned long board_at;
+#ifdef __GO32__
+
#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);}
#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);}
#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb)
#define GET_WORD(x) ( dosmemget(x,2,&sb), sb)
-
static unsigned char bb;
static unsigned short sb;
+#else /* win32 */
+
+#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y)
+#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y)
+#define GET_BYTE(x) (*(volatile unsigned char *)(x))
+#define GET_WORD(x) (*(volatile unsigned short *)(x))
+#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
+#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
+#endif
static struct sw
{
@@ -98,18 +112,51 @@ static struct sw
{0x17, 0xdc000},
0};
+#ifdef _MSC_VER
+/* Get the base of the data segment. This is needed to calculate the offset
+ between data segment addresses and the base of linear memory, which is where
+ device registers reside. Note that this is really only necessary for
+ Win32s, since Win95 and NT keep the data segment at linear 0. */
+
+static unsigned long
+get_ds_base (void)
+{
+ unsigned short dsval;
+ LDT_ENTRY ldt;
+ unsigned long dsbase;
+
+ __asm
+ {
+ mov dsval,ds
+ }
+
+ dsbase = 0;
+
+ GetThreadSelectorEntry (GetCurrentThread(), dsval, &ldt);
+
+ dsbase = ldt.HighWord.Bits.BaseHi << 24 | ldt.HighWord.Bits.BaseMid << 16
+ | ldt.BaseLow;
+
+ return dsbase;
+}
+#else /* !_MSC_VER */
+#define get_ds_base() 0
+#endif /* _MSC_VER */
+
static int
e7000pc_init ()
{
- /* Look around in memory for the board's signature */
-
int try;
+ unsigned long dsbase;
- for (try = 0; sigs[try].sw; try++)
+ dsbase = get_ds_base ();
+ /* Look around in memory for the board's signature */
+
+ for (try = 0; sigs[try].sw; try++)
{
int val;
- board_at = sigs[try].addr;
+ board_at = sigs[try].addr - dsbase;
fa = board_at + OFF_FA;
fb = board_at + OFF_FB;
cpd = board_at + OFF_CPD;
@@ -123,12 +170,12 @@ e7000pc_init ()
if (val == (0xaaa0 | sigs[try].sw))
{
- if (GET_BYTE (pon) & 0xf)
+ if (GET_WORD (pon) & 0xf)
{
- SET_BYTE(fa, 0);
- SET_BYTE (fb, 0);
+ SET_WORD (fa, 0);
+ SET_WORD (fb, 0);
- SET_BYTE (irqtop, 1); /* Disable interrupts from e7000 */
+ SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */
SET_WORD (ready, 1);
printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
sigs[try].addr);
@@ -151,26 +198,28 @@ its I/O space, remove other unneeded cards, etc etc\n");
static int pbuf_size;
static int pbuf_index;
-static
-int
-e7000_get ()
+/* Return next byte from cdp. If no more, then return -1. */
+
+static int
+e7000_get (void)
{
static char pbuf[1000];
char tmp[1000];
int x;
+
if (pbuf_index < pbuf_size)
{
x = pbuf[pbuf_index++];
}
- else if ((GET_BYTE (fb) & 1))
+ else if ((GET_WORD (fb) & 1))
{
int i;
- pbuf_size = GET_WORD(cdp + 2);
+ pbuf_size = GET_WORD (cdp + 2);
dosmemget (cdp + 8, pbuf_size + 1, tmp);
/* Tell the E7000 we've eaten */
- SET_BYTE(fb,0);
+ SET_WORD (fb, 0);
/* Swap it around */
for (i = 0; i < pbuf_size; i++)
{
@@ -186,6 +235,9 @@ e7000_get ()
return x;
}
+/* Works just like read(), except that it takes a TIMEOUT in seconds. Note
+ that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */
+
static int
dosasync_read (fd, buf, len, timeout)
int fd;
@@ -197,7 +249,6 @@ dosasync_read (fd, buf, len, timeout)
long now;
long then;
int i = 0;
- int p;
/* Then look for some more if we're still hungry */
time (&now);
@@ -241,7 +292,6 @@ dosasync_write (fd, buf, len)
{
int i;
char dummy[1000];
-
/* Construct copy locally */
((short *)dummy)[0] = CMD_CI;
@@ -254,14 +304,13 @@ dosasync_write (fd, buf, len)
}
/* Wait for the card to get ready */
- while ((GET_BYTE(fa) & 1) != 0)
- ;
+ while (GET_WORD (fa) & 1) ;
/* Blast onto the ISA card */
dosmemput (dummy, 8 + len + 1, cpd);
- SET_BYTE(fa, 1);
- SET_BYTE(irqtod, 1); /* Interrupt the E7000 */
+ SET_WORD (fa, 1);
+ SET_WORD (irqtod, 1); /* Interrupt the E7000 */
return len;
}
@@ -403,6 +452,7 @@ static struct serial_ops e7000pc_ops =
e7000pc_print_tty_state,
e7000pc_noflush_set_tty_state,
e7000pc_setbaudrate,
+ e7000pc_noop, /* wait for output to drain */
};
void
diff --git a/contrib/gdb/gdb/ser-go32.c b/contrib/gdb/gdb/ser-go32.c
index 4af25f1..f776161 100644
--- a/contrib/gdb/gdb/ser-go32.c
+++ b/contrib/gdb/gdb/ser-go32.c
@@ -848,6 +848,7 @@ static struct serial_ops dos_ops =
dos_noflush_set_tty_state,
dos_setbaudrate,
dos_setstopbits,
+ dos_noop, /* wait for output to drain */
};
diff --git a/contrib/gdb/gdb/ser-mac.c b/contrib/gdb/gdb/ser-mac.c
index e27a9dd0..df0040e 100644
--- a/contrib/gdb/gdb/ser-mac.c
+++ b/contrib/gdb/gdb/ser-mac.c
@@ -328,7 +328,7 @@ mac_close (serial_t scb)
if (output_refnum)
{
if (0 /* custom buffer */)
- SetSetBuf (input_refnum, mac_output_buffer, 0);
+ SerSetBuf (input_refnum, mac_output_buffer, 0);
CloseDriver (output_refnum);
output_refnum = 0;
}
@@ -352,6 +352,7 @@ static struct serial_ops mac_ops =
mac_noflush_set_tty_state,
mac_set_baud_rate,
mac_set_stop_bits,
+ mac_noop, /* wait for output to drain */
};
void
diff --git a/contrib/gdb/gdb/ser-ocd.c b/contrib/gdb/gdb/ser-ocd.c
new file mode 100644
index 0000000..971f84e
--- /dev/null
+++ b/contrib/gdb/gdb/ser-ocd.c
@@ -0,0 +1,209 @@
+/* Remote serial interface for Macraigor Systems implementation of
+ On-Chip Debugging using serial target box or serial wiggler
+
+ Copyright 1994, 1997 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "serial.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+static int ser_ocd_open PARAMS ((serial_t scb, const char *name));
+static void ser_ocd_raw PARAMS ((serial_t scb));
+static int ser_ocd_readchar PARAMS ((serial_t scb, int timeout));
+static int ser_ocd_setbaudrate PARAMS ((serial_t scb, int rate));
+static int ser_ocd_write PARAMS ((serial_t scb, const char *str, int len));
+static void ser_ocd_close PARAMS ((serial_t scb));
+static serial_ttystate ser_ocd_get_tty_state PARAMS ((serial_t scb));
+static int ser_ocd_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
+
+#ifdef _WIN32
+/* On Windows, this function pointer is initialized to a function in
+ the wiggler DLL. */
+static int (*dll_do_command) PARAMS ((const char *, char *));
+#endif
+
+static int
+ocd_open (scb, name)
+ serial_t scb;
+ const char *name;
+{
+#ifdef _WIN32
+ /* Find the wiggler DLL which talks to the board. */
+ if (dll_do_command == NULL)
+ {
+ HINSTANCE handle;
+
+ /* FIXME: Should the user be able to configure this? */
+ handle = LoadLibrary ("Wigglers.dll");
+ if (handle == NULL)
+ error ("Can't load Wigglers.dll");
+
+ dll_do_command = ((int (*) PARAMS ((const char *, char *)))
+ GetProcAddress (handle, "do_command"));
+ if (dll_do_command == NULL)
+ error ("Can't find do_command function in Wigglers.dll");
+ }
+#else
+ /* No wiggler DLLs on Unix yet, fail. */
+ error ("Wiggler library not available for this type of host.");
+#endif /* _WIN32 */
+ return 0;
+}
+
+static int
+ocd_noop (scb)
+ serial_t scb;
+{
+ return 0;
+}
+
+static void
+ocd_raw (scb)
+ serial_t scb;
+{
+ /* Always in raw mode */
+}
+
+static void
+ocd_readremote ()
+{
+}
+
+/* We need a buffer to store responses from the Wigglers.dll */
+#define WIGGLER_BUFF_SIZE 512
+unsigned char from_wiggler_buffer[WIGGLER_BUFF_SIZE];
+unsigned char * wiggler_buffer_ptr; /* curr spot in buffer */
+
+static int
+ocd_readchar (scb, timeout)
+ serial_t scb;
+ int timeout;
+{
+ /* Catch attempts at reading past the end of the buffer */
+ if (wiggler_buffer_ptr >
+ (from_wiggler_buffer + (sizeof (char *) * WIGGLER_BUFF_SIZE)))
+ error ("ocd_readchar asked to read past the end of the buffer!");
+
+ return (int) *wiggler_buffer_ptr++; /* return curr char and increment ptr */
+}
+
+struct ocd_ttystate {
+ int dummy;
+};
+
+/* ocd_{get set}_tty_state() are both dummys to fill out the function
+ vector. Someday, they may do something real... */
+
+static serial_ttystate
+ocd_get_tty_state (scb)
+ serial_t scb;
+{
+ struct ocd_ttystate *state;
+
+ state = (struct ocd_ttystate *) xmalloc (sizeof *state);
+
+ return (serial_ttystate) state;
+}
+
+static int
+ocd_set_tty_state (scb, ttystate)
+ serial_t scb;
+ serial_ttystate ttystate;
+{
+ return 0;
+}
+
+static int
+ocd_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
+ serial_t scb;
+ serial_ttystate new_ttystate;
+ serial_ttystate old_ttystate;
+{
+ return 0;
+}
+
+static void
+ocd_print_tty_state (scb, ttystate)
+ serial_t scb;
+ serial_ttystate ttystate;
+{
+ /* Nothing to print. */
+ return;
+}
+
+static int
+ocd_setbaudrate (scb, rate)
+ serial_t scb;
+ int rate;
+{
+ return 0;
+}
+
+static int
+ocd_write (scb, str, len)
+ serial_t scb;
+ const char *str;
+ int len;
+{
+ char c;
+
+#ifdef _WIN32
+ /* send packet to Wigglers.dll and store response so we can give it to
+ remote-wiggler.c when get_packet is run */
+ dll_do_command (str, from_wiggler_buffer);
+ wiggler_buffer_ptr = from_wiggler_buffer;
+#endif
+
+ return 0;
+}
+
+static void
+ocd_close (scb)
+ serial_t scb;
+{
+}
+
+static struct serial_ops ocd_ops =
+{
+ "ocd",
+ 0,
+ ocd_open,
+ ocd_close,
+ ocd_readchar,
+ ocd_write,
+ ocd_noop, /* flush output */
+ ocd_noop, /* flush input */
+ ocd_noop, /* send break -- currently used only for nindy */
+ ocd_raw,
+ ocd_get_tty_state,
+ ocd_set_tty_state,
+ ocd_print_tty_state,
+ ocd_noflush_set_tty_state,
+ ocd_setbaudrate,
+ ocd_noop, /* wait for output to drain */
+};
+
+void
+_initialize_ser_ocd_bdm ()
+{
+ serial_add_interface (&ocd_ops);
+}
diff --git a/contrib/gdb/gdb/ser-tcp.c b/contrib/gdb/gdb/ser-tcp.c
index 388293f..c551337 100644
--- a/contrib/gdb/gdb/ser-tcp.c
+++ b/contrib/gdb/gdb/ser-tcp.c
@@ -1,5 +1,5 @@
/* Serial interface for raw TCP connections on Un*x like systems
- Copyright 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,7 +25,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
+
+#ifndef __CYGWIN32__
#include <netinet/tcp.h>
+#endif
+
#include "signals.h"
#include "gdb_string.h"
@@ -45,6 +49,12 @@ static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
static void tcp_close PARAMS ((serial_t scb));
static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
+static int tcp_return_0 PARAMS ((serial_t));
+static int tcp_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
+ serial_ttystate));
+static void tcp_print_tty_state PARAMS ((serial_t, serial_ttystate));
+
+void _initialize_ser_tcp PARAMS ((void));
/* Open up a raw tcp socket */
@@ -175,7 +185,7 @@ tcp_raw(scb)
*/
static int
-wait_for(scb, timeout)
+wait_for (scb, timeout)
serial_t scb;
int timeout;
{
@@ -200,12 +210,14 @@ wait_for(scb, timeout)
numfds = select(scb->fd+1, &readfds, 0, &exceptfds, 0);
if (numfds <= 0)
- if (numfds == 0)
- return SERIAL_TIMEOUT;
- else if (errno == EINTR)
- continue;
- else
- return SERIAL_ERROR; /* Got an error from select or poll */
+ {
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from select or poll */
+ }
return 0;
}
@@ -217,7 +229,7 @@ wait_for(scb, timeout)
dead, or -3 for any other error (see errno in that case). */
static int
-tcp_readchar(scb, timeout)
+tcp_readchar (scb, timeout)
serial_t scb;
int timeout;
{
@@ -239,12 +251,14 @@ tcp_readchar(scb, timeout)
}
if (scb->bufcnt <= 0)
- if (scb->bufcnt == 0)
- return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
- distinguish between EOF & timeouts
- someday] */
- else
- return SERIAL_ERROR; /* Got an error from read */
+ {
+ if (scb->bufcnt == 0)
+ return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
+ distinguish between EOF & timeouts
+ someday] */
+ else
+ return SERIAL_ERROR; /* Got an error from read */
+ }
scb->bufcnt--;
scb->bufp = scb->buf;
@@ -334,6 +348,7 @@ static struct serial_ops tcp_ops =
tcp_noflush_set_tty_state,
tcp_setbaudrate,
tcp_setstopbits,
+ tcp_return_0, /* wait for output to drain */
};
void
diff --git a/contrib/gdb/gdb/ser-unix.c b/contrib/gdb/gdb/ser-unix.c
index a4a00e5..f279c94 100644
--- a/contrib/gdb/gdb/ser-unix.c
+++ b/contrib/gdb/gdb/ser-unix.c
@@ -1,5 +1,5 @@
/* Serial interface for local (hardwired) serial ports on Un*x like systems
- Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -69,12 +69,25 @@ static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
static int rate_to_code PARAMS ((int rate));
static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
-/* FIXME: static void hardwire_restore PARAMS ((serial_t scb)); */
static void hardwire_close PARAMS ((serial_t scb));
static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
+static int hardwire_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
+ serial_ttystate));
+static void hardwire_print_tty_state PARAMS ((serial_t, serial_ttystate));
+static int hardwire_drain_output PARAMS ((serial_t));
+static int hardwire_flush_output PARAMS ((serial_t));
+static int hardwire_flush_input PARAMS ((serial_t));
+static int hardwire_send_break PARAMS ((serial_t));
+static int hardwire_setstopbits PARAMS ((serial_t, int));
+
+void _initialize_ser_hardwire PARAMS ((void));
+
+#ifdef __CYGWIN32__
+extern void (*ui_loop_hook) PARAMS ((int));
+#endif
/* Open up a real live device for serial I/O */
@@ -91,13 +104,11 @@ hardwire_open(scb, name)
}
static int
-get_tty_state(scb, state)
+get_tty_state (scb, state)
serial_t scb;
struct hardwire_ttystate *state;
{
#ifdef HAVE_TERMIOS
- extern int errno;
-
if (tcgetattr(scb->fd, &state->termios) < 0)
return -1;
@@ -269,6 +280,38 @@ hardwire_print_tty_state (scb, ttystate)
#endif
}
+/* Wait for the output to drain away, as opposed to flushing (discarding) it */
+
+static int
+hardwire_drain_output (scb)
+ serial_t scb;
+{
+#ifdef HAVE_TERMIOS
+ return tcdrain (scb->fd);
+#endif
+
+#ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCSBRK, 1);
+#endif
+
+#ifdef HAVE_SGTTY
+ /* Get the current state and then restore it using TIOCSETP,
+ which should cause the output to drain and pending input
+ to be discarded. */
+ {
+ struct hardwire_ttystate state;
+ if (get_tty_state (scb, &state))
+ {
+ return (-1);
+ }
+ else
+ {
+ return (ioctl (scb->fd, TIOCSETP, &state.sgttyb));
+ }
+ }
+#endif
+}
+
static int
hardwire_flush_output (scb)
serial_t scb;
@@ -391,7 +434,9 @@ wait_for(scb, timeout)
serial_t scb;
int timeout;
{
+#ifndef __CYGWIN32__
scb->timeout_remaining = 0;
+#endif
#ifdef HAVE_SGTTY
{
@@ -500,21 +545,37 @@ wait_for(scb, timeout)
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
-
static int
-hardwire_readchar(scb, timeout)
+hardwire_readchar (scb, timeout)
serial_t scb;
int timeout;
{
int status;
+#ifdef __CYGWIN32__
+ int t;
+#endif
if (scb->bufcnt-- > 0)
return *scb->bufp++;
+#ifdef __CYGWIN32__
+ if (timeout > 0)
+ timeout++;
+#endif
+
while (1)
{
+#ifdef __CYGWIN32__
+ t = timeout == 0 ? 0 : 1;
+ scb->timeout_remaining = timeout < 0 ? timeout : timeout - t;
+ status = wait_for (scb, t);
+
+ /* -2 means disable timer */
+ if (ui_loop_hook)
+ ui_loop_hook (-2);
+#else
status = wait_for (scb, timeout);
-
+#endif
if (status < 0)
return status;
@@ -531,6 +592,10 @@ hardwire_readchar(scb, timeout)
timeout = scb->timeout_remaining;
continue;
}
+#ifdef __CYGWIN32__
+ else if (scb->timeout_remaining < 0)
+ continue;
+#endif
else
return SERIAL_TIMEOUT;
}
@@ -579,6 +644,18 @@ baudtab[] =
{9600, B9600},
{19200, B19200},
{38400, B38400},
+#ifdef B57600
+ {57600, B57600},
+#endif
+#ifdef B115200
+ {115200, B115200},
+#endif
+#ifdef B230400
+ {230400, B230400},
+#endif
+#ifdef B460800
+ {460800, B460800},
+#endif
{-1, -1},
};
@@ -721,6 +798,7 @@ static struct serial_ops hardwire_ops =
hardwire_noflush_set_tty_state,
hardwire_setbaudrate,
hardwire_setstopbits,
+ hardwire_drain_output, /* wait for output to drain */
};
void
diff --git a/contrib/gdb/gdb/serial.c b/contrib/gdb/gdb/serial.c
index 18c6cde..ce420ee 100644
--- a/contrib/gdb/gdb/serial.c
+++ b/contrib/gdb/gdb/serial.c
@@ -1,5 +1,5 @@
/* Generic serial interface routines
- Copyright 1992, 1993, 1996 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
This file is part of GDB.
@@ -38,75 +38,110 @@ static serial_t scb_base;
/* Non-NULL gives filename which contains a recording of the remote session,
suitable for playback by gdbserver. */
-char *serial_logfile = NULL;
-FILE *serial_logfp = NULL;
+static char *serial_logfile = NULL;
+static GDB_FILE *serial_logfp = NULL;
+
+static struct serial_ops *serial_interface_lookup PARAMS ((char *));
+static void serial_logchar PARAMS ((int, int, int));
+static char logbase_hex[] = "hex";
+static char logbase_octal[] = "octal";
+static char logbase_ascii[] = "ascii";
+static char *logbase_enums[] = {logbase_hex, logbase_octal, logbase_ascii, NULL};
+static char *serial_logbase = logbase_ascii;
-static int serial_reading = 0;
-static int serial_writing = 0;
+static int serial_current_type = 0;
-void
-serial_log_command (cmd)
- const char *cmd;
-{
- if (serial_reading || serial_writing)
- {
- fputc_unfiltered ('\n', serial_logfp);
- serial_reading = 0;
- serial_writing = 0;
- }
- fprintf_unfiltered (serial_logfp, "c %s\n", cmd);
- /* Make sure that the log file is as up-to-date as possible,
- in case we are getting ready to dump core or something. */
- fflush (serial_logfp);
-}
+/* Log char CH of type CHTYPE, with TIMEOUT */
+
+/* Define bogus char to represent a BREAK. Should be careful to choose a value
+ that can't be confused with a normal char, or an error code. */
+#define SERIAL_BREAK 1235
static void
-serial_logchar (ch)
+serial_logchar (ch_type, ch, timeout)
+ int ch_type;
int ch;
+ int timeout;
{
+ if (ch_type != serial_current_type)
+ {
+ fprintf_unfiltered (serial_logfp, "\n%c ", ch_type);
+ serial_current_type = ch_type;
+ }
+
+ if (serial_logbase != logbase_ascii)
+ fputc_unfiltered (' ', serial_logfp);
+
switch (ch)
{
- case '\\': fputs_unfiltered ("\\\\", serial_logfp); break;
- case '\b': fputs_unfiltered ("\\b", serial_logfp); break;
- case '\f': fputs_unfiltered ("\\f", serial_logfp); break;
- case '\n': fputs_unfiltered ("\\n", serial_logfp); break;
- case '\r': fputs_unfiltered ("\\r", serial_logfp); break;
- case '\t': fputs_unfiltered ("\\t", serial_logfp); break;
- case '\v': fputs_unfiltered ("\\v", serial_logfp); break;
- default: fprintf_unfiltered (serial_logfp, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); break;
+ case SERIAL_TIMEOUT:
+ fprintf_unfiltered (serial_logfp, "<Timeout: %d seconds>", timeout);
+ return;
+ case SERIAL_ERROR:
+ fprintf_unfiltered (serial_logfp, "<Error: %s>", safe_strerror (errno));
+ return;
+ case SERIAL_EOF:
+ fputs_unfiltered ("<Eof>", serial_logfp);
+ return;
+ case SERIAL_BREAK:
+ fputs_unfiltered ("<Break>", serial_logfp);
+ return;
+ default:
+ if (serial_logbase == logbase_hex)
+ fprintf_unfiltered (serial_logfp, "%02x", ch & 0xff);
+ else if (serial_logbase == logbase_octal)
+ fprintf_unfiltered (serial_logfp, "%03o", ch & 0xff);
+ else
+ switch (ch)
+ {
+ case '\\': fputs_unfiltered ("\\\\", serial_logfp); break;
+ case '\b': fputs_unfiltered ("\\b", serial_logfp); break;
+ case '\f': fputs_unfiltered ("\\f", serial_logfp); break;
+ case '\n': fputs_unfiltered ("\\n", serial_logfp); break;
+ case '\r': fputs_unfiltered ("\\r", serial_logfp); break;
+ case '\t': fputs_unfiltered ("\\t", serial_logfp); break;
+ case '\v': fputs_unfiltered ("\\v", serial_logfp); break;
+ default: fprintf_unfiltered (serial_logfp, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); break;
+ }
}
}
+void
+serial_log_command (cmd)
+ const char *cmd;
+{
+ if (!serial_logfp)
+ return;
+
+ serial_current_type = 'c';
+
+ fputs_unfiltered ("\nc ", serial_logfp);
+ fputs_unfiltered (cmd, serial_logfp);
+
+ /* Make sure that the log file is as up-to-date as possible,
+ in case we are getting ready to dump core or something. */
+ gdb_flush (serial_logfp);
+}
+
int
serial_write (scb, str, len)
serial_t scb;
const char *str;
int len;
{
- int count;
-
if (serial_logfp != NULL)
{
- if (serial_reading)
- {
- fputc_unfiltered ('\n', serial_logfp);
- serial_reading = 0;
- }
- if (!serial_writing)
- {
- serial_logchar ('w');
- serial_logchar (' ');
- serial_writing = 1;
- }
+ int count;
+
for (count = 0; count < len; count++)
- {
- serial_logchar (str[count]);
- }
+ serial_logchar ('w', str[count] & 0xff, 0);
+
/* Make sure that the log file is as up-to-date as possible,
in case we are getting ready to dump core or something. */
- fflush (serial_logfp);
+ gdb_flush (serial_logfp);
}
+
return (scb -> ops -> write (scb, str, len));
}
@@ -120,25 +155,26 @@ serial_readchar (scb, timeout)
ch = scb -> ops -> readchar (scb, timeout);
if (serial_logfp != NULL)
{
- if (serial_writing)
- {
- fputc_unfiltered ('\n', serial_logfp);
- serial_writing = 0;
- }
- if (!serial_reading)
- {
- serial_logchar ('r');
- serial_logchar (' ');
- serial_reading = 1;
- }
- serial_logchar (ch);
+ serial_logchar ('r', ch, timeout);
+
/* Make sure that the log file is as up-to-date as possible,
in case we are getting ready to dump core or something. */
- fflush (serial_logfp);
+ gdb_flush (serial_logfp);
}
+
return (ch);
}
+int
+serial_send_break (scb)
+ serial_t scb;
+{
+ if (serial_logfp != NULL)
+ serial_logchar ('w', SERIAL_BREAK, 0);
+
+ return (scb -> ops -> send_break (scb));
+}
+
static struct serial_ops *
serial_interface_lookup (name)
char *name;
@@ -176,7 +212,9 @@ serial_open (name)
return scb;
}
- if (strcmp (name, "pc") == 0)
+ if (strcmp (name, "ocd") == 0)
+ ops = serial_interface_lookup ("ocd");
+ else if (strcmp (name, "pc") == 0)
ops = serial_interface_lookup ("pc");
else if (strchr (name, ':'))
ops = serial_interface_lookup ("tcp");
@@ -210,11 +248,9 @@ serial_open (name)
if (serial_logfile != NULL)
{
- serial_logfp = fopen (serial_logfile, "w");
+ serial_logfp = gdb_fopen (serial_logfile, "w");
if (serial_logfp == NULL)
- {
- perror_with_name (serial_logfile);
- }
+ perror_with_name (serial_logfile);
}
return scb;
@@ -259,7 +295,7 @@ serial_fdopen (fd)
}
void
-serial_close(scb, really_close)
+serial_close (scb, really_close)
serial_t scb;
int really_close;
{
@@ -269,13 +305,11 @@ serial_close(scb, really_close)
if (serial_logfp)
{
- if (serial_reading || serial_writing)
- {
- fputc_unfiltered ('\n', serial_logfp);
- serial_reading = 0;
- serial_writing = 0;
- }
- fclose (serial_logfp);
+ fputs_unfiltered ("\nEnd of log\n", serial_logfp);
+ serial_current_type = 0;
+
+ /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
+ gdb_fclose (&serial_logfp);
serial_logfp = NULL;
}
@@ -474,11 +508,19 @@ _initialize_serial ()
Use <CR>~. or <CR>~^D to break out.");
#endif /* 0 */
- add_show_from_set (add_set_cmd ("remotelogfile", no_class,
- var_filename, (char *)&serial_logfile,
- "Set filename for remote session recording.\n\
+ add_show_from_set
+ (add_set_cmd ("remotelogfile", no_class,
+ var_filename, (char *) &serial_logfile,
+ "Set filename for remote session recording.\n\
This file is used to record the remote session for future playback\n\
-by gdbserver.", &setlist),
- &showlist);
-
+by gdbserver.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_enum_cmd ("remotelogbase", no_class,
+ logbase_enums, (char *) &serial_logbase,
+ "Set numerical base for remote session logging",
+ &setlist),
+ &showlist);
}
diff --git a/contrib/gdb/gdb/serial.h b/contrib/gdb/gdb/serial.h
index 8abcb3d..04332bc 100644
--- a/contrib/gdb/gdb/serial.h
+++ b/contrib/gdb/gdb/serial.h
@@ -50,7 +50,9 @@ struct serial_ops {
void (*close) PARAMS ((serial_t));
int (*readchar) PARAMS ((serial_t, int timeout));
int (*write) PARAMS ((serial_t, const char *str, int len));
+ /* Discard pending output */
int (*flush_output) PARAMS ((serial_t));
+ /* Discard pending input */
int (*flush_input) PARAMS ((serial_t));
int (*send_break) PARAMS ((serial_t));
void (*go_raw) PARAMS ((serial_t));
@@ -61,6 +63,8 @@ struct serial_ops {
PARAMS ((serial_t, serial_ttystate, serial_ttystate));
int (*setbaudrate) PARAMS ((serial_t, int rate));
int (*setstopbits) PARAMS ((serial_t, int num));
+ /* Wait for output to drain */
+ int (*drain_output) PARAMS ((serial_t));
};
/* Add a new serial interface to the interface list */
@@ -83,7 +87,12 @@ serial_t serial_fdopen PARAMS ((const int fd));
#define SERIAL_FDOPEN(FD) serial_fdopen(FD)
-/* Flush pending output. Might also flush input (if this system can't flush
+/* Allow pending output to drain. */
+
+#define SERIAL_DRAIN_OUTPUT(SERIAL_T) \
+ ((SERIAL_T)->ops->drain_output((SERIAL_T)))
+
+/* Flush (discard) pending output. Might also flush input (if this system can't flush
only output). */
#define SERIAL_FLUSH_OUTPUT(SERIAL_T) \
@@ -97,8 +106,9 @@ serial_t serial_fdopen PARAMS ((const int fd));
/* Send a break between 0.25 and 0.5 seconds long. */
-#define SERIAL_SEND_BREAK(SERIAL_T) \
- ((*(SERIAL_T)->ops->send_break) (SERIAL_T))
+extern int serial_send_break PARAMS ((serial_t scb));
+
+#define SERIAL_SEND_BREAK(SERIAL_T) serial_send_break (SERIAL_T)
/* Turn the port into raw mode. */
@@ -176,7 +186,6 @@ extern void serial_printf PARAMS ((serial_t desc, const char *, ...))
/* File in which to record the remote debugging session */
-extern char *serial_logfile;
-extern FILE *serial_logfp;
+extern void serial_log_command PARAMS ((const char *));
#endif /* SERIAL_H */
diff --git a/contrib/gdb/gdb/sol-thread.c b/contrib/gdb/gdb/sol-thread.c
new file mode 100644
index 0000000..3fe6268
--- /dev/null
+++ b/contrib/gdb/gdb/sol-thread.c
@@ -0,0 +1,1673 @@
+/* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This module implements a sort of half target that sits between the
+ machine-independent parts of GDB and the /proc interface (procfs.c) to
+ provide access to the Solaris user-mode thread implementation.
+
+ Solaris threads are true user-mode threads, which are invoked via the thr_*
+ and pthread_* (native and Posix respectivly) interfaces. These are mostly
+ implemented in user-space, with all thread context kept in various
+ structures that live in the user's heap. These should not be confused with
+ lightweight processes (LWPs), which are implemented by the kernel, and
+ scheduled without explicit intervention by the process.
+
+ Just to confuse things a little, Solaris threads (both native and Posix) are
+ actually implemented using LWPs. In general, there are going to be more
+ threads than LWPs. There is no fixed correspondence between a thread and an
+ LWP. When a thread wants to run, it gets scheduled onto the first available
+ LWP and can therefore migrate from one LWP to another as time goes on. A
+ sleeping thread may not be associated with an LWP at all!
+
+ To make it possible to mess with threads, Sun provides a library called
+ libthread_db.so.1 (not to be confused with libthread_db.so.0, which doesn't
+ have a published interface). This interface has an upper part, which it
+ provides, and a lower part which I provide. The upper part consists of the
+ td_* routines, which allow me to find all the threads, query their state,
+ etc... The lower part consists of all of the ps_*, which are used by the
+ td_* routines to read/write memory, manipulate LWPs, lookup symbols, etc...
+ The ps_* routines actually do most of their work by calling functions in
+ procfs.c. */
+
+#include "defs.h"
+#include <thread.h>
+#include <proc_service.h>
+#include <thread_db.h>
+#include "gdbthread.h"
+#include "target.h"
+#include "inferior.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <dlfcn.h>
+#include "gdbcmd.h"
+
+extern struct target_ops sol_thread_ops; /* Forward declaration */
+extern struct target_ops sol_core_ops; /* Forward declaration */
+
+/* place to store core_ops before we overwrite it */
+static struct target_ops orig_core_ops;
+
+struct target_ops sol_thread_ops;
+struct target_ops sol_core_ops;
+
+extern int procfs_suppress_run;
+extern struct target_ops procfs_ops; /* target vector for procfs.c */
+extern struct target_ops core_ops; /* target vector for corelow.c */
+extern char *procfs_pid_to_str PARAMS ((int pid));
+
+/* Note that these prototypes differ slightly from those used in procfs.c
+ for of two reasons. One, we can't use gregset_t, as that's got a whole
+ different meaning under Solaris (also, see above). Two, we can't use the
+ pointer form here as these are actually arrays of ints (for Sparc's at
+ least), and are automatically coerced into pointers to ints when used as
+ parameters. That makes it impossible to avoid a compiler warning when
+ passing pr{g fp}regset_t's from a parameter to an argument of one of
+ these functions. */
+
+extern void supply_gregset PARAMS ((const prgregset_t));
+extern void fill_gregset PARAMS ((prgregset_t, int));
+extern void supply_fpregset PARAMS ((const prfpregset_t *));
+extern void fill_fpregset PARAMS ((prfpregset_t *, int));
+
+/* This struct is defined by us, but mainly used for the proc_service interface.
+ We don't have much use for it, except as a handy place to get a real pid
+ for memory accesses. */
+
+struct ps_prochandle
+{
+ pid_t pid;
+};
+
+struct string_map
+{
+ int num;
+ char *str;
+};
+
+static struct ps_prochandle main_ph;
+static td_thragent_t *main_ta;
+static int sol_thread_active = 0;
+
+static struct cleanup * save_inferior_pid PARAMS ((void));
+static void restore_inferior_pid PARAMS ((int pid));
+static char *td_err_string PARAMS ((td_err_e errcode));
+static char *td_state_string PARAMS ((td_thr_state_e statecode));
+static int thread_to_lwp PARAMS ((int thread_id, int default_lwp));
+static void sol_thread_resume PARAMS ((int pid, int step,
+ enum target_signal signo));
+static int lwp_to_thread PARAMS ((int lwp));
+static int sol_thread_alive PARAMS ((int pid));
+static void sol_core_close PARAMS ((int quitting));
+
+static void init_sol_thread_ops PARAMS ((void));
+static void init_sol_core_ops PARAMS ((void));
+
+#define THREAD_FLAG 0x80000000
+#define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
+#define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0)
+#define GET_LWP(LWP_ID) (TIDGET(LWP_ID))
+#define GET_THREAD(THREAD_ID) (((THREAD_ID) >> 16) & 0x7fff)
+#define BUILD_LWP(LWP_ID, PID) ((LWP_ID) << 16 | (PID))
+#define BUILD_THREAD(THREAD_ID, PID) (THREAD_FLAG | BUILD_LWP (THREAD_ID, PID))
+
+/* Pointers to routines from lithread_db resolved by dlopen() */
+
+static void
+ (*p_td_log) (const int on_off);
+static td_err_e
+ (*p_td_ta_new) (const struct ps_prochandle *ph_p, td_thragent_t **ta_pp);
+static td_err_e
+ (*p_td_ta_delete) (td_thragent_t *ta_p);
+static td_err_e
+ (*p_td_init) (void);
+static td_err_e
+ (*p_td_ta_get_ph) (const td_thragent_t *ta_p, struct ps_prochandle **ph_pp);
+static td_err_e
+ (*p_td_ta_get_nthreads) (const td_thragent_t *ta_p, int *nthread_p);
+static td_err_e
+ (*p_td_ta_tsd_iter) (const td_thragent_t *ta_p, td_key_iter_f *cb, void *cbdata_p);
+static td_err_e
+ (*p_td_ta_thr_iter) (const td_thragent_t *ta_p, td_thr_iter_f *cb, void *cbdata_p, td_thr_state_e state,
+ int ti_pri, sigset_t *ti_sigmask_p, unsigned ti_user_flags);
+static td_err_e
+ (*p_td_thr_validate) (const td_thrhandle_t *th_p);
+static td_err_e
+ (*p_td_thr_tsd) (const td_thrhandle_t *th_p, const thread_key_t key, void **data_pp);
+static td_err_e
+ (*p_td_thr_get_info) (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p);
+static td_err_e
+ (*p_td_thr_getfpregs) (const td_thrhandle_t *th_p, prfpregset_t *fpregset);
+static td_err_e
+ (*p_td_thr_getxregsize) (const td_thrhandle_t *th_p, int *xregsize);
+static td_err_e
+ (*p_td_thr_getxregs) (const td_thrhandle_t *th_p, const caddr_t xregset);
+static td_err_e
+ (*p_td_thr_sigsetmask) (const td_thrhandle_t *th_p, const sigset_t ti_sigmask);
+static td_err_e
+ (*p_td_thr_setprio) (const td_thrhandle_t *th_p, const int ti_pri);
+static td_err_e
+ (*p_td_thr_setsigpending) (const td_thrhandle_t *th_p, const uchar_t ti_pending_flag, const sigset_t ti_pending);
+static td_err_e
+ (*p_td_thr_setfpregs) (const td_thrhandle_t *th_p, const prfpregset_t *fpregset);
+static td_err_e
+ (*p_td_thr_setxregs) (const td_thrhandle_t *th_p, const caddr_t xregset);
+static td_err_e
+ (*p_td_ta_map_id2thr) (const td_thragent_t *ta_p, thread_t tid, td_thrhandle_t *th_p);
+static td_err_e
+ (*p_td_ta_map_lwp2thr) (const td_thragent_t *ta_p, lwpid_t lwpid, td_thrhandle_t *th_p);
+static td_err_e
+ (*p_td_thr_getgregs) (const td_thrhandle_t *th_p, prgregset_t regset);
+static td_err_e
+ (*p_td_thr_setgregs) (const td_thrhandle_t *th_p, const prgregset_t regset);
+
+/*
+
+LOCAL FUNCTION
+
+ td_err_string - Convert a thread_db error code to a string
+
+SYNOPSIS
+
+ char * td_err_string (errcode)
+
+DESCRIPTION
+
+ Return the thread_db error string associated with errcode. If errcode
+ is unknown, then return a message.
+
+ */
+
+static char *
+td_err_string (errcode)
+ td_err_e errcode;
+{
+ static struct string_map
+ td_err_table[] = {
+ {TD_OK, "generic \"call succeeded\""},
+ {TD_ERR, "generic error."},
+ {TD_NOTHR, "no thread can be found to satisfy query"},
+ {TD_NOSV, "no synch. variable can be found to satisfy query"},
+ {TD_NOLWP, "no lwp can be found to satisfy query"},
+ {TD_BADPH, "invalid process handle"},
+ {TD_BADTH, "invalid thread handle"},
+ {TD_BADSH, "invalid synchronization handle"},
+ {TD_BADTA, "invalid thread agent"},
+ {TD_BADKEY, "invalid key"},
+ {TD_NOMSG, "td_thr_event_getmsg() called when there was no message"},
+ {TD_NOFPREGS, "FPU register set not available for given thread"},
+ {TD_NOLIBTHREAD, "application not linked with libthread"},
+ {TD_NOEVENT, "requested event is not supported"},
+ {TD_NOCAPAB, "capability not available"},
+ {TD_DBERR, "Debugger service failed"},
+ {TD_NOAPLIC, "Operation not applicable to"},
+ {TD_NOTSD, "No thread specific data for this thread"},
+ {TD_MALLOC, "Malloc failed"},
+ {TD_PARTIALREG, "Only part of register set was writen/read"},
+ {TD_NOXREGS, "X register set not available for given thread"}
+ };
+ const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
+ int i;
+ static char buf[50];
+
+ for (i = 0; i < td_err_size; i++)
+ if (td_err_table[i].num == errcode)
+ return td_err_table[i].str;
+
+ sprintf (buf, "Unknown thread_db error code: %d", errcode);
+
+ return buf;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ td_state_string - Convert a thread_db state code to a string
+
+SYNOPSIS
+
+ char * td_state_string (statecode)
+
+DESCRIPTION
+
+ Return the thread_db state string associated with statecode. If
+ statecode is unknown, then return a message.
+
+ */
+
+static char *
+td_state_string (statecode)
+ td_thr_state_e statecode;
+{
+ static struct string_map
+ td_thr_state_table[] = {
+ {TD_THR_ANY_STATE, "any state"},
+ {TD_THR_UNKNOWN, "unknown"},
+ {TD_THR_STOPPED, "stopped"},
+ {TD_THR_RUN, "run"},
+ {TD_THR_ACTIVE, "active"},
+ {TD_THR_ZOMBIE, "zombie"},
+ {TD_THR_SLEEP, "sleep"},
+ {TD_THR_STOPPED_ASLEEP, "stopped asleep"}
+ };
+ const int td_thr_state_table_size = sizeof td_thr_state_table / sizeof (struct string_map);
+ int i;
+ static char buf[50];
+
+ for (i = 0; i < td_thr_state_table_size; i++)
+ if (td_thr_state_table[i].num == statecode)
+ return td_thr_state_table[i].str;
+
+ sprintf (buf, "Unknown thread_db state code: %d", statecode);
+
+ return buf;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id.
+
+SYNOPSIS
+
+ int thread_to_lwp (thread_id, default_lwp)
+
+DESCRIPTION
+
+ This function converts a Posix or Solaris thread id to a lightweight
+ process id. If thread_id is non-existent, that's an error. If it's
+ an inactive thread, then we return default_lwp.
+
+NOTES
+
+ This function probably shouldn't call error()...
+
+ */
+
+static int
+thread_to_lwp (thread_id, default_lwp)
+ int thread_id;
+ int default_lwp;
+{
+ td_thrinfo_t ti;
+ td_thrhandle_t th;
+ td_err_e val;
+
+ if (is_lwp (thread_id))
+ return thread_id; /* It's already an LWP id */
+
+ /* It's a thread. Convert to lwp */
+
+ val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
+ if (val == TD_NOTHR)
+ return -1; /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val));
+
+ val = p_td_thr_get_info (&th, &ti);
+ if (val == TD_NOTHR)
+ return -1; /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val));
+
+ if (ti.ti_state != TD_THR_ACTIVE)
+ {
+ if (default_lwp != -1)
+ return default_lwp;
+ error ("thread_to_lwp: thread state not active: %s",
+ td_state_string (ti.ti_state));
+ }
+
+ return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
+}
+
+/*
+
+LOCAL FUNCTION
+
+ lwp_to_thread - Convert a LWP id to a Posix or Solaris thread id.
+
+SYNOPSIS
+
+ int lwp_to_thread (lwp_id)
+
+DESCRIPTION
+
+ This function converts a lightweight process id to a Posix or Solaris
+ thread id. If thread_id is non-existent, that's an error.
+
+NOTES
+
+ This function probably shouldn't call error()...
+
+ */
+
+static int
+lwp_to_thread (lwp)
+ int lwp;
+{
+ td_thrinfo_t ti;
+ td_thrhandle_t th;
+ td_err_e val;
+
+ if (is_thread (lwp))
+ return lwp; /* It's already a thread id */
+
+ /* It's an lwp. Convert it to a thread id. */
+
+ if (!sol_thread_alive (lwp))
+ return -1; /* defunct lwp */
+
+ val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
+ if (val == TD_NOTHR)
+ return -1; /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val));
+
+ val = p_td_thr_validate (&th);
+ if (val == TD_NOTHR)
+ return lwp; /* libthread doesn't know about it, just return lwp */
+ else if (val != TD_OK)
+ error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val));
+
+ val = p_td_thr_get_info (&th, &ti);
+ if (val == TD_NOTHR)
+ return -1; /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val));
+
+ return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
+}
+
+/*
+
+LOCAL FUNCTION
+
+ save_inferior_pid - Save inferior_pid on the cleanup list
+ restore_inferior_pid - Restore inferior_pid from the cleanup list
+
+SYNOPSIS
+
+ struct cleanup *save_inferior_pid ()
+ void restore_inferior_pid (int pid)
+
+DESCRIPTION
+
+ These two functions act in unison to restore inferior_pid in
+ case of an error.
+
+NOTES
+
+ inferior_pid is a global variable that needs to be changed by many of
+ these routines before calling functions in procfs.c. In order to
+ guarantee that inferior_pid gets restored (in case of errors), you
+ need to call save_inferior_pid before changing it. At the end of the
+ function, you should invoke do_cleanups to restore it.
+
+ */
+
+
+static struct cleanup *
+save_inferior_pid ()
+{
+ return make_cleanup (restore_inferior_pid, inferior_pid);
+}
+
+static void
+restore_inferior_pid (pid)
+ int pid;
+{
+ inferior_pid = pid;
+}
+
+
+/* Most target vector functions from here on actually just pass through to
+ procfs.c, as they don't need to do anything specific for threads. */
+
+
+/* ARGSUSED */
+static void
+sol_thread_open (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ procfs_ops.to_open (arg, from_tty);
+}
+
+/* Attach to process PID, then initialize for debugging it
+ and wait for the trace-trap that results from attaching. */
+
+static void
+sol_thread_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ procfs_ops.to_attach (args, from_tty);
+ /* Must get symbols from solibs before libthread_db can run! */
+ SOLIB_ADD ((char *)0, from_tty, (struct target_ops *)0);
+ if (sol_thread_active)
+ {
+ printf_filtered ("sol-thread active.\n");
+ main_ph.pid = inferior_pid; /* Save for xfer_memory */
+ push_target (&sol_thread_ops);
+ inferior_pid = lwp_to_thread (inferior_pid);
+ if (inferior_pid == -1)
+ inferior_pid = main_ph.pid;
+ else
+ add_thread (inferior_pid);
+ }
+ /* XXX - might want to iterate over all the threads and register them. */
+}
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+sol_thread_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ unpush_target (&sol_thread_ops);
+ procfs_ops.to_detach (args, from_tty);
+}
+
+/* Resume execution of process PID. If STEP is nozero, then
+ just single step it. If SIGNAL is nonzero, restart it with that
+ signal activated. We may have to convert pid from a thread-id to an LWP id
+ for procfs. */
+
+static void
+sol_thread_resume (pid, step, signo)
+ int pid;
+ int step;
+ enum target_signal signo;
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid);
+ if (inferior_pid == -1)
+ inferior_pid = procfs_first_available ();
+
+ if (pid != -1)
+ {
+ int save_pid = pid;
+
+ pid = thread_to_lwp (pid, -2);
+ if (pid == -2) /* Inactive thread */
+ error ("This version of Solaris can't start inactive threads.");
+ if (info_verbose && pid == -1)
+ warning ("Specified thread %d seems to have terminated",
+ GET_THREAD (save_pid));
+ }
+
+ procfs_ops.to_resume (pid, step, signo);
+
+ do_cleanups (old_chain);
+}
+
+/* Wait for any threads to stop. We may have to convert PID from a thread id
+ to a LWP id, and vice versa on the way out. */
+
+static int
+sol_thread_wait (pid, ourstatus)
+ int pid;
+ struct target_waitstatus *ourstatus;
+{
+ int rtnval;
+ int save_pid;
+ struct cleanup *old_chain;
+
+ save_pid = inferior_pid;
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid);
+ if (inferior_pid == -1)
+ inferior_pid = procfs_first_available ();
+
+ if (pid != -1)
+ {
+ int save_pid = pid;
+
+ pid = thread_to_lwp (pid, -2);
+ if (pid == -2) /* Inactive thread */
+ error ("This version of Solaris can't start inactive threads.");
+ if (info_verbose && pid == -1)
+ warning ("Specified thread %d seems to have terminated",
+ GET_THREAD (save_pid));
+ }
+
+ rtnval = procfs_ops.to_wait (pid, ourstatus);
+
+ if (ourstatus->kind != TARGET_WAITKIND_EXITED)
+ {
+ /* Map the LWP of interest back to the appropriate thread ID */
+ rtnval = lwp_to_thread (rtnval);
+ if (rtnval == -1)
+ rtnval = save_pid;
+
+ /* See if we have a new thread */
+ if (is_thread (rtnval)
+ && rtnval != save_pid
+ && !in_thread_list (rtnval))
+ {
+ printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
+ add_thread (rtnval);
+ }
+ }
+
+ /* During process initialization, we may get here without the thread package
+ being initialized, since that can only happen after we've found the shared
+ libs. */
+
+ do_cleanups (old_chain);
+
+ return rtnval;
+}
+
+static void
+sol_thread_fetch_registers (regno)
+ int regno;
+{
+ thread_t thread;
+ td_thrhandle_t thandle;
+ td_err_e val;
+ prgregset_t gregset;
+ prfpregset_t fpregset;
+#if 0
+ int xregsize;
+ caddr_t xregset;
+#endif
+
+ if (!is_thread (inferior_pid))
+ { /* LWP: pass the request on to procfs.c */
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (regno);
+ else
+ orig_core_ops.to_fetch_registers (regno);
+ return;
+ }
+
+ /* Solaris thread: convert inferior_pid into a td_thrhandle_t */
+
+ thread = GET_THREAD (inferior_pid);
+
+ if (thread == 0)
+ error ("sol_thread_fetch_registers: thread == 0");
+
+ val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
+ if (val != TD_OK)
+ error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
+ td_err_string (val));
+
+ /* Get the integer regs */
+
+ val = p_td_thr_getgregs (&thandle, gregset);
+ if (val != TD_OK
+ && val != TD_PARTIALREG)
+ error ("sol_thread_fetch_registers: td_thr_getgregs %s",
+ td_err_string (val));
+
+ /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp
+ are saved (by a thread context switch). */
+
+ /* And, now the fp regs */
+
+ val = p_td_thr_getfpregs (&thandle, &fpregset);
+ if (val != TD_OK
+ && val != TD_NOFPREGS)
+ error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
+ td_err_string (val));
+
+/* Note that we must call supply_{g fp}regset *after* calling the td routines
+ because the td routines call ps_lget* which affect the values stored in the
+ registers array. */
+
+ supply_gregset (gregset);
+ supply_fpregset (&fpregset);
+
+#if 0
+/* thread_db doesn't seem to handle this right */
+ val = td_thr_getxregsize (&thandle, &xregsize);
+ if (val != TD_OK && val != TD_NOXREGS)
+ error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
+ td_err_string (val));
+
+ if (val == TD_OK)
+ {
+ xregset = alloca (xregsize);
+ val = td_thr_getxregs (&thandle, xregset);
+ if (val != TD_OK)
+ error ("sol_thread_fetch_registers: td_thr_getxregs %s",
+ td_err_string (val));
+ }
+#endif
+}
+
+static void
+sol_thread_store_registers (regno)
+ int regno;
+{
+ thread_t thread;
+ td_thrhandle_t thandle;
+ td_err_e val;
+ prgregset_t regset;
+ prfpregset_t fpregset;
+#if 0
+ int xregsize;
+ caddr_t xregset;
+#endif
+
+ if (!is_thread (inferior_pid))
+ { /* LWP: pass the request on to procfs.c */
+ procfs_ops.to_store_registers (regno);
+ return;
+ }
+
+ /* Solaris thread: convert inferior_pid into a td_thrhandle_t */
+
+ thread = GET_THREAD (inferior_pid);
+
+ val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_ta_map_id2thr %s",
+ td_err_string (val));
+
+ if (regno != -1)
+ { /* Not writing all the regs */
+ /* save new register value */
+ char old_value[REGISTER_SIZE];
+ memcpy(old_value, & registers[REGISTER_BYTE(regno)], REGISTER_SIZE);
+
+ val = p_td_thr_getgregs (&thandle, regset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_getgregs %s",
+ td_err_string (val));
+ val = p_td_thr_getfpregs (&thandle, &fpregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_getfpregs %s",
+ td_err_string (val));
+
+ /* restore new register value */
+ memcpy(& registers[REGISTER_BYTE(regno)], old_value, REGISTER_SIZE);
+
+#if 0
+/* thread_db doesn't seem to handle this right */
+ val = td_thr_getxregsize (&thandle, &xregsize);
+ if (val != TD_OK && val != TD_NOXREGS)
+ error ("sol_thread_store_registers: td_thr_getxregsize %s",
+ td_err_string (val));
+
+ if (val == TD_OK)
+ {
+ xregset = alloca (xregsize);
+ val = td_thr_getxregs (&thandle, xregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_getxregs %s",
+ td_err_string (val));
+ }
+#endif
+ }
+
+ fill_gregset (regset, regno);
+ fill_fpregset (&fpregset, regno);
+
+ val = p_td_thr_setgregs (&thandle, regset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_setgregs %s",
+ td_err_string (val));
+ val = p_td_thr_setfpregs (&thandle, &fpregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_setfpregs %s",
+ td_err_string (val));
+
+#if 0
+/* thread_db doesn't seem to handle this right */
+ val = td_thr_getxregsize (&thandle, &xregsize);
+ if (val != TD_OK && val != TD_NOXREGS)
+ error ("sol_thread_store_registers: td_thr_getxregsize %s",
+ td_err_string (val));
+
+ /* Should probably do something about writing the xregs here, but what are
+ they? */
+#endif
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+sol_thread_prepare_to_store ()
+{
+ procfs_ops.to_prepare_to_store ();
+}
+
+static int
+sol_thread_xfer_memory (memaddr, myaddr, len, dowrite, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int dowrite;
+ struct target_ops *target; /* ignored */
+{
+ int retval;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ if (is_thread (inferior_pid) || /* A thread */
+ !target_thread_alive (inferior_pid)) /* An lwp, but not alive */
+ inferior_pid = procfs_first_available (); /* Find any live lwp. */
+ /* Note: don't need to call switch_to_thread; we're just reading memory. */
+
+ if (target_has_execution)
+ retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
+ else
+ retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len,
+ dowrite, target);
+
+ do_cleanups (old_chain);
+
+ return retval;
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+sol_thread_files_info (ignore)
+ struct target_ops *ignore;
+{
+ procfs_ops.to_files_info (ignore);
+}
+
+static void
+sol_thread_kill_inferior ()
+{
+ procfs_ops.to_kill ();
+}
+
+static void
+sol_thread_notice_signals (pid)
+ int pid;
+{
+ procfs_ops.to_notice_signals (PIDGET (pid));
+}
+
+/* Fork an inferior process, and start debugging it with /proc. */
+
+static void
+sol_thread_create_inferior (exec_file, allargs, env)
+ char *exec_file;
+ char *allargs;
+ char **env;
+{
+ procfs_ops.to_create_inferior (exec_file, allargs, env);
+
+ if (sol_thread_active && inferior_pid != 0)
+ {
+ main_ph.pid = inferior_pid; /* Save for xfer_memory */
+
+ push_target (&sol_thread_ops);
+
+ inferior_pid = lwp_to_thread (inferior_pid);
+ if (inferior_pid == -1)
+ inferior_pid = main_ph.pid;
+
+ add_thread (inferior_pid);
+ }
+}
+
+/* This routine is called whenever a new symbol table is read in, or when all
+ symbol tables are removed. libthread_db can only be initialized when it
+ finds the right variables in libthread.so. Since it's a shared library,
+ those variables don't show up until the library gets mapped and the symbol
+ table is read in. */
+
+void
+sol_thread_new_objfile (objfile)
+ struct objfile *objfile;
+{
+ td_err_e val;
+
+ if (!objfile)
+ {
+ sol_thread_active = 0;
+
+ return;
+ }
+
+ /* don't do anything if init failed to resolve the libthread_db library */
+ if (!procfs_suppress_run)
+ return;
+
+ /* Now, initialize the thread debugging library. This needs to be done after
+ the shared libraries are located because it needs information from the
+ user's thread library. */
+
+ val = p_td_init ();
+ if (val != TD_OK)
+ error ("target_new_objfile: td_init: %s", td_err_string (val));
+
+ val = p_td_ta_new (&main_ph, &main_ta);
+ if (val == TD_NOLIBTHREAD)
+ return;
+ else if (val != TD_OK)
+ error ("target_new_objfile: td_ta_new: %s", td_err_string (val));
+
+ sol_thread_active = 1;
+}
+
+/* Clean up after the inferior dies. */
+
+static void
+sol_thread_mourn_inferior ()
+{
+ unpush_target (&sol_thread_ops);
+ procfs_ops.to_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
+
+static int
+sol_thread_can_run ()
+{
+ return procfs_suppress_run;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ sol_thread_alive - test thread for "aliveness"
+
+SYNOPSIS
+
+ static bool sol_thread_alive (int pid);
+
+DESCRIPTION
+
+ returns true if thread still active in inferior.
+
+ */
+
+static int
+sol_thread_alive (pid)
+ int pid;
+{
+ if (is_thread (pid)) /* non-kernel thread */
+ {
+ td_err_e val;
+ td_thrhandle_t th;
+
+ pid = GET_THREAD (pid);
+ if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
+ return 0; /* thread not found */
+ if ((val = p_td_thr_validate (&th)) != TD_OK)
+ return 0; /* thread not valid */
+ return 1; /* known thread: return true */
+ }
+ else /* kernel thread (LWP): let procfs test it */
+ {
+ if (target_has_execution)
+ return procfs_ops.to_thread_alive (pid);
+ else
+ return orig_core_ops.to_thread_alive (pid);
+ }
+}
+
+static void
+sol_thread_stop ()
+{
+ procfs_ops.to_stop ();
+}
+
+/* These routines implement the lower half of the thread_db interface. Ie: the
+ ps_* routines. */
+
+/* Various versions of <proc_service.h> have slightly
+ different function prototypes. In particular, we have
+
+ NEWER OLDER
+ struct ps_prochandle * const struct ps_prochandle *
+ void* char*
+ const void* char*
+ int size_t
+
+ Which one you have depends on solaris version and what
+ patches you've applied. On the theory that there are
+ only two major variants, we have configure check the
+ prototype of ps_pdwrite (), and use that info to make
+ appropriate typedefs here. */
+
+#ifdef PROC_SERVICE_IS_OLD
+typedef const struct ps_prochandle * gdb_ps_prochandle_t;
+typedef char * gdb_ps_read_buf_t;
+typedef char * gdb_ps_write_buf_t;
+typedef int gdb_ps_size_t;
+#else
+typedef struct ps_prochandle * gdb_ps_prochandle_t;
+typedef void * gdb_ps_read_buf_t;
+typedef const void * gdb_ps_write_buf_t;
+typedef size_t gdb_ps_size_t;
+#endif
+
+
+/* The next four routines are called by thread_db to tell us to stop and stop
+ a particular process or lwp. Since GDB ensures that these are all stopped
+ by the time we call anything in thread_db, these routines need to do
+ nothing. */
+
+ps_err_e
+ps_pstop (gdb_ps_prochandle_t ph)
+{
+ return PS_OK;
+}
+
+ps_err_e
+ps_pcontinue (gdb_ps_prochandle_t ph)
+{
+ return PS_OK;
+}
+
+ps_err_e
+ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ return PS_OK;
+}
+
+ps_err_e
+ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ return PS_OK;
+}
+
+ps_err_e
+ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
+ const char *ld_symbol_name, paddr_t *ld_symbol_addr)
+{
+ struct minimal_symbol *ms;
+
+ ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
+
+ if (!ms)
+ return PS_NOSYM;
+
+ *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
+
+ return PS_OK;
+}
+
+/* Common routine for reading and writing memory. */
+
+static ps_err_e
+rw_common (int dowrite, const struct ps_prochandle *ph, paddr_t addr,
+ char *buf, int size)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ if (is_thread (inferior_pid) || /* A thread */
+ !target_thread_alive (inferior_pid)) /* An lwp, but not alive */
+ inferior_pid = procfs_first_available (); /* Find any live lwp. */
+ /* Note: don't need to call switch_to_thread; we're just reading memory. */
+
+ while (size > 0)
+ {
+ int cc;
+
+ if (target_has_execution)
+ cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, &procfs_ops);
+ else
+ cc = orig_core_ops.to_xfer_memory (addr, buf, size, dowrite, &core_ops);
+
+ if (cc < 0)
+ {
+ if (dowrite == 0)
+ print_sys_errmsg ("rw_common (): read", errno);
+ else
+ print_sys_errmsg ("rw_common (): write", errno);
+
+ do_cleanups (old_chain);
+
+ return PS_ERR;
+ }
+ size -= cc;
+ buf += cc;
+ }
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+ps_err_e
+ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (0, ph, addr, buf, size);
+}
+
+ps_err_e
+ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (1, ph, addr, (char*) buf, size);
+}
+
+ps_err_e
+ps_ptread (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (0, ph, addr, buf, size);
+}
+
+ps_err_e
+ps_ptwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (1, ph, addr, (char*) buf, size);
+}
+
+/* Get integer regs */
+
+ps_err_e
+ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ prgregset_t gregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
+
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (-1);
+ else
+ orig_core_ops.to_fetch_registers (-1);
+ fill_gregset (gregset, -1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+/* Set integer regs */
+
+ps_err_e
+ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ const prgregset_t gregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
+
+ supply_gregset (gregset);
+ if (target_has_execution)
+ procfs_ops.to_store_registers (-1);
+ else
+ orig_core_ops.to_store_registers (-1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+void
+ps_plog (const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+
+ vfprintf_filtered (gdb_stderr, fmt, args);
+}
+
+/* Get size of extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
+{
+#if 0
+ int lwp_fd;
+ int regsize;
+ ps_err_e val;
+
+ val = get_lwp_fd (ph, lwpid, &lwp_fd);
+ if (val != PS_OK)
+ return val;
+
+ if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
+ {
+ if (errno == EINVAL)
+ return PS_NOFREGS; /* XXX Wrong code, but this is the closest
+ thing in proc_service.h */
+
+ print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
+ return PS_ERR;
+ }
+#endif
+
+ return PS_OK;
+}
+
+/* Get extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+#if 0
+ int lwp_fd;
+ ps_err_e val;
+
+ val = get_lwp_fd (ph, lwpid, &lwp_fd);
+ if (val != PS_OK)
+ return val;
+
+ if (ioctl (lwp_fd, PIOCGXREG, xregset))
+ {
+ print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
+ return PS_ERR;
+ }
+#endif
+
+ return PS_OK;
+}
+
+/* Set extra register set. Currently a noop. */
+
+ps_err_e
+ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+#if 0
+ int lwp_fd;
+ ps_err_e val;
+
+ val = get_lwp_fd (ph, lwpid, &lwp_fd);
+ if (val != PS_OK)
+ return val;
+
+ if (ioctl (lwp_fd, PIOCSXREG, xregset))
+ {
+ print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
+ return PS_ERR;
+ }
+#endif
+
+ return PS_OK;
+}
+
+/* Get floating-point regs. */
+
+ps_err_e
+ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ prfpregset_t *fpregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
+
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (-1);
+ else
+ orig_core_ops.to_fetch_registers (-1);
+ fill_fpregset (fpregset, -1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+/* Set floating-point regs. */
+
+ps_err_e
+ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ const prfpregset_t *fpregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_pid ();
+
+ inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
+
+ supply_fpregset (fpregset);
+ if (target_has_execution)
+ procfs_ops.to_store_registers (-1);
+ else
+ orig_core_ops.to_store_registers (-1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+#ifdef TM_I386SOL2_H
+
+/* Get local descriptor table. */
+
+#include <sys/procfs.h>
+#include <sys/reg.h>
+#include <sys/sysi86.h>
+
+static int nldt_allocated = 0;
+static struct ssd *ldt_bufp = NULL;
+
+ps_err_e
+ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ struct ssd *pldt)
+{
+ gregset_t gregset;
+ int lwp_fd;
+ ps_err_e val;
+ int nldt;
+ int i;
+
+ /* Get procfs file descriptor for the LWP. */
+ lwp_fd = procfs_get_pid_fd (BUILD_LWP (lwpid, PIDGET (inferior_pid)));
+ if (lwp_fd < 0)
+ return PS_BADLID;
+
+ /* Fetch registers und LDT descriptors. */
+ if (ioctl (lwp_fd, PIOCGREG, &gregset) == -1)
+ return PS_ERR;
+
+ if (ioctl (lwp_fd, PIOCNLDT, &nldt) == -1)
+ return PS_ERR;
+
+ if (nldt_allocated < nldt)
+ {
+ ldt_bufp
+ = (struct ssd *) xrealloc (ldt_bufp, (nldt + 1) * sizeof (struct ssd));
+ nldt_allocated = nldt;
+ }
+
+ if (ioctl (lwp_fd, PIOCLDT, ldt_bufp) == -1)
+ return PS_ERR;
+
+ /* Search LDT for the LWP via register GS. */
+ for (i = 0; i < nldt; i++)
+ {
+ if (ldt_bufp[i].sel == (gregset[GS] & 0xffff))
+ {
+ *pldt = ldt_bufp[i];
+ return PS_OK;
+ }
+ }
+
+ /* LDT not found. */
+ return PS_ERR;
+}
+#endif /* TM_I386SOL2_H */
+
+/* Convert a pid to printable form. */
+
+char *
+solaris_pid_to_str (pid)
+ int pid;
+{
+ static char buf[100];
+
+ /* in case init failed to resolve the libthread_db library */
+ if (!procfs_suppress_run)
+ return procfs_pid_to_str (pid);
+
+ if (is_thread (pid))
+ {
+ int lwp;
+
+ lwp = thread_to_lwp (pid, -2);
+
+ if (lwp == -1)
+ sprintf (buf, "Thread %d (defunct)", GET_THREAD (pid));
+ else if (lwp != -2)
+ sprintf (buf, "Thread %d (LWP %d)", GET_THREAD (pid), GET_LWP (lwp));
+ else
+ sprintf (buf, "Thread %d ", GET_THREAD (pid));
+ }
+ else if (GET_LWP (pid) != 0)
+ sprintf (buf, "LWP %d ", GET_LWP (pid));
+ else
+ sprintf (buf, "process %d ", PIDGET (pid));
+
+ return buf;
+}
+
+
+/* Worker bee for find_new_threads
+ Callback function that gets called once per USER thread (i.e., not
+ kernel) thread. */
+
+static int
+sol_find_new_threads_callback(th, ignored)
+ const td_thrhandle_t *th;
+ void *ignored;
+{
+ td_err_e retval;
+ td_thrinfo_t ti;
+ int pid;
+
+ if ((retval = p_td_thr_get_info(th, &ti)) != TD_OK)
+ {
+ return -1;
+ }
+ pid = BUILD_THREAD(ti.ti_tid, PIDGET(inferior_pid));
+ if (!in_thread_list(pid))
+ add_thread(pid);
+
+ return 0;
+}
+
+void
+sol_find_new_threads()
+{
+ /* don't do anything if init failed to resolve the libthread_db library */
+ if (!procfs_suppress_run)
+ return;
+
+ if (inferior_pid == -1)
+ {
+ printf_filtered("No process.\n");
+ return;
+ }
+ p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *)0,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+}
+
+static void
+sol_core_open (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ orig_core_ops.to_open (filename, from_tty);
+}
+
+static void
+sol_core_close (quitting)
+ int quitting;
+{
+ orig_core_ops.to_close (quitting);
+}
+
+static void
+sol_core_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ unpush_target (&core_ops);
+ orig_core_ops.to_detach (args, from_tty);
+}
+
+static void
+sol_core_files_info (t)
+ struct target_ops *t;
+{
+ orig_core_ops.to_files_info (t);
+}
+
+#ifdef MAINTENANCE_CMDS
+/* Worker bee for info sol-thread command. This is a callback function that
+ gets called once for each Solaris thread (ie. not kernel thread) in the
+ inferior. Print anything interesting that we can think of. */
+
+static int
+info_cb (th, s)
+ const td_thrhandle_t *th;
+ void *s;
+{
+ td_err_e ret;
+ td_thrinfo_t ti;
+ struct minimal_symbol *msym;
+
+ if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK)
+ {
+ printf_filtered ("%s thread #%d, lwp %d, ",
+ ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
+ ti.ti_tid, ti.ti_lid);
+ switch (ti.ti_state) {
+ default:
+ case TD_THR_UNKNOWN: printf_filtered ("<unknown state>"); break;
+ case TD_THR_STOPPED: printf_filtered ("(stopped)"); break;
+ case TD_THR_RUN: printf_filtered ("(run) "); break;
+ case TD_THR_ACTIVE: printf_filtered ("(active) "); break;
+ case TD_THR_ZOMBIE: printf_filtered ("(zombie) "); break;
+ case TD_THR_SLEEP: printf_filtered ("(asleep) "); break;
+ case TD_THR_STOPPED_ASLEEP:
+ printf_filtered ("(stopped asleep)"); break;
+ }
+ /* Print thr_create start function: */
+ if (ti.ti_startfunc != 0)
+ if (msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc))
+ printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym));
+ else
+ printf_filtered (" startfunc: 0x%08x\n", ti.ti_startfunc);
+
+ /* If thread is asleep, print function that went to sleep: */
+ if (ti.ti_state == TD_THR_SLEEP)
+ if (msym = lookup_minimal_symbol_by_pc (ti.ti_pc))
+ printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym));
+ else
+ printf_filtered (" - Sleep func: 0x%08x\n", ti.ti_startfunc);
+
+ /* Wrap up line, if necessary */
+ if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
+ printf_filtered ("\n"); /* don't you hate counting newlines? */
+ }
+ else
+ warning ("info sol-thread: failed to get info for thread.");
+
+ return 0;
+}
+
+/* List some state about each Solaris user thread in the inferior. */
+
+static void
+info_solthreads (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ p_td_ta_thr_iter (main_ta, info_cb, args,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+}
+#endif /* MAINTENANCE_CMDS */
+
+static int
+ignore (addr, contents)
+ CORE_ADDR addr;
+ char *contents;
+{
+ return 0;
+}
+
+
+static void
+init_sol_thread_ops ()
+{
+ sol_thread_ops.to_shortname = "solaris-threads";
+ sol_thread_ops.to_longname = "Solaris threads and pthread.";
+ sol_thread_ops.to_doc = "Solaris threads and pthread support.";
+ sol_thread_ops.to_open = sol_thread_open;
+ sol_thread_ops.to_close = 0;
+ sol_thread_ops.to_attach = sol_thread_attach;
+ sol_thread_ops.to_detach = sol_thread_detach;
+ sol_thread_ops.to_resume = sol_thread_resume;
+ sol_thread_ops.to_wait = sol_thread_wait;
+ sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
+ sol_thread_ops.to_store_registers = sol_thread_store_registers;
+ sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
+ sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory;
+ sol_thread_ops.to_files_info = sol_thread_files_info;
+ sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ sol_thread_ops.to_terminal_init = terminal_init_inferior;
+ sol_thread_ops.to_terminal_inferior = terminal_inferior;
+ sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ sol_thread_ops.to_terminal_ours = terminal_ours;
+ sol_thread_ops.to_terminal_info = child_terminal_info;
+ sol_thread_ops.to_kill = sol_thread_kill_inferior;
+ sol_thread_ops.to_load = 0;
+ sol_thread_ops.to_lookup_symbol = 0;
+ sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
+ sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
+ sol_thread_ops.to_can_run = sol_thread_can_run;
+ sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
+ sol_thread_ops.to_thread_alive = sol_thread_alive;
+ sol_thread_ops.to_stop = sol_thread_stop;
+ sol_thread_ops.to_stratum = process_stratum;
+ sol_thread_ops.to_has_all_memory = 1;
+ sol_thread_ops.to_has_memory = 1;
+ sol_thread_ops.to_has_stack = 1;
+ sol_thread_ops.to_has_registers = 1;
+ sol_thread_ops.to_has_execution = 1;
+ sol_thread_ops.to_has_thread_control = tc_none;
+ sol_thread_ops.to_sections = 0;
+ sol_thread_ops.to_sections_end = 0;
+ sol_thread_ops.to_magic = OPS_MAGIC;
+}
+
+
+static void
+init_sol_core_ops ()
+{
+ sol_core_ops.to_shortname = "solaris-core";
+ sol_core_ops.to_longname = "Solaris core threads and pthread.";
+ sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
+ sol_core_ops.to_open = sol_core_open;
+ sol_core_ops.to_close = sol_core_close;
+ sol_core_ops.to_attach = sol_thread_attach;
+ sol_core_ops.to_detach = sol_core_detach;
+ /* sol_core_ops.to_resume = 0; */
+ /* sol_core_ops.to_wait = 0; */
+ sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
+ /* sol_core_ops.to_store_registers = 0; */
+ /* sol_core_ops.to_prepare_to_store = 0; */
+ sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
+ sol_core_ops.to_files_info = sol_core_files_info;
+ sol_core_ops.to_insert_breakpoint = ignore;
+ sol_core_ops.to_remove_breakpoint = ignore;
+ /* sol_core_ops.to_terminal_init = 0; */
+ /* sol_core_ops.to_terminal_inferior = 0; */
+ /* sol_core_ops.to_terminal_ours_for_output = 0; */
+ /* sol_core_ops.to_terminal_ours = 0; */
+ /* sol_core_ops.to_terminal_info = 0; */
+ /* sol_core_ops.to_kill = 0; */
+ /* sol_core_ops.to_load = 0; */
+ /* sol_core_ops.to_lookup_symbol = 0; */
+ sol_core_ops.to_create_inferior = sol_thread_create_inferior;
+ sol_core_ops.to_stratum = core_stratum;
+ sol_core_ops.to_has_all_memory = 0;
+ sol_core_ops.to_has_memory = 1;
+ sol_core_ops.to_has_stack = 1;
+ sol_core_ops.to_has_registers = 1;
+ sol_core_ops.to_has_execution = 0;
+ sol_core_ops.to_has_thread_control = tc_none;
+ sol_core_ops.to_sections = 0;
+ sol_core_ops.to_sections_end = 0;
+ sol_core_ops.to_magic = OPS_MAGIC;
+}
+
+/* we suppress the call to add_target of core_ops in corelow because
+ if there are two targets in the stratum core_stratum, find_core_target
+ won't know which one to return. see corelow.c for an additonal
+ comment on coreops_suppress_target. */
+int coreops_suppress_target = 1;
+
+void
+_initialize_sol_thread ()
+{
+ void *dlhandle;
+
+ init_sol_thread_ops ();
+ init_sol_core_ops ();
+
+ dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
+ if (!dlhandle)
+ goto die;
+
+#define resolve(X) \
+ if (!(p_##X = dlsym (dlhandle, #X))) \
+ goto die;
+
+ resolve (td_log);
+ resolve (td_ta_new);
+ resolve (td_ta_delete);
+ resolve (td_init);
+ resolve (td_ta_get_ph);
+ resolve (td_ta_get_nthreads);
+ resolve (td_ta_tsd_iter);
+ resolve (td_ta_thr_iter);
+ resolve (td_thr_validate);
+ resolve (td_thr_tsd);
+ resolve (td_thr_get_info);
+ resolve (td_thr_getfpregs);
+ resolve (td_thr_getxregsize);
+ resolve (td_thr_getxregs);
+ resolve (td_thr_sigsetmask);
+ resolve (td_thr_setprio);
+ resolve (td_thr_setsigpending);
+ resolve (td_thr_setfpregs);
+ resolve (td_thr_setxregs);
+ resolve (td_ta_map_id2thr);
+ resolve (td_ta_map_lwp2thr);
+ resolve (td_thr_getgregs);
+ resolve (td_thr_setgregs);
+
+ add_target (&sol_thread_ops);
+
+ procfs_suppress_run = 1;
+
+#ifdef MAINTENANCE_CMDS
+ add_cmd ("sol-threads", class_maintenance, info_solthreads,
+ "Show info on Solaris user threads.\n", &maintenanceinfolist);
+#endif /* MAINTENANCE_CMDS */
+
+ memcpy(&orig_core_ops, &core_ops, sizeof (struct target_ops));
+ memcpy(&core_ops, &sol_core_ops, sizeof (struct target_ops));
+ add_target (&core_ops);
+
+ return;
+
+ die:
+
+ fprintf_unfiltered (gdb_stderr, "[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
+
+ if (dlhandle)
+ dlclose (dlhandle);
+
+ /* allow the user to debug non-threaded core files */
+ add_target(&core_ops);
+
+ return;
+}
diff --git a/contrib/gdb/gdb/solib.c b/contrib/gdb/gdb/solib.c
index 3a20b55..6d6fd4a 100644
--- a/contrib/gdb/gdb/solib.c
+++ b/contrib/gdb/gdb/solib.c
@@ -1,5 +1,5 @@
/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -70,6 +70,7 @@ static char *solib_break_names[] = {
"r_debug_state",
"_r_debug_state",
"_dl_debug_state",
+ "rtld_db_dlactivity",
NULL
};
#endif
@@ -148,12 +149,20 @@ static struct so_list *so_list_head; /* List of known shared objects */
static CORE_ADDR debug_base; /* Base of dynamic linker structures */
static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+static int solib_cleanup_queued = 0; /* make_run_cleanup called */
+
extern int
fdmatch PARAMS ((int, int)); /* In libiberty */
/* Local function prototypes */
static void
+do_clear_solib PARAMS ((PTR));
+
+static int
+match_main PARAMS ((char *));
+
+static void
special_symbol_handling PARAMS ((struct so_list *));
static void
@@ -165,8 +174,7 @@ enable_break PARAMS ((void));
static void
info_sharedlibrary_command PARAMS ((char *, int));
-static int
-symbol_add_stub PARAMS ((char *));
+static int symbol_add_stub PARAMS ((PTR));
static struct so_list *
find_solib PARAMS ((struct so_list *));
@@ -177,8 +185,7 @@ first_link_map_member PARAMS ((void));
static CORE_ADDR
locate_base PARAMS ((void));
-static void
-solib_map_sections PARAMS ((struct so_list *));
+static int solib_map_sections PARAMS ((PTR));
#ifdef SVR4_SHARED_LIBS
@@ -198,6 +205,17 @@ solib_add_common_symbols PARAMS ((struct rtc_symb *));
#endif
+void _initialize_solib PARAMS ((void));
+
+/* If non-zero, this is a prefix that will be added to the front of the name
+ shared libraries with an absolute filename for loading. */
+static char *solib_absolute_prefix = NULL;
+
+/* If non-empty, this is a search path for loading non-absolute shared library
+ symbol files. This takes precedence over the environment variables PATH
+ and LD_LIBRARY_PATH. */
+static char *solib_search_path = NULL;
+
/*
LOCAL FUNCTION
@@ -206,7 +224,7 @@ LOCAL FUNCTION
SYNOPSIS
- static void solib_map_sections (struct so_list *so)
+ static int solib_map_sections (struct so_list *so)
DESCRIPTION
@@ -225,10 +243,11 @@ FIXMES
expansion stuff?).
*/
-static void
-solib_map_sections (so)
- struct so_list *so;
+static int
+solib_map_sections (arg)
+ PTR arg;
{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
char *scratch_pathname;
int scratch_chan;
@@ -237,10 +256,38 @@ solib_map_sections (so)
bfd *abfd;
filename = tilde_expand (so -> so_name);
- old_chain = make_cleanup (free, filename);
- scratch_chan = openp (get_in_environ (inferior_environ, "PATH"),
- 1, filename, O_RDONLY, 0, &scratch_pathname);
+ if (solib_absolute_prefix && ROOTED_P (filename))
+ /* Prefix shared libraries with absolute filenames with
+ SOLIB_ABSOLUTE_PREFIX. */
+ {
+ char *pfxed_fn;
+ int pfx_len;
+
+ pfx_len = strlen (solib_absolute_prefix);
+
+ /* Remove trailing slashes. */
+ while (pfx_len > 0 && SLASH_P (solib_absolute_prefix[pfx_len - 1]))
+ pfx_len--;
+
+ pfxed_fn = xmalloc (pfx_len + strlen (filename) + 1);
+ strcpy (pfxed_fn, solib_absolute_prefix);
+ strcat (pfxed_fn, filename);
+ free (filename);
+
+ filename = pfxed_fn;
+ }
+
+ old_chain = make_cleanup (free, filename);
+
+ scratch_chan = -1;
+
+ if (solib_search_path)
+ scratch_chan = openp (solib_search_path,
+ 1, filename, O_RDONLY, 0, &scratch_pathname);
+ if (scratch_chan < 0)
+ scratch_chan = openp (get_in_environ (inferior_environ, "PATH"),
+ 1, filename, O_RDONLY, 0, &scratch_pathname);
if (scratch_chan < 0)
{
scratch_chan = openp (get_in_environ
@@ -297,6 +344,8 @@ solib_map_sections (so)
/* Free the file names, close the file now. */
do_cleanups (old_chain);
+
+ return (1);
}
#ifndef SVR4_SHARED_LIBS
@@ -350,7 +399,6 @@ solib_add_common_symbols (rtc_symp)
struct nlist inferior_rtc_nlist;
int len;
char *name;
- char *origname;
/* Remove any runtime common symbols from previous runs. */
@@ -364,7 +412,7 @@ solib_add_common_symbols (rtc_symp)
}
init_minimal_symbol_collection ();
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
while (rtc_symp)
{
@@ -381,18 +429,16 @@ solib_add_common_symbols (rtc_symp)
behind the name of the symbol. */
len = inferior_rtc_nlist.n_value - inferior_rtc_nlist.n_un.n_strx;
- origname = name = xmalloc (len);
+ name = xmalloc (len);
read_memory ((CORE_ADDR) inferior_rtc_nlist.n_un.n_name, name, len);
/* Allocate the runtime common objfile if necessary. */
if (rt_common_objfile == NULL)
allocate_rt_common_objfile ();
- name = obsavestring (name, strlen (name),
- &rt_common_objfile -> symbol_obstack);
prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value,
mst_bss, rt_common_objfile);
- free (origname);
+ free (name);
}
rtc_symp = inferior_rtc_symb.rtc_next;
}
@@ -537,7 +583,7 @@ look_for_base (fd, baseaddr)
if (fd == -1
|| (exec_bfd != NULL
- && fdmatch (fileno ((GDB_FILE *)(exec_bfd -> iostream)), fd)))
+ && fdmatch (fileno ((FILE *)(exec_bfd -> iostream)), fd)))
{
return (0);
}
@@ -645,8 +691,7 @@ elf_locate_base ()
/* Find the DT_DEBUG entry in the the .dynamic section.
For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
no DT_DEBUG entries. */
- /* FIXME: In lack of a 64 bit ELF ABI the following code assumes
- a 32 bit ELF ABI target. */
+#ifndef TARGET_ELF64
for (bufend = buf + dyninfo_sect_size;
buf < bufend;
buf += sizeof (Elf32_External_Dyn))
@@ -677,6 +722,25 @@ elf_locate_base ()
}
#endif
}
+#else /* ELF64 */
+ for (bufend = buf + dyninfo_sect_size;
+ buf < bufend;
+ buf += sizeof (Elf64_External_Dyn))
+ {
+ Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *)buf;
+ long dyn_tag;
+ CORE_ADDR dyn_ptr;
+
+ dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
+ if (dyn_tag == DT_NULL)
+ break;
+ else if (dyn_tag == DT_DEBUG)
+ {
+ dyn_ptr = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
+ return dyn_ptr;
+ }
+ }
+#endif
/* DT_DEBUG entry not found. */
return 0;
@@ -760,7 +824,7 @@ locate_base ()
debug_base = elf_locate_base ();
#ifdef HANDLE_SVR4_EXEC_EMULATORS
/* Try it the hard way for emulated executables. */
- else if (inferior_pid != 0)
+ else if (inferior_pid != 0 && target_has_execution)
proc_iterate_over_mappings (look_for_base);
#endif
}
@@ -902,6 +966,13 @@ find_solib (so_list_ptr)
else
{
so_list_head = new;
+
+ if (! solib_cleanup_queued)
+ {
+ make_run_cleanup (do_clear_solib, NULL);
+ solib_cleanup_queued = 1;
+ }
+
}
so_list_next = new;
read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),
@@ -918,12 +989,17 @@ find_solib (so_list_ptr)
target_read_string ((CORE_ADDR) LM_NAME (new), &buffer,
MAX_PATH_SIZE - 1, &errcode);
if (errcode != 0)
- error ("find_solib: Can't read pathname for load map: %s\n",
- safe_strerror (errcode));
+ {
+ warning ("find_solib: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ return (so_list_next);
+ }
strncpy (new -> so_name, buffer, MAX_PATH_SIZE - 1);
new -> so_name[MAX_PATH_SIZE - 1] = '\0';
free (buffer);
- solib_map_sections (new);
+ catch_errors (solib_map_sections, new,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
}
}
return (so_list_next);
@@ -933,16 +1009,38 @@ find_solib (so_list_ptr)
static int
symbol_add_stub (arg)
- char *arg;
+ PTR arg;
{
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+
+ if (so -> textsection)
+ text_addr = so -> textsection -> addr;
+ else if (so -> abfd != NULL)
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ lowest_sect = bfd_get_section_by_name (so -> abfd, ".text");
+ if (lowest_sect == NULL)
+ bfd_map_over_sections (so -> abfd, find_lowest_section,
+ (PTR) &lowest_sect);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so -> abfd, lowest_sect)
+ + (CORE_ADDR) LM_ADDR (so);
+ }
+ ALL_OBJFILES (so -> objfile)
+ {
+ if (strcmp (so -> objfile -> name, so -> so_name) == 0)
+ return 1;
+ }
so -> objfile =
symbol_file_add (so -> so_name, so -> from_tty,
- (so->textsection == NULL
- ? 0
- : (unsigned int) so -> textsection -> addr),
- 0, 0, 0);
+ text_addr,
+ 0, 0, 0, 0, 1);
return (1);
}
@@ -1021,7 +1119,7 @@ solib_add (arg_string, from_tty, target)
here, otherwise we dereference a potential dangling pointer
for each call to target_read/write_memory within this routine. */
update_coreops = core_ops.to_sections == target->to_sections;
-
+
/* Reallocate the target's section table including the new size. */
if (target -> to_sections)
{
@@ -1076,7 +1174,7 @@ solib_add (arg_string, from_tty, target)
}
}
else if (catch_errors
- (symbol_add_stub, (char *) so,
+ (symbol_add_stub, so,
"Error while reading shared library symbols:\n",
RETURN_MASK_ALL))
{
@@ -1118,30 +1216,41 @@ info_sharedlibrary_command (ignore, from_tty)
{
register struct so_list *so = NULL; /* link map state variable */
int header_done = 0;
-
+ int addr_width;
+ char *addr_fmt;
+
if (exec_bfd == NULL)
{
printf_unfiltered ("No exec file.\n");
return;
}
+
+#ifndef TARGET_ELF64
+ addr_width = 8+4;
+ addr_fmt = "08l";
+#else
+ addr_width = 16+4;
+ addr_fmt = "016l";
+#endif
+
while ((so = find_solib (so)) != NULL)
{
if (so -> so_name[0])
{
if (!header_done)
{
- printf_unfiltered("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read",
- "Shared Object Library");
+ printf_unfiltered("%-*s%-*s%-12s%s\n", addr_width, "From",
+ addr_width, "To", "Syms Read",
+ "Shared Object Library");
header_done++;
}
- /* FIXME-32x64: need print_address_numeric with field width or
- some such. */
- printf_unfiltered ("%-12s",
+
+ printf_unfiltered ("%-*s", addr_width,
local_hex_string_custom ((unsigned long) LM_ADDR (so),
- "08l"));
- printf_unfiltered ("%-12s",
+ addr_fmt));
+ printf_unfiltered ("%-*s", addr_width,
local_hex_string_custom ((unsigned long) so -> lmend,
- "08l"));
+ addr_fmt));
printf_unfiltered ("%-12s", so -> symbols_loaded ? "Yes" : "No");
printf_unfiltered ("%s\n", so -> so_name);
}
@@ -1218,7 +1327,7 @@ clear_solib()
else
/* This happens for the executable on SVR4. */
bfd_filename = NULL;
-
+
next = so_list_head -> next;
if (bfd_filename)
free ((PTR)bfd_filename);
@@ -1228,6 +1337,34 @@ clear_solib()
debug_base = 0;
}
+static void
+do_clear_solib (dummy)
+ PTR dummy;
+{
+ solib_cleanup_queued = 0;
+ clear_solib ();
+}
+
+#ifdef SVR4_SHARED_LIBS
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ SVR4 run time loader. */
+
+static CORE_ADDR interp_text_sect_low;
+static CORE_ADDR interp_text_sect_high;
+static CORE_ADDR interp_plt_sect_low;
+static CORE_ADDR interp_plt_sect_high;
+
+int
+in_svr4_dynsym_resolve_code (pc)
+ CORE_ADDR pc;
+{
+ return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
+ || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
+ || in_plt_section (pc, NULL));
+}
+#endif
+
/*
LOCAL FUNCTION
@@ -1388,6 +1525,9 @@ enable_break ()
remove_solib_event_breakpoints ();
#ifdef SVR4_SHARED_LIBS
+ interp_text_sect_low = interp_text_sect_high = 0;
+ interp_plt_sect_low = interp_plt_sect_high = 0;
+
/* Find the .interp section; if not found, warn the user and drop
into the old breakpoint at symbol code. */
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
@@ -1412,7 +1552,7 @@ enable_break ()
This address is stored on the stack. However, I've been unable
to find any magic formula to find it for Solaris (appears to
- be trivial on Linux). Therefore, we have to try an alternate
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
mechanism to find the dynamic linker's base address. */
tmp_bfd = bfd_openr (buf, gnutarget);
if (tmp_bfd == NULL)
@@ -1431,6 +1571,25 @@ enable_break ()
linker) and subtracting the offset of the entry point. */
load_addr = read_pc () - tmp_bfd->start_address;
+ /* Record the relocated start and end address of the dynamic linker
+ text and plt section for in_svr4_dynsym_resolve_code. */
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ if (interp_sect)
+ {
+ interp_text_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_text_sect_high =
+ interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+ if (interp_sect)
+ {
+ interp_plt_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_plt_sect_high =
+ interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+
/* Now try to set a breakpoint in the dynamic linker. */
for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
{
@@ -1451,9 +1610,7 @@ enable_break ()
/* For whatever reason we couldn't set a breakpoint in the dynamic
linker. Warn and drop into the old code. */
bkpt_at_symbol:
- warning ("Unable to find dynamic linker breakpoint function.");
- warning ("GDB will be unable to debug shared library initializers");
- warning ("and track explicitly loaded dynamic code.");
+ warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.");
}
#endif
@@ -1472,7 +1629,7 @@ bkpt_at_symbol:
}
/* Nothing good happened. */
- return 0;
+ success = 0;
#endif /* BKPT_AT_SYMBOL */
@@ -1554,8 +1711,8 @@ solib_create_inferior_hook()
return;
}
-#ifndef SVR4_SHARED_LIBS
- /* Only SunOS needs the loop below, other systems should be using the
+#if !defined(SVR4_SHARED_LIBS) || defined(_SCO_DS)
+ /* SCO and SunOS need the loop below, other systems should be using the
special shared library breakpoints and the shared library breakpoint
service routine.
@@ -1574,7 +1731,8 @@ solib_create_inferior_hook()
}
while (stop_signal != TARGET_SIGNAL_TRAP);
stop_soon_quietly = 0;
-
+
+#if !defined(_SCO_DS)
/* We are now either at the "mapping complete" breakpoint (or somewhere
else, a condition we aren't prepared to deal with anyway), so adjust
the PC as necessary after a breakpoint, disable the breakpoint, and
@@ -1593,6 +1751,7 @@ solib_create_inferior_hook()
if (auto_solib_add)
solib_add ((char *) 0, 0, (struct target_ops *) 0);
+#endif /* ! _SCO_DS */
#endif
}
@@ -1710,5 +1869,20 @@ must be loaded manually, using `sharedlibrary'.",
&setlist),
&showlist);
+ add_show_from_set
+ (add_set_cmd ("solib-absolute-prefix", class_support, var_filename,
+ (char *) &solib_absolute_prefix,
+ "Set prefix for loading absolute shared library symbol files.\n\
+For other (relative) files, you can add values using `set solib-search-path'.",
+ &setlist),
+ &showlist);
+ add_show_from_set
+ (add_set_cmd ("solib-search-path", class_support, var_string,
+ (char *) &solib_search_path,
+ "Set the search path for loading non-absolute shared library symbol files.\n\
+This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.",
+ &setlist),
+ &showlist);
+
#endif /* HAVE_LINK_H */
}
diff --git a/contrib/gdb/gdb/solib.h b/contrib/gdb/gdb/solib.h
index 959e59e..eafef48 100644
--- a/contrib/gdb/gdb/solib.h
+++ b/contrib/gdb/gdb/solib.h
@@ -1,5 +1,5 @@
/* Shared library declarations for GDB, the GNU Debugger.
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -44,9 +44,140 @@ solib_add PARAMS ((char *, int, struct target_ops *));
#define SOLIB_CREATE_INFERIOR_HOOK(PID) solib_create_inferior_hook()
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.)
+
+ This functionality is presently not implemented for this target.
+ */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0)
+
extern void
solib_create_inferior_hook PARAMS((void)); /* solib.c */
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+*/
+
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+(0)
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_RESTART() \
+ (0)
+
/* If we can't set a breakpoint, and it's in a shared library, just
disable it. */
@@ -58,3 +189,15 @@ solib_address PARAMS ((CORE_ADDR)); /* solib.c */
/* If ADDR lies in a shared library, return its name. */
#define PC_SOLIB(addr) solib_address (addr)
+
+#ifdef SVR4_SHARED_LIBS
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ SVR4 run time loader. */
+
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) in_svr4_dynsym_resolve_code (pc)
+
+extern int
+in_svr4_dynsym_resolve_code PARAMS ((CORE_ADDR));
+
+#endif
diff --git a/contrib/gdb/gdb/somread.c b/contrib/gdb/gdb/somread.c
index ab8d531..c03abd0 100644
--- a/contrib/gdb/gdb/somread.c
+++ b/contrib/gdb/gdb/somread.c
@@ -20,8 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "bfd.h"
-#include "som.h"
-#include "libhppa.h"
#include <syms.h>
#include "symtab.h"
#include "symfile.h"
@@ -32,7 +30,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "complaints.h"
#include "gdb_string.h"
#include "demangle.h"
-#include <sys/file.h>
+#include "som.h"
+#include "libhppa.h"
/* Various things we might complain about... */
@@ -55,21 +54,19 @@ som_symtab_read PARAMS ((bfd *, struct objfile *,
static struct section_offsets *
som_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
-static void
-record_minimal_symbol PARAMS ((char *, CORE_ADDR,
- enum minimal_symbol_type,
- struct objfile *));
+/* FIXME: These should really be in a common header somewhere */
-static void
-record_minimal_symbol (name, address, ms_type, objfile)
- char *name;
- CORE_ADDR address;
- enum minimal_symbol_type ms_type;
- struct objfile *objfile;
-{
- name = obsavestring (name, strlen (name), &objfile -> symbol_obstack);
- prim_record_minimal_symbol (name, address, ms_type, objfile);
-}
+extern void
+hpread_build_psymtabs PARAMS ((struct objfile *, struct section_offsets *, int));
+
+extern void
+hpread_symfile_finish PARAMS ((struct objfile *));
+
+extern void
+hpread_symfile_init PARAMS ((struct objfile *));
+
+extern void
+do_pxdb PARAMS ((bfd *));
/*
@@ -129,11 +126,19 @@ som_symtab_read (abfd, objfile, section_offsets)
There's nothing in the header which easily allows us to do
this. The only reliable way I know of is to check for the
existance of a $SHLIB_INFO$ section with a non-zero size. */
- shlib_info = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
- if (shlib_info)
- dynamic = (bfd_section_size (objfile->obfd, shlib_info) != 0);
- else
- dynamic = 0;
+ /* The code below is not a reliable way to check whether an
+ * executable is dynamic, so I commented it out - RT
+ * shlib_info = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
+ * if (shlib_info)
+ * dynamic = (bfd_section_size (objfile->obfd, shlib_info) != 0);
+ * else
+ * dynamic = 0;
+ */
+ /* I replaced the code with a simple check for text offset not being
+ * zero. Still not 100% reliable, but a more reliable way of asking
+ * "is this a dynamic executable?" than the above. RT
+ */
+ dynamic = (text_offset != 0);
endbufp = buf + number_of_symbols;
for (bufp = buf; bufp < endbufp; ++bufp)
@@ -288,11 +293,15 @@ som_symtab_read (abfd, objfile, section_offsets)
/* This can happen for common symbols when -E is passed to the
final link. No idea _why_ that would make the linker force
- common symbols to have an SS_UNSAT scope, but it does. */
+ common symbols to have an SS_UNSAT scope, but it does.
+
+ This also happens for weak symbols, but their type is
+ ST_DATA. */
case SS_UNSAT:
switch (bufp->symbol_type)
{
case ST_STORAGE:
+ case ST_DATA:
symname = bufp->name.n_strx + stringtab;
bufp->symbol_value += data_offset;
ms_type = mst_data;
@@ -311,9 +320,8 @@ som_symtab_read (abfd, objfile, section_offsets)
error ("Invalid symbol data; bad HP string table offset: %d",
bufp->name.n_strx);
- record_minimal_symbol (symname,
- bufp->symbol_value, ms_type,
- objfile);
+ prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
+ objfile);
}
}
@@ -355,22 +363,48 @@ som_symfile_read (objfile, section_offsets, mainline)
bfd *abfd = objfile->obfd;
struct cleanup *back_to;
- init_minimal_symbol_collection ();
- back_to = make_cleanup (discard_minimal_symbols, 0);
+ do_pxdb (symfile_bfd_open (objfile->name));
- /* Process the normal SOM symbol table first. */
+ init_minimal_symbol_collection ();
+ back_to = make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
+
+ /* Read in the import list and the export list. Currently
+ the export list isn't used; the import list is used in
+ hp-symtab-read.c to handle static vars declared in other
+ shared libraries. */
+ init_import_symbols (objfile);
+#if 0 /* Export symbols not used today 1997-08-05 */
+ init_export_symbols (objfile);
+#else
+ objfile->export_list = NULL;
+ objfile->export_list_size = 0;
+#endif
+ /* Process the normal SOM symbol table first.
+ This reads in the DNTT and string table, but doesn't
+ actually scan the DNTT. It does scan the linker symbol
+ table and thus build up a "minimal symbol table". */
+
som_symtab_read (abfd, objfile, section_offsets);
- /* Now read information from the stabs debug sections. */
+ /* Now read information from the stabs debug sections.
+ This is a no-op for SOM.
+ Perhaps it is intended for some kind of mixed STABS/SOM
+ situation? */
stabsect_build_psymtabs (objfile, section_offsets, mainline,
"$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
- /* Now read the native debug information. */
+ /* Now read the native debug information.
+ This builds the psymtab. This used to be done via a scan of
+ the DNTT, but is now done via the PXDB-built quick-lookup tables
+ together with a scan of the GNTT. See hp-psymtab-read.c. */
hpread_build_psymtabs (objfile, section_offsets, mainline);
/* Install any minimal symbols that have been collected as the current
- minimal symbols for this objfile. */
+ minimal symbols for this objfile.
+ Further symbol-reading is done incrementally, file-by-file,
+ in a step known as "psymtab-to-symtab" expansion. hp-symtab-read.c
+ contains the code to do the actual DNTT scanning and symtab building. */
install_minimal_symbols (objfile);
/* Force hppa-tdep.c to re-read the unwind descriptors. */
@@ -435,9 +469,7 @@ som_symfile_offsets (objfile, addr)
objfile->num_sections = SECT_OFF_MAX;
section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile -> psymbol_obstack,
- sizeof (struct section_offsets)
- + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
+ obstack_alloc (&objfile -> psymbol_obstack, SIZEOF_SECTION_OFFSETS);
/* First see if we're a shared library. If so, get the section
offsets from the library, else get them from addr. */
@@ -449,6 +481,307 @@ som_symfile_offsets (objfile, addr)
return section_offsets;
}
+
+
+
+/* Check if a given symbol NAME is in the import list
+ of OBJFILE.
+ 1 => true, 0 => false
+ This is used in hp_symtab_read.c to deal with static variables
+ that are defined in a different shared library than the one
+ whose symbols are being processed. */
+
+int is_in_import_list (name, objfile)
+ char * name;
+ struct objfile * objfile;
+{
+ register int i;
+
+ if (!objfile ||
+ !name ||
+ !*name)
+ return 0;
+
+ for (i=0; i < objfile->import_list_size; i++)
+ if (objfile->import_list[i] && STREQ (name, objfile->import_list[i]))
+ return 1;
+ return 0;
+}
+
+
+/* Read in and initialize the SOM import list which is present
+ for all executables and shared libraries. The import list
+ consists of the symbols that are referenced in OBJFILE but
+ not defined there. (Variables that are imported are dealt
+ with as "loc_indirect" vars.)
+ Return value = number of import symbols read in. */
+int
+init_import_symbols (objfile)
+ struct objfile * objfile;
+{
+ unsigned int import_list;
+ unsigned int import_list_size;
+ unsigned int string_table;
+ unsigned int string_table_size;
+ char * string_buffer;
+ register int i;
+ register int j;
+ register int k;
+ asection * text_section; /* section handle */
+ unsigned int dl_header[12]; /* SOM executable header */
+
+ /* A struct for an entry in the SOM import list */
+ typedef struct {
+ int name; /* index into the string table */
+ short dont_care1; /* we don't use this */
+ unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */
+ unsigned int reserved2 : 8; /* not used */
+ } SomImportEntry;
+
+ /* We read 100 entries in at a time from the disk file. */
+# define SOM_READ_IMPORTS_NUM 100
+# define SOM_READ_IMPORTS_CHUNK_SIZE (sizeof (SomImportEntry) * SOM_READ_IMPORTS_NUM)
+ SomImportEntry buffer[SOM_READ_IMPORTS_NUM];
+
+ /* Initialize in case we error out */
+ objfile->import_list = NULL;
+ objfile->import_list_size = 0;
+
+#if 0 /* DEBUGGING */
+ printf ("Processing import list for %s\n", objfile->name);
+#endif
+
+ /* It doesn't work, for some reason, to read in space $TEXT$;
+ the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
+ text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
+ if (!text_section)
+ return 0;
+ /* Get the SOM executable header */
+ bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int));
+
+ /* Check header version number for 10.x HP-UX */
+ /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912.
+ FIXME: Change for future HP-UX releases and mods to the SOM executable format */
+ if (dl_header[0] != 93092112)
+ return 0;
+
+ import_list = dl_header[4];
+ import_list_size = dl_header[5];
+ if (!import_list_size)
+ return 0;
+ string_table = dl_header[10];
+ string_table_size = dl_header[11];
+ if (!string_table_size)
+ return 0;
+
+ /* Suck in SOM string table */
+ string_buffer = (char *) xmalloc (string_table_size);
+ bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
+ string_table, string_table_size);
+
+ /* Allocate import list in the psymbol obstack; this has nothing
+ to do with psymbols, just a matter of convenience. We want the
+ import list to be freed when the objfile is deallocated */
+ objfile->import_list
+ = (ImportEntry *) obstack_alloc (&objfile->psymbol_obstack,
+ import_list_size * sizeof (ImportEntry));
+
+ /* Read in the import entries, a bunch at a time */
+ for (j=0, k=0;
+ j < (import_list_size / SOM_READ_IMPORTS_NUM);
+ j++)
+ {
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ import_list + j * SOM_READ_IMPORTS_CHUNK_SIZE,
+ SOM_READ_IMPORTS_CHUNK_SIZE);
+ for (i=0; i < SOM_READ_IMPORTS_NUM; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->import_list[k]
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->import_list[k], string_buffer + buffer[i].name);
+ /* Some day we might want to record the type and other information too */
+ }
+ else /* null type */
+ objfile->import_list[k] = NULL;
+
+#if 0 /* DEBUGGING */
+ printf ("Import String %d:%d (%d), type %d is %s\n", j, i, k,
+ (int) buffer[i].type, objfile->import_list[k]);
+#endif
+ }
+ }
+
+ /* Get the leftovers */
+ if (k < import_list_size)
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ import_list + k * sizeof (SomImportEntry),
+ (import_list_size - k) * sizeof (SomImportEntry));
+ for (i=0; k < import_list_size; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->import_list[k]
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->import_list[k], string_buffer + buffer[i].name);
+ /* Some day we might want to record the type and other information too */
+ }
+ else
+ objfile->import_list[k] = NULL;
+#if 0 /* DEBUGGING */
+ printf ("Import String F:%d (%d), type %d, is %s\n", i, k,
+ (int) buffer[i].type, objfile->import_list[k]);
+#endif
+ }
+
+ objfile->import_list_size = import_list_size;
+ free (string_buffer);
+ return import_list_size;
+}
+
+/* Read in and initialize the SOM export list which is present
+ for all executables and shared libraries. The import list
+ consists of the symbols that are referenced in OBJFILE but
+ not defined there. (Variables that are imported are dealt
+ with as "loc_indirect" vars.)
+ Return value = number of import symbols read in. */
+int
+init_export_symbols (objfile)
+ struct objfile * objfile;
+{
+ unsigned int export_list;
+ unsigned int export_list_size;
+ unsigned int string_table;
+ unsigned int string_table_size;
+ char * string_buffer;
+ register int i;
+ register int j;
+ register int k;
+ asection * text_section; /* section handle */
+ unsigned int dl_header[12]; /* SOM executable header */
+
+ /* A struct for an entry in the SOM export list */
+ typedef struct {
+ int next; /* for hash table use -- we don't use this */
+ int name; /* index into string table */
+ int value; /* offset or plabel */
+ int dont_care1; /* not used */
+ unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */
+ char dont_care2; /* not used */
+ short dont_care3; /* not used */
+ } SomExportEntry;
+
+ /* We read 100 entries in at a time from the disk file. */
+# define SOM_READ_EXPORTS_NUM 100
+# define SOM_READ_EXPORTS_CHUNK_SIZE (sizeof (SomExportEntry) * SOM_READ_EXPORTS_NUM)
+ SomExportEntry buffer[SOM_READ_EXPORTS_NUM];
+
+ /* Initialize in case we error out */
+ objfile->export_list = NULL;
+ objfile->export_list_size = 0;
+
+#if 0 /* DEBUGGING */
+ printf ("Processing export list for %s\n", objfile->name);
+#endif
+
+ /* It doesn't work, for some reason, to read in space $TEXT$;
+ the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
+ text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
+ if (!text_section)
+ return 0;
+ /* Get the SOM executable header */
+ bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int));
+
+ /* Check header version number for 10.x HP-UX */
+ /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912.
+ FIXME: Change for future HP-UX releases and mods to the SOM executable format */
+ if (dl_header[0] != 93092112)
+ return 0;
+
+ export_list = dl_header[8];
+ export_list_size = dl_header[9];
+ if (!export_list_size)
+ return 0;
+ string_table = dl_header[10];
+ string_table_size = dl_header[11];
+ if (!string_table_size)
+ return 0;
+
+ /* Suck in SOM string table */
+ string_buffer = (char *) xmalloc (string_table_size);
+ bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
+ string_table, string_table_size);
+
+ /* Allocate export list in the psymbol obstack; this has nothing
+ to do with psymbols, just a matter of convenience. We want the
+ export list to be freed when the objfile is deallocated */
+ objfile->export_list
+ = (ExportEntry *) obstack_alloc (&objfile->psymbol_obstack,
+ export_list_size * sizeof (ExportEntry));
+
+ /* Read in the export entries, a bunch at a time */
+ for (j=0, k=0;
+ j < (export_list_size / SOM_READ_EXPORTS_NUM);
+ j++)
+ {
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ export_list + j * SOM_READ_EXPORTS_CHUNK_SIZE,
+ SOM_READ_EXPORTS_CHUNK_SIZE);
+ for (i=0; i < SOM_READ_EXPORTS_NUM; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->export_list[k].name
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name);
+ objfile->export_list[k].address = buffer[i].value;
+ /* Some day we might want to record the type and other information too */
+ }
+ else /* null type */
+ {
+ objfile->export_list[k].name = NULL;
+ objfile->export_list[k].address = 0;
+ }
+#if 0 /* DEBUGGING */
+ printf ("Export String %d:%d (%d), type %d is %s\n", j, i, k,
+ (int) buffer[i].type, objfile->export_list[k].name);
+#endif
+ }
+ }
+
+ /* Get the leftovers */
+ if (k < export_list_size)
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ export_list + k * sizeof (SomExportEntry),
+ (export_list_size - k) * sizeof (SomExportEntry));
+ for (i=0; k < export_list_size; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->export_list[k].name
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name);
+ /* Some day we might want to record the type and other information too */
+ objfile->export_list[k].address = buffer[i].value;
+ }
+ else
+ {
+ objfile->export_list[k].name = NULL;
+ objfile->export_list[k].address = 0;
+ }
+#if 0 /* DEBUGGING */
+ printf ("Export String F:%d (%d), type %d, value %x is %s\n", i, k,
+ (int) buffer[i].type, buffer[i].value, objfile->export_list[k].name);
+#endif
+ }
+
+ objfile->export_list_size = export_list_size;
+ free (string_buffer);
+ return export_list_size;
+}
+
+
/* Register that we are able to handle SOM object file formats. */
diff --git a/contrib/gdb/gdb/somsolib.c b/contrib/gdb/gdb/somsolib.c
index 1c32837..870177c 100644
--- a/contrib/gdb/gdb/somsolib.c
+++ b/contrib/gdb/gdb/somsolib.c
@@ -1,5 +1,5 @@
/* Handle HP SOM shared libraries for GDB, the GNU Debugger.
- Copyright 1993, 1996 Free Software Foundation, Inc.
+ Copyright 1993, 1996, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -34,7 +34,39 @@ and by Cygnus Support. */
#include "objfiles.h"
#include "inferior.h"
#include "gdb-stabs.h"
+#include "gdb_stat.h"
#include "gdbcmd.h"
+#include "assert.h"
+#include "language.h"
+
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* Uncomment this to turn on some debugging output.
+ */
+
+/* #define SOLIB_DEBUG
+ */
+
+/* Defined in exec.c; used to prevent dangling pointer bug.
+ */
+extern struct target_ops exec_ops;
+
+/* This lives in hppa-tdep.c. */
+extern struct unwind_table_entry *find_unwind_entry PARAMS ((CORE_ADDR pc));
+
+/* These ought to be defined in some public interface, but aren't. They
+ define the meaning of the various bits in the distinguished __dld_flags
+ variable that is declared in every debuggable a.out on HP-UX, and that
+ is shared between the debugger and the dynamic linker.
+ */
+#define DLD_FLAGS_MAPPRIVATE 0x1
+#define DLD_FLAGS_HOOKVALID 0x2
+#define DLD_FLAGS_LISTVALID 0x4
+#define DLD_FLAGS_BOR_ENABLE 0x8
/* TODO:
@@ -61,7 +93,9 @@ struct som_solib_mapped_entry
/* Version of this library. */
short library_version;
- /* Start of text address, link-time text location, end of text address. */
+ /* Start of text address,
+ * link-time text location (length of text area),
+ * end of text address. */
CORE_ADDR text_addr;
CORE_ADDR text_link_addr;
CORE_ADDR text_end;
@@ -79,6 +113,26 @@ struct som_solib_mapped_entry
/* There are other fields, but I don't have information as to what is
contained in them. */
+
+ /* For versions from HPUX-10.30 and up */
+
+ /* Address in target of offset from thread-local register of
+ * start of this thread's data. I.e., the first thread-local
+ * variable in this shared library starts at *(tsd_start_addr)
+ * from that area pointed to by cr27 (mpsfu_hi).
+ *
+ * We do the indirection as soon as we read it, so from then
+ * on it's the offset itself.
+ */
+ CORE_ADDR tsd_start_addr;
+
+ /* Following this are longwords holding:
+ *
+ * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name),
+ * ptr to __data_start, ptr to __data_end
+ */
+
+
};
/* A structure to keep track of all the known shared objects. */
@@ -89,14 +143,287 @@ struct so_list
bfd *abfd;
struct section_table *sections;
struct section_table *sections_end;
+/* elz: added this field to store the address in target space (in the
+ library) of the library descriptor (handle) which we read into
+ som_solib_mapped_entry structure*/
+ CORE_ADDR solib_addr;
struct so_list *next;
+
};
static struct so_list *so_list_head;
+
+/* This is the cumulative size in bytes of the symbol tables of all
+ shared objects on the so_list_head list. (When we say size, here
+ we mean of the information before it is brought into memory and
+ potentially expanded by GDB.) When adding a new shlib, this value
+ is compared against the threshold size, held by auto_solib_add
+ (in megabytes). If adding symbols for the new shlib would cause
+ the total size to exceed the threshold, then the new shlib's symbols
+ are not loaded.
+ */
+static LONGEST som_solib_total_st_size;
+
+/* When the threshold is reached for any shlib, we refuse to add
+ symbols for subsequent shlibs, even if those shlibs' symbols would
+ be small enough to fit under the threshold. (Although this may
+ result in one, early large shlib preventing the loading of later,
+ smalller shlibs' symbols, it allows us to issue one informational
+ message. The alternative, to issue a message for each shlib whose
+ symbols aren't loaded, could be a big annoyance where the threshold
+ is exceeded due to a very large number of shlibs.)
+ */
+static int som_solib_st_size_threshold_exceeded;
+
+/* These addresses should be filled in by som_solib_create_inferior_hook.
+ They are also used elsewhere in this module.
+ */
+typedef struct {
+ CORE_ADDR address;
+ struct unwind_table_entry * unwind;
+} addr_and_unwind_t;
+
+/* When adding fields, be sure to clear them in _initialize_som_solib. */
+static struct {
+ boolean is_valid;
+ addr_and_unwind_t hook;
+ addr_and_unwind_t hook_stub;
+ addr_and_unwind_t load;
+ addr_and_unwind_t load_stub;
+ addr_and_unwind_t unload;
+ addr_and_unwind_t unload2;
+ addr_and_unwind_t unload_stub;
+} dld_cache;
+
+
+
static void som_sharedlibrary_info_command PARAMS ((char *, int));
-/* Add symbols from shared libraries into the symtab list. */
+static void som_solib_sharedlibrary_command PARAMS ((char *, int));
+
+static LONGEST
+som_solib_sizeof_symbol_table (filename)
+ char * filename;
+{
+ bfd * abfd;
+ int desc;
+ char * absolute_name;
+ LONGEST st_size = (LONGEST) 0;
+ asection * sect;
+
+ /* We believe that filename was handed to us by the dynamic linker, and
+ is therefore always an absolute path.
+ */
+ desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, 0, &absolute_name);
+ if (desc < 0)
+ {
+ perror_with_name (filename);
+ }
+ filename = absolute_name;
+
+ abfd = bfd_fdopenr (filename, gnutarget, desc);
+ if (! abfd)
+ {
+ close (desc);
+ make_cleanup (free, filename);
+ error ("\"%s\": can't open to read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ if (!bfd_check_format (abfd, bfd_object)) /* Reads in section info */
+ {
+ bfd_close (abfd); /* This also closes desc */
+ make_cleanup (free, filename);
+ error ("\"%s\": can't read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Sum the sizes of the various sections that compose debug info. */
+
+ /* This contains non-DOC information. */
+ sect = bfd_get_section_by_name (abfd, "$DEBUG$");
+ if (sect)
+ st_size += (LONGEST) bfd_section_size (abfd, sect);
+
+ /* This contains DOC information. */
+ sect = bfd_get_section_by_name (abfd, "$PINFO$");
+ if (sect)
+ st_size += (LONGEST) bfd_section_size (abfd, sect);
+
+ bfd_close (abfd); /* This also closes desc */
+ free (filename);
+
+ /* Unfortunately, just summing the sizes of various debug info
+ sections isn't a very accurate measurement of how much heap
+ space the debugger will need to hold them. It also doesn't
+ account for space needed by linker (aka "minimal") symbols.
+
+ Anecdotal evidence suggests that just summing the sizes of
+ debug-info-related sections understates the heap space needed
+ to represent it internally by about an order of magnitude.
+
+ Since it's not exactly brain surgery we're doing here, rather
+ than attempt to more accurately measure the size of a shlib's
+ symbol table in GDB's heap, we'll just apply a 10x fudge-
+ factor to the debug info sections' size-sum. No, this doesn't
+ account for minimal symbols in non-debuggable shlibs. But it
+ all roughly washes out in the end.
+ */
+ return st_size * (LONGEST) 10;
+}
+
+
+static void
+som_solib_add_solib_objfile (so, name, from_tty, text_addr)
+ struct so_list * so;
+ char * name;
+ int from_tty;
+ CORE_ADDR text_addr;
+{
+ obj_private_data_t *obj_private;
+
+ so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0, 0, 1);
+ so->abfd = so->objfile->obfd;
+
+ /* Mark this as a shared library and save private data.
+ */
+ so->objfile->flags |= OBJF_SHARED;
+
+ if( so->objfile->obj_private == NULL )
+ {
+ obj_private = (obj_private_data_t *)
+ obstack_alloc( &so->objfile->psymbol_obstack,
+ sizeof( obj_private_data_t ));
+ obj_private->unwind_info = NULL;
+ obj_private->so_info = NULL;
+ so->objfile->obj_private = (PTR) obj_private;
+ }
+
+ obj_private = (obj_private_data_t *) so->objfile->obj_private;
+ obj_private->so_info = so;
+
+ if (!bfd_check_format (so->abfd, bfd_object))
+ {
+ error ("\"%s\": not in executable format: %s.",
+ name, bfd_errmsg (bfd_get_error ()));
+ }
+}
+
+
+static void
+som_solib_load_symbols (so, name, from_tty, text_addr, target)
+ struct so_list * so;
+ char * name;
+ int from_tty;
+ CORE_ADDR text_addr;
+ struct target_ops * target;
+{
+ struct section_table * p;
+ int status;
+ char buf[4];
+ CORE_ADDR presumed_data_start;
+
+#ifdef SOLIB_DEBUG
+ printf( "--Adding symbols for shared library \"%s\"\n", name );
+#endif
+
+ som_solib_add_solib_objfile (so, name, from_tty, text_addr);
+
+ /* Now we need to build a section table for this library since
+ we might be debugging a core file from a dynamically linked
+ executable in which the libraries were not privately mapped. */
+ if (build_section_table (so->abfd,
+ &so->sections,
+ &so->sections_end))
+ {
+ error ("Unable to build section table for shared library\n.");
+ return;
+ }
+
+ /* Relocate all the sections based on where they got loaded. */
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ if (p->the_bfd_section->flags & SEC_CODE)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT);
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT);
+ }
+ else if (p->the_bfd_section->flags & SEC_DATA)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA);
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA);
+ }
+ }
+
+ /* Now see if we need to map in the text and data for this shared
+ library (for example debugging a core file which does not use
+ private shared libraries.).
+
+ Carefully peek at the first text address in the library. If the
+ read succeeds, then the libraries were privately mapped and were
+ included in the core dump file.
+
+ If the peek failed, then the libraries were not privately mapped
+ and are not in the core file, we'll have to read them in ourselves. */
+ status = target_read_memory (text_addr, buf, 4);
+ if (status != 0)
+ {
+ int old, new;
+ int update_coreops;
+ int update_execops;
+
+ /* We must update the to_sections field in the core_ops structure
+ here, otherwise we dereference a potential dangling pointer
+ for each call to target_read/write_memory within this routine. */
+ update_coreops = core_ops.to_sections == target->to_sections;
+
+ /* Ditto exec_ops (this was a bug).
+ */
+ update_execops = exec_ops.to_sections == target->to_sections;
+
+ new = so->sections_end - so->sections;
+ /* Add sections from the shared library to the core target. */
+ if (target->to_sections)
+ {
+ old = target->to_sections_end - target->to_sections;
+ target->to_sections = (struct section_table *)
+ xrealloc ((char *)target->to_sections,
+ ((sizeof (struct section_table)) * (old + new)));
+ }
+ else
+ {
+ old = 0;
+ target->to_sections = (struct section_table *)
+ xmalloc ((sizeof (struct section_table)) * new);
+ }
+ target->to_sections_end = (target->to_sections + old + new);
+
+ /* Update the to_sections field in the core_ops structure
+ if needed, ditto exec_ops. */
+ if (update_coreops)
+ {
+ core_ops.to_sections = target->to_sections;
+ core_ops.to_sections_end = target->to_sections_end;
+ }
+
+ if (update_execops)
+ {
+ exec_ops.to_sections = target->to_sections;
+ exec_ops.to_sections_end = target->to_sections_end;
+ }
+
+ /* Copy over the old data before it gets clobbered. */
+ memcpy ((char *)(target->to_sections + old),
+ so->sections,
+ ((sizeof (struct section_table)) * new));
+ }
+}
+
+
+/* Add symbols from shared libraries into the symtab list, unless the
+ size threshold (specified by auto_solib_add, in megabytes) would
+ be exceeded. */
void
som_solib_add (arg_string, from_tty, target)
@@ -111,6 +438,7 @@ som_solib_add (arg_string, from_tty, target)
int status;
unsigned int dld_flags;
char buf[4], *re_err;
+ int threshold_warning_given = 0;
/* First validate our arguments. */
if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
@@ -157,15 +485,18 @@ som_solib_add (arg_string, from_tty, target)
}
dld_flags = extract_unsigned_integer (buf, 4);
- /* __dld_list may not be valid. If it's not valid tell the user. */
- if ((dld_flags & 4) == 0)
+ /* __dld_list may not be valid. If not, then we punt, warning the user if
+ we were called as a result of the add-symfile command.
+ */
+ if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
{
- error ("__dld_list is not valid according to __dld_flags.\n");
+ if (from_tty)
+ error ("__dld_list is not valid according to __dld_flags.\n");
return;
}
/* If the libraries were not mapped private, warn the user. */
- if ((dld_flags & 1) == 0)
+ if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0)
warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
@@ -201,7 +532,7 @@ som_solib_add (arg_string, from_tty, target)
/* Using the information in __dld_list is the preferred method
to get at shared library information. It doesn't depend on
- any functions in /usr/lib/end.o and has a chance of working
+ any functions in /opt/langtools/lib/end.o and has a chance of working
with hpux10 when it is released. */
status = target_read_memory (addr, buf, 4);
if (status != 0)
@@ -222,6 +553,14 @@ som_solib_add (arg_string, from_tty, target)
while (so_list_tail && so_list_tail->next)
so_list_tail = so_list_tail->next;
+#ifdef SOLIB_DEBUG
+ printf( "--About to read shared library list data\n" );
+#endif
+
+ /* "addr" will always point to the base of the
+ * current data entry describing the current
+ * shared library.
+ */
while (1)
{
CORE_ADDR name_addr, text_addr;
@@ -229,8 +568,9 @@ som_solib_add (arg_string, from_tty, target)
char *name;
struct so_list *new_so;
struct so_list *so_list = so_list_head;
- struct section_table *p;
struct stat statbuf;
+ LONGEST st_size;
+ int is_main_program;
if (addr == 0)
break;
@@ -276,18 +616,41 @@ som_solib_add (arg_string, from_tty, target)
if (status != 0)
goto err;
- addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
+ addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
continue;
}
/* If we've already loaded this one or it's the main program, skip it. */
- if (so_list || !strcmp (name, symfile_objfile->name))
+ is_main_program = (strcmp (name, symfile_objfile->name) == 0);
+ if (so_list || is_main_program)
{
+ /* This is the "next" pointer in the strcuture.
+ */
status = target_read_memory (addr + 36, buf, 4);
if (status != 0)
goto err;
addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
+
+ /* Record the main program's symbol table size. */
+ if (is_main_program && !so_list)
+ {
+ st_size = som_solib_sizeof_symbol_table (name);
+ som_solib_total_st_size += st_size;
+ }
+
+ /* Was this a shlib that we noted but didn't load the symbols for?
+ If so, were we invoked this time from the command-line, via
+ a 'sharedlibrary' or 'add-symbol-file' command? If yes to
+ both, we'd better load the symbols this time.
+ */
+ if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL))
+ som_solib_load_symbols (so_list,
+ name,
+ from_tty,
+ so_list->som_solib.text_addr,
+ target);
+
continue;
}
@@ -300,7 +663,6 @@ som_solib_add (arg_string, from_tty, target)
text_addr = extract_unsigned_integer (buf, 4);
-
new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
memset ((char *)new_so, 0, sizeof (struct so_list));
if (so_list_head == NULL)
@@ -314,7 +676,10 @@ som_solib_add (arg_string, from_tty, target)
so_list_tail = new_so;
}
- /* Fill in all the entries in GDB's shared library list. */
+ /* Fill in all the entries in GDB's shared library list.
+ */
+
+ new_so->solib_addr = addr;
new_so->som_solib.name = name;
status = target_read_memory (addr + 4, buf, 4);
if (status != 0)
@@ -322,9 +687,16 @@ som_solib_add (arg_string, from_tty, target)
new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
+ /* Following is "high water mark", highest version number
+ * seen, rather than plain version number.
+ */
new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
new_so->som_solib.text_addr = text_addr;
+ /* Q: What about longword at "addr + 8"?
+ * A: It's read above, out of order, into "text_addr".
+ */
+
status = target_read_memory (addr + 12, buf, 4);
if (status != 0)
goto err;
@@ -366,96 +738,95 @@ som_solib_add (arg_string, from_tty, target)
goto err;
new_so->som_solib.next = (void *)extract_unsigned_integer (buf, 4);
- addr = (CORE_ADDR)new_so->som_solib.next;
-
- new_so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0);
- new_so->abfd = new_so->objfile->obfd;
- if (!bfd_check_format (new_so->abfd, bfd_object))
- {
- error ("\"%s\": not in executable format: %s.",
- name, bfd_errmsg (bfd_get_error ()));
- }
+ /* Note that we don't re-set "addr" to the next pointer
+ * until after we've read the trailing data.
+ */
- /* Now we need to build a section table for this library since
- we might be debugging a core file from a dynamically linked
- executable in which the libraries were not privately mapped. */
- if (build_section_table (new_so->abfd,
- &new_so->sections,
- &new_so->sections_end))
- {
- error ("Unable to build section table for shared library\n.");
- return;
- }
-
- /* Relocate all the sections based on where they got loaded. */
- for (p = new_so->sections; p < new_so->sections_end; p++)
- {
- if (p->the_bfd_section->flags & SEC_CODE)
- {
- p->addr += text_addr - new_so->som_solib.text_link_addr;
- p->endaddr += text_addr - new_so->som_solib.text_link_addr;
- }
- else if (p->the_bfd_section->flags & SEC_DATA)
- {
- p->addr += new_so->som_solib.data_start;
- p->endaddr += new_so->som_solib.data_start;
- }
- }
-
- /* Now see if we need to map in the text and data for this shared
- library (for example debugging a core file which does not use
- private shared libraries.).
-
- Carefully peek at the first text address in the library. If the
- read succeeds, then the libraries were privately mapped and were
- included in the core dump file.
-
- If the peek failed, then the libraries were not privately mapped
- and are not in the core file, we'll have to read them in ourselves. */
- status = target_read_memory (text_addr, buf, 4);
+ status = target_read_memory (addr + 40, buf, 4);
+ new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
if (status != 0)
- {
- int old, new;
- int update_coreops;
+ goto err;
- /* We must update the to_sections field in the core_ops structure
- here, otherwise we dereference a potential dangling pointer
- for each call to target_read/write_memory within this routine. */
- update_coreops = core_ops.to_sections == target->to_sections;
+ /* Now indirect via that value!
+ */
+ status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4);
+ new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
+ if (status != 0)
+ goto err;
+#ifdef SOLIB_DEBUG
+ printf( "\n+ library \"%s\" is described at 0x%x\n", name, addr );
+ printf( " 'version' is %d\n", new_so->som_solib.struct_version );
+ printf( " 'bind_mode' is %d\n", new_so->som_solib.bind_mode );
+ printf( " 'library_version' is %d\n", new_so->som_solib.library_version );
+ printf( " 'text_addr' is 0x%x\n", new_so->som_solib.text_addr );
+ printf( " 'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr );
+ printf( " 'text_end' is 0x%x\n", new_so->som_solib.text_end );
+ printf( " 'data_start' is 0x%x\n", new_so->som_solib.data_start );
+ printf( " 'bss_start' is 0x%x\n", new_so->som_solib.bss_start );
+ printf( " 'data_end' is 0x%x\n", new_so->som_solib.data_end );
+ printf( " 'got_value' is %x\n", new_so->som_solib.got_value );
+ printf( " 'next' is 0x%x\n", new_so->som_solib.next );
+ printf( " 'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr );
+#endif
+
+ /* Go on to the next shared library descriptor.
+ */
+ addr = (CORE_ADDR)new_so->som_solib.next;
- new = new_so->sections_end - new_so->sections;
- /* Add sections from the shared library to the core target. */
- if (target->to_sections)
- {
- old = target->to_sections_end - target->to_sections;
- target->to_sections = (struct section_table *)
- xrealloc ((char *)target->to_sections,
- ((sizeof (struct section_table)) * (old + new)));
- }
- else
- {
- old = 0;
- target->to_sections = (struct section_table *)
- xmalloc ((sizeof (struct section_table)) * new);
- }
- target->to_sections_end = (target->to_sections + old + new);
- /* Update the to_sections field in the core_ops structure
- if needed. */
- if (update_coreops)
- {
- core_ops.to_sections = target->to_sections;
- core_ops.to_sections_end = target->to_sections_end;
- }
- /* Copy over the old data before it gets clobbered. */
- memcpy ((char *)(target->to_sections + old),
- new_so->sections,
- ((sizeof (struct section_table)) * new));
- }
+ /* At this point, we have essentially hooked the shlib into the
+ "info share" command. However, we haven't yet loaded its
+ symbol table. We must now decide whether we ought to, i.e.,
+ whether doing so would exceed the symbol table size threshold.
+
+ If the threshold has just now been exceeded, then we'll issue
+ a warning message (which explains how to load symbols manually,
+ if the user so desires).
+
+ If the threshold has just now or previously been exceeded,
+ we'll just add the shlib to the list of object files, but won't
+ actually load its symbols. (This is more useful than it might
+ sound, for it allows us to e.g., still load and use the shlibs'
+ unwind information for stack tracebacks.)
+ */
+
+ /* Note that we DON'T want to preclude the user from using the
+ add-symbol-file command! Thus, we only worry about the threshold
+ when we're invoked for other reasons.
+ */
+ st_size = som_solib_sizeof_symbol_table (name);
+ som_solib_st_size_threshold_exceeded =
+ !from_tty &&
+ ((st_size + som_solib_total_st_size) > (auto_solib_add * (LONGEST)1000000));
+
+ if (som_solib_st_size_threshold_exceeded)
+ {
+ if (! threshold_warning_given)
+ warning ("Symbols for some libraries have not been loaded, because\ndoing so would exceed the size threshold specified by auto-solib-add.\nTo manually load symbols, use the 'sharedlibrary' command.\nTo raise the threshold, set auto-solib-add to a larger value and rerun\nthe program.\n");
+ threshold_warning_given = 1;
+
+ /* We'll still make note of this shlib, even if we don't
+ read its symbols. This allows us to use its unwind
+ information well enough to know how to e.g., correctly
+ do a traceback from a PC within the shlib, even if we
+ can't symbolize those PCs...
+ */
+ som_solib_add_solib_objfile (new_so, name, from_tty, text_addr);
+ continue;
+ }
+
+ som_solib_total_st_size += st_size;
+
+ /* This fills in new_so->objfile, among others. */
+ som_solib_load_symbols (new_so, name, from_tty, text_addr, target);
}
+#ifdef SOLIB_DEBUG
+ printf( "--Done reading shared library data\n" );
+#endif
+
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
@@ -497,7 +868,7 @@ som_solib_create_inferior_hook()
struct minimal_symbol *msymbol;
unsigned int dld_flags, status, have_endo;
asection *shlib_info;
- char shadow_contents[BREAKPOINT_MAX], buf[4];
+ char buf[4];
struct objfile *objfile;
CORE_ADDR anaddr;
@@ -523,7 +894,7 @@ som_solib_create_inferior_hook()
if (msymbol == NULL)
{
warning ("Unable to find __d_pid symbol in object file.");
- warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
@@ -534,59 +905,68 @@ som_solib_create_inferior_hook()
if (status != 0)
{
warning ("Unable to write __d_pid");
- warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
/* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
This will force the dynamic linker to call __d_trap when significant
- events occur. */
+ events occur.
+
+ Note that the above is the pre-HP-UX 9.0 behaviour. At 9.0 and above,
+ the dld provides an export stub named "__d_trap" as well as the
+ function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
+ We'll look first for the old flavor and then the new.
+ */
msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
if (msymbol == NULL)
+ msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
+ if (msymbol == NULL)
{
warning ("Unable to find _DLD_HOOK symbol in object file.");
- warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ dld_cache.hook.address = anaddr;
/* Grrr, this might not be an export symbol! We have to find the
export stub. */
ALL_OBJFILES (objfile)
{
struct unwind_table_entry *u;
- extern struct unwind_table_entry *find_unwind_entry PARAMS ((CORE_ADDR pc));
+ struct minimal_symbol *msymbol2;
/* What a crock. */
- msymbol = lookup_minimal_symbol_solib_trampoline (SYMBOL_NAME (msymbol),
- NULL, objfile);
+ msymbol2 = lookup_minimal_symbol_solib_trampoline (SYMBOL_NAME (msymbol),
+ NULL, objfile);
/* Found a symbol with the right name. */
- if (msymbol)
+ if (msymbol2)
{
struct unwind_table_entry *u;
/* It must be a shared library trampoline. */
- if (SYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+ if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline)
continue;
/* It must also be an export stub. */
- u = find_unwind_entry (SYMBOL_VALUE (msymbol));
- if (!u || u->stub_type != EXPORT)
+ u = find_unwind_entry (SYMBOL_VALUE (msymbol2));
+ if (!u || u->stub_unwind.stub_type != EXPORT)
continue;
/* OK. Looks like the correct import stub. */
- anaddr = SYMBOL_VALUE (msymbol);
- break;
+ anaddr = SYMBOL_VALUE (msymbol2);
+ dld_cache.hook_stub.address = anaddr;
}
- }
+ }
store_unsigned_integer (buf, 4, anaddr);
msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
if (msymbol == NULL)
{
warning ("Unable to find __dld_hook symbol in object file.");
- warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
@@ -599,7 +979,7 @@ som_solib_create_inferior_hook()
if (msymbol == NULL)
{
warning ("Unable to find __dld_d_trap symbol in object file.");
- warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
@@ -617,34 +997,33 @@ keep_going:
if (msymbol == NULL)
{
error ("Unable to find __dld_flags symbol in object file.\n");
- goto keep_going;
- return;
}
anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+
/* Read the current contents. */
status = target_read_memory (anaddr, buf, 4);
if (status != 0)
{
error ("Unable to read __dld_flags\n");
- return;
}
dld_flags = extract_unsigned_integer (buf, 4);
/* Turn on the flags we care about. */
- dld_flags |= (0x5 | (have_endo << 1));
+ dld_flags |= DLD_FLAGS_MAPPRIVATE;
+ if (have_endo)
+ dld_flags |= DLD_FLAGS_HOOKVALID;
store_unsigned_integer (buf, 4, dld_flags);
status = target_write_memory (anaddr, buf, 4);
if (status != 0)
{
error ("Unable to write __dld_flags\n");
- return;
}
/* Now find the address of _start and set a breakpoint there.
We still need this code for two reasons:
- * Not all sites have /usr/lib/end.o, so it's not always
+ * Not all sites have /opt/langtools/lib/end.o, so it's not always
possible to track the dynamic linker's events.
* At this time no events are triggered for shared libraries
@@ -654,7 +1033,6 @@ keep_going:
if (msymbol == NULL)
{
error ("Unable to find _start symbol in object file.\n");
- return;
}
anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
@@ -668,7 +1046,6 @@ keep_going:
{
struct so_list *temp;
- free_objfile (so_list_head->objfile);
temp = so_list_head;
free (so_list_head);
so_list_head = temp->next;
@@ -676,6 +1053,322 @@ keep_going:
clear_symtab_users ();
}
+
+static void
+reset_inferior_pid (saved_inferior_pid)
+ int saved_inferior_pid;
+{
+ inferior_pid = saved_inferior_pid;
+}
+
+
+/* This operation removes the "hook" between GDB and the dynamic linker,
+ which causes the dld to notify GDB of shared library events.
+
+ After this operation completes, the dld will no longer notify GDB of
+ shared library events. To resume notifications, GDB must call
+ som_solib_create_inferior_hook.
+
+ This operation does not remove any knowledge of shared libraries which
+ GDB may already have been notified of.
+ */
+void
+som_solib_remove_inferior_hook (pid)
+ int pid;
+{
+ CORE_ADDR addr;
+ struct minimal_symbol * msymbol;
+ int status;
+ char dld_flags_buffer [TARGET_INT_BIT/TARGET_CHAR_BIT];
+ unsigned int dld_flags_value;
+ int saved_inferior_pid = inferior_pid;
+ struct cleanup * old_cleanups = make_cleanup (reset_inferior_pid, saved_inferior_pid);
+
+ /* Ensure that we're really operating on the specified process. */
+ inferior_pid = pid;
+
+ /* We won't bother to remove the solib breakpoints from this process.
+
+ In fact, on PA64 the breakpoint is hard-coded into the dld callback,
+ and thus we're not supposed to remove it.
+
+ Rather, we'll merely clear the dld_flags bit that enables callbacks.
+ */
+ msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
+
+ addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ status = target_read_memory (addr, dld_flags_buffer, TARGET_INT_BIT/TARGET_CHAR_BIT);
+
+ dld_flags_value = extract_unsigned_integer (dld_flags_buffer,
+ sizeof (dld_flags_value));
+
+ dld_flags_value &= ~DLD_FLAGS_HOOKVALID;
+ store_unsigned_integer (dld_flags_buffer,
+ sizeof (dld_flags_value),
+ dld_flags_value);
+ status = target_write_memory (addr, dld_flags_buffer, TARGET_INT_BIT/TARGET_CHAR_BIT);
+
+ do_cleanups (old_cleanups);
+}
+
+
+/* This function creates a breakpoint on the dynamic linker hook, which
+ is called when e.g., a shl_load or shl_unload call is made. This
+ breakpoint will only trigger when a shl_load call is made.
+
+ If filename is NULL, then loads of any dll will be caught. Else,
+ only loads of the file whose pathname is the string contained by
+ filename will be caught.
+
+ Undefined behaviour is guaranteed if this function is called before
+ som_solib_create_inferior_hook.
+ */
+void
+som_solib_create_catch_load_hook (pid, tempflag, filename, cond_string)
+ int pid;
+ int tempflag;
+ char * filename;
+ char * cond_string;
+{
+ create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
+}
+
+/* This function creates a breakpoint on the dynamic linker hook, which
+ is called when e.g., a shl_load or shl_unload call is made. This
+ breakpoint will only trigger when a shl_unload call is made.
+
+ If filename is NULL, then unloads of any dll will be caught. Else,
+ only unloads of the file whose pathname is the string contained by
+ filename will be caught.
+
+ Undefined behaviour is guaranteed if this function is called before
+ som_solib_create_inferior_hook.
+ */
+void
+som_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string)
+ int pid;
+ int tempflag;
+ char * filename;
+ char * cond_string;
+{
+ create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
+}
+
+int
+som_solib_have_load_event (pid)
+ int pid;
+{
+ CORE_ADDR event_kind;
+
+ event_kind = read_register (ARG0_REGNUM);
+ return (event_kind == SHL_LOAD);
+}
+
+int
+som_solib_have_unload_event (pid)
+ int pid;
+{
+ CORE_ADDR event_kind;
+
+ event_kind = read_register (ARG0_REGNUM);
+ return (event_kind == SHL_UNLOAD);
+}
+
+static char *
+som_solib_library_pathname (pid)
+ int pid;
+{
+ CORE_ADDR dll_handle_address;
+ CORE_ADDR dll_pathname_address;
+ struct som_solib_mapped_entry dll_descriptor;
+ char * p;
+ static char dll_pathname [1024];
+
+ /* Read the descriptor of this newly-loaded library. */
+ dll_handle_address = read_register (ARG1_REGNUM);
+ read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor));
+
+ /* We can find a pointer to the dll's pathname within the descriptor. */
+ dll_pathname_address = (CORE_ADDR) dll_descriptor.name;
+
+ /* Read the pathname, one byte at a time. */
+ p = dll_pathname;
+ for (;;)
+ {
+ char b;
+ read_memory (dll_pathname_address++, (char *) &b, 1);
+ *p++ = b;
+ if (b == '\0')
+ break;
+ }
+
+ return dll_pathname;
+}
+
+char *
+som_solib_loaded_library_pathname (pid)
+ int pid;
+{
+ if (! som_solib_have_load_event (pid))
+ error ("Must have a load event to use this query");
+
+ return som_solib_library_pathname (pid);
+}
+
+char *
+som_solib_unloaded_library_pathname (pid)
+ int pid;
+{
+ if (! som_solib_have_unload_event (pid))
+ error ("Must have an unload event to use this query");
+
+ return som_solib_library_pathname (pid);
+}
+
+static void
+som_solib_desire_dynamic_linker_symbols ()
+{
+ struct objfile *objfile;
+ struct unwind_table_entry *u;
+ struct minimal_symbol * dld_msymbol;
+
+ /* Do we already know the value of these symbols? If so, then
+ we've no work to do.
+
+ (If you add clauses to this test, be sure to likewise update the
+ test within the loop.)
+ */
+ if (dld_cache.is_valid)
+ return;
+
+ ALL_OBJFILES (objfile)
+ {
+ dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
+ if (dld_msymbol != NULL)
+ {
+ dld_cache.load.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
+ }
+
+ dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
+ NULL,
+ objfile);
+ if (dld_msymbol != NULL)
+ {
+ if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
+ {
+ u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
+ if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
+ {
+ dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.load_stub.unwind = u;
+ }
+ }
+ }
+
+ dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
+ if (dld_msymbol != NULL)
+ {
+ dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
+
+ /* ??rehrauer: I'm not sure exactly what this is, but it appears
+ that on some HPUX 10.x versions, there's two unwind regions to
+ cover the body of "shl_unload", the second being 4 bytes past
+ the end of the first. This is a large hack to handle that
+ case, but since I don't seem to have any legitimate way to
+ look for this thing via the symbol table...
+ */
+ if (dld_cache.unload.unwind != NULL)
+ {
+ u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
+ if (u != NULL)
+ {
+ dld_cache.unload2.address = u->region_start;
+ dld_cache.unload2.unwind = u;
+ }
+ }
+ }
+
+ dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
+ NULL,
+ objfile);
+ if (dld_msymbol != NULL)
+ {
+ if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
+ {
+ u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
+ if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
+ {
+ dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.unload_stub.unwind = u;
+ }
+ }
+ }
+
+ /* Did we find everything we were looking for? If so, stop. */
+ if ((dld_cache.load.address != NULL) && (dld_cache.load_stub.address != NULL)
+ && (dld_cache.unload.address != NULL) && (dld_cache.unload_stub.address != NULL))
+ {
+ dld_cache.is_valid = 1;
+ break;
+ }
+ }
+
+ dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
+ dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
+
+ /* We're prepared not to find some of these symbols, which is why
+ this function is a "desire" operation, and not a "require".
+ */
+}
+
+int
+som_solib_in_dynamic_linker (pid, pc)
+ int pid;
+ CORE_ADDR pc;
+{
+ struct unwind_table_entry * u_pc;
+
+ /* Are we in the dld itself?
+
+ ??rehrauer: Large hack -- We'll assume that any address in a
+ shared text region is the dld's text. This would obviously
+ fall down if the user attached to a process, whose shlibs
+ weren't mapped to a (writeable) private region. However, in
+ that case the debugger probably isn't able to set the fundamental
+ breakpoint in the dld callback anyways, so this hack should be
+ safe.
+ */
+ if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
+ return 1;
+
+ /* Cache the address of some symbols that are part of the dynamic
+ linker, if not already known.
+ */
+ som_solib_desire_dynamic_linker_symbols ();
+
+ /* Are we in the dld callback? Or its export stub? */
+ u_pc = find_unwind_entry (pc);
+ if (u_pc == NULL)
+ return 0;
+
+ if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
+ return 1;
+
+ /* Or the interface of the dld (i.e., "shl_load" or friends)? */
+ if ((u_pc == dld_cache.load.unwind)
+ || (u_pc == dld_cache.unload.unwind)
+ || (u_pc == dld_cache.unload2.unwind)
+ || (u_pc == dld_cache.load_stub.unwind)
+ || (u_pc == dld_cache.unload_stub.unwind))
+ return 1;
+
+ /* Apparently this address isn't part of the dld's text. */
+ return 0;
+}
+
+
/* Return the GOT value for the shared library in which ADDR belongs. If
ADDR isn't in any known shared library, return zero. */
@@ -699,6 +1392,34 @@ som_solib_get_got_by_pc (addr)
return got_value;
}
+/* elz:
+ Return the address of the handle of the shared library
+ in which ADDR belongs. If
+ ADDR isn't in any known shared library, return zero. */
+/* this function is used in hppa_fix_call_dummy in hppa-tdep.c*/
+
+CORE_ADDR
+som_solib_get_solib_by_pc (addr)
+ CORE_ADDR addr;
+{
+ struct so_list *so_list = so_list_head;
+
+ while (so_list)
+ {
+ if (so_list->som_solib.text_addr <= addr
+ && so_list->som_solib.text_end > addr)
+ {
+ break;
+ }
+ so_list = so_list->next;
+ }
+ if (so_list)
+ return so_list->solib_addr;
+ else
+ return 0;
+}
+
+
int
som_solib_section_offsets (objfile, offsets)
struct objfile *objfile;
@@ -774,7 +1495,10 @@ som_sharedlibrary_info_command (ignore, from_tty)
flags = so_list->som_solib.struct_version << 24;
flags |= so_list->som_solib.bind_mode << 16;
flags |= so_list->som_solib.library_version;
- printf_unfiltered ("%s\n", so_list->som_solib.name);
+ printf_unfiltered ("%s", so_list->som_solib.name);
+ if (so_list->objfile == NULL)
+ printf_unfiltered (" (symbols not loaded)");
+ printf_unfiltered ("\n");
printf_unfiltered (" %-12s", local_hex_string_custom (flags, "08l"));
printf_unfiltered ("%-12s",
local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
@@ -799,6 +1523,80 @@ som_solib_sharedlibrary_command (args, from_tty)
som_solib_add (args, from_tty, (struct target_ops *) 0);
}
+
+
+char *
+som_solib_address (addr)
+ CORE_ADDR addr;
+{
+ struct so_list * so = so_list_head;
+
+ while (so)
+ {
+ /* Is this address within this shlib's text range? If so,
+ return the shlib's name.
+ */
+ if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end))
+ return so->som_solib.name;
+
+ /* Nope, keep looking... */
+ so = so->next;
+ }
+
+ /* No, we couldn't prove that the address is within a shlib. */
+ return NULL;
+}
+
+
+void
+som_solib_restart ()
+{
+ struct so_list * sl = so_list_head;
+
+ /* Before the shlib info vanishes, use it to disable any breakpoints
+ that may still be active in those shlibs.
+ */
+ disable_breakpoints_in_shlibs (0);
+
+ /* Discard all the shlib descriptors.
+ */
+ while (sl)
+ {
+ struct so_list * next_sl = sl->next;
+ free (sl);
+ sl = next_sl;
+ }
+ so_list_head = NULL;
+
+ som_solib_total_st_size = (LONGEST) 0;
+ som_solib_st_size_threshold_exceeded = 0;
+
+ dld_cache.is_valid = 0;
+
+ dld_cache.hook.address = 0;
+ dld_cache.hook.unwind = NULL;
+
+ dld_cache.hook_stub.address = 0;
+ dld_cache.hook_stub.unwind = NULL;
+
+ dld_cache.load.address = 0;
+ dld_cache.load.unwind = NULL;
+
+ dld_cache.load_stub.address = 0;
+ dld_cache.load_stub.unwind = NULL;
+
+ dld_cache.unload.address = 0;
+ dld_cache.unload.unwind = NULL;
+
+ dld_cache.unload2.address = 0;
+ dld_cache.unload2.unwind = NULL;
+
+ dld_cache.unload_stub.address = 0;
+ dld_cache.unload_stub.unwind = NULL;
+}
+
+
+
void
_initialize_som_solib ()
{
@@ -809,12 +1607,34 @@ _initialize_som_solib ()
add_show_from_set
(add_set_cmd ("auto-solib-add", class_support, var_zinteger,
(char *) &auto_solib_add,
- "Set autoloading of shared library symbols at startup.\n\
+ "Set autoloading size threshold (in megabytes) of shared library symbols.\n\
If nonzero, symbols from all shared object libraries will be loaded\n\
automatically when the inferior begins execution or when the dynamic linker\n\
-informs gdb that a new library has been loaded. Otherwise, symbols\n\
-must be loaded manually, using `sharedlibrary'.",
+informs gdb that a new library has been loaded, until the symbol table\n\
+of the program and libraries exceeds this threshold.\n\
+Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
&setlist),
&showlist);
+ /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how much
+ data space a process can use. We ought to be reading MAXDSIZ and
+ setting auto_solib_add to some large fraction of that value. If
+ not that, we maybe ought to be setting it smaller than the default
+ for MAXDSIZ (that being 64Mb, I believe). However, [1] this threshold
+ is only crudely approximated rather than actually measured, and [2]
+ 50 Mbytes is too small for debugging gdb itself. Thus, the arbitrary
+ 100 figure.
+ */
+ auto_solib_add = 100; /* Megabytes */
+
+ som_solib_restart ();
+}
+
+/* Get some HPUX-specific data from a shared lib.
+ */
+CORE_ADDR
+so_lib_thread_start_addr( so )
+ struct so_list *so;
+{
+ return so->som_solib.tsd_start_addr;
}
diff --git a/contrib/gdb/gdb/somsolib.h b/contrib/gdb/gdb/somsolib.h
index 6fe0200..b969169 100644
--- a/contrib/gdb/gdb/somsolib.h
+++ b/contrib/gdb/gdb/somsolib.h
@@ -49,3 +49,129 @@ som_solib_section_offsets PARAMS ((struct objfile *, struct section_offsets *));
extern void
som_solib_create_inferior_hook PARAMS((void));
+
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.)
+ */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) som_solib_remove_inferior_hook(PID)
+
+extern void
+som_solib_remove_inferior_hook PARAMS((int));
+
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded.
+ */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \
+ som_solib_create_catch_load_hook (pid, tempflag, filename, cond_string)
+
+extern void
+som_solib_create_catch_load_hook PARAMS((int, int, char *, char *));
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded.
+ */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \
+ som_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string)
+
+extern void
+som_solib_create_catch_unload_hook PARAMS((int, int, char *, char *));
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+ */
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+ som_solib_have_load_event (pid)
+
+extern int
+som_solib_have_load_event PARAMS((int));
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+ */
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ som_solib_loaded_library_pathname (pid)
+
+extern char *
+som_solib_loaded_library_pathname PARAMS((int));
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+ */
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ som_solib_have_unload_event (pid)
+
+extern int
+som_solib_have_unload_event PARAMS((int));
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+ */
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ som_solib_unloaded_library_pathname (pid)
+
+extern char *
+som_solib_unloaded_library_pathname PARAMS((int));
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed.
+ */
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ som_solib_in_dynamic_linker (pid, pc)
+
+extern int
+som_solib_in_dynamic_linker PARAMS((int, CORE_ADDR));
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_RESTART() \
+ som_solib_restart ()
+
+extern void
+som_solib_restart PARAMS((void));
+
+/* If we can't set a breakpoint, and it's in a shared library, just
+ disable it. */
+
+#define DISABLE_UNSETTABLE_BREAK(addr) (som_solib_address(addr) != NULL)
+
+extern char *
+som_solib_address PARAMS ((CORE_ADDR)); /* somsolib.c */
+
+/* If ADDR lies in a shared library, return its name. */
+
+#define PC_SOLIB(addr) som_solib_address (addr)
diff --git a/contrib/gdb/gdb/source.c b/contrib/gdb/gdb/source.c
index 5e7af03..9fe9742 100644
--- a/contrib/gdb/gdb/source.c
+++ b/contrib/gdb/gdb/source.c
@@ -1,5 +1,5 @@
/* List lines of source files for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 88, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/types.h>
#include "gdb_string.h"
-#include <sys/param.h>
#include "gdb_stat.h"
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
@@ -42,9 +41,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "annotate.h"
#include "gdbtypes.h"
-/* Prototypes for local functions. */
+#ifdef CRLF_SOURCE_FILES
+
+/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
+ host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
+ much faster than defining LSEEK_NOT_LINEAR. */
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#define OPEN_MODE (O_RDONLY | O_BINARY)
+#define FDOPEN_MODE FOPEN_RB
+
+#else /* ! defined (CRLF_SOURCE_FILES) */
+
+#define OPEN_MODE O_RDONLY
+#define FDOPEN_MODE FOPEN_RT
-static int open_source_file PARAMS ((struct symtab *));
+#endif /* ! defined (CRLF_SOURCE_FILES) */
+
+/* Forward declarations */
+
+int open_source_file PARAMS ((struct symtab *));
+
+void find_source_lines PARAMS ((struct symtab *, int));
+
+/* Prototypes for exported functions. */
+
+void _initialize_source PARAMS ((void));
+
+/* Prototypes for local functions. */
static int get_filename_and_charpos PARAMS ((struct symtab *, char **));
@@ -62,13 +89,6 @@ static void source_info PARAMS ((char *, int));
static void show_directories PARAMS ((char *, int));
-static void find_source_lines PARAMS ((struct symtab *, int));
-
-/* If we use this declaration, it breaks because of fucking ANSI "const" stuff
- on some systems. We just have to not declare it at all, have it default
- to int, and possibly botch on a few systems. Thanks, ANSIholes... */
-/* extern char *strstr(); */
-
/* Path of directories to search for source files.
Same format as the PATH environment variable's value. */
@@ -99,6 +119,12 @@ static int last_line_listed;
static int first_line_listed;
+/* Saves the name of the last source file visited and a possible error code.
+ Used to prevent repeating annoying "No such file or directories" msgs */
+
+static struct symtab *last_source_visited = NULL;
+static int last_source_error = 0;
+
/* Set the source file default for the "list" command to be S.
@@ -185,6 +211,8 @@ select_source_symtab (s)
current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
}
}
+ if (current_source_symtab)
+ return;
error ("Can't find a default source file");
}
@@ -255,7 +283,10 @@ directory_command (dirname, from_tty)
}
}
else
- mod_path (dirname, &source_path);
+ {
+ mod_path (dirname, &source_path);
+ last_source_visited = NULL;
+ }
if (from_tty)
show_directories ((char *)0, from_tty);
forget_cached_source_info ();
@@ -307,7 +338,7 @@ mod_path (dirname, which_path)
}
}
-#ifndef WIN32
+#ifndef _WIN32
/* On win32 h:\ is different to h: */
if (SLASH_P (p[-1]))
/* Sigh. "foo/" => "foo" */
@@ -450,7 +481,8 @@ source_info (ignore, from_tty)
printf_filtered ("Contains %d line%s.\n", s->nlines,
s->nlines == 1 ? "" : "s");
- printf_filtered("Source language is %s.\n", language_str (s->language));
+ printf_filtered ("Source language is %s.\n", language_str (s->language));
+ printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
}
@@ -493,7 +525,7 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
if (!path)
path = ".";
-#ifdef WIN32
+#ifdef _WIN32
mode |= O_BINARY;
#endif
@@ -592,10 +624,42 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
return fd;
}
+
+/* This is essentially a convenience, for clients that want the behaviour
+ of openp, using source_path, but that really don't want the file to be
+ opened but want instead just to know what the full pathname is (as
+ qualified against source_path).
+
+ The current working directory is searched first.
+
+ If the file was found, this function returns 1, and FULL_PATHNAME is
+ set to the fully-qualified pathname.
+
+ Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
+ */
+int
+source_full_path_of (filename, full_pathname)
+ char * filename;
+ char ** full_pathname;
+{
+ int fd;
+
+ fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
+ if (fd < 0)
+ {
+ *full_pathname = NULL;
+ return 0;
+ }
+
+ close (fd);
+ return 1;
+}
+
+
/* Open a source file given a symtab S. Returns a file descriptor or
negative number for error. */
-static int
+int
open_source_file (s)
struct symtab *s;
{
@@ -607,7 +671,7 @@ open_source_file (s)
/* Quick way out if we already know its full name */
if (s->fullname)
{
- result = open (s->fullname, O_RDONLY);
+ result = open (s->fullname, OPEN_MODE);
if (result >= 0)
return result;
/* Didn't work -- free old one, try again. */
@@ -636,13 +700,13 @@ open_source_file (s)
}
}
- result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
+ result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
if (result < 0)
{
/* Didn't work. Try using just the basename. */
p = basename (s->filename);
if (p != s->filename)
- result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
+ result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
}
#ifdef MPW
if (result < 0)
@@ -650,14 +714,14 @@ open_source_file (s)
/* Didn't work. Try using just the MPW basename. */
p = (char *) mpw_basename (s->filename);
if (p != s->filename)
- result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
+ result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
}
if (result < 0)
{
/* Didn't work. Try using the mixed Unix/MPW basename. */
p = (char *) mpw_mixed_basename (s->filename);
if (p != s->filename)
- result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
+ result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
}
#endif /* MPW */
@@ -705,7 +769,7 @@ symtab_to_filename (s)
to be open on descriptor DESC.
All set S->nlines to the number of such lines. */
-static void
+void
find_source_lines (s, desc)
struct symtab *s;
int desc;
@@ -715,7 +779,7 @@ find_source_lines (s, desc)
int nlines = 0;
int lines_allocated = 1000;
int *line_charpos;
- long exec_mtime;
+ long mtime = 0;
int size;
line_charpos = (int *) xmmalloc (s -> objfile -> md,
@@ -723,11 +787,16 @@ find_source_lines (s, desc)
if (fstat (desc, &st) < 0)
perror_with_name (s->filename);
- if (exec_bfd)
+ if (s && s->objfile && s->objfile->obfd)
+ mtime = bfd_get_mtime(s->objfile->obfd);
+ else if (exec_bfd)
+ mtime = bfd_get_mtime(exec_bfd);
+
+ if (mtime && mtime < st.st_mtime)
{
- exec_mtime = bfd_get_mtime(exec_bfd);
- if (exec_mtime && exec_mtime < st.st_mtime)
- printf_filtered ("Source file is more recent than executable.\n");
+ if (tui_version)
+ printf_filtered ("\n");
+ warning("Source file is more recent than executable.\n");
}
#ifdef LSEEK_NOT_LINEAR
@@ -766,7 +835,9 @@ find_source_lines (s, desc)
data = (char *) xmalloc (size);
old_cleanups = make_cleanup (free, data);
- if (myread (desc, data, size) < 0)
+ /* Reassign `size' to result of read for systems where \r\n -> \n. */
+ size = myread (desc, data, size);
+ if (size < 0)
perror_with_name (s->filename);
end = data + size;
p = data;
@@ -900,12 +971,13 @@ identify_source_line (s, line, mid_statement, pc)
current_source_symtab = s;
return 1;
}
+
/* Print source lines from the file of symtab S,
- starting with line number LINE and stopping before line number STOPLINE. */
+ starting with line number LINE and stopping before line number STOPLINE. */
-void
-print_source_lines (s, line, stopline, noerror)
+static void
+print_source_lines_base (s, line, stopline, noerror)
struct symtab *s;
int line, stopline;
int noerror;
@@ -920,17 +992,37 @@ print_source_lines (s, line, stopline, noerror)
current_source_line = line;
first_line_listed = line;
- desc = open_source_file (s);
+
+ /* Only prints "No such file or directory" once */
+ if ((s != last_source_visited) || (! last_source_error))
+ {
+ last_source_visited = s;
+ desc = open_source_file (s);
+ }
+ else
+ {
+ desc = last_source_error;
+ noerror = 1;
+ }
+
if (desc < 0)
{
- if (! noerror) {
- char *name = alloca (strlen (s->filename) + 100);
- sprintf (name, "%s:%d", s->filename, line);
- print_sys_errmsg (name, errno);
- }
+ last_source_error = desc;
+
+ if (! noerror)
+ {
+ char *name = alloca (strlen (s->filename) + 100);
+ sprintf (name, "%d\t%s", line, s->filename);
+ print_sys_errmsg (name, errno);
+ }
+ else
+ printf_filtered ("%d\tin %s\n", line, s->filename);
+
return;
}
+ last_source_error = 0;
+
if (s->line_charpos == 0)
find_source_lines (s, desc);
@@ -947,7 +1039,7 @@ print_source_lines (s, line, stopline, noerror)
perror_with_name (s->filename);
}
- stream = fdopen (desc, FOPEN_RT);
+ stream = fdopen (desc, FDOPEN_MODE);
clearerr (stream);
while (nlines-- > 0)
@@ -959,9 +1051,15 @@ print_source_lines (s, line, stopline, noerror)
do
{
if (c < 040 && c != '\t' && c != '\n' && c != '\r')
- printf_filtered ("^%c", c + 0100);
+ printf_filtered ("^%c", c + 0100);
else if (c == 0177)
printf_filtered ("^?");
+#ifdef CRLF_SOURCE_FILES
+ else if (c == '\r')
+ {
+ /* Just skip \r characters. */
+ }
+#endif
else
printf_filtered ("%c", c);
} while (c != '\n' && (c = fgetc (stream)) >= 0);
@@ -970,6 +1068,43 @@ print_source_lines (s, line, stopline, noerror)
fclose (stream);
}
+/* Show source lines from the file of symtab S, starting with line
+ number LINE and stopping before line number STOPLINE. If this is the
+ not the command line version, then the source is shown in the source
+ window otherwise it is simply printed */
+
+void
+print_source_lines (s, line, stopline, noerror)
+ struct symtab *s;
+ int line, stopline, noerror;
+{
+#if defined(TUI)
+ if (!tui_version ||
+ m_winPtrIsNull(srcWin) || !srcWin->generic.isVisible )
+ print_source_lines_base(s, line, stopline, noerror);
+ else
+ {
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr();
+ extern void tui_vAddWinToLayout PARAMS ((va_list));
+ extern void tui_vUpdateSourceWindowsWithLine PARAMS ((va_list));
+
+ /* Regardless of whether we can open the file,
+ set current_source_symtab. */
+ current_source_symtab = s;
+ current_source_line = line;
+ first_line_listed = line;
+
+ /* make sure that the source window is displayed */
+ tuiDo((TuiOpaqueFuncPtr)tui_vAddWinToLayout, SRC_WIN);
+
+ tuiDo((TuiOpaqueFuncPtr)tui_vUpdateSourceWindowsWithLine, s, line);
+ tuiDo((TuiOpaqueFuncPtr)tui_vUpdateLocatorFilename, s->filename);
+ }
+#else
+ print_source_lines_base(s, line, stopline, noerror);
+#endif
+}
+
/* Print a list of files and line numbers which a user may choose from
@@ -1149,9 +1284,19 @@ list_command (arg, from_tty)
else if (sal.symtab == 0)
error ("No default source file yet. Do \"help list\".");
else if (no_end)
- print_source_lines (sal.symtab,
+ if (lines_to_list % 2 == 0)
+ print_source_lines (sal.symtab,
+ max (sal.line - (lines_to_list / 2), 1),
+ sal.line + (lines_to_list / 2), 0);
+ else
+ /* If lines_to_list is odd, then we round down in
+ * one of the lines_to_list/2 computations, round up in
+ * the other, so the total window size around the specified
+ * line comes out right.
+ */
+ print_source_lines (sal.symtab,
max (sal.line - (lines_to_list / 2), 1),
- sal.line + (lines_to_list / 2), 0);
+ sal.line + ((1+lines_to_list) / 2), 0);
else
print_source_lines (sal.symtab, sal.line,
(dummy_end
@@ -1172,11 +1317,12 @@ line_info (arg, from_tty)
CORE_ADDR start_pc, end_pc;
int i;
+ INIT_SAL (&sal); /* initialize to zeroes */
+
if (arg == 0)
{
sal.symtab = current_source_symtab;
sal.line = last_line_listed;
- sal.pc = 0;
sals.nelts = 1;
sals.sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
@@ -1269,9 +1415,33 @@ forward_search_command (regex, from_tty)
register int c;
register int desc;
register FILE *stream;
- int line = last_line_listed + 1;
+ int line;
char *msg;
+#if defined(TUI)
+ /*
+ ** If this is the TUI, search from the first line displayed in
+ ** the source window, otherwise, search from last_line_listed+1
+ ** in current_source_symtab
+ */
+ if (!tui_version)
+ line = last_line_listed;
+ else
+ {
+ if (srcWin->generic.isVisible && srcWin->generic.contentSize > 0)
+ line = ((TuiWinContent)
+ srcWin->generic.content)[0]->whichElement.source.lineOrAddr.lineNo;
+ else
+ {
+ printf_filtered("No source displayed.\nExpression not found.\n");
+ return;
+ }
+ }
+ line++;
+#else
+ line = last_line_listed + 1;
+#endif
+
msg = (char *) re_comp (regex);
if (msg)
error (msg);
@@ -1279,8 +1449,6 @@ forward_search_command (regex, from_tty)
if (current_source_symtab == 0)
select_source_symtab (0);
- /* Search from last_line_listed+1 in current_source_symtab */
-
desc = open_source_file (current_source_symtab);
if (desc < 0)
perror_with_name (current_source_symtab->filename);
@@ -1300,7 +1468,7 @@ forward_search_command (regex, from_tty)
perror_with_name (current_source_symtab->filename);
}
- stream = fdopen (desc, FOPEN_RT);
+ stream = fdopen (desc, FDOPEN_MODE);
clearerr (stream);
while (1) {
static char *buf = NULL;
@@ -1331,6 +1499,8 @@ forward_search_command (regex, from_tty)
{
/* Match! */
fclose (stream);
+ if (tui_version)
+ print_source_lines_base (current_source_symtab, line, line+1, 0);
print_source_lines (current_source_symtab, line, line+1, 0);
set_internalvar (lookup_internalvar ("_"),
value_from_longest (builtin_type_int,
@@ -1354,8 +1524,31 @@ reverse_search_command (regex, from_tty)
register int c;
register int desc;
register FILE *stream;
- int line = last_line_listed - 1;
+ int line;
char *msg;
+#if defined(TUI)
+ /*
+ ** If this is the TUI, search from the first line displayed in
+ ** the source window, otherwise, search from last_line_listed-1
+ ** in current_source_symtab
+ */
+ if (!tui_version)
+ line = last_line_listed;
+ else
+ {
+ if (srcWin->generic.isVisible && srcWin->generic.contentSize > 0)
+ line = ((TuiWinContent)
+ srcWin->generic.content)[0]->whichElement.source.lineOrAddr.lineNo;
+ else
+ {
+ printf_filtered("No source displayed.\nExpression not found.\n");
+ return;
+ }
+ }
+ line--;
+#else
+ line = last_line_listed - 1;
+#endif
msg = (char *) re_comp (regex);
if (msg)
@@ -1364,8 +1557,6 @@ reverse_search_command (regex, from_tty)
if (current_source_symtab == 0)
select_source_symtab (0);
- /* Search from last_line_listed-1 in current_source_symtab */
-
desc = open_source_file (current_source_symtab);
if (desc < 0)
perror_with_name (current_source_symtab->filename);
@@ -1385,7 +1576,7 @@ reverse_search_command (regex, from_tty)
perror_with_name (current_source_symtab->filename);
}
- stream = fdopen (desc, FOPEN_RT);
+ stream = fdopen (desc, FDOPEN_MODE);
clearerr (stream);
while (line > 1)
{
@@ -1406,8 +1597,9 @@ reverse_search_command (regex, from_tty)
{
/* Match! */
fclose (stream);
- print_source_lines (current_source_symtab,
- line, line+1, 0);
+ if (tui_version)
+ print_source_lines_base (current_source_symtab, line, line+1, 0);
+ print_source_lines (current_source_symtab, line, line+1, 0);
set_internalvar (lookup_internalvar ("_"),
value_from_longest (builtin_type_int,
(LONGEST) line));
@@ -1447,6 +1639,10 @@ DIR can also be $cwd for the current working directory, or $cdir for the\n\
directory in which the source file was compiled into object code.\n\
With no argument, reset the search path to $cdir:$cwd, the default.",
&cmdlist);
+
+ if (dbx_commands)
+ add_com_alias("use", "directory", class_files, 0);
+
c->completer = filename_completer;
add_cmd ("directories", no_class, show_directories,
@@ -1455,6 +1651,16 @@ $cwd in the path means the current working directory.\n\
$cdir in the path means the compilation directory of the source file.",
&showlist);
+ if (xdb_commands)
+ {
+ add_com_alias("D", "directory", class_files, 0);
+ add_cmd ("ld", no_class, show_directories,
+ "Current search path for finding source files.\n\
+$cwd in the path means the current working directory.\n\
+$cdir in the path means the compilation directory of the source file.",
+ &cmdlist);
+ }
+
add_info ("source", source_info,
"Information about the current source file.");
@@ -1480,6 +1686,12 @@ The matching line number is also stored as the value of \"$_\".");
"Search backward for regular expression (see regex(3)) from last line listed.\n\
The matching line number is also stored as the value of \"$_\".");
+ if (xdb_commands)
+ {
+ add_com_alias("/", "forward-search", class_files, 0);
+ add_com_alias("?", "reverse-search", class_files, 0);
+ }
+
add_com ("list", class_files, list_command,
concat ("List specified function or line.\n\
With no argument, lists ten more lines after or around previous listing.\n\
@@ -1495,7 +1707,13 @@ Lines can be specified in these ways:\n\
*ADDRESS, to list around the line containing that address.\n\
With two args if one is empty it stands for ten lines away from the other arg.", NULL));
- add_com_alias ("l", "list", class_files, 1);
+ if (!xdb_commands)
+ add_com_alias ("l", "list", class_files, 1);
+ else
+ add_com_alias ("v", "list", class_files, 1);
+
+ if (dbx_commands)
+ add_com_alias ("file", "list", class_files, 1);
add_show_from_set
(add_set_cmd ("listsize", class_support, var_uinteger,
diff --git a/contrib/gdb/gdb/srec.h b/contrib/gdb/gdb/srec.h
index 1446bda..8253e03 100644
--- a/contrib/gdb/gdb/srec.h
+++ b/contrib/gdb/gdb/srec.h
@@ -1,5 +1,5 @@
/* S-record download support for GDB, the GNU debugger.
- Copyright 1995 Free Software Foundation, Inc.
+ Copyright 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
@@ -17,8 +17,9 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-void load_srec PARAMS ((serial_t desc, const char *file, int maxrecsize,
- int flags, int hashmark));
+void load_srec PARAMS ((serial_t desc, const char *file, bfd_vma load_offset,
+ int maxrecsize, int flags, int hashmark,
+ int (*waitack)(void)));
/* S-record capability flags */
diff --git a/contrib/gdb/gdb/stabsread.c b/contrib/gdb/gdb/stabsread.c
index 80fbd77..c5d31e1 100644
--- a/contrib/gdb/gdb/stabsread.c
+++ b/contrib/gdb/gdb/stabsread.c
@@ -1,5 +1,5 @@
/* Support routines for decoding "stabs" debugging information format.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -75,6 +75,13 @@ struct field_info
} *fnlist;
};
+static void
+read_one_struct_field PARAMS ((struct field_info *, char **, char *,
+ struct type *, struct objfile *));
+
+static char *
+get_substring PARAMS ((char **, int));
+
static struct type *
dbx_alloc_type PARAMS ((int [2], struct objfile *));
@@ -143,6 +150,44 @@ static int
read_cpp_abbrev PARAMS ((struct field_info *, char **, struct type *,
struct objfile *));
+/* new functions added for cfront support */
+
+static int
+copy_cfront_struct_fields PARAMS ((struct field_info *, struct type *,
+ struct objfile *));
+
+static char *
+get_cfront_method_physname PARAMS ((char *));
+
+static int
+read_cfront_baseclasses PARAMS ((struct field_info *, char **,
+ struct type *, struct objfile *));
+
+static int
+read_cfront_static_fields PARAMS ((struct field_info *, char**,
+ struct type *, struct objfile *));
+static int
+read_cfront_member_functions PARAMS ((struct field_info *, char **,
+ struct type *, struct objfile *));
+
+/* end new functions added for cfront support */
+
+static void
+add_live_range PARAMS ((struct objfile *, struct symbol *,
+ CORE_ADDR, CORE_ADDR));
+
+static int
+resolve_live_range PARAMS ((struct objfile *, struct symbol *, char *));
+
+static int
+process_reference PARAMS ((char **string));
+
+static CORE_ADDR
+ref_search_value PARAMS ((int refnum));
+
+static int
+resolve_symbol_reference PARAMS ((struct objfile *, struct symbol *, char *));
+
static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' };
static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' };
@@ -155,43 +200,46 @@ static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' };
#define BELIEVE_PCC_PROMOTION 0
#endif
-struct complaint invalid_cpp_abbrev_complaint =
+static struct complaint invalid_cpp_abbrev_complaint =
{"invalid C++ abbreviation `%s'", 0, 0};
-struct complaint invalid_cpp_type_complaint =
+static struct complaint invalid_cpp_type_complaint =
{"C++ abbreviated type name unknown at symtab pos %d", 0, 0};
-struct complaint member_fn_complaint =
+static struct complaint member_fn_complaint =
{"member function type missing, got '%c'", 0, 0};
-struct complaint const_vol_complaint =
+static struct complaint const_vol_complaint =
{"const/volatile indicator missing, got '%c'", 0, 0};
-struct complaint error_type_complaint =
+static struct complaint error_type_complaint =
{"debug info mismatch between compiler and debugger", 0, 0};
-struct complaint invalid_member_complaint =
+static struct complaint invalid_member_complaint =
{"invalid (minimal) member type data format at symtab pos %d.", 0, 0};
-struct complaint range_type_base_complaint =
+static struct complaint range_type_base_complaint =
{"base type %d of range type is not defined", 0, 0};
-struct complaint reg_value_complaint =
+static struct complaint reg_value_complaint =
{"register number %d too large (max %d) in symbol %s", 0, 0};
-struct complaint vtbl_notfound_complaint =
+static struct complaint vtbl_notfound_complaint =
{"virtual function table pointer not found when defining class `%s'", 0, 0};
-struct complaint unrecognized_cplus_name_complaint =
+static struct complaint unrecognized_cplus_name_complaint =
{"Unknown C++ symbol name `%s'", 0, 0};
-struct complaint rs6000_builtin_complaint =
+static struct complaint rs6000_builtin_complaint =
{"Unknown builtin type %d", 0, 0};
-struct complaint unresolved_sym_chain_complaint =
+static struct complaint unresolved_sym_chain_complaint =
{"%s: common block `%s' from global_sym_chain unresolved", 0, 0};
-struct complaint stabs_general_complaint =
+static struct complaint stabs_general_complaint =
+ {"%s", 0, 0};
+
+static struct complaint lrs_general_complaint =
{"%s", 0, 0};
/* Make a list of forward references which haven't been defined. */
@@ -313,7 +361,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
{
real_filenum = this_object_header_files[filenum];
- if (real_filenum >= n_header_files)
+ if (real_filenum >= N_HEADER_FILES (current_objfile))
{
struct type *temp_type;
struct type **temp_type_p;
@@ -327,7 +375,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
return temp_type_p;
}
- f = &header_files[real_filenum];
+ f = HEADER_FILES (current_objfile) + real_filenum;
f_orig_length = f->length;
if (index >= f_orig_length)
@@ -427,7 +475,7 @@ patch_block_stabs (symbols, stabs, objfile)
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
SYMBOL_NAME (sym) =
- obstack_copy0 (&objfile->symbol_obstack, name, pp - name);
+ obsavestring (name, pp - name, &objfile->symbol_obstack);
pp += 2;
if (*(pp-1) == 'F' || *(pp-1) == 'f')
{
@@ -497,6 +545,736 @@ read_type_number (pp, typenums)
#define REG_STRUCT_HAS_ADDR(gcc_p,type) 0
#endif
+#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */
+#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */
+#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */
+#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */
+
+#define CFRONT_VISIBILITY_PRIVATE '2' /* Stabs character for private field */
+#define CFRONT_VISIBILITY_PUBLIC '1' /* Stabs character for public field */
+
+/* This code added to support parsing of ARM/Cfront stabs strings */
+
+/* Get substring from string up to char c, advance string pointer past
+ suibstring. */
+
+static char *
+get_substring (p, c)
+ char ** p;
+ int c;
+{
+ char *str;
+ str = *p;
+ *p = strchr (*p, c);
+ if (*p)
+ {
+ **p = 0;
+ (*p)++;
+ }
+ else
+ str = 0;
+ return str;
+}
+
+/* Physname gets strcat'd onto sname in order to recreate the mangled
+ name (see funtion gdb_mangle_name in gdbtypes.c). For cfront, make
+ the physname look like that of g++ - take out the initial mangling
+ eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */
+
+static char *
+get_cfront_method_physname (fname)
+ char *fname;
+{
+ int len = 0;
+ /* FIXME would like to make this generic for g++ too, but
+ that is already handled in read_member_funcctions */
+ char * p = fname;
+
+ /* search ahead to find the start of the mangled suffix */
+ if (*p == '_' && *(p+1)=='_') /* compiler generated; probably a ctor/dtor */
+ p += 2;
+ while (p && (unsigned) ((p+1) - fname) < strlen (fname) && *(p+1) != '_')
+ p = strchr (p, '_');
+ if (!(p && *p == '_' && *(p+1) == '_'))
+ error ("Invalid mangled function name %s",fname);
+ p += 2; /* advance past '__' */
+
+ /* struct name length and name of type should come next; advance past it */
+ while (isdigit (*p))
+ {
+ len = len * 10 + (*p - '0');
+ p++;
+ }
+ p += len;
+
+ return p;
+}
+
+/* Read base classes within cfront class definition.
+ eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+ ^^^^^^^^^^^^^^^^^^
+
+ A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+ ^
+ */
+
+static int
+read_cfront_baseclasses (fip, pp, type, objfile)
+ struct field_info *fip;
+ struct objfile *objfile;
+ char ** pp;
+ struct type *type;
+{
+ static struct complaint msg_unknown = {"\
+ Unsupported token in stabs string %s.\n",
+ 0, 0};
+ static struct complaint msg_notfound = {"\
+ Unable to find base type for %s.\n",
+ 0, 0};
+ int bnum = 0;
+ char * p;
+ int i;
+ struct nextfield *new;
+
+ if (**pp == ';') /* no base classes; return */
+ {
+ ++(*pp);
+ return 1;
+ }
+
+ /* first count base classes so we can allocate space before parsing */
+ for (p = *pp; p && *p && *p != ';'; p++)
+ {
+ if (*p == ' ')
+ bnum++;
+ }
+ bnum++; /* add one more for last one */
+
+ /* now parse the base classes until we get to the start of the methods
+ (code extracted and munged from read_baseclasses) */
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_N_BASECLASSES(type) = bnum;
+
+ /* allocate space */
+ {
+ int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type));
+ char *pointer;
+
+ pointer = (char *) TYPE_ALLOC (type, num_bytes);
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+ }
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+ for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+ {
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (free, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new -> next = fip -> list;
+ fip -> list = new;
+ FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */
+
+ STABS_CONTINUE (pp, objfile);
+
+ /* virtual? eg: v2@Bvir */
+ if (**pp=='v')
+ {
+ SET_TYPE_FIELD_VIRTUAL (type, i);
+ ++(*pp);
+ }
+
+ /* access? eg: 2@Bvir */
+ /* Note: protected inheritance not supported in cfront */
+ switch (*(*pp)++)
+ {
+ case CFRONT_VISIBILITY_PRIVATE:
+ new -> visibility = VISIBILITY_PRIVATE;
+ break;
+ case CFRONT_VISIBILITY_PUBLIC:
+ new -> visibility = VISIBILITY_PUBLIC;
+ break;
+ default:
+ /* Bad visibility format. Complain and treat it as
+ public. */
+ {
+ static struct complaint msg = {
+ "Unknown visibility `%c' for baseclass", 0, 0};
+ complain (&msg, new -> visibility);
+ new -> visibility = VISIBILITY_PUBLIC;
+ }
+ }
+
+ /* "@" comes next - eg: @Bvir */
+ if (**pp!='@')
+ {
+ complain (&msg_unknown, *pp);
+ return 1;
+ }
+ ++(*pp);
+
+
+ /* Set the bit offset of the portion of the object corresponding
+ to this baseclass. Always zero in the absence of
+ multiple inheritance. */
+ /* Unable to read bit position from stabs;
+ Assuming no multiple inheritance for now FIXME! */
+ /* We may have read this in the structure definition;
+ now we should fixup the members to be the actual base classes */
+ FIELD_BITPOS (new->field) = 0;
+
+ /* Get the base class name and type */
+ {
+ char * bname; /* base class name */
+ struct symbol * bsym; /* base class */
+ char * p1, * p2;
+ p1 = strchr (*pp,' ');
+ p2 = strchr (*pp,';');
+ if (p1<p2)
+ bname = get_substring (pp,' ');
+ else
+ bname = get_substring (pp,';');
+ if (!bname || !*bname)
+ {
+ complain (&msg_unknown, *pp);
+ return 1;
+ }
+ /* FIXME! attach base info to type */
+ bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name*/
+ if (bsym)
+ {
+ new -> field.type = SYMBOL_TYPE(bsym);
+ new -> field.name = type_name_no_tag (new -> field.type);
+ }
+ else
+ {
+ complain (&msg_notfound, *pp);
+ return 1;
+ }
+ }
+
+ /* If more base classes to parse, loop again.
+ We ate the last ' ' or ';' in get_substring,
+ so on exit we will have skipped the trailing ';' */
+ /* if invalid, return 0; add code to detect - FIXME! */
+ }
+ return 1;
+}
+
+/* read cfront member functions.
+ pp points to string starting with list of functions
+ eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+*/
+
+static int
+read_cfront_member_functions (fip, pp, type, objfile)
+ struct field_info *fip;
+ char **pp;
+ struct type *type;
+ struct objfile *objfile;
+{
+ /* This code extracted from read_member_functions
+ so as to do the similar thing for our funcs */
+
+ int nfn_fields = 0;
+ int length = 0;
+ /* Total number of member functions defined in this class. If the class
+ defines two `f' functions, and one `g' function, then this will have
+ the value 3. */
+ int total_length = 0;
+ int i;
+ struct next_fnfield
+ {
+ struct next_fnfield *next;
+ struct fn_field fn_field;
+ } *sublist;
+ struct type *look_ahead_type;
+ struct next_fnfieldlist *new_fnlist;
+ struct next_fnfield *new_sublist;
+ char *main_fn_name;
+ char * fname;
+ struct symbol * ref_func = 0;
+
+ /* Process each list until we find the end of the member functions.
+ eg: p = "__ct__1AFv foo__1AFv ;;;" */
+
+ STABS_CONTINUE (pp, objfile); /* handle \\ */
+
+ while (**pp != ';' && (fname = get_substring (pp, ' '), fname))
+ {
+ int is_static = 0;
+ int sublist_count = 0;
+ char * pname;
+ if (fname[0] == '*') /* static member */
+ {
+ is_static=1;
+ sublist_count++;
+ fname++;
+ }
+ ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /* demangled name */
+ if (!ref_func)
+ {
+ static struct complaint msg = {"\
+ Unable to find function symbol for %s\n",
+ 0, 0};
+ complain (&msg, fname);
+ continue;
+ }
+ sublist = NULL;
+ look_ahead_type = NULL;
+ length = 0;
+
+ new_fnlist = (struct next_fnfieldlist *)
+ xmalloc (sizeof (struct next_fnfieldlist));
+ make_cleanup (free, new_fnlist);
+ memset (new_fnlist, 0, sizeof (struct next_fnfieldlist));
+
+ /* The following is code to work around cfront generated stabs.
+ The stabs contains full mangled name for each field.
+ We try to demangle the name and extract the field name out of it. */
+ {
+ char *dem, *dem_p, *dem_args;
+ int dem_len;
+ dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS);
+ if (dem != NULL)
+ {
+ dem_p = strrchr (dem, ':');
+ if (dem_p != 0 && *(dem_p-1) == ':')
+ dem_p++;
+ /* get rid of args */
+ dem_args = strchr (dem_p, '(');
+ if (dem_args == NULL)
+ dem_len = strlen (dem_p);
+ else
+ dem_len = dem_args - dem_p;
+ main_fn_name =
+ obsavestring (dem_p, dem_len, &objfile -> type_obstack);
+ }
+ else
+ {
+ main_fn_name =
+ obsavestring (fname, strlen (fname), &objfile -> type_obstack);
+ }
+ } /* end of code for cfront work around */
+
+ new_fnlist -> fn_fieldlist.name = main_fn_name;
+
+ /*-------------------------------------------------*/
+ /* Set up the sublists
+ Sublists are stuff like args, static, visibility, etc.
+ so in ARM, we have to set that info some other way.
+ Multiple sublists happen if overloading
+ eg: foo::26=##1;:;2A.;
+ In g++, we'd loop here thru all the sublists... */
+
+ new_sublist =
+ (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield));
+ make_cleanup (free, new_sublist);
+ memset (new_sublist, 0, sizeof (struct next_fnfield));
+
+ /* eat 1; from :;2A.; */
+ new_sublist -> fn_field.type = SYMBOL_TYPE(ref_func); /* normally takes a read_type */
+ /* Make this type look like a method stub for gdb */
+ TYPE_FLAGS (new_sublist -> fn_field.type) |= TYPE_FLAG_STUB;
+ TYPE_CODE (new_sublist -> fn_field.type) = TYPE_CODE_METHOD;
+
+ /* If this is just a stub, then we don't have the real name here. */
+ if (TYPE_FLAGS (new_sublist -> fn_field.type) & TYPE_FLAG_STUB)
+ {
+ if (!TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type))
+ TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type) = type;
+ new_sublist -> fn_field.is_stub = 1;
+ }
+
+ /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i
+ physname gets strcat'd in order to recreate the onto mangled name */
+ pname = get_cfront_method_physname (fname);
+ new_sublist -> fn_field.physname = savestring (pname, strlen (pname));
+
+
+ /* Set this member function's visibility fields.
+ Unable to distinguish access from stabs definition!
+ Assuming public for now. FIXME!
+ (for private, set new_sublist->fn_field.is_private = 1,
+ for public, set new_sublist->fn_field.is_protected = 1) */
+
+ /* Unable to distinguish const/volatile from stabs definition!
+ Assuming normal for now. FIXME! */
+
+ new_sublist -> fn_field.is_const = 0;
+ new_sublist -> fn_field.is_volatile = 0; /* volatile not implemented in cfront */
+
+ /* Set virtual/static function info
+ How to get vtable offsets ?
+ Assuming normal for now FIXME!!
+ For vtables, figure out from whence this virtual function came.
+ It may belong to virtual function table of
+ one of its baseclasses.
+ set:
+ new_sublist -> fn_field.voffset = vtable offset,
+ new_sublist -> fn_field.fcontext = look_ahead_type;
+ where look_ahead_type is type of baseclass */
+ if (is_static)
+ new_sublist -> fn_field.voffset = VOFFSET_STATIC;
+ else /* normal member function. */
+ new_sublist -> fn_field.voffset = 0;
+ new_sublist -> fn_field.fcontext = 0;
+
+
+ /* Prepare new sublist */
+ new_sublist -> next = sublist;
+ sublist = new_sublist;
+ length++;
+
+ /* In g++, we loop thu sublists - now we set from functions. */
+ new_fnlist -> fn_fieldlist.fn_fields = (struct fn_field *)
+ obstack_alloc (&objfile -> type_obstack,
+ sizeof (struct fn_field) * length);
+ memset (new_fnlist -> fn_fieldlist.fn_fields, 0,
+ sizeof (struct fn_field) * length);
+ for (i = length; (i--, sublist); sublist = sublist -> next)
+ {
+ new_fnlist -> fn_fieldlist.fn_fields[i] = sublist -> fn_field;
+ }
+
+ new_fnlist -> fn_fieldlist.length = length;
+ new_fnlist -> next = fip -> fnlist;
+ fip -> fnlist = new_fnlist;
+ nfn_fields++;
+ total_length += length;
+ STABS_CONTINUE (pp, objfile); /* handle \\ */
+ } /* end of loop */
+
+ if (nfn_fields)
+ {
+ /* type should already have space */
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields);
+ memset (TYPE_FN_FIELDLISTS (type), 0,
+ sizeof (struct fn_fieldlist) * nfn_fields);
+ TYPE_NFN_FIELDS (type) = nfn_fields;
+ TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+ }
+
+ /* end of scope for reading member func */
+
+ /* eg: ";;" */
+
+ /* Skip trailing ';' and bump count of number of fields seen */
+ if (**pp == ';')
+ (*pp)++;
+ else
+ return 0;
+ return 1;
+}
+
+/* This routine fixes up partial cfront types that were created
+ while parsing the stabs. The main need for this function is
+ to add information such as methods to classes.
+ Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */
+int
+resolve_cfront_continuation (objfile, sym, p)
+ struct objfile * objfile;
+ struct symbol * sym;
+ char * p;
+{
+ struct symbol * ref_sym=0;
+ char * sname;
+ /* snarfed from read_struct_type */
+ struct field_info fi;
+ struct type *type;
+ struct cleanup *back_to;
+
+ /* Need to make sure that fi isn't gunna conflict with struct
+ in case struct already had some fnfs */
+ fi.list = NULL;
+ fi.fnlist = NULL;
+ back_to = make_cleanup (null_cleanup, 0);
+
+ /* We only accept structs, classes and unions at the moment.
+ Other continuation types include t (typedef), r (long dbl), ...
+ We may want to add support for them as well;
+ right now they are handled by duplicating the symbol information
+ into the type information (see define_symbol) */
+ if (*p != 's' /* structs */
+ && *p != 'c' /* class */
+ && *p != 'u') /* union */
+ return 0; /* only handle C++ types */
+ p++;
+
+ /* Get symbol typs name and validate
+ eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */
+ sname = get_substring (&p, ';');
+ if (!sname || strcmp (sname, SYMBOL_NAME(sym)))
+ error ("Internal error: base symbol type name does not match\n");
+
+ /* Find symbol's internal gdb reference using demangled_name.
+ This is the real sym that we want;
+ sym was a temp hack to make debugger happy */
+ ref_sym = lookup_symbol (SYMBOL_NAME(sym), 0, STRUCT_NAMESPACE, 0, 0);
+ type = SYMBOL_TYPE(ref_sym);
+
+
+ /* Now read the baseclasses, if any, read the regular C struct or C++
+ class member fields, attach the fields to the type, read the C++
+ member functions, attach them to the type, and then read any tilde
+ field (baseclass specifier for the class holding the main vtable). */
+
+ if (!read_cfront_baseclasses (&fi, &p, type, objfile)
+ /* g++ does this next, but cfront already did this:
+ || !read_struct_fields (&fi, &p, type, objfile) */
+ || !copy_cfront_struct_fields (&fi, type, objfile)
+ || !read_cfront_member_functions (&fi, &p, type, objfile)
+ || !read_cfront_static_fields (&fi, &p, type, objfile)
+ || !attach_fields_to_type (&fi, type, objfile)
+ || !attach_fn_fields_to_type (&fi, type)
+ /* g++ does this next, but cfront doesn't seem to have this:
+ || !read_tilde_fields (&fi, &p, type, objfile) */
+ )
+ {
+ type = error_type (&p, objfile);
+ }
+
+ do_cleanups (back_to);
+ return 0;
+}
+/* End of code added to support parsing of ARM/Cfront stabs strings */
+
+
+/* This routine fixes up symbol references/aliases to point to the original
+ symbol definition. Returns 0 on failure, non-zero on success. */
+
+static int
+resolve_symbol_reference (objfile, sym, p)
+ struct objfile *objfile;
+ struct symbol *sym;
+ char *p;
+{
+ int refnum;
+ struct symbol *ref_sym=0;
+ struct alias_list *alias;
+
+ /* If this is not a symbol reference return now. */
+ if (*p != '#')
+ return 0;
+
+ /* Use "#<num>" as the name; we'll fix the name later.
+ We stored the original symbol name as "#<id>=<name>"
+ so we can now search for "#<id>" to resolving the reference.
+ We'll fix the names later by removing the "#<id>" or "#<id>=" */
+
+ /*---------------------------------------------------------*/
+ /* Get the reference id number, and
+ advance p past the names so we can parse the rest.
+ eg: id=2 for p : "2=", "2=z:r(0,1)" "2:r(0,1);l(#5,#6),l(#7,#4)" */
+ /*---------------------------------------------------------*/
+
+ /* This gets reference name from string. sym may not have a name. */
+
+ /* Get the reference number associated with the reference id in the
+ gdb stab string. From that reference number, get the main/primary
+ symbol for this alias. */
+ refnum = process_reference (&p);
+ ref_sym = ref_search (refnum);
+ if (!ref_sym)
+ {
+ complain (&lrs_general_complaint, "symbol for reference not found");
+ return 0;
+ }
+
+ /* Parse the stab of the referencing symbol
+ now that we have the referenced symbol.
+ Add it as a new symbol and a link back to the referenced symbol.
+ eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
+
+
+ /* If the stab symbol table and string contain:
+ RSYM 0 5 00000000 868 #15=z:r(0,1)
+ LBRAC 0 0 00000000 899 #5=
+ SLINE 0 16 00000003 923 #6=
+ Then the same symbols can be later referenced by:
+ RSYM 0 5 00000000 927 #15:r(0,1);l(#5,#6)
+ This is used in live range splitting to:
+ 1) specify that a symbol (#15) is actually just a new storage
+ class for a symbol (#15=z) which was previously defined.
+ 2) specify that the beginning and ending ranges for a symbol
+ (#15) are the values of the beginning (#5) and ending (#6)
+ symbols. */
+
+ /* Read number as reference id.
+ eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
+ /* FIXME! Might I want to use SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ in case of "l(0,0)"? */
+
+ /*--------------------------------------------------*/
+ /* Add this symbol to the reference list. */
+ /*--------------------------------------------------*/
+
+ alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack,
+ sizeof (struct alias_list));
+ if (!alias)
+ {
+ complain (&lrs_general_complaint, "Unable to allocate alias list memory");
+ return 0;
+ }
+
+ alias->next = 0;
+ alias->sym = sym;
+
+ if (!SYMBOL_ALIASES (ref_sym))
+ {
+ SYMBOL_ALIASES (ref_sym) = alias;
+ }
+ else
+ {
+ struct alias_list *temp;
+
+ /* Get to the end of the list. */
+ for (temp = SYMBOL_ALIASES (ref_sym);
+ temp->next;
+ temp = temp->next)
+ ;
+ temp->next = alias;
+ }
+
+ /* Want to fix up name so that other functions (eg. valops)
+ will correctly print the name.
+ Don't add_symbol_to_list so that lookup_symbol won't find it.
+ nope... needed for fixups. */
+ SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym);
+
+ /* Done! */
+ return 1;
+}
+
+/* Structure for storing pointers to reference definitions for fast lookup
+ during "process_later". */
+
+struct ref_map
+{
+ char *stabs;
+ CORE_ADDR value;
+ struct symbol *sym;
+};
+
+#define MAX_CHUNK_REFS 100
+#define REF_CHUNK_SIZE (MAX_CHUNK_REFS * sizeof (struct ref_map))
+#define REF_MAP_SIZE(ref_chunk) ((ref_chunk) * REF_CHUNK_SIZE)
+
+static struct ref_map *ref_map;
+
+/* Ptr to free cell in chunk's linked list. */
+static int ref_count = 0;
+
+/* Number of chunks malloced. */
+static int ref_chunk = 0;
+
+/* Create array of pointers mapping refids to symbols and stab strings.
+ Add pointers to reference definition symbols and/or their values as we
+ find them, using their reference numbers as our index.
+ These will be used later when we resolve references. */
+void
+ref_add (refnum, sym, stabs, value)
+ int refnum;
+ struct symbol *sym;
+ char *stabs;
+ CORE_ADDR value;
+{
+ if (ref_count == 0)
+ ref_chunk = 0;
+ if (refnum >= ref_count)
+ ref_count = refnum + 1;
+ if (ref_count > ref_chunk * MAX_CHUNK_REFS)
+ {
+ int new_slots = ref_count - ref_chunk * MAX_CHUNK_REFS;
+ int new_chunks = new_slots / MAX_CHUNK_REFS + 1;
+ ref_map = (struct ref_map *)
+ xrealloc (ref_map, REF_MAP_SIZE (ref_chunk + new_chunks));
+ memset (ref_map + ref_chunk * MAX_CHUNK_REFS, 0, new_chunks * REF_CHUNK_SIZE);
+ ref_chunk += new_chunks;
+ }
+ ref_map[refnum].stabs = stabs;
+ ref_map[refnum].sym = sym;
+ ref_map[refnum].value = value;
+}
+
+/* Return defined sym for the reference REFNUM. */
+struct symbol *
+ref_search (refnum)
+ int refnum;
+{
+ if (refnum < 0 || refnum > ref_count)
+ return 0;
+ return ref_map[refnum].sym;
+}
+
+/* Return value for the reference REFNUM. */
+
+static CORE_ADDR
+ref_search_value (refnum)
+ int refnum;
+{
+ if (refnum < 0 || refnum > ref_count)
+ return 0;
+ return ref_map[refnum].value;
+}
+
+/* Parse a reference id in STRING and return the resulting
+ reference number. Move STRING beyond the reference id. */
+
+static int
+process_reference (string)
+ char **string;
+{
+ char *p;
+ int refnum = 0;
+
+ if (**string != '#')
+ return 0;
+
+ /* Advance beyond the initial '#'. */
+ p = *string + 1;
+
+ /* Read number as reference id. */
+ while (*p && isdigit (*p))
+ {
+ refnum = refnum * 10 + *p - '0';
+ p++;
+ }
+ *string = p;
+ return refnum;
+}
+
+/* If STRING defines a reference, store away a pointer to the reference
+ definition for later use. Return the reference number. */
+
+int
+symbol_reference_defined (string)
+ char **string;
+{
+ char *p = *string;
+ int refnum = 0;
+
+ refnum = process_reference (&p);
+
+ /* Defining symbols end in '=' */
+ if (*p == '=')
+ {
+ /* Symbol is being defined here. */
+ *string = p + 1;
+ return refnum;
+ }
+ else
+ {
+ /* Must be a reference. Either the symbol has already been defined,
+ or this is a forward reference to it. */
+ *string = p;
+ return -1;
+ }
+}
+
/* ARGSUSED */
struct symbol *
define_symbol (valu, string, desc, type, objfile)
@@ -530,7 +1308,7 @@ define_symbol (valu, string, desc, type, objfile)
while (p[1] == ':')
{
p += 2;
- p = strchr(p, ':');
+ p = strchr (p, ':');
}
/* If a nameless stab entry, all we need is the type, not the symbol.
@@ -599,6 +1377,52 @@ define_symbol (valu, string, desc, type, objfile)
goto normal; /* Do *something* with it */
}
}
+ else if (string[0] == '#')
+ {
+ /* Special GNU C extension for referencing symbols. */
+ char *s;
+ int refnum, nlen;
+
+ /* If STRING defines a new reference id, then add it to the
+ reference map. Else it must be referring to a previously
+ defined symbol, so add it to the alias list of the previously
+ defined symbol. */
+ s = string;
+ refnum = symbol_reference_defined (&s);
+ if (refnum >= 0)
+ ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
+ else
+ if (!resolve_symbol_reference (objfile, sym, string))
+ return NULL;
+
+ /* S..P contains the name of the symbol. We need to store
+ the correct name into SYMBOL_NAME. */
+ nlen = p - s;
+ if (refnum >= 0)
+ {
+ if (nlen > 0)
+ {
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile -> symbol_obstack, nlen);
+ strncpy (SYMBOL_NAME (sym), s, nlen);
+ SYMBOL_NAME (sym)[nlen] = '\0';
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ else
+ /* FIXME! Want SYMBOL_NAME (sym) = 0;
+ Get error if leave name 0. So give it something. */
+ {
+ nlen = p - string;
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile -> symbol_obstack, nlen);
+ strncpy (SYMBOL_NAME (sym), string, nlen);
+ SYMBOL_NAME (sym)[nlen] = '\0';
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ }
+ /* Advance STRING beyond the reference id. */
+ string = s;
+ }
else
{
normal:
@@ -779,17 +1603,56 @@ define_symbol (valu, string, desc, type, objfile)
in GDB. E.g. "int" is converted to "function returning int". */
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC)
SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+
+ /* All functions in C++ have prototypes. */
+ if (SYMBOL_LANGUAGE (sym) == language_cplus)
+ TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+
/* fall into process_prototype_types */
process_prototype_types:
- /* Sun acc puts declared types of arguments here. We don't care
- about their actual types (FIXME -- we should remember the whole
- function prototype), but the list may define some new types
- that we have to remember, so we must scan it now. */
- while (*p == ';') {
- p++;
- read_type (&p, objfile);
- }
+ /* Sun acc puts declared types of arguments here. */
+ if (*p == ';')
+ {
+ struct type *ftype = SYMBOL_TYPE (sym);
+ int nsemi = 0;
+ int nparams = 0;
+ char *p1 = p;
+
+ /* Obtain a worst case guess for the number of arguments
+ by counting the semicolons. */
+ while (*p1)
+ {
+ if (*p1++ == ';')
+ nsemi++;
+ }
+
+ /* Allocate parameter information fields and fill them in. */
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nsemi * sizeof (struct field));
+ while (*p++ == ';')
+ {
+ struct type *ptype;
+
+ /* A type number of zero indicates the start of varargs.
+ FIXME: GDB currently ignores vararg functions. */
+ if (p[0] == '0' && p[1] == '\0')
+ break;
+ ptype = read_type (&p, objfile);
+
+ /* The Sun compilers mark integer arguments, which should
+ be promoted to the width of the calling conventions, with
+ a type which references itself. This type is turned into
+ a TYPE_CODE_VOID type by read_type, and we have to turn
+ it back into builtin_type_int here.
+ FIXME: Do we need a new builtin_type_promoted_int_arg ? */
+ if (TYPE_CODE (ptype) == TYPE_CODE_VOID)
+ ptype = builtin_type_int;
+ TYPE_FIELD_TYPE (ftype, nparams++) = ptype;
+ }
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+ }
break;
case 'F':
@@ -806,11 +1669,18 @@ define_symbol (valu, string, desc, type, objfile)
corresponding linker definition to find the value.
These definitions appear at the end of the namelist. */
SYMBOL_TYPE (sym) = read_type (&p, objfile);
- i = hashname (SYMBOL_NAME (sym));
- SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
- global_sym_chain[i] = sym;
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ /* Don't add symbol references to global_sym_chain.
+ Symbol references don't have valid names and wont't match up with
+ minimal symbols when the global_sym_chain is relocated.
+ We'll fixup symbol references when we fixup the defining symbol. */
+ if (SYMBOL_NAME (sym) && SYMBOL_NAME (sym)[0] != '#')
+ {
+ i = hashname (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
+ global_sym_chain[i] = sym;
+ }
add_symbol_to_list (sym, &global_symbols);
break;
@@ -1033,7 +1903,7 @@ define_symbol (valu, string, desc, type, objfile)
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = valu;
#ifdef STATIC_TRANSFORM_NAME
- if (SYMBOL_NAME (sym)[0] == '$')
+ if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
{
struct minimal_symbol *msym;
msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
@@ -1161,7 +2031,7 @@ define_symbol (valu, string, desc, type, objfile)
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = valu;
#ifdef STATIC_TRANSFORM_NAME
- if (SYMBOL_NAME (sym)[0] == '$')
+ if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
{
struct minimal_symbol *msym;
msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
@@ -1215,6 +2085,31 @@ define_symbol (valu, string, desc, type, objfile)
add_symbol_to_list (sym, &local_symbols);
break;
+ /* New code added to support cfront stabs strings.
+ Note: case 'P' already handled above */
+ case 'Z':
+ /* Cfront type continuation coming up!
+ Find the original definition and add to it.
+ We'll have to do this for the typedef too,
+ since we cloned the symbol to define a type in read_type.
+ Stabs info examples:
+ __1C :Ztl
+ foo__1CFv :ZtF (first def foo__1CFv:F(0,3);(0,24))
+ C:ZsC;;__ct__1CFv func1__1CFv func2__1CFv ... ;;;
+ where C is the name of the class.
+ Unfortunately, we can't lookup the original symbol yet 'cuz
+ we haven't finished reading all the symbols.
+ Instead, we save it for processing later */
+ process_later (sym, p, resolve_cfront_continuation);
+ SYMBOL_TYPE (sym) = error_type (&p, objfile); /* FIXME! change later */
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ /* Don't add to list - we'll delete it later when
+ we add the continuation to the real sym */
+ return sym;
+ /* End of new code added to support cfront stabs strings */
+
default:
SYMBOL_TYPE (sym) = error_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_CONST;
@@ -1227,26 +2122,161 @@ define_symbol (valu, string, desc, type, objfile)
/* When passing structures to a function, some systems sometimes pass
the address in a register, not the structure itself. */
- if (REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
- SYMBOL_TYPE (sym))
- && ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
- || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)
- || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING)
- || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET)))
+ if (REG_STRUCT_HAS_ADDR (processing_gcc_compilation, SYMBOL_TYPE (sym))
+ && (SYMBOL_CLASS (sym) == LOC_REGPARM || SYMBOL_CLASS (sym) == LOC_ARG))
{
- /* If REG_STRUCT_HAS_ADDR yields non-zero we have to
- convert LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */
- if (SYMBOL_CLASS (sym) == LOC_REGPARM)
- SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
- /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th and
- subsequent arguments on the sparc, for example). */
- else if (SYMBOL_CLASS (sym) == LOC_ARG)
- SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ struct type *symbol_type = check_typedef (SYMBOL_TYPE (sym));
+
+ if ((TYPE_CODE (symbol_type) == TYPE_CODE_STRUCT)
+ || (TYPE_CODE (symbol_type) == TYPE_CODE_UNION)
+ || (TYPE_CODE (symbol_type) == TYPE_CODE_BITSTRING)
+ || (TYPE_CODE (symbol_type) == TYPE_CODE_SET))
+ {
+ /* If REG_STRUCT_HAS_ADDR yields non-zero we have to convert
+ LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */
+ if (SYMBOL_CLASS (sym) == LOC_REGPARM)
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+ /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th
+ and subsequent arguments on the sparc, for example). */
+ else if (SYMBOL_CLASS (sym) == LOC_ARG)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ }
}
+ /* Is there more to parse? For example LRS/alias information? */
+ while (*p && *p == ';')
+ {
+ p++;
+ if (*p && *p == 'l')
+ {
+ /* GNU extensions for live range splitting may be appended to
+ the end of the stab string. eg. "l(#1,#2);l(#3,#5)" */
+
+ /* Resolve the live range and add it to SYM's live range list. */
+ if (!resolve_live_range (objfile, sym, p))
+ return NULL;
+
+ /* Find end of live range info. */
+ p = strchr (p, ')');
+ if (!*p || *p != ')')
+ {
+ complain (&lrs_general_complaint, "live range format not recognized");
+ return NULL;
+ }
+ p++;
+ }
+ }
return sym;
}
+/* Add the live range found in P to the symbol SYM in objfile OBJFILE. Returns
+ non-zero on success, zero otherwise. */
+
+static int
+resolve_live_range (objfile, sym, p)
+ struct objfile *objfile;
+ struct symbol *sym;
+ char *p;
+{
+ int refnum;
+ CORE_ADDR start, end;
+
+ /* Sanity check the beginning of the stabs string. */
+ if (!*p || *p != 'l')
+ {
+ complain (&lrs_general_complaint, "live range string 1");
+ return 0;
+ }
+ p++;
+
+ if (!*p || *p != '(')
+ {
+ complain (&lrs_general_complaint, "live range string 2");
+ return 0;
+ }
+ p++;
+
+ /* Get starting value of range and advance P past the reference id.
+
+ ?!? In theory, the process_reference should never fail, but we should
+ catch that case just in case the compiler scrogged the stabs. */
+ refnum = process_reference (&p);
+ start = ref_search_value (refnum);
+ if (!start)
+ {
+ complain (&lrs_general_complaint, "Live range symbol not found 1");
+ return 0;
+ }
+
+ if (!*p || *p != ',')
+ {
+ complain (&lrs_general_complaint, "live range string 3");
+ return 0;
+ }
+ p++;
+
+ /* Get ending value of range and advance P past the reference id.
+
+ ?!? In theory, the process_reference should never fail, but we should
+ catch that case just in case the compiler scrogged the stabs. */
+ refnum = process_reference (&p);
+ end = ref_search_value (refnum);
+ if (!end)
+ {
+ complain (&lrs_general_complaint, "Live range symbol not found 2");
+ return 0;
+ }
+
+ if (!*p || *p != ')')
+ {
+ complain (&lrs_general_complaint, "live range string 4");
+ return 0;
+ }
+
+ /* Now that we know the bounds of the range, add it to the
+ symbol. */
+ add_live_range (objfile, sym, start, end);
+
+ return 1;
+}
+
+/* Add a new live range defined by START and END to the symbol SYM
+ in objfile OBJFILE. */
+
+static void
+add_live_range (objfile, sym, start, end)
+ struct objfile *objfile;
+ struct symbol *sym;
+ CORE_ADDR start, end;
+{
+ struct range_list *r, *rs;
+
+ if (start >= end)
+ {
+ complain (&lrs_general_complaint, "end of live range follows start");
+ return;
+ }
+
+ /* Alloc new live range structure. */
+ r = (struct range_list *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct range_list));
+ r->start = start;
+ r->end = end;
+ r->next = 0;
+
+ /* Append this range to the symbol's range list. */
+ if (!SYMBOL_RANGES (sym))
+ SYMBOL_RANGES (sym) = r;
+ else
+ {
+ /* Get the last range for the symbol. */
+ for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next)
+ ;
+ rs->next = r;
+ }
+}
+
/* Skip rest of this symbol and return an error type.
@@ -1319,7 +2349,6 @@ read_type (pp, objfile)
register struct type *type = 0;
struct type *type1;
int typenums[2];
- int xtypenums[2];
char type_descriptor;
/* Size in bits of type if specified by a type attribute, or -1 if
@@ -1346,52 +2375,9 @@ read_type (pp, objfile)
return dbx_alloc_type (typenums, objfile);
/* Type is being defined here. */
- /* Skip the '='. */
- ++(*pp);
-
- while (**pp == '@')
- {
- char *p = *pp + 1;
- /* It might be a type attribute or a member type. */
- if (isdigit (*p) || *p == '(' || *p == '-')
- /* Member type. */
- break;
- else
- {
- /* Type attributes. */
- char *attr = p;
-
- /* Skip to the semicolon. */
- while (*p != ';' && *p != '\0')
- ++p;
- *pp = p;
- if (*p == '\0')
- return error_type (pp, objfile);
- else
- /* Skip the semicolon. */
- ++*pp;
-
- switch (*attr)
- {
- case 's':
- type_size = atoi (attr + 1);
- if (type_size <= 0)
- type_size = -1;
- break;
-
- case 'S':
- is_string = 1;
- break;
-
- default:
- /* Ignore unrecognized type attributes, so future compilers
- can invent new ones. */
- break;
- }
- }
- }
- /* Skip the type descriptor, we get it below with (*pp)[-1]. */
- ++(*pp);
+ /* Skip the '='.
+ Also skip the type descriptor - we get it below with (*pp)[-1]. */
+ (*pp)+=2;
}
else
{
@@ -1401,6 +2387,7 @@ read_type (pp, objfile)
(*pp)++;
}
+ again:
type_descriptor = (*pp)[-1];
switch (type_descriptor)
{
@@ -1442,19 +2429,25 @@ read_type (pp, objfile)
}
}
- q1 = strchr(*pp, '<');
- p = strchr(*pp, ':');
+ q1 = strchr (*pp, '<');
+ p = strchr (*pp, ':');
if (p == NULL)
return error_type (pp, objfile);
- while (q1 && p > q1 && p[1] == ':')
+ if (q1 && p > q1 && p[1] == ':')
{
- q2 = strchr(q1, '>');
- if (!q2 || q2 < p)
- break;
- p += 2;
- p = strchr(p, ':');
- if (p == NULL)
- return error_type (pp, objfile);
+ int nesting_level = 0;
+ for (q2 = q1; *q2; q2++)
+ {
+ if (*q2 == '<')
+ nesting_level++;
+ else if (*q2 == '>')
+ nesting_level--;
+ else if (*q2 == ':' && nesting_level == 0)
+ break;
+ }
+ p = q2;
+ if (*p != ':')
+ return error_type (pp, objfile);
}
to = type_name =
(char *)obstack_alloc (&objfile->type_obstack, p - *pp + 1);
@@ -1519,58 +2512,35 @@ read_type (pp, objfile)
case '8':
case '9':
case '(':
+ (*pp)--;
- {
- char *pp_saved;
-
- (*pp)--;
- pp_saved = *pp;
+ /* We deal with something like t(1,2)=(3,4)=... which
+ the Lucid compiler and recent gcc versions (post 2.7.3) use. */
- /* Peek ahead at the number to detect void. */
- if (read_type_number (pp, xtypenums) != 0)
- return error_type (pp, objfile);
-
- if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
- /* It's being defined as itself. That means it is "void". */
- type = init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
+ /* Allocate and enter the typedef type first.
+ This handles recursive types. */
+ type = dbx_alloc_type (typenums, objfile);
+ TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
+ { struct type *xtype = read_type (pp, objfile);
+ if (type == xtype)
+ {
+ /* It's being defined as itself. That means it is "void". */
+ TYPE_CODE (type) = TYPE_CODE_VOID;
+ TYPE_LENGTH (type) = 1;
+ }
+ else if (type_size >= 0 || is_string)
+ {
+ *type = *xtype;
+ TYPE_NAME (type) = NULL;
+ TYPE_TAG_NAME (type) = NULL;
+ }
else
{
- struct type *xtype;
-
- /* Go back to the number and have read_type get it. This means
- that we can deal with something like t(1,2)=(3,4)=... which
- the Lucid compiler uses. */
- *pp = pp_saved;
- xtype = read_type (pp, objfile);
-
- /* The type is being defined to another type. So we copy the type.
- This loses if we copy a C++ class and so we lose track of how
- the names are mangled (but g++ doesn't output stabs like this
- now anyway). */
-
- type = alloc_type (objfile);
- if (SYMBOL_LINE (current_symbol) == 0)
- {
- *type = *xtype;
- /* The idea behind clearing the names is that the only purpose
- for defining a type to another type is so that the name of
- one can be different. So we probably don't need to worry
- much about the case where the compiler doesn't give a name
- to the new type. */
- TYPE_NAME (type) = NULL;
- TYPE_TAG_NAME (type) = NULL;
- }
- else
- {
- TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
- TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
- TYPE_TARGET_TYPE (type) = xtype;
- }
+ TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
+ TYPE_TARGET_TYPE (type) = xtype;
}
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums) = type;
- break;
}
+ break;
/* In the following types, we must be sure to overwrite any existing
type that the typenums refer to, rather than allocating a new one
@@ -1600,7 +2570,7 @@ read_type (pp, objfile)
++*pp;
while (**pp != ')')
{
- t = read_type(pp, objfile);
+ t = read_type (pp, objfile);
if (**pp == ',') ++*pp;
}
}
@@ -1628,21 +2598,54 @@ read_type (pp, objfile)
/* FIXME! For now, we ignore const and volatile qualifiers. */
break;
-/* FIXME -- we should be doing smash_to_XXX types here. */
- case '@': /* Member (class & variable) type */
- {
- struct type *domain = read_type (pp, objfile);
- struct type *memtype;
+ case '@':
+ if (isdigit (**pp) || **pp == '(' || **pp == '-')
+ { /* Member (class & variable) type */
+ /* FIXME -- we should be doing smash_to_XXX types here. */
- if (**pp != ',')
- /* Invalid member type data format. */
- return error_type (pp, objfile);
- ++*pp;
+ struct type *domain = read_type (pp, objfile);
+ struct type *memtype;
- memtype = read_type (pp, objfile);
- type = dbx_alloc_type (typenums, objfile);
- smash_to_member_type (type, domain, memtype);
- }
+ if (**pp != ',')
+ /* Invalid member type data format. */
+ return error_type (pp, objfile);
+ ++*pp;
+
+ memtype = read_type (pp, objfile);
+ type = dbx_alloc_type (typenums, objfile);
+ smash_to_member_type (type, domain, memtype);
+ }
+ else /* type attribute */
+ {
+ char *attr = *pp;
+ /* Skip to the semicolon. */
+ while (**pp != ';' && **pp != '\0')
+ ++(*pp);
+ if (**pp == '\0')
+ return error_type (pp, objfile);
+ else
+ ++*pp; /* Skip the semicolon. */
+
+ switch (*attr)
+ {
+ case 's':
+ type_size = atoi (attr + 1);
+ if (type_size <= 0)
+ type_size = -1;
+ break;
+
+ case 'S':
+ is_string = 1;
+ break;
+
+ default:
+ /* Ignore unrecognized type attributes, so future compilers
+ can invent new ones. */
+ break;
+ }
+ ++*pp;
+ goto again;
+ }
break;
case '#': /* Method (class & fn) type */
@@ -1889,11 +2892,11 @@ rs6000_builtin_type (typenum)
break;
case 25:
/* Complex type consisting of two IEEE single precision values. */
- rettype = init_type (TYPE_CODE_ERROR, 8, 0, "complex", NULL);
+ rettype = init_type (TYPE_CODE_COMPLEX, 8, 0, "complex", NULL);
break;
case 26:
/* Complex type consisting of two IEEE double precision values. */
- rettype = init_type (TYPE_CODE_ERROR, 16, 0, "double complex", NULL);
+ rettype = init_type (TYPE_CODE_COMPLEX, 16, 0, "double complex", NULL);
break;
case 27:
rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL);
@@ -1928,11 +2931,6 @@ rs6000_builtin_type (typenum)
/* This page contains subroutines of read_type. */
-#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */
-#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */
-#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */
-#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */
-
/* Read member function stabs info for C++ classes. The form of each member
function data is:
@@ -2310,12 +3308,12 @@ read_cpp_abbrev (fip, pp, type, objfile)
{
int nbits;
- fip->list->field.bitpos = read_huge_number (pp, ';', &nbits);
+ FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits);
if (nbits != 0)
return 0;
}
/* This field is unpacked. */
- fip->list->field.bitsize = 0;
+ FIELD_BITSIZE (fip->list->field) = 0;
fip->list->visibility = VISIBILITY_PRIVATE;
}
else
@@ -2353,12 +3351,12 @@ read_one_struct_field (fip, pp, p, type, objfile)
dem_p = strrchr (dem, ':');
if (dem_p != 0 && *(dem_p-1)==':')
dem_p++;
- fip->list->field.name =
- obsavestring (dem_p, strlen(dem_p), &objfile -> type_obstack);
+ FIELD_NAME (fip->list->field) =
+ obsavestring (dem_p, strlen (dem_p), &objfile -> type_obstack);
}
else
{
- fip->list->field.name =
+ FIELD_NAME (fip->list->field) =
obsavestring (*pp, p - *pp, &objfile -> type_obstack);
}
*p = save_p;
@@ -2393,17 +3391,14 @@ read_one_struct_field (fip, pp, p, type, objfile)
fip -> list -> field.bitpos = (long)-2; /* nested type */
p = ++(*pp);
}
- else
+ else ...;
#endif
- {
- /* Static class member. */
- fip -> list -> field.bitpos = (long) -1;
- }
while (*p != ';')
{
p++;
}
- fip -> list -> field.bitsize = (long) savestring (*pp, p - *pp);
+ /* Static class member. */
+ SET_FIELD_PHYSNAME (fip->list->field, savestring (*pp, p - *pp));
*pp = p + 1;
return;
}
@@ -2418,13 +3413,13 @@ read_one_struct_field (fip, pp, p, type, objfile)
{
int nbits;
- fip -> list -> field.bitpos = read_huge_number (pp, ',', &nbits);
+ FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits);
if (nbits != 0)
{
complain (&stabs_general_complaint, "bad structure-type format");
return;
}
- fip -> list -> field.bitsize = read_huge_number (pp, ';', &nbits);
+ FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits);
if (nbits != 0)
{
complain (&stabs_general_complaint, "bad structure-type format");
@@ -2432,7 +3427,8 @@ read_one_struct_field (fip, pp, p, type, objfile)
}
}
- if (fip -> list -> field.bitpos == 0 && fip -> list -> field.bitsize == 0)
+ if (FIELD_BITPOS (fip->list->field) == 0
+ && FIELD_BITSIZE (fip->list->field) == 0)
{
/* This can happen in two cases: (1) at least for gcc 2.4.5 or so,
it is a field which has been optimized out. The correct stab for
@@ -2458,23 +3454,24 @@ read_one_struct_field (fip, pp, p, type, objfile)
Note that forward refs cannot be packed,
and treat enums as if they had the width of ints. */
- if (TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_INT
- && TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_BOOL
- && TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_ENUM)
+ struct type *field_type = check_typedef (FIELD_TYPE (fip->list->field));
+
+ if (TYPE_CODE (field_type) != TYPE_CODE_INT
+ && TYPE_CODE (field_type) != TYPE_CODE_RANGE
+ && TYPE_CODE (field_type) != TYPE_CODE_BOOL
+ && TYPE_CODE (field_type) != TYPE_CODE_ENUM)
{
- fip -> list -> field.bitsize = 0;
+ FIELD_BITSIZE (fip->list->field) = 0;
}
- if ((fip -> list -> field.bitsize
- == TARGET_CHAR_BIT * TYPE_LENGTH (fip -> list -> field.type)
- || (TYPE_CODE (fip -> list -> field.type) == TYPE_CODE_ENUM
- && (fip -> list -> field.bitsize
- == TARGET_INT_BIT)
- )
+ if ((FIELD_BITSIZE (fip->list->field)
+ == TARGET_CHAR_BIT * TYPE_LENGTH (field_type)
+ || (TYPE_CODE (field_type) == TYPE_CODE_ENUM
+ && FIELD_BITSIZE (fip->list->field) == TARGET_INT_BIT )
)
&&
- fip -> list -> field.bitpos % 8 == 0)
+ FIELD_BITPOS (fip->list->field) % 8 == 0)
{
- fip -> list -> field.bitsize = 0;
+ FIELD_BITSIZE (fip->list->field) = 0;
}
}
}
@@ -2648,7 +3645,7 @@ read_baseclasses (fip, pp, type, objfile)
memset (new, 0, sizeof (struct nextfield));
new -> next = fip -> list;
fip -> list = new;
- new -> field.bitsize = 0; /* this should be an unpacked field! */
+ FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */
STABS_CONTINUE (pp, objfile);
switch (**pp)
@@ -2694,7 +3691,7 @@ read_baseclasses (fip, pp, type, objfile)
corresponding to this baseclass. Always zero in the absence of
multiple inheritance. */
- new -> field.bitpos = read_huge_number (pp, ',', &nbits);
+ FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits);
if (nbits != 0)
return 0;
}
@@ -2822,6 +3819,143 @@ attach_fn_fields_to_type (fip, type)
return 1;
}
+/* read cfront class static data.
+ pp points to string starting with the list of static data
+ eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+ ^^^^^^^^
+
+ A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+ ^
+ */
+
+static int
+read_cfront_static_fields (fip, pp, type, objfile)
+ struct field_info *fip;
+ char **pp;
+ struct type *type;
+ struct objfile *objfile;
+{
+ struct nextfield * new;
+ struct type *stype;
+ char * sname;
+ struct symbol * ref_static=0;
+
+ if (**pp==';') /* no static data; return */
+ {
+ ++(*pp);
+ return 1;
+ }
+
+ /* Process each field in the list until we find the terminating ";" */
+
+ /* eg: p = "as__1A ;;;" */
+ STABS_CONTINUE (pp, objfile); /* handle \\ */
+ while (**pp!=';' && (sname = get_substring (pp, ' '), sname))
+ {
+ ref_static = lookup_symbol (sname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name*/
+ if (!ref_static)
+ {
+ static struct complaint msg = {"\
+ Unable to find symbol for static data field %s\n",
+ 0, 0};
+ complain (&msg, sname);
+ continue;
+ }
+ stype = SYMBOL_TYPE(ref_static);
+
+ /* allocate a new fip */
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (free, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new -> next = fip -> list;
+ fip -> list = new;
+
+ /* set visibility */
+ /* FIXME! no way to tell visibility from stabs??? */
+ new -> visibility = VISIBILITY_PUBLIC;
+
+ /* set field info into fip */
+ fip -> list -> field.type = stype;
+
+ /* set bitpos & bitsize */
+ SET_FIELD_PHYSNAME (fip->list->field, savestring (sname, strlen (sname)));
+
+ /* set name field */
+ /* The following is code to work around cfront generated stabs.
+ The stabs contains full mangled name for each field.
+ We try to demangle the name and extract the field name out of it.
+ */
+ if (ARM_DEMANGLING)
+ {
+ char *dem, *dem_p;
+ dem = cplus_demangle (sname, DMGL_ANSI | DMGL_PARAMS);
+ if (dem != NULL)
+ {
+ dem_p = strrchr (dem, ':');
+ if (dem_p != 0 && *(dem_p-1)==':')
+ dem_p++;
+ fip->list->field.name =
+ obsavestring (dem_p, strlen (dem_p), &objfile -> type_obstack);
+ }
+ else
+ {
+ fip->list->field.name =
+ obsavestring (sname, strlen (sname), &objfile -> type_obstack);
+ }
+ } /* end of code for cfront work around */
+ } /* loop again for next static field */
+ return 1;
+}
+
+/* Copy structure fields to fip so attach_fields_to_type will work.
+ type has already been created with the initial instance data fields.
+ Now we want to be able to add the other members to the class,
+ so we want to add them back to the fip and reattach them again
+ once we have collected all the class members. */
+
+static int
+copy_cfront_struct_fields (fip, type, objfile)
+ struct field_info *fip;
+ struct type *type;
+ struct objfile *objfile;
+{
+ int nfields = TYPE_NFIELDS(type);
+ int i;
+ struct nextfield * new;
+
+ /* Copy the fields into the list of fips and reset the types
+ to remove the old fields */
+
+ for (i=0; i<nfields; i++)
+ {
+ /* allocate a new fip */
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (free, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new -> next = fip -> list;
+ fip -> list = new;
+
+ /* copy field info into fip */
+ new -> field = TYPE_FIELD (type, i);
+ /* set visibility */
+ if (TYPE_FIELD_PROTECTED (type, i))
+ new -> visibility = VISIBILITY_PROTECTED;
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ new -> visibility = VISIBILITY_PRIVATE;
+ else
+ new -> visibility = VISIBILITY_PUBLIC;
+ }
+ /* Now delete the fields from the type since we will be
+ allocing new space once we get the rest of the fields
+ in attach_fields_to_type.
+ The pointer TYPE_FIELDS(type) is left dangling but should
+ be freed later by objstack_free */
+ TYPE_FIELDS (type)=0;
+ TYPE_NFIELDS (type) = 0;
+
+ return 1;
+}
+
/* Create the vector of fields, and record how big it is.
We need this info to record proper virtual function table information
for this class's virtual functions. */
@@ -3156,7 +4290,6 @@ read_enum_type (pp, type, objfile)
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
- TYPE_FIELD_VALUE (type, n) = 0;
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
TYPE_FIELD_BITSIZE (type, n) = 0;
}
@@ -3170,8 +4303,9 @@ read_enum_type (pp, type, objfile)
/* Sun's ACC uses a somewhat saner method for specifying the builtin
typedefs in every file (for int, long, etc):
- type = b <signed> <width>; <offset>; <nbits>
- signed = u or s. Possible c in addition to u or s (for char?).
+ type = b <signed> <width> <format type>; <offset>; <nbits>
+ signed = u or s.
+ optional format type = c or b for char or boolean.
offset = offset from high order bit to start bit of type.
width is # bytes in object of this type, nbits is # bits in type.
@@ -3188,6 +4322,7 @@ read_sun_builtin_type (pp, typenums, objfile)
int type_bits;
int nbits;
int signed_type;
+ enum type_code code = TYPE_CODE_INT;
switch (**pp)
{
@@ -3205,10 +4340,16 @@ read_sun_builtin_type (pp, typenums, objfile)
/* For some odd reason, all forms of char put a c here. This is strange
because no other type has this honor. We can safely ignore this because
we actually determine 'char'acterness by the number of bits specified in
- the descriptor. */
+ the descriptor.
+ Boolean forms, e.g Fortran logical*X, put a b here. */
if (**pp == 'c')
(*pp)++;
+ else if (**pp == 'b')
+ {
+ code = TYPE_CODE_BOOL;
+ (*pp)++;
+ }
/* The first number appears to be the number of bytes occupied
by this type, except that unsigned short is 4 instead of 2.
@@ -3241,7 +4382,7 @@ read_sun_builtin_type (pp, typenums, objfile)
signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
objfile);
else
- return init_type (TYPE_CODE_INT,
+ return init_type (code,
type_bits / TARGET_CHAR_BIT,
signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
objfile);
@@ -3272,7 +4413,7 @@ read_sun_floating_type (pp, typenums, objfile)
|| details == NF_COMPLEX32)
/* This is a type we can't handle, but we do know the size.
We also will be able to give it a name. */
- return init_type (TYPE_CODE_ERROR, nbytes, 0, NULL, objfile);
+ return init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile);
return init_type (TYPE_CODE_FLT, nbytes, 0, NULL, objfile);
}
@@ -3476,20 +4617,28 @@ read_range_type (pp, typenums, objfile)
if (self_subrange && n2 == 0 && n3 == 0)
return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
- /* If n3 is zero and n2 is positive, we want a floating type,
- and n2 is the width in bytes.
-
- Fortran programs appear to use this for complex types also,
- and they give no way to distinguish between double and single-complex!
+ /* If n3 is zero and n2 is positive, we want a floating type, and n2
+ is the width in bytes.
- GDB does not have complex types.
+ Fortran programs appear to use this for complex types also. To
+ distinguish between floats and complex, g77 (and others?) seem
+ to use self-subranges for the complexes, and subranges of int for
+ the floats.
- Just return the complex as a float of that size. It won't work right
- for the complex values, but at least it makes the file loadable. */
+ Also note that for complexes, g77 sets n2 to the size of one of
+ the member floats, not the whole complex beast. My guess is that
+ this was to work well with pre-COMPLEX versions of gdb. */
if (n3 == 0 && n2 > 0)
{
- return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+ if (self_subrange)
+ {
+ return init_type (TYPE_CODE_COMPLEX, 2 * n2, 0, NULL, objfile);
+ }
+ else
+ {
+ return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+ }
}
/* If the upper bound is -1, it must really be an unsigned int. */
@@ -3678,6 +4827,7 @@ common_block_end (objfile)
sym = (struct symbol *)
obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
+ /* Note: common_block_name already saved on symbol_obstack */
SYMBOL_NAME (sym) = common_block_name;
SYMBOL_CLASS (sym) = LOC_BLOCK;
@@ -3834,88 +4984,128 @@ scan_file_globals (objfile)
{
int hash;
struct minimal_symbol *msymbol;
- struct symbol *sym, *prev;
+ struct symbol *sym, *prev, *rsym;
+ struct objfile *resolve_objfile;
- /* Avoid expensive loop through all minimal symbols if there are
- no unresolved symbols. */
- for (hash = 0; hash < HASHSIZE; hash++)
- {
- if (global_sym_chain[hash])
- break;
- }
- if (hash >= HASHSIZE)
- return;
+ /* SVR4 based linkers copy referenced global symbols from shared
+ libraries to the main executable.
+ If we are scanning the symbols for a shared library, try to resolve
+ them from the minimal symbols of the main executable first. */
- for (msymbol = objfile -> msymbols;
- msymbol && SYMBOL_NAME (msymbol) != NULL;
- msymbol++)
- {
- QUIT;
+ if (symfile_objfile && objfile != symfile_objfile)
+ resolve_objfile = symfile_objfile;
+ else
+ resolve_objfile = objfile;
- /* Skip static symbols. */
- switch (MSYMBOL_TYPE (msymbol))
+ while (1)
+ {
+ /* Avoid expensive loop through all minimal symbols if there are
+ no unresolved symbols. */
+ for (hash = 0; hash < HASHSIZE; hash++)
{
- case mst_file_text:
- case mst_file_data:
- case mst_file_bss:
- continue;
- default:
- break;
+ if (global_sym_chain[hash])
+ break;
}
+ if (hash >= HASHSIZE)
+ return;
- prev = NULL;
+ for (msymbol = resolve_objfile -> msymbols;
+ msymbol && SYMBOL_NAME (msymbol) != NULL;
+ msymbol++)
+ {
+ QUIT;
- /* Get the hash index and check all the symbols
- under that hash index. */
+ /* Skip static symbols. */
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_file_text:
+ case mst_file_data:
+ case mst_file_bss:
+ continue;
+ default:
+ break;
+ }
- hash = hashname (SYMBOL_NAME (msymbol));
+ prev = NULL;
- for (sym = global_sym_chain[hash]; sym;)
- {
- if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
- STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
+ /* Get the hash index and check all the symbols
+ under that hash index. */
+
+ hash = hashname (SYMBOL_NAME (msymbol));
+
+ for (sym = global_sym_chain[hash]; sym;)
{
- /* Splice this symbol out of the hash chain and
- assign the value we have to it. */
- if (prev)
+ if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
+ STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
{
- SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
- }
- else
- {
- global_sym_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
- }
-
- /* Check to see whether we need to fix up a common block. */
- /* Note: this code might be executed several times for
- the same symbol if there are multiple references. */
- if (SYMBOL_CLASS (sym) == LOC_BLOCK)
- {
- fix_common_block (sym, SYMBOL_VALUE_ADDRESS (msymbol));
- }
- else
- {
- SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol);
- }
+ struct alias_list *aliases;
- SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol);
-
- if (prev)
- {
- sym = SYMBOL_VALUE_CHAIN (prev);
+ /* Splice this symbol out of the hash chain and
+ assign the value we have to it. */
+ if (prev)
+ {
+ SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
+ }
+ else
+ {
+ global_sym_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
+ }
+
+ /* Check to see whether we need to fix up a common block. */
+ /* Note: this code might be executed several times for
+ the same symbol if there are multiple references. */
+
+ /* If symbol has aliases, do minimal symbol fixups for each.
+ These live aliases/references weren't added to
+ global_sym_chain hash but may also need to be fixed up. */
+ /* FIXME: Maybe should have added aliases to the global chain, resolved symbol name, then treated aliases as normal
+ symbols? Still, we wouldn't want to add_to_list. */
+ /* Now do the same for each alias of this symbol */
+ rsym = sym;
+ aliases = SYMBOL_ALIASES (sym);
+ while (rsym)
+ {
+ if (SYMBOL_CLASS (rsym) == LOC_BLOCK)
+ {
+ fix_common_block (rsym,
+ SYMBOL_VALUE_ADDRESS (msymbol));
+ }
+ else
+ {
+ SYMBOL_VALUE_ADDRESS (rsym)
+ = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ SYMBOL_SECTION (rsym) = SYMBOL_SECTION (msymbol);
+ if (aliases)
+ {
+ rsym = aliases->sym;
+ aliases = aliases->next;
+ }
+ else
+ rsym = NULL;
+ }
+
+
+ if (prev)
+ {
+ sym = SYMBOL_VALUE_CHAIN (prev);
+ }
+ else
+ {
+ sym = global_sym_chain[hash];
+ }
}
else
{
- sym = global_sym_chain[hash];
+ prev = sym;
+ sym = SYMBOL_VALUE_CHAIN (sym);
}
}
- else
- {
- prev = sym;
- sym = SYMBOL_VALUE_CHAIN (sym);
- }
}
+ if (resolve_objfile == objfile)
+ break;
+ resolve_objfile = objfile;
}
/* Change the storage class of any remaining unresolved globals to
@@ -3937,7 +5127,7 @@ scan_file_globals (objfile)
SYMBOL_CLASS (prev) = LOC_UNRESOLVED;
else
complain (&unresolved_sym_chain_complaint,
- objfile->name, SYMBOL_NAME (prev));
+ objfile -> name, SYMBOL_NAME (prev));
}
}
memset (global_sym_chain, 0, sizeof (global_sym_chain));
diff --git a/contrib/gdb/gdb/stabsread.h b/contrib/gdb/gdb/stabsread.h
index b348738..77ea291 100644
--- a/contrib/gdb/gdb/stabsread.h
+++ b/contrib/gdb/gdb/stabsread.h
@@ -106,11 +106,15 @@ struct header_file
};
-EXTERN struct header_file *header_files;
+/* The table of header_files of this OBJFILE. */
+#define HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->header_files)
-EXTERN int n_header_files;
+/* The actual length of HEADER_FILES. */
+#define N_HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->n_header_files)
-EXTERN int n_allocated_header_files;
+/* The allocated lengh of HEADER_FILES. */
+#define N_ALLOCATED_HEADER_FILES(OBJFILE) \
+ (DBX_SYMFILE_INFO (OBJFILE)->n_allocated_header_files)
/* Within each object file, various header files are assigned numbers.
A type is defined or referred to with a pair of numbers
@@ -118,7 +122,7 @@ EXTERN int n_allocated_header_files;
and TYPENUM is the number within that header file.
TYPENUM is the index within the vector of types for that header file.
- FILENUM == 1 is special; it refers to the main source of the object file,
+ FILENUM == 0 is special; it refers to the main source of the object file,
and not to any header file. FILENUM != 1 is interpreted by looking it up
in the following table, which contains indices in header_files. */
@@ -163,6 +167,7 @@ end_stabs PARAMS ((void));
extern void
finish_global_stabs PARAMS ((struct objfile *objfile));
+
EXTERN int os9k_stabs;
@@ -187,8 +192,14 @@ start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *,
struct partial_symbol **));
extern struct partial_symtab *
-end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
- struct partial_symtab **, int));
+end_psymtab PARAMS ((struct partial_symtab *pst,
+ char **include_list,
+ int num_includes,
+ int capping_symbol_offset,
+ CORE_ADDR capping_text,
+ struct partial_symtab **dependency_list,
+ int number_dependencies,
+ int textlow_not_set));
extern void
process_one_symbol PARAMS ((int, int, CORE_ADDR, char *,
@@ -222,4 +233,17 @@ extern void stabsect_build_psymtabs
extern void elfstab_offset_sections PARAMS ((struct objfile *,
struct partial_symtab *));
+extern void process_later
+ PARAMS ((struct symbol *, char *,
+ int (*f) PARAMS ((struct objfile *, struct symbol *, char *))));
+
+extern int symbol_reference_defined PARAMS ((char **));
+
+extern void ref_add PARAMS ((int, struct symbol *, char *, CORE_ADDR));
+
+extern struct symbol * ref_search PARAMS ((int));
+
+extern int resolve_cfront_continuation
+ PARAMS ((struct objfile * objfile, struct symbol * sym, char * p));
+
#undef EXTERN
diff --git a/contrib/gdb/gdb/stack.c b/contrib/gdb/gdb/stack.c
index be52e98..e36316e 100644
--- a/contrib/gdb/gdb/stack.c
+++ b/contrib/gdb/gdb/stack.c
@@ -1,5 +1,5 @@
/* Print and select stack frames for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,7 +18,7 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
+#include <ctype.h>
#include "defs.h"
#include "gdb_string.h"
#include "value.h"
@@ -37,43 +37,65 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "symfile.h"
#include "objfiles.h"
+/* Prototypes for exported functions. */
+
+void args_info PARAMS ((char *, int));
+
+void locals_info PARAMS ((char *, int));
+
+void (*selected_frame_level_changed_hook) PARAMS ((int));
+
+void _initialize_stack PARAMS ((void));
+
+/* Prototypes for local functions. */
+
static void return_command PARAMS ((char *, int));
static void down_command PARAMS ((char *, int));
+static void down_silently_base PARAMS ((char *));
+
static void down_silently_command PARAMS ((char *, int));
static void up_command PARAMS ((char *, int));
+static void up_silently_base PARAMS ((char *));
+
static void up_silently_command PARAMS ((char *, int));
-static void frame_command PARAMS ((char *, int));
+void frame_command PARAMS ((char *, int));
static void select_frame_command PARAMS ((char *, int));
-static void args_info PARAMS ((char *, int));
-
static void print_frame_arg_vars PARAMS ((struct frame_info *, GDB_FILE *));
static void catch_info PARAMS ((char *, int));
-static void locals_info PARAMS ((char *, int));
+static void args_plus_locals_info PARAMS ((char *, int));
-static void print_frame_label_vars PARAMS ((struct frame_info *, int,
+static void print_frame_label_vars PARAMS ((struct frame_info *,
+ int,
GDB_FILE *));
-static void print_frame_local_vars PARAMS ((struct frame_info *, GDB_FILE *));
+static void print_frame_local_vars PARAMS ((struct frame_info *,
+ int,
+ GDB_FILE *));
static int print_block_frame_labels PARAMS ((struct block *, int *,
GDB_FILE *));
static int print_block_frame_locals PARAMS ((struct block *,
struct frame_info *,
+ int,
GDB_FILE *));
+static void print_frame_info_base PARAMS ((struct frame_info *, int, int, int));
+
+static void print_stack_frame_base PARAMS ((struct frame_info *, int, int));
+
static void backtrace_command PARAMS ((char *, int));
-static struct frame_info *parse_frame_specification PARAMS ((char *));
+struct frame_info *parse_frame_specification PARAMS ((char *));
static void frame_info PARAMS ((char *, int));
@@ -108,16 +130,65 @@ struct print_stack_frame_args {
int args;
};
-static int print_stack_frame_stub PARAMS ((char *));
+static int print_stack_frame_base_stub PARAMS ((char *));
-/* Pass the args the way catch_errors wants them. */
+/* Show and print the frame arguments.
+ Pass the args the way catch_errors wants them. */
static int
-print_stack_frame_stub (args)
+show_and_print_stack_frame_stub (args)
char *args;
{
struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
+ /* Reversed order of these so tuiDo() doesn't occur
+ * in the middle of "Breakpoint 1 ... [location]" printing = RT
+ */
+ if (tui_version)
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
print_frame_info (p->fi, p->level, p->source, p->args);
+
+ return 0;
+}
+
+/* Show or print the frame arguments.
+ Pass the args the way catch_errors wants them. */
+static int
+print_stack_frame_stub (args)
+ char *args;
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
+
+ if (tui_version)
+ print_frame_info (p->fi, p->level, p->source, p->args);
+ else
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
+ return 0;
+}
+
+/* Print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not
+ defined). */
+
+/* Pass the args the way catch_errors wants them. */
+static int
+print_stack_frame_base_stub (args)
+ char *args;
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
+
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
+ return 0;
+}
+
+/* print the frame arguments to the terminal.
+ Pass the args the way catch_errors wants them. */
+static int
+print_only_stack_frame_stub (args)
+ char *args;
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *)args;
+
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
return 0;
}
@@ -131,6 +202,59 @@ print_stack_frame_stub (args)
If SOURCE is 1, print the source line as well.
If SOURCE is -1, print ONLY the source line. */
+static void
+print_stack_frame_base (fi, level, source)
+ struct frame_info *fi;
+ int level;
+ int source;
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ALL);
+}
+
+/* Show and print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
+void
+show_and_print_stack_frame (fi, level, source)
+ struct frame_info *fi;
+ int level;
+ int source;
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (show_and_print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ALL);
+}
+
+
+/* Show or print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
void
print_stack_frame (fi, level, source)
struct frame_info *fi;
@@ -147,18 +271,45 @@ print_stack_frame (fi, level, source)
catch_errors (print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ALL);
}
+/* Print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
+void
+print_only_stack_frame (fi, level, source)
+ struct frame_info *fi;
+ int level;
+ int source;
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (print_only_stack_frame_stub,
+ (char *)&args, "", RETURN_MASK_ALL);
+}
+
struct print_args_args {
struct symbol *func;
struct frame_info *fi;
};
-static int print_args_stub PARAMS ((char *));
+static int print_args_stub PARAMS ((PTR));
/* Pass the args the way catch_errors wants them. */
static int
print_args_stub (args)
- char *args;
+ PTR args;
{
int numargs;
struct print_args_args *p = (struct print_args_args *)args;
@@ -168,13 +319,20 @@ print_args_stub (args)
return 0;
}
-/* LEVEL is the level of the frame, or -1 if it is the innermost frame
- but we don't want to print the level. */
+/* Print information about a frame for frame "fi" at level "level".
+ * Used in "where" output, also used to emit breakpoint or step messages.
+ * LEVEL is the level of the frame, or -1 if it is the innermost frame
+ * but we don't want to print the level.
+ * The meaning of the SOURCE argument is:
+ * -1: Print only source line
+ * 0: Print only location
+ * 1: Print location and source line
+ */
-void
-print_frame_info (fi, level, source, args)
+static void
+print_frame_info_base (fi, level, source, args)
struct frame_info *fi;
- register int level;
+ int level;
int source;
int args;
{
@@ -280,20 +438,40 @@ print_frame_info (fi, level, source, args)
}
else
{
+ /* I'd like to use SYMBOL_SOURCE_NAME() here, to display
+ * the demangled name that we already have stored in
+ * the symbol table, but we stored a version with
+ * DMGL_PARAMS turned on, and here we don't want
+ * to display parameters. So call the demangler again,
+ * with DMGL_ANSI only. RT
+ * (Yes, I know that printf_symbol_filtered() will
+ * again try to demangle the name on the fly, but
+ * the issue is that if cplus_demangle() fails here,
+ * it'll fail there too. So we want to catch the failure
+ * ("demangled==NULL" case below) here, while we still
+ * have our hands on the function symbol.)
+ */
+ char * demangled;
funname = SYMBOL_NAME (func);
funlang = SYMBOL_LANGUAGE (func);
+ if (funlang == language_cplus) {
+ demangled = cplus_demangle (funname, DMGL_ANSI);
+ if (demangled == NULL)
+ /* If the demangler fails, try the demangled name
+ * from the symbol table. This'll have parameters,
+ * but that's preferable to diplaying a mangled name.
+ */
+ funname = SYMBOL_SOURCE_NAME (func);
+ }
}
}
else
{
- if (find_pc_section (fi->pc))
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+ if (msymbol != NULL)
{
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
- if (msymbol != NULL)
- {
- funname = SYMBOL_NAME (msymbol);
- funlang = SYMBOL_LANGUAGE (msymbol);
- }
+ funname = SYMBOL_NAME (msymbol);
+ funlang = SYMBOL_LANGUAGE (msymbol);
}
}
@@ -322,7 +500,7 @@ print_frame_info (fi, level, source, args)
struct print_args_args args;
args.fi = fi;
args.func = func;
- catch_errors (print_args_stub, (char *)&args, "", RETURN_MASK_ALL);
+ catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
QUIT;
}
printf_filtered (")");
@@ -352,7 +530,7 @@ print_frame_info (fi, level, source, args)
}
#endif
#ifdef PC_SOLIB
- if (!funname)
+ if (!funname || (!sal.symtab || !sal.symtab->filename))
{
char *lib = PC_SOLIB (fi->pc);
if (lib)
@@ -375,14 +553,14 @@ print_frame_info (fi, level, source, args)
fi->pc);
if (!done)
{
- if (addressprint && mid_statement)
+ if (addressprint && mid_statement && !tui_version)
{
print_address_numeric (fi->pc, 1, gdb_stdout);
printf_filtered ("\t");
}
if (print_frame_info_listing_hook)
print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
- else
+ else if (!tui_version)
print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
}
current_source_line = max (sal.line - lines_to_list/2, 1);
@@ -394,12 +572,53 @@ print_frame_info (fi, level, source, args)
gdb_flush (gdb_stdout);
}
+
+
+void
+stack_publish_stopped_with_no_frame()
+{
+ TUIDO(((TuiOpaqueFuncPtr)tuiUpdateOnEnd));
+
+ return;
+}
+
+/* Show or print the frame info. If this is the tui, it will be shown in
+ the source display */
+void
+print_frame_info(fi, level, source, args)
+ struct frame_info *fi;
+ register int level;
+ int source;
+ int args;
+{
+ if (!tui_version)
+ print_frame_info_base(fi, level, source, args);
+ else
+ {
+ if (fi && (frame_in_dummy(fi) || fi->signal_handler_caller))
+ print_frame_info_base(fi, level, source, args);
+ else
+ {
+ TUIDO(((TuiOpaqueFuncPtr)tui_vShowFrameInfo, fi));
+ }
+ }
+}
+
+/* Show the frame info. If this is the tui, it will be shown in
+ the source display otherwise, nothing is done */
+void
+show_stack_frame(fi)
+ struct frame_info *fi;
+{
+ TUIDO(((TuiOpaqueFuncPtr)tui_vShowFrameInfo, fi));
+}
+
/* Read a frame specification in whatever the appropriate format is.
Call error() if the specification is in any way invalid (i.e.
this function never returns NULL). */
-static struct frame_info *
+struct frame_info *
parse_frame_specification (frame_exp)
char *frame_exp;
{
@@ -520,7 +739,6 @@ frame_info (addr_exp, from_tty)
int from_tty;
{
struct frame_info *fi;
- struct frame_saved_regs fsr;
struct symtab_and_line sal;
struct symbol *func;
struct symtab *s;
@@ -544,8 +762,32 @@ frame_info (addr_exp, from_tty)
s = find_pc_symtab(fi->pc);
if (func)
{
- funname = SYMBOL_NAME (func);
- funlang = SYMBOL_LANGUAGE (func);
+ /* I'd like to use SYMBOL_SOURCE_NAME() here, to display
+ * the demangled name that we already have stored in
+ * the symbol table, but we stored a version with
+ * DMGL_PARAMS turned on, and here we don't want
+ * to display parameters. So call the demangler again,
+ * with DMGL_ANSI only. RT
+ * (Yes, I know that printf_symbol_filtered() will
+ * again try to demangle the name on the fly, but
+ * the issue is that if cplus_demangle() fails here,
+ * it'll fail there too. So we want to catch the failure
+ * ("demangled==NULL" case below) here, while we still
+ * have our hands on the function symbol.)
+ */
+ char * demangled;
+ funname = SYMBOL_NAME (func);
+ funlang = SYMBOL_LANGUAGE (func);
+ if (funlang == language_cplus)
+ {
+ demangled = cplus_demangle (funname, DMGL_ANSI);
+ /* If the demangler fails, try the demangled name
+ * from the symbol table. This'll have parameters,
+ * but that's preferable to diplaying a mangled name.
+ */
+ if (demangled == NULL)
+ funname = SYMBOL_SOURCE_NAME (func);
+ }
}
else
{
@@ -570,7 +812,7 @@ frame_info (addr_exp, from_tty)
print_address_numeric (fi->frame, 1, gdb_stdout);
printf_filtered (":\n");
}
- printf_filtered (" %s = ", reg_names[PC_REGNUM]);
+ printf_filtered (" %s = ", REGISTER_NAME (PC_REGNUM));
print_address_numeric (fi->pc, 1, gdb_stdout);
wrap_here (" ");
@@ -585,7 +827,7 @@ frame_info (addr_exp, from_tty)
printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line);
puts_filtered ("; ");
wrap_here (" ");
- printf_filtered ("saved %s ", reg_names[PC_REGNUM]);
+ printf_filtered ("saved %s ", REGISTER_NAME (PC_REGNUM));
print_address_numeric (FRAME_SAVED_PC (fi), 1, gdb_stdout);
printf_filtered ("\n");
@@ -661,36 +903,39 @@ frame_info (addr_exp, from_tty)
}
}
-#if defined (FRAME_FIND_SAVED_REGS)
- get_frame_saved_regs (fi, &fsr);
- /* The sp is special; what's returned isn't the save address, but
- actually the value of the previous frame's sp. */
- printf_filtered (" Previous frame's sp is ");
- print_address_numeric (fsr.regs[SP_REGNUM], 1, gdb_stdout);
- printf_filtered ("\n");
- count = 0;
- numregs = ARCH_NUM_REGS;
- for (i = 0; i < numregs; i++)
- if (fsr.regs[i] && i != SP_REGNUM)
- {
- if (count == 0)
- puts_filtered (" Saved registers:\n ");
- else
- puts_filtered (",");
- wrap_here (" ");
- printf_filtered (" %s at ", reg_names[i]);
- print_address_numeric (fsr.regs[i], 1, gdb_stdout);
- count++;
- }
- if (count)
- puts_filtered ("\n");
-#else /* Have FRAME_FIND_SAVED_REGS. */
- /* We could get some information about saved registers by calling
- get_saved_register on each register. Which info goes with which frame
- is necessarily lost, however, and I suspect that the users don't care
- whether they get the info. */
- puts_filtered ("\n");
-#endif /* Have FRAME_FIND_SAVED_REGS. */
+ FRAME_INIT_SAVED_REGS (fi);
+ if (fi->saved_regs != NULL)
+ {
+ /* The sp is special; what's returned isn't the save address, but
+ actually the value of the previous frame's sp. */
+ printf_filtered (" Previous frame's sp is ");
+ print_address_numeric (fi->saved_regs[SP_REGNUM], 1, gdb_stdout);
+ printf_filtered ("\n");
+ count = 0;
+ numregs = ARCH_NUM_REGS;
+ for (i = 0; i < numregs; i++)
+ if (fi->saved_regs[i] && i != SP_REGNUM)
+ {
+ if (count == 0)
+ puts_filtered (" Saved registers:\n ");
+ else
+ puts_filtered (",");
+ wrap_here (" ");
+ printf_filtered (" %s at ", REGISTER_NAME (i));
+ print_address_numeric (fi->saved_regs[i], 1, gdb_stdout);
+ count++;
+ }
+ if (count)
+ puts_filtered ("\n");
+ }
+ else
+ {
+ /* We could get some information about saved registers by
+ calling get_saved_register on each register. Which info goes
+ with which frame is necessarily lost, however, and I suspect
+ that the users don't care whether they get the info. */
+ puts_filtered ("\n");
+ }
}
#if 0
@@ -727,8 +972,9 @@ backtrace_limit_info (arg, from_tty)
/* Print briefly all stack frames or just the innermost COUNT frames. */
static void
-backtrace_command (count_exp, from_tty)
+backtrace_command_1 (count_exp, show_locals, from_tty)
char *count_exp;
+ int show_locals;
int from_tty;
{
struct frame_info *fi;
@@ -809,25 +1055,104 @@ backtrace_command (count_exp, from_tty)
means further attempts to backtrace would fail (on the other
hand, perhaps the code does or could be fixed to make sure
the frame->prev field gets set to NULL in that case). */
- print_frame_info (fi, trailing_level + i, 0, 1);
+ print_frame_info_base (fi, trailing_level + i, 0, 1);
+ if (show_locals)
+ print_frame_local_vars(fi, 1, gdb_stdout);
}
/* If we've stopped before the end, mention that. */
if (fi && from_tty)
printf_filtered ("(More stack frames follow...)\n");
}
+
+static void
+backtrace_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ struct cleanup *old_chain = (struct cleanup *)NULL;
+ char **argv = (char **)NULL;
+ int argIndicatingFullTrace = (-1), totArgLen = 0, argc = 0;
+ char *argPtr = arg;
+
+ if (arg != (char *)NULL)
+ {
+ int i;
+
+ argv = buildargv(arg);
+ old_chain = make_cleanup ((make_cleanup_func) freeargv, (char *)argv);
+ argc = 0;
+ for (i = 0; (argv[i] != (char *)NULL); i++)
+ {
+ int j;
+
+ for (j = 0; (j < strlen(argv[i])); j++)
+ argv[i][j] = tolower(argv[i][j]);
+
+ if (argIndicatingFullTrace < 0 && subsetCompare(argv[i], "full"))
+ argIndicatingFullTrace = argc;
+ else
+ {
+ argc++;
+ totArgLen += strlen(argv[i]);
+ }
+ }
+ totArgLen += argc;
+ if (argIndicatingFullTrace >= 0)
+ {
+ if (totArgLen > 0)
+ {
+ argPtr = (char *)xmalloc(totArgLen + 1);
+ if (!argPtr)
+ nomem(0);
+ else
+ {
+ memset(argPtr, 0, totArgLen + 1);
+ for (i = 0; (i < (argc + 1)); i++)
+ {
+ if (i != argIndicatingFullTrace)
+ {
+ strcat(argPtr, argv[i]);
+ strcat(argPtr, " ");
+ }
+ }
+ }
+ }
+ else
+ argPtr = (char *)NULL;
+ }
+ }
+
+ backtrace_command_1 (argPtr, (argIndicatingFullTrace >= 0), from_tty);
+
+ if (argIndicatingFullTrace >= 0 && totArgLen > 0)
+ free(argPtr);
+
+ if (old_chain)
+ do_cleanups(old_chain);
+}
+
+static void
+backtrace_full_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ backtrace_command_1 (arg, 1, from_tty);
+}
+
/* Print the local variables of a block B active in FRAME.
Return 1 if any variables were printed; 0 otherwise. */
static int
-print_block_frame_locals (b, fi, stream)
+print_block_frame_locals (b, fi, num_tabs, stream)
struct block *b;
register struct frame_info *fi;
+ int num_tabs;
register GDB_FILE *stream;
{
int nsyms;
- register int i;
+ register int i, j;
register struct symbol *sym;
register int values_printed = 0;
@@ -843,6 +1168,8 @@ print_block_frame_locals (b, fi, stream)
case LOC_STATIC:
case LOC_BASEREG:
values_printed = 1;
+ for (j = 0; j < num_tabs; j++)
+ fputs_filtered("\t", stream);
fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
fputs_filtered (" = ", stream);
print_variable_value (sym, fi, stream);
@@ -908,8 +1235,9 @@ print_block_frame_labels (b, have_default, stream)
on the function running in FRAME. */
static void
-print_frame_local_vars (fi, stream)
+print_frame_local_vars (fi, num_tabs, stream)
register struct frame_info *fi;
+ register int num_tabs;
register GDB_FILE *stream;
{
register struct block *block = get_frame_block (fi);
@@ -923,7 +1251,7 @@ print_frame_local_vars (fi, stream)
while (block != 0)
{
- if (print_block_frame_locals (block, fi, stream))
+ if (print_block_frame_locals (block, fi, num_tabs, stream))
values_printed = 1;
/* After handling the function's top-level block, stop.
Don't continue to its superblock, the block of
@@ -1012,14 +1340,14 @@ print_frame_label_vars (fi, this_level_only, stream)
}
/* ARGSUSED */
-static void
+void
locals_info (args, from_tty)
char *args;
int from_tty;
{
if (!selected_frame)
error ("No frame selected.");
- print_frame_local_vars (selected_frame, gdb_stdout);
+ print_frame_local_vars (selected_frame, 0, gdb_stdout);
}
static void
@@ -1027,9 +1355,29 @@ catch_info (ignore, from_tty)
char *ignore;
int from_tty;
{
+ struct symtab_and_line * sal;
+
+ /* Check for target support for exception handling */
+ sal = target_enable_exception_callback (EX_EVENT_CATCH, 1);
+ if (sal)
+ {
+ /* Currently not handling this */
+ /* Ideally, here we should interact with the C++ runtime
+ system to find the list of active handlers, etc. */
+ fprintf_filtered (gdb_stdout, "Info catch not supported with this target/compiler combination.\n");
+#if 0
if (!selected_frame)
error ("No frame selected.");
- print_frame_label_vars (selected_frame, 0, gdb_stdout);
+#endif
+ }
+ else
+ {
+ /* Assume g++ compiled code -- old v 4.16 behaviour */
+ if (!selected_frame)
+ error ("No frame selected.");
+
+ print_frame_label_vars (selected_frame, 0, gdb_stdout);
+ }
}
static void
@@ -1097,7 +1445,7 @@ print_frame_arg_vars (fi, stream)
}
}
-static void
+void
args_info (ignore, from_tty)
char *ignore;
int from_tty;
@@ -1106,6 +1454,17 @@ args_info (ignore, from_tty)
error ("No frame selected.");
print_frame_arg_vars (selected_frame, gdb_stdout);
}
+
+
+static void
+args_plus_locals_info (ignore, from_tty)
+ char *ignore;
+ int from_tty;
+{
+ args_info(ignore, from_tty);
+ locals_info(ignore, from_tty);
+}
+
/* Select frame FI, and note that its stack level is LEVEL.
LEVEL may be -1 if an actual level number is not known. */
@@ -1119,6 +1478,8 @@ select_frame (fi, level)
selected_frame = fi;
selected_frame_level = level;
+ if (selected_frame_level_changed_hook)
+ selected_frame_level_changed_hook (level);
/* Ensure that symbols for this frame are read in. Also, determine the
source language of this frame, and switch to it if desired. */
@@ -1131,9 +1492,48 @@ select_frame (fi, level)
&& language_mode == language_mode_auto) {
set_language(s->language);
}
+ /* elz: this if here fixes the problem with the pc not being displayed
+ in the tui asm layout, with no debug symbols. The value of s
+ would be 0 here, and select_source_symtab would abort the
+ command by calling the 'error' function*/
+ if (s)
+ {
+ TUIDO(((TuiOpaqueFuncPtr)tui_vSelectSourceSymtab, s));
+ }
}
}
+
+/* Select frame FI, noting that its stack level is LEVEL. Also print
+ the stack frame and show the source if this is the tui version. */
+void
+select_and_print_frame(fi, level)
+ struct frame_info *fi;
+ int level;
+{
+ select_frame(fi, level);
+ if (fi)
+ {
+ print_stack_frame(fi, level, 1);
+ TUIDO(((TuiOpaqueFuncPtr)tui_vCheckDataValues, fi));
+ }
+}
+
+
+/* Select frame FI, noting that its stack level is LEVEL. Be silent if
+ not the TUI */
+void
+select_and_maybe_print_frame (fi, level)
+ struct frame_info *fi;
+ int level;
+{
+ if (!tui_version)
+ select_frame(fi, level);
+ else
+ select_and_print_frame(fi, level);
+}
+
+
/* Store the selected frame and its level into *FRAMEP and *LEVELP.
If there is no selected frame, *FRAMEP is set to NULL. */
@@ -1241,23 +1641,34 @@ select_frame_command (level_exp, from_tty)
With arg, behaves like select_frame and then prints the selected
frame. */
-static void
+void
frame_command (level_exp, from_tty)
char *level_exp;
int from_tty;
{
select_frame_command (level_exp, from_tty);
- print_stack_frame (selected_frame, selected_frame_level, 1);
+ show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
}
+/* The XDB Compatibility command to print the current frame. */
+
+void
+current_frame_command (level_exp, from_tty)
+ char *level_exp;
+ int from_tty;
+{
+ if (target_has_stack == 0 || selected_frame == 0)
+ error ("No stack.");
+ print_only_stack_frame (selected_frame, selected_frame_level, 1);
+ }
+
/* Select the frame up one or COUNT stack levels
from the previously selected frame, and print it briefly. */
/* ARGSUSED */
static void
-up_silently_command (count_exp, from_tty)
+up_silently_base (count_exp)
char *count_exp;
- int from_tty;
{
register struct frame_info *fi;
int count = 1, count1;
@@ -1275,12 +1686,22 @@ up_silently_command (count_exp, from_tty)
}
static void
+up_silently_command (count_exp, from_tty)
+ char *count_exp;
+ int from_tty;
+{
+ up_silently_base(count_exp);
+ if (tui_version)
+ print_stack_frame (selected_frame, selected_frame_level, 1);
+}
+
+static void
up_command (count_exp, from_tty)
char *count_exp;
int from_tty;
{
- up_silently_command (count_exp, from_tty);
- print_stack_frame (selected_frame, selected_frame_level, 1);
+ up_silently_base (count_exp);
+ show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
}
/* Select the frame down one or COUNT stack levels
@@ -1288,9 +1709,8 @@ up_command (count_exp, from_tty)
/* ARGSUSED */
static void
-down_silently_command (count_exp, from_tty)
+down_silently_base (count_exp)
char *count_exp;
- int from_tty;
{
register struct frame_info *frame;
int count = -1, count1;
@@ -1316,14 +1736,24 @@ down_silently_command (count_exp, from_tty)
select_frame (frame, selected_frame_level + count - count1);
}
+/* ARGSUSED */
+static void
+down_silently_command (count_exp, from_tty)
+ char *count_exp;
+ int from_tty;
+{
+ down_silently_base (count_exp);
+ if (tui_version)
+ print_stack_frame (selected_frame, selected_frame_level, 1);
+}
static void
down_command (count_exp, from_tty)
char *count_exp;
int from_tty;
{
- down_silently_command (count_exp, from_tty);
- print_stack_frame (selected_frame, selected_frame_level, 1);
+ down_silently_base (count_exp);
+ show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
}
static void
@@ -1408,10 +1838,72 @@ return_command (retval_exp, from_tty)
select_frame_command ("0", 0);
}
+/* Sets the scope to input function name, provided that the
+ function is within the current stack frame */
+
+struct function_bounds
+{
+ CORE_ADDR low, high;
+};
+
+static void
+func_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ struct frame_info *fp;
+ int found = 0;
+ struct symtabs_and_lines sals;
+ int i;
+ int level = 1;
+ struct function_bounds *func_bounds = (struct function_bounds *) NULL;
+
+ if (arg != (char *) NULL)
+ return;
+
+ fp = parse_frame_specification ("0");
+ sals = decode_line_spec (arg, 1);
+ func_bounds = (struct function_bounds *) xmalloc (
+ sizeof (struct function_bounds) * sals.nelts);
+ for (i = 0; (i < sals.nelts && !found); i++)
+ {
+ if (sals.sals[i].pc == (CORE_ADDR) 0 ||
+ find_pc_partial_function (sals.sals[i].pc,
+ (char **) NULL,
+ &func_bounds[i].low,
+ &func_bounds[i].high) == 0)
+ {
+ func_bounds[i].low =
+ func_bounds[i].high = (CORE_ADDR) NULL;
+ }
+ }
+
+ do
+ {
+ for (i = 0; (i < sals.nelts && !found); i++)
+ found = (fp->pc >= func_bounds[i].low &&
+ fp->pc < func_bounds[i].high);
+ if (!found)
+ {
+ level = 1;
+ fp = find_relative_frame (fp, &level);
+ }
+ }
+ while (!found && level == 0);
+
+ if (func_bounds)
+ free (func_bounds);
+
+ if (!found)
+ printf_filtered ("'%s' not within current stack frame.\n", arg);
+ else if (fp != selected_frame)
+ select_and_print_frame (fp, level);
+}
+
/* Gets the language of the current frame. */
enum language
-get_frame_language()
+get_frame_language ()
{
register struct symtab *s;
enum language flang; /* The language of the current frame */
@@ -1469,6 +1961,12 @@ a command file or a user-defined command.");
add_com_alias ("f", "frame", class_stack, 1);
+ if (xdb_commands)
+ {
+ add_com("L", class_stack, current_frame_command,
+ "Print the current stack frame.\n");
+ add_com_alias ("V", "frame", class_stack, 1);
+ }
add_com ("select-frame", class_stack, select_frame_command,
"Select a stack frame without printing anything.\n\
An argument specifies the frame to select.\n\
@@ -1476,8 +1974,19 @@ It can be a stack frame number or the address of the frame.\n");
add_com ("backtrace", class_stack, backtrace_command,
"Print backtrace of all stack frames, or innermost COUNT frames.\n\
-With a negative argument, print outermost -COUNT frames.");
+With a negative argument, print outermost -COUNT frames.\n\
+Use of the 'full' qualifier also prints the values of the local variables.\n");
add_com_alias ("bt", "backtrace", class_stack, 0);
+ if (xdb_commands)
+ {
+ add_com_alias ("t", "backtrace", class_stack, 0);
+ add_com ("T", class_stack, backtrace_full_command,
+ "Print backtrace of all stack frames, or innermost COUNT frames \n\
+and the values of the local variables.\n\
+With a negative argument, print outermost -COUNT frames.\n\
+Usage: T <count>\n");
+ }
+
add_com_alias ("where", "backtrace", class_alias, 0);
add_info ("stack", backtrace_command,
"Backtrace of the stack, or innermost COUNT frames.");
@@ -1489,6 +1998,14 @@ With a negative argument, print outermost -COUNT frames.");
"Local variables of current stack frame.");
add_info ("args", args_info,
"Argument variables of current stack frame.");
+ if (xdb_commands)
+ add_com("l", class_info, args_plus_locals_info,
+ "Argument and local variables of current stack frame.");
+
+ if (dbx_commands)
+ add_com("func", class_stack, func_command,
+ "Select the stack frame that contains <func>.\nUsage: func <name>\n");
+
add_info ("catch", catch_info,
"Exceptions that can be caught in the current stack frame.");
diff --git a/contrib/gdb/gdb/symfile.c b/contrib/gdb/gdb/symfile.c
index 62c4f61..ee60c93 100644
--- a/contrib/gdb/gdb/symfile.c
+++ b/contrib/gdb/gdb/symfile.c
@@ -1,5 +1,5 @@
/* Generic symbol file reading for the GNU debugger, GDB.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998
Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -34,10 +34,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "complaints.h"
#include "demangle.h"
#include "inferior.h" /* for write_pc */
-
+#include "gdb-stabs.h"
#include "obstack.h"
-#include <assert.h>
+#include <assert.h>
#include <sys/types.h>
#include <fcntl.h>
#include "gdb_string.h"
@@ -52,6 +52,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define O_BINARY 0
#endif
+#ifdef HPUXHPPA
+
+/* Some HP-UX related globals to clear when a new "main"
+ symbol file is loaded. HP-specific. */
+
+extern int hp_som_som_object_present;
+extern int hp_cxx_exception_support_initialized;
+#define RESET_HP_UX_GLOBALS() do {\
+ hp_som_som_object_present = 0; /* indicates HP-compiled code */ \
+ hp_cxx_exception_support_initialized = 0; /* must reinitialize exception stuff */ \
+ } while (0)
+#endif
+
+int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
+void (*pre_add_symbol_hook) PARAMS ((char *));
+void (*post_add_symbol_hook) PARAMS ((void));
+
/* Global variables owned by this file */
int readnow_symbol_files; /* Read full symbols immediately */
@@ -67,34 +84,65 @@ struct complaint empty_symtab_complaint = {
extern int info_verbose;
+extern void report_transfer_performance PARAMS ((unsigned long,
+ time_t, time_t));
+
/* Functions this file defines */
-static void
-set_initial_language PARAMS ((void));
+#if 0
+static int simple_read_overlay_region_table PARAMS ((void));
+static void simple_free_overlay_region_table PARAMS ((void));
+#endif
-static void
-load_command PARAMS ((char *, int));
+static void set_initial_language PARAMS ((void));
-static void
-add_symbol_file_command PARAMS ((char *, int));
+static void load_command PARAMS ((char *, int));
-static void
-add_shared_symbol_files_command PARAMS ((char *, int));
+static void add_symbol_file_command PARAMS ((char *, int));
-static void
-cashier_psymtab PARAMS ((struct partial_symtab *));
+static void add_shared_symbol_files_command PARAMS ((char *, int));
-static int
-compare_psymbols PARAMS ((const void *, const void *));
+static void cashier_psymtab PARAMS ((struct partial_symtab *));
-static int
-compare_symbols PARAMS ((const void *, const void *));
+static int compare_psymbols PARAMS ((const void *, const void *));
-static bfd *
-symfile_bfd_open PARAMS ((char *));
+static int compare_symbols PARAMS ((const void *, const void *));
-static void
-find_sym_fns PARAMS ((struct objfile *));
+bfd *symfile_bfd_open PARAMS ((char *));
+
+static void find_sym_fns PARAMS ((struct objfile *));
+
+static void decrement_reading_symtab PARAMS ((void *));
+
+static void overlay_invalidate_all PARAMS ((void));
+
+static int overlay_is_mapped PARAMS ((struct obj_section *));
+
+void list_overlays_command PARAMS ((char *, int));
+
+void map_overlay_command PARAMS ((char *, int));
+
+void unmap_overlay_command PARAMS ((char *, int));
+
+static void overlay_auto_command PARAMS ((char *, int));
+
+static void overlay_manual_command PARAMS ((char *, int));
+
+static void overlay_off_command PARAMS ((char *, int));
+
+static void overlay_load_command PARAMS ((char *, int));
+
+static void overlay_command PARAMS ((char *, int));
+
+static void simple_free_overlay_table PARAMS ((void));
+
+static void read_target_long_array PARAMS ((CORE_ADDR, unsigned int *, int));
+
+static int simple_read_overlay_table PARAMS ((void));
+
+static int simple_overlay_update_1 PARAMS ((struct obj_section *));
+
+void _initialize_symfile PARAMS ((void));
/* List of all available sym_fns. On gdb startup, each object file reader
calls add_symtab_fns() to register information on each format it is
@@ -111,15 +159,25 @@ int symbol_reloading = SYMBOL_RELOADING_DEFAULT;
int symbol_reloading = 0;
#endif
-/* If true, then shared library symbols will be added automatically
- when the inferior is created, new libraries are loaded, or when
- attaching to the inferior. This is almost always what users
+/* If non-zero, then on HP-UX (i.e., platforms that use somsolib.c),
+ this variable is interpreted as a threshhold. If adding a new
+ library's symbol table to those already known to the debugger would
+ exceed this threshhold, then the shlib's symbols are not added.
+
+ If non-zero on other platforms, shared library symbols will be added
+ automatically when the inferior is created, new libraries are loaded,
+ or when attaching to the inferior. This is almost always what users
will want to have happen; but for very large programs, the startup
time will be excessive, and so if this is a problem, the user can
clear this flag and then add the shared library symbols as needed.
Note that there is a potential for confusion, since if the shared
library symbols are not loaded, commands like "info fun" will *not*
- report all the functions that are actually present. */
+ report all the functions that are actually present.
+
+ Note that HP-UX interprets this variable to mean, "threshhold size
+ in megabytes, where zero means never add". Other platforms interpret
+ this variable to mean, "always add if non-zero, never add if zero."
+ */
int auto_solib_add = 1;
@@ -181,7 +239,19 @@ compare_psymbols (s1p, s2p)
}
else
{
- return (STRCMP (st1 + 2, st2 + 2));
+ /* Note: I replaced the STRCMP line (commented out below)
+ * with a simpler "strcmp()" which compares the 2 strings
+ * from the beginning. (STRCMP is a macro which first compares
+ * the initial characters, then falls back on strcmp).
+ * The reason is that the STRCMP line was tickling a C compiler
+ * bug on HP-UX 10.30, which is avoided with the simpler
+ * code. The performance gain from the more complicated code
+ * is negligible, given that we have already checked the
+ * initial 2 characters above. I reported the compiler bug,
+ * and once it is fixed the original line can be put back. RT
+ */
+ /* return ( STRCMP (st1 + 2, st2 + 2)); */
+ return ( strcmp (st1, st2));
}
}
@@ -230,9 +300,10 @@ sort_symtab_syms (s)
}
}
-/* Make a copy of the string at PTR with SIZE characters in the symbol obstack
- (and add a null character at the end in the copy).
- Returns the address of the copy. */
+/* Make a null terminated copy of the string at PTR with SIZE characters in
+ the obstack pointed to by OBSTACKP . Returns the address of the copy.
+ Note that the string at PTR does not have to be null terminated, I.E. it
+ may be part of a larger string and we are only saving a substring. */
char *
obsavestring (ptr, size, obstackp)
@@ -241,8 +312,9 @@ obsavestring (ptr, size, obstackp)
struct obstack *obstackp;
{
register char *p = (char *) obstack_alloc (obstackp, size + 1);
- /* Open-coded memcpy--saves function call time.
- These strings are usually short. */
+ /* Open-coded memcpy--saves function call time. These strings are usually
+ short. FIXME: Is this really still true with a compiler that can
+ inline memcpy? */
{
register char *p1 = ptr;
register char *p2 = p;
@@ -254,8 +326,8 @@ obsavestring (ptr, size, obstackp)
return p;
}
-/* Concatenate strings S1, S2 and S3; return the new string.
- Space is found in the symbol_obstack. */
+/* Concatenate strings S1, S2 and S3; return the new string. Space is found
+ in the obstack pointed to by OBSTACKP. */
char *
obconcat (obstackp, s1, s2, s3)
@@ -371,6 +443,31 @@ find_lowest_section (abfd, sect, obj)
*lowest = sect;
}
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+ of how to represent it for fast symbol reading. This is the default
+ version of the sym_fns.sym_offsets function for symbol readers that
+ don't need to do anything special. It allocates a section_offsets table
+ for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
+
+struct section_offsets *
+default_symfile_offsets (objfile, addr)
+ struct objfile *objfile;
+ CORE_ADDR addr;
+{
+ struct section_offsets *section_offsets;
+ int i;
+
+ objfile->num_sections = SECT_OFF_MAX;
+ section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile -> psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+
+ for (i = 0; i < SECT_OFF_MAX; i++)
+ ANOFFSET (section_offsets, i) = addr;
+
+ return section_offsets;
+}
+
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
@@ -399,13 +496,13 @@ syms_from_objfile (objfile, addr, mainline, verbo)
/* Make sure that partially constructed symbol tables will be cleaned up
if an error occurs during symbol reading. */
- old_chain = make_cleanup (free_objfile, objfile);
+ old_chain = make_cleanup ((make_cleanup_func) free_objfile, objfile);
if (mainline)
{
/* We will modify the main symbol table, make sure that all its users
will be cleaned up if an error occurs during symbol reading. */
- make_cleanup (clear_symtab_users, 0);
+ make_cleanup ((make_cleanup_func) clear_symtab_users, 0);
/* Since no error yet, throw away the old symbol table. */
@@ -572,17 +669,25 @@ new_symfile_objfile (objfile, mainline, verbo)
as dynamically loaded code. If !mainline, ADDR is the address
where the text segment was loaded.
+ USER_LOADED is TRUE if the add-symbol-file command was how this
+ symbol file came to be processed.
+
+ IS_SOLIB is TRUE if this symbol file represents a solib, as discovered
+ by the target's implementation of the solib package.
+
Upon success, returns a pointer to the objfile that was added.
Upon failure, jumps back to command level (never returns). */
struct objfile *
-symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
+symbol_file_add (name, from_tty, addr, mainline, mapped, readnow, user_loaded, is_solib)
char *name;
int from_tty;
CORE_ADDR addr;
int mainline;
int mapped;
int readnow;
+ int user_loaded;
+ int is_solib;
{
struct objfile *objfile;
struct partial_symtab *psymtab;
@@ -599,7 +704,7 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
&& !query ("Load new symbol table from \"%s\"? ", name))
error ("Not confirmed.");
- objfile = allocate_objfile (abfd, mapped);
+ objfile = allocate_objfile (abfd, mapped, user_loaded, is_solib);
/* If the objfile uses a mapped symbol file, and we have a psymtab for
it, then skip reading any symbols at this time. */
@@ -626,12 +731,17 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
performed, or need to read an unmapped symbol table. */
if (from_tty || info_verbose)
{
- printf_filtered ("Reading symbols from %s...", name);
- wrap_here ("");
- gdb_flush (gdb_stdout);
+ if (pre_add_symbol_hook)
+ pre_add_symbol_hook (name);
+ else
+ {
+ printf_filtered ("Reading symbols from %s...", name);
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ }
}
syms_from_objfile (objfile, addr, mainline, from_tty);
- }
+ }
/* We now have at least a partial symbol table. Check to see if the
user requested that all symbols be read on initial access via either
@@ -657,12 +767,19 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
if (from_tty || info_verbose)
{
- printf_filtered ("done.\n");
- gdb_flush (gdb_stdout);
+ if (post_add_symbol_hook)
+ post_add_symbol_hook ();
+ else
+ {
+ printf_filtered ("done.\n");
+ gdb_flush (gdb_stdout);
+ }
}
new_symfile_objfile (objfile, mainline, from_tty);
+ target_new_objfile (objfile);
+
return (objfile);
}
@@ -698,11 +815,23 @@ symbol_file_command (args, from_tty)
symfile_objfile -> name))
error ("Not confirmed.");
free_all_objfiles ();
+
+ /* solib descriptors may have handles to objfiles. Since their
+ storage has just been released, we'd better wipe the solib
+ descriptors as well.
+ */
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+
symfile_objfile = NULL;
if (from_tty)
{
printf_unfiltered ("No symbol file now.\n");
}
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
}
else
{
@@ -710,7 +839,7 @@ symbol_file_command (args, from_tty)
{
nomem (0);
}
- cleanups = make_cleanup (freeargv, (char *) argv);
+ cleanups = make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
while (*argv != NULL)
{
if (STREQ (*argv, "-mapped"))
@@ -742,11 +871,16 @@ symbol_file_command (args, from_tty)
if (text_relocation == (CORE_ADDR)0)
return;
else if (text_relocation == (CORE_ADDR)-1)
- symbol_file_add (name, from_tty, (CORE_ADDR)0, 1, mapped,
- readnow);
+ {
+ symbol_file_add (name, from_tty, (CORE_ADDR)0,
+ 1, mapped, readnow, 1, 0);
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+ }
else
symbol_file_add (name, from_tty, (CORE_ADDR)text_relocation,
- 0, mapped, readnow);
+ 0, mapped, readnow, 1, 0);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -761,6 +895,7 @@ symbol_file_command (args, from_tty)
{
error ("no symbol file name was specified");
}
+ TUIDO(((TuiOpaqueFuncPtr)tuiDisplayMainFunction));
do_cleanups (cleanups);
}
}
@@ -803,7 +938,7 @@ set_initial_language ()
malloc'd` copy of NAME (tilde-expanded and made absolute).
In case of trouble, error() is called. */
-static bfd *
+bfd *
symfile_bfd_open (name)
char *name;
{
@@ -811,10 +946,21 @@ symfile_bfd_open (name)
int desc;
char *absolute_name;
+
+
name = tilde_expand (name); /* Returns 1st new malloc'd copy */
/* Look down path for it, allocate 2nd new malloc'd copy. */
desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
+#if defined(__GO32__) || defined(_WIN32)
+ if (desc < 0)
+ {
+ char *exename = alloca (strlen (name) + 5);
+ strcat (strcpy (exename, name), ".exe");
+ desc = openp (getenv ("PATH"), 1, exename, O_RDONLY | O_BINARY,
+ 0, &absolute_name);
+ }
+#endif
if (desc < 0)
{
make_cleanup (free, name);
@@ -844,7 +990,6 @@ symfile_bfd_open (name)
error ("\"%s\": can't read symbols: %s.", name,
bfd_errmsg (bfd_get_error ()));
}
-
return (sym_bfd);
}
@@ -916,6 +1061,8 @@ load_command (arg, from_tty)
to worry about finding it, and (b) On VMS, fork() is very slow and so
we don't want to run a subprocess. On the other hand, I'm not sure how
performance compares. */
+#define GENERIC_LOAD_CHUNK 256
+#define VALIDATE_DOWNLOAD 0
void
generic_load (filename, from_tty)
char *filename;
@@ -925,7 +1072,20 @@ generic_load (filename, from_tty)
asection *s;
bfd *loadfile_bfd;
time_t start_time, end_time; /* Start and end times of download */
- unsigned long data_count; /* Number of bytes transferred to memory */
+ unsigned long data_count = 0; /* Number of bytes transferred to memory */
+ int n;
+ unsigned long load_offset = 0; /* offset to add to vma for each section */
+ char buf[GENERIC_LOAD_CHUNK+8];
+#if VALIDATE_DOWNLOAD
+ char verify_buffer[GENERIC_LOAD_CHUNK+8] ;
+#endif
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+ n = sscanf(filename, "%s 0x%lx", buf, &load_offset);
+ if (n > 1 )
+ filename = buf;
+ else
+ load_offset = 0;
loadfile_bfd = bfd_openr (filename, gnutarget);
if (loadfile_bfd == NULL)
@@ -936,7 +1096,7 @@ generic_load (filename, from_tty)
/* FIXME: should be checking for errors from bfd_close (for one thing,
on error it does not free all the storage associated with the
bfd). */
- old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
+ old_cleanups = make_cleanup ((make_cleanup_func) bfd_close, loadfile_bfd);
if (!bfd_check_format (loadfile_bfd, bfd_object))
{
@@ -949,45 +1109,87 @@ generic_load (filename, from_tty)
for (s = loadfile_bfd->sections; s; s = s->next)
{
if (s->flags & SEC_LOAD)
- {
- bfd_size_type size;
-
- size = bfd_get_section_size_before_reloc (s);
- if (size > 0)
- {
- char *buffer;
- struct cleanup *old_chain;
- bfd_vma vma;
-
- data_count += size;
-
- buffer = xmalloc (size);
- old_chain = make_cleanup (free, buffer);
-
- vma = bfd_get_section_vma (loadfile_bfd, s);
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size > 0)
+ {
+ char *buffer;
+ struct cleanup *old_chain;
+ bfd_vma lma;
+ unsigned long l = size ;
+ int err;
+ char *sect;
+ unsigned long sent;
+ unsigned long len;
+
+ l = l > GENERIC_LOAD_CHUNK ? GENERIC_LOAD_CHUNK : l ;
+
+ buffer = xmalloc (size);
+ old_chain = make_cleanup (free, buffer);
+
+ lma = s->lma;
+ lma += load_offset;
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_get_section_name (loadfile_bfd, s),
+ (unsigned long) size);
+ print_address_numeric (lma, 1, gdb_stdout);
+ printf_filtered ("\n");
+
+ bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
+
+ sect = (char *) bfd_get_section_name (loadfile_bfd, s);
+ sent = 0;
+ do
+ {
+ len = (size - sent) < l ? (size - sent) : l;
+ sent += len;
+ err = target_write_memory (lma, buffer, len);
+ if (ui_load_progress_hook)
+ if (ui_load_progress_hook (sect, sent))
+ error ("Canceled the download");
+#if VALIDATE_DOWNLOAD
+ /* Broken memories and broken monitors manifest themselves
+ here when bring new computers to life.
+ This doubles already slow downloads.
+ */
+ if (err) break ;
+ {
+ target_read_memory(lma,verify_buffer,len) ;
+ if (0 != bcmp(buffer,verify_buffer,len))
+ error("Download verify failed at %08x",
+ (unsigned long)lma) ;
+ }
- /* Is this really necessary? I guess it gives the user something
- to look at during a long download. */
- printf_filtered ("Loading section %s, size 0x%lx vma ",
- bfd_get_section_name (loadfile_bfd, s),
- (unsigned long) size);
- print_address_numeric (vma, 1, gdb_stdout);
- printf_filtered ("\n");
-
- bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
-
- target_write_memory (vma, buffer, size);
-
- do_cleanups (old_chain);
- }
- }
+#endif
+ data_count += len ;
+ lma += len;
+ buffer += len;
+ } /* od */
+ while (err == 0 && sent < size);
+
+ if (err != 0)
+ error ("Memory access error while loading section %s.",
+ bfd_get_section_name (loadfile_bfd, s));
+
+ do_cleanups (old_chain);
+ }
+ }
}
end_time = time (NULL);
-
- /* We were doing this in remote-mips.c, I suspect it is right
- for other targets too. */
- write_pc (loadfile_bfd->start_address);
+ {
+ unsigned long entry ;
+ entry = bfd_get_start_address(loadfile_bfd) ;
+ printf_filtered ("Start address 0x%lx , load size %d\n", entry,data_count);
+ /* We were doing this in remote-mips.c, I suspect it is right
+ for other targets too. */
+ write_pc (entry);
+ }
/* FIXME: are we supposed to call symbol_file_add or not? According to
a comment from remote-mips.c (where a call to symbol_file_add was
@@ -995,13 +1197,27 @@ generic_load (filename, from_tty)
loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c
does. */
- if (end_time != start_time)
- printf_filtered ("Transfer rate: %d bits/sec.\n",
- (data_count * 8)/(end_time - start_time));
+ report_transfer_performance (data_count, start_time, end_time);
do_cleanups (old_cleanups);
}
+/* Report how fast the transfer went. */
+
+void
+report_transfer_performance (data_count, start_time, end_time)
+unsigned long data_count;
+time_t start_time, end_time;
+{
+ printf_filtered ("Transfer rate: ");
+ if (end_time != start_time)
+ printf_filtered ("%d bits/sec",
+ (data_count * 8) / (end_time - start_time));
+ else
+ printf_filtered ("%d bits in <1 sec", (data_count * 8));
+ printf_filtered (".\n");
+}
+
/* This function allows the addition of incrementally linked object files.
It does not modify any state in the target, only in the debugger. */
@@ -1081,11 +1297,14 @@ add_symbol_file_command (args, from_tty)
}
/* FIXME-32x64: Assumes text_addr fits in a long. */
- if (!query ("add symbol table from file \"%s\" at text_addr = %s?\n",
- name, local_hex_string ((unsigned long)text_addr)))
+ if ((from_tty)
+ && (!query ("add symbol table from file \"%s\" at text_addr = %s?\n",
+ name, local_hex_string ((unsigned long)text_addr))))
error ("Not confirmed.");
- symbol_file_add (name, 0, text_addr, 0, mapped, readnow);
+ symbol_file_add (name, from_tty, text_addr, 0, mapped, readnow,
+ 1, /* user_loaded */
+ 0); /* We'll guess it's ! is_solib */
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1159,9 +1378,10 @@ reread_symbols ()
/* If we get an error, blow away this objfile (not sure if
that is the correct response for things like shared
libraries). */
- old_cleanups = make_cleanup (free_objfile, objfile);
+ old_cleanups = make_cleanup ((make_cleanup_func) free_objfile,
+ objfile);
/* We need to do this whenever any symbols go away. */
- make_cleanup (clear_symtab_users, 0);
+ make_cleanup ((make_cleanup_func) clear_symtab_users, 0);
/* Clean up any state BFD has sitting around. We don't need
to close the descriptor but BFD lacks a way of closing the
@@ -1250,7 +1470,12 @@ reread_symbols ()
distinguishing between the main file and additional files
in this way seems rather dubious. */
if (objfile == symfile_objfile)
- (*objfile->sf->sym_new_init) (objfile);
+ {
+ (*objfile->sf->sym_new_init) (objfile);
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+ }
(*objfile->sf->sym_init) (objfile);
clear_complaints (1, 1);
@@ -1298,31 +1523,150 @@ reread_symbols ()
}
+
+typedef struct {
+ char *ext;
+ enum language lang;
+} filename_language;
+
+static filename_language * filename_language_table;
+static int fl_table_size, fl_table_next;
+
+static void
+add_filename_language (ext, lang)
+ char *ext;
+ enum language lang;
+{
+ if (fl_table_next >= fl_table_size)
+ {
+ fl_table_size += 10;
+ filename_language_table = realloc (filename_language_table,
+ fl_table_size);
+ }
+
+ filename_language_table[fl_table_next].ext = strsave (ext);
+ filename_language_table[fl_table_next].lang = lang;
+ fl_table_next++;
+}
+
+static char *ext_args;
+
+static void
+set_ext_lang_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int i;
+ char *cp = ext_args;
+ enum language lang;
+
+ /* First arg is filename extension, starting with '.' */
+ if (*cp != '.')
+ error ("'%s': Filename extension must begin with '.'", ext_args);
+
+ /* Find end of first arg. */
+ while (*cp && !isspace (*cp))
+ cp++;
+
+ if (*cp == '\0')
+ error ("'%s': two arguments required -- filename extension and language",
+ ext_args);
+
+ /* Null-terminate first arg */
+ *cp++ = '\0';
+
+ /* Find beginning of second arg, which should be a source language. */
+ while (*cp && isspace (*cp))
+ cp++;
+
+ if (*cp == '\0')
+ error ("'%s': two arguments required -- filename extension and language",
+ ext_args);
+
+ /* Lookup the language from among those we know. */
+ lang = language_enum (cp);
+
+ /* Now lookup the filename extension: do we already know it? */
+ for (i = 0; i < fl_table_next; i++)
+ if (0 == strcmp (ext_args, filename_language_table[i].ext))
+ break;
+
+ if (i >= fl_table_next)
+ {
+ /* new file extension */
+ add_filename_language (ext_args, lang);
+ }
+ else
+ {
+ /* redefining a previously known filename extension */
+
+ /* if (from_tty) */
+ /* query ("Really make files of type %s '%s'?", */
+ /* ext_args, language_str (lang)); */
+
+ free (filename_language_table[i].ext);
+ filename_language_table[i].ext = strsave (ext_args);
+ filename_language_table[i].lang = lang;
+ }
+}
+
+static void
+info_ext_lang_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int i;
+
+ printf_filtered ("Filename extensions and the languages they represent:");
+ printf_filtered ("\n\n");
+ for (i = 0; i < fl_table_next; i++)
+ printf_filtered ("\t%s\t- %s\n",
+ filename_language_table[i].ext,
+ language_str (filename_language_table[i].lang));
+}
+
+static void
+init_filename_language_table ()
+{
+ if (fl_table_size == 0) /* protect against repetition */
+ {
+ fl_table_size = 20;
+ fl_table_next = 0;
+ filename_language_table =
+ xmalloc (fl_table_size * sizeof (*filename_language_table));
+ add_filename_language (".c", language_c);
+ add_filename_language (".C", language_cplus);
+ add_filename_language (".cc", language_cplus);
+ add_filename_language (".cp", language_cplus);
+ add_filename_language (".cpp", language_cplus);
+ add_filename_language (".cxx", language_cplus);
+ add_filename_language (".c++", language_cplus);
+ add_filename_language (".java", language_java);
+ add_filename_language (".class", language_java);
+ add_filename_language (".ch", language_chill);
+ add_filename_language (".c186", language_chill);
+ add_filename_language (".c286", language_chill);
+ add_filename_language (".f", language_fortran);
+ add_filename_language (".F", language_fortran);
+ add_filename_language (".s", language_asm);
+ add_filename_language (".S", language_asm);
+ }
+}
+
enum language
deduce_language_from_filename (filename)
char *filename;
{
- char *c;
-
- if (0 == filename)
- ; /* Get default */
- else if (0 == (c = strrchr (filename, '.')))
- ; /* Get default. */
- else if (STREQ (c, ".c"))
- return language_c;
- else if (STREQ (c, ".cc") || STREQ (c, ".C") || STREQ (c, ".cxx")
- || STREQ (c, ".cpp") || STREQ (c, ".cp") || STREQ (c, ".c++"))
- return language_cplus;
- else if (STREQ (c, ".ch") || STREQ (c, ".c186") || STREQ (c, ".c286"))
- return language_chill;
- else if (STREQ (c, ".f") || STREQ (c, ".F"))
- return language_fortran;
- else if (STREQ (c, ".mod"))
- return language_m2;
- else if (STREQ (c, ".s") || STREQ (c, ".S"))
- return language_asm;
-
- return language_unknown; /* default */
+ int i;
+ char *cp;
+
+ if (filename != NULL)
+ if ((cp = strrchr (filename, '.')) != NULL)
+ for (i = 0; i < fl_table_next; i++)
+ if (strcmp (cp, filename_language_table[i].ext) == 0)
+ return filename_language_table[i].lang;
+
+ return language_unknown;
}
/* allocate_symtab:
@@ -1336,7 +1680,6 @@ deduce_language_from_filename (filename)
symtab->dirname
symtab->free_code
symtab->free_ptr
- initialize any EXTRA_SYMTAB_INFO
possibly free_named_symtabs (symtab->filename);
*/
@@ -1354,6 +1697,8 @@ allocate_symtab (filename, objfile)
&objfile -> symbol_obstack);
symtab -> fullname = NULL;
symtab -> language = deduce_language_from_filename (filename);
+ symtab -> debugformat = obsavestring ("unknown", 7,
+ &objfile -> symbol_obstack);
/* Hook it to the objfile it comes from */
@@ -1361,6 +1706,10 @@ allocate_symtab (filename, objfile)
symtab -> next = objfile -> symtabs;
objfile -> symtabs = symtab;
+ /* FIXME: This should go away. It is only defined for the Z8000,
+ and the Z8000 definition of this macro doesn't have anything to
+ do with the now-nonexistent EXTRA_SYMTAB_INFO macro, it's just
+ here for convenience. */
#ifdef INIT_EXTRA_SYMTAB_INFO
INIT_EXTRA_SYMTAB_INFO (symtab);
#endif
@@ -1390,18 +1739,57 @@ allocate_psymtab (filename, objfile)
&objfile -> psymbol_obstack);
psymtab -> symtab = NULL;
- /* Hook it to the objfile it comes from */
+ /* Prepend it to the psymtab list for the objfile it belongs to.
+ Psymtabs are searched in most recent inserted -> least recent
+ inserted order. */
psymtab -> objfile = objfile;
psymtab -> next = objfile -> psymtabs;
objfile -> psymtabs = psymtab;
+#if 0
+ {
+ struct partial_symtab **prev_pst;
+ psymtab -> objfile = objfile;
+ psymtab -> next = NULL;
+ prev_pst = &(objfile -> psymtabs);
+ while ((*prev_pst) != NULL)
+ prev_pst = &((*prev_pst) -> next);
+ (*prev_pst) = psymtab;
+ }
+#endif
return (psymtab);
}
+void
+discard_psymtab (pst)
+ struct partial_symtab *pst;
+{
+ struct partial_symtab **prev_pst;
+
+ /* From dbxread.c:
+ Empty psymtabs happen as a result of header files which don't
+ have any symbols in them. There can be a lot of them. But this
+ check is wrong, in that a psymtab with N_SLINE entries but
+ nothing else is not empty, but we don't realize that. Fixing
+ that without slowing things down might be tricky. */
+
+ /* First, snip it out of the psymtab chain */
+
+ prev_pst = &(pst->objfile->psymtabs);
+ while ((*prev_pst) != pst)
+ prev_pst = &((*prev_pst)->next);
+ (*prev_pst) = pst->next;
+
+ /* Next, put it on a free list for recycling */
+
+ pst->next = pst->objfile->free_psymtabs;
+ pst->objfile->free_psymtabs = pst;
+}
+
/* Reset all data structures in gdb which may contain references to symbol
- table date. */
+ table data. */
void
clear_symtab_users ()
@@ -1416,6 +1804,7 @@ clear_symtab_users ()
current_source_symtab = 0;
current_source_line = 0;
clear_pc_function_cache ();
+ target_new_objfile (NULL);
}
/* clear_symtab_users_once:
@@ -1700,6 +2089,83 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, coreaddr,
OBJSTAT (objfile, n_psyms++);
}
+/* Add a symbol with a long value to a psymtab. This differs from
+ * add_psymbol_to_list above in taking both a mangled and a demangled
+ * name. */
+
+void
+add_psymbol_with_dem_name_to_list (name, namelength, dem_name, dem_namelength,
+ namespace, class, list, val, coreaddr, language, objfile)
+ char *name;
+ int namelength;
+ char *dem_name;
+ int dem_namelength;
+ namespace_enum namespace;
+ enum address_class class;
+ struct psymbol_allocation_list *list;
+ long val; /* Value as a long */
+ CORE_ADDR coreaddr; /* Value as a CORE_ADDR */
+ enum language language;
+ struct objfile *objfile;
+{
+ register struct partial_symbol *psym;
+ char *buf = alloca (namelength + 1);
+ /* psymbol is static so that there will be no uninitialized gaps in the
+ structure which might contain random data, causing cache misses in
+ bcache. */
+ static struct partial_symbol psymbol;
+
+ /* Create local copy of the partial symbol */
+
+ memcpy (buf, name, namelength);
+ buf[namelength] = '\0';
+ SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
+
+ buf = alloca (dem_namelength + 1);
+ memcpy (buf, dem_name, dem_namelength);
+ buf[dem_namelength] = '\0';
+
+ switch (language)
+ {
+ case language_c:
+ case language_cplus:
+ SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) =
+ bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+ break;
+ case language_chill:
+ SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) =
+ bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+
+ /* FIXME What should be done for the default case? Ignoring for now. */
+ }
+
+ /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+ if (val != 0)
+ {
+ SYMBOL_VALUE (&psymbol) = val;
+ }
+ else
+ {
+ SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
+ }
+ SYMBOL_SECTION (&psymbol) = 0;
+ SYMBOL_LANGUAGE (&psymbol) = language;
+ PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_CLASS (&psymbol) = class;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+ /* Stash the partial symbol away in the cache */
+ psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+
+ /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+ if (list->next >= list->list + list->size)
+ {
+ extend_psymbol_list (list, objfile);
+ }
+ *list->next++ = psym;
+ OBJSTAT (objfile, n_psyms++);
+}
+
/* Initialize storage for partial symbols. */
void
@@ -1724,16 +2190,761 @@ init_psymbol_list (objfile, total_symbols)
objfile -> global_psymbols.size = total_symbols / 10;
objfile -> static_psymbols.size = total_symbols / 10;
- objfile -> global_psymbols.next =
- objfile -> global_psymbols.list = (struct partial_symbol **)
- xmmalloc (objfile -> md, objfile -> global_psymbols.size
- * sizeof (struct partial_symbol *));
- objfile -> static_psymbols.next =
- objfile -> static_psymbols.list = (struct partial_symbol **)
- xmmalloc (objfile -> md, objfile -> static_psymbols.size
- * sizeof (struct partial_symbol *));
+
+ if (objfile -> global_psymbols.size > 0)
+ {
+ objfile -> global_psymbols.next =
+ objfile -> global_psymbols.list = (struct partial_symbol **)
+ xmmalloc (objfile -> md, (objfile -> global_psymbols.size
+ * sizeof (struct partial_symbol *)));
+ }
+ if (objfile -> static_psymbols.size > 0)
+ {
+ objfile -> static_psymbols.next =
+ objfile -> static_psymbols.list = (struct partial_symbol **)
+ xmmalloc (objfile -> md, (objfile -> static_psymbols.size
+ * sizeof (struct partial_symbol *)));
+ }
}
-
+
+/* OVERLAYS:
+ The following code implements an abstraction for debugging overlay sections.
+
+ The target model is as follows:
+ 1) The gnu linker will permit multiple sections to be mapped into the
+ same VMA, each with its own unique LMA (or load address).
+ 2) It is assumed that some runtime mechanism exists for mapping the
+ sections, one by one, from the load address into the VMA address.
+ 3) This code provides a mechanism for gdb to keep track of which
+ sections should be considered to be mapped from the VMA to the LMA.
+ This information is used for symbol lookup, and memory read/write.
+ For instance, if a section has been mapped then its contents
+ should be read from the VMA, otherwise from the LMA.
+
+ Two levels of debugger support for overlays are available. One is
+ "manual", in which the debugger relies on the user to tell it which
+ overlays are currently mapped. This level of support is
+ implemented entirely in the core debugger, and the information about
+ whether a section is mapped is kept in the objfile->obj_section table.
+
+ The second level of support is "automatic", and is only available if
+ the target-specific code provides functionality to read the target's
+ overlay mapping table, and translate its contents for the debugger
+ (by updating the mapped state information in the obj_section tables).
+
+ The interface is as follows:
+ User commands:
+ overlay map <name> -- tell gdb to consider this section mapped
+ overlay unmap <name> -- tell gdb to consider this section unmapped
+ overlay list -- list the sections that GDB thinks are mapped
+ overlay read-target -- get the target's state of what's mapped
+ overlay off/manual/auto -- set overlay debugging state
+ Functional interface:
+ find_pc_mapped_section(pc): if the pc is in the range of a mapped
+ section, return that section.
+ find_pc_overlay(pc): find any overlay section that contains
+ the pc, either in its VMA or its LMA
+ overlay_is_mapped(sect): true if overlay is marked as mapped
+ section_is_overlay(sect): true if section's VMA != LMA
+ pc_in_mapped_range(pc,sec): true if pc belongs to section's VMA
+ pc_in_unmapped_range(...): true if pc belongs to section's LMA
+ overlay_mapped_address(...): map an address from section's LMA to VMA
+ overlay_unmapped_address(...): map an address from section's VMA to LMA
+ symbol_overlayed_address(...): Return a "current" address for symbol:
+ either in VMA or LMA depending on whether
+ the symbol's section is currently mapped
+ */
+
+/* Overlay debugging state: */
+
+int overlay_debugging = 0; /* 0 == off, 1 == manual, -1 == auto */
+int overlay_cache_invalid = 0; /* True if need to refresh mapped state */
+
+/* Target vector for refreshing overlay mapped state */
+static void simple_overlay_update PARAMS ((struct obj_section *));
+void (*target_overlay_update) PARAMS ((struct obj_section *))
+ = simple_overlay_update;
+
+/* Function: section_is_overlay (SECTION)
+ Returns true if SECTION has VMA not equal to LMA, ie.
+ SECTION is loaded at an address different from where it will "run". */
+
+int
+section_is_overlay (section)
+ asection *section;
+{
+ if (overlay_debugging)
+ if (section && section->lma != 0 &&
+ section->vma != section->lma)
+ return 1;
+
+ return 0;
+}
+
+/* Function: overlay_invalidate_all (void)
+ Invalidate the mapped state of all overlay sections (mark it as stale). */
+
+static void
+overlay_invalidate_all ()
+{
+ struct objfile *objfile;
+ struct obj_section *sect;
+
+ ALL_OBJSECTIONS (objfile, sect)
+ if (section_is_overlay (sect->the_bfd_section))
+ sect->ovly_mapped = -1;
+}
+
+/* Function: overlay_is_mapped (SECTION)
+ Returns true if section is an overlay, and is currently mapped.
+ Private: public access is thru function section_is_mapped.
+
+ Access to the ovly_mapped flag is restricted to this function, so
+ that we can do automatic update. If the global flag
+ OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
+ overlay_invalidate_all. If the mapped state of the particular
+ section is stale, then call TARGET_OVERLAY_UPDATE to refresh it. */
+
+static int
+overlay_is_mapped (osect)
+ struct obj_section *osect;
+{
+ if (osect == 0 || !section_is_overlay (osect->the_bfd_section))
+ return 0;
+
+ switch (overlay_debugging)
+ {
+ default:
+ case 0: return 0; /* overlay debugging off */
+ case -1: /* overlay debugging automatic */
+ /* Unles there is a target_overlay_update function,
+ there's really nothing useful to do here (can't really go auto) */
+ if (target_overlay_update)
+ {
+ if (overlay_cache_invalid)
+ {
+ overlay_invalidate_all ();
+ overlay_cache_invalid = 0;
+ }
+ if (osect->ovly_mapped == -1)
+ (*target_overlay_update) (osect);
+ }
+ /* fall thru to manual case */
+ case 1: /* overlay debugging manual */
+ return osect->ovly_mapped == 1;
+ }
+}
+
+/* Function: section_is_mapped
+ Returns true if section is an overlay, and is currently mapped. */
+
+int
+section_is_mapped (section)
+ asection *section;
+{
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ ALL_OBJSECTIONS (objfile, osect)
+ if (osect->the_bfd_section == section)
+ return overlay_is_mapped (osect);
+
+ return 0;
+}
+
+/* Function: pc_in_unmapped_range
+ If PC falls into the lma range of SECTION, return true, else false. */
+
+CORE_ADDR
+pc_in_unmapped_range (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ int size;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ {
+ size = bfd_get_section_size_before_reloc (section);
+ if (section->lma <= pc && pc < section->lma + size)
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: pc_in_mapped_range
+ If PC falls into the vma range of SECTION, return true, else false. */
+
+CORE_ADDR
+pc_in_mapped_range (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ int size;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ {
+ size = bfd_get_section_size_before_reloc (section);
+ if (section->vma <= pc && pc < section->vma + size)
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: overlay_unmapped_address (PC, SECTION)
+ Returns the address corresponding to PC in the unmapped (load) range.
+ May be the same as PC. */
+
+CORE_ADDR
+overlay_unmapped_address (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ if (overlay_debugging)
+ if (section && section_is_overlay (section) &&
+ pc_in_mapped_range (pc, section))
+ return pc + section->lma - section->vma;
+
+ return pc;
+}
+
+/* Function: overlay_mapped_address (PC, SECTION)
+ Returns the address corresponding to PC in the mapped (runtime) range.
+ May be the same as PC. */
+
+CORE_ADDR
+overlay_mapped_address (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ if (overlay_debugging)
+ if (section && section_is_overlay (section) &&
+ pc_in_unmapped_range (pc, section))
+ return pc + section->vma - section->lma;
+
+ return pc;
+}
+
+
+/* Function: symbol_overlayed_address
+ Return one of two addresses (relative to the VMA or to the LMA),
+ depending on whether the section is mapped or not. */
+
+CORE_ADDR
+symbol_overlayed_address (address, section)
+ CORE_ADDR address;
+ asection *section;
+{
+ if (overlay_debugging)
+ {
+ /* If the symbol has no section, just return its regular address. */
+ if (section == 0)
+ return address;
+ /* If the symbol's section is not an overlay, just return its address */
+ if (!section_is_overlay (section))
+ return address;
+ /* If the symbol's section is mapped, just return its address */
+ if (section_is_mapped (section))
+ return address;
+ /*
+ * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
+ * then return its LOADED address rather than its vma address!!
+ */
+ return overlay_unmapped_address (address, section);
+ }
+ return address;
+}
+
+/* Function: find_pc_overlay (PC)
+ Return the best-match overlay section for PC:
+ If PC matches a mapped overlay section's VMA, return that section.
+ Else if PC matches an unmapped section's VMA, return that section.
+ Else if PC matches an unmapped section's LMA, return that section. */
+
+asection *
+find_pc_overlay (pc)
+ CORE_ADDR pc;
+{
+ struct objfile *objfile;
+ struct obj_section *osect, *best_match = NULL;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (section_is_overlay (osect->the_bfd_section))
+ {
+ if (pc_in_mapped_range (pc, osect->the_bfd_section))
+ {
+ if (overlay_is_mapped (osect))
+ return osect->the_bfd_section;
+ else
+ best_match = osect;
+ }
+ else if (pc_in_unmapped_range (pc, osect->the_bfd_section))
+ best_match = osect;
+ }
+ return best_match ? best_match->the_bfd_section : NULL;
+}
+
+/* Function: find_pc_mapped_section (PC)
+ If PC falls into the VMA address range of an overlay section that is
+ currently marked as MAPPED, return that section. Else return NULL. */
+
+asection *
+find_pc_mapped_section (pc)
+ CORE_ADDR pc;
+{
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (pc_in_mapped_range (pc, osect->the_bfd_section) &&
+ overlay_is_mapped (osect))
+ return osect->the_bfd_section;
+
+ return NULL;
+}
+
+/* Function: list_overlays_command
+ Print a list of mapped sections and their PC ranges */
+
+void
+list_overlays_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int nmapped = 0;
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (overlay_is_mapped (osect))
+ {
+ const char *name;
+ bfd_vma lma, vma;
+ int size;
+
+ vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
+ lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+
+ printf_filtered ("Section %s, loaded at ", name);
+ print_address_numeric (lma, 1, gdb_stdout);
+ puts_filtered (" - ");
+ print_address_numeric (lma + size, 1, gdb_stdout);
+ printf_filtered (", mapped at ");
+ print_address_numeric (vma, 1, gdb_stdout);
+ puts_filtered (" - ");
+ print_address_numeric (vma + size, 1, gdb_stdout);
+ puts_filtered ("\n");
+
+ nmapped ++;
+ }
+ if (nmapped == 0)
+ printf_filtered ("No sections are mapped.\n");
+}
+
+/* Function: map_overlay_command
+ Mark the named section as mapped (ie. residing at its VMA address). */
+
+void
+map_overlay_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct objfile *objfile, *objfile2;
+ struct obj_section *sec, *sec2;
+ asection *bfdsec;
+
+ if (!overlay_debugging)
+ error ("Overlay debugging not enabled. Use the 'OVERLAY ON' command.");
+
+ if (args == 0 || *args == 0)
+ error ("Argument required: name of an overlay section");
+
+ /* First, find a section matching the user supplied argument */
+ ALL_OBJSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ /* Now, check to see if the section is an overlay. */
+ bfdsec = sec->the_bfd_section;
+ if (!section_is_overlay (bfdsec))
+ continue; /* not an overlay section */
+
+ /* Mark the overlay as "mapped" */
+ sec->ovly_mapped = 1;
+
+ /* Next, make a pass and unmap any sections that are
+ overlapped by this new section: */
+ ALL_OBJSECTIONS (objfile2, sec2)
+ if (sec2->ovly_mapped &&
+ sec != sec2 &&
+ sec->the_bfd_section != sec2->the_bfd_section &&
+ (pc_in_mapped_range (sec2->addr, sec->the_bfd_section) ||
+ pc_in_mapped_range (sec2->endaddr, sec->the_bfd_section)))
+ {
+ if (info_verbose)
+ printf_filtered ("Note: section %s unmapped by overlap\n",
+ bfd_section_name (objfile->obfd,
+ sec2->the_bfd_section));
+ sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */
+ }
+ return;
+ }
+ error ("No overlay section called %s", args);
+}
+
+/* Function: unmap_overlay_command
+ Mark the overlay section as unmapped
+ (ie. resident in its LMA address range, rather than the VMA range). */
+
+void
+unmap_overlay_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct objfile *objfile;
+ struct obj_section *sec;
+
+ if (!overlay_debugging)
+ error ("Overlay debugging not enabled. Use the 'OVERLAY ON' command.");
+
+ if (args == 0 || *args == 0)
+ error ("Argument required: name of an overlay section");
+
+ /* First, find a section matching the user supplied argument */
+ ALL_OBJSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ if (!sec->ovly_mapped)
+ error ("Section %s is not mapped", args);
+ sec->ovly_mapped = 0;
+ return;
+ }
+ error ("No overlay section called %s", args);
+}
+
+/* Function: overlay_auto_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_auto_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ overlay_debugging = -1;
+ if (info_verbose)
+ printf_filtered ("Automatic overlay debugging enabled.");
+}
+
+/* Function: overlay_manual_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_manual_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ overlay_debugging = 1;
+ if (info_verbose)
+ printf_filtered ("Overlay debugging enabled.");
+}
+
+/* Function: overlay_off_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_off_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ overlay_debugging = 0;
+ if (info_verbose)
+ printf_filtered ("Overlay debugging disabled.");
+}
+
+static void
+overlay_load_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (target_overlay_update)
+ (*target_overlay_update) (NULL);
+ else
+ error ("This target does not know how to read its overlay state.");
+}
+
+/* Function: overlay_command
+ A place-holder for a mis-typed command */
+
+/* Command list chain containing all defined "overlay" subcommands. */
+struct cmd_list_element *overlaylist;
+
+static void
+overlay_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ printf_unfiltered
+ ("\"overlay\" must be followed by the name of an overlay command.\n");
+ help_list (overlaylist, "overlay ", -1, gdb_stdout);
+}
+
+
+/* Target Overlays for the "Simplest" overlay manager:
+
+ This is GDB's default target overlay layer. It works with the
+ minimal overlay manager supplied as an example by Cygnus. The
+ entry point is via a function pointer "target_overlay_update",
+ so targets that use a different runtime overlay manager can
+ substitute their own overlay_update function and take over the
+ function pointer.
+
+ The overlay_update function pokes around in the target's data structures
+ to see what overlays are mapped, and updates GDB's overlay mapping with
+ this information.
+
+ In this simple implementation, the target data structures are as follows:
+ unsigned _novlys; /# number of overlay sections #/
+ unsigned _ovly_table[_novlys][4] = {
+ {VMA, SIZE, LMA, MAPPED}, /# one entry per overlay section #/
+ {..., ..., ..., ...},
+ }
+ unsigned _novly_regions; /# number of overlay regions #/
+ unsigned _ovly_region_table[_novly_regions][3] = {
+ {VMA, SIZE, MAPPED_TO_LMA}, /# one entry per overlay region #/
+ {..., ..., ...},
+ }
+ These functions will attempt to update GDB's mappedness state in the
+ symbol section table, based on the target's mappedness state.
+
+ To do this, we keep a cached copy of the target's _ovly_table, and
+ attempt to detect when the cached copy is invalidated. The main
+ entry point is "simple_overlay_update(SECT), which looks up SECT in
+ the cached table and re-reads only the entry for that section from
+ the target (whenever possible).
+ */
+
+/* Cached, dynamically allocated copies of the target data structures: */
+static unsigned (*cache_ovly_table)[4] = 0;
+#if 0
+static unsigned (*cache_ovly_region_table)[3] = 0;
+#endif
+static unsigned cache_novlys = 0;
+#if 0
+static unsigned cache_novly_regions = 0;
+#endif
+static CORE_ADDR cache_ovly_table_base = 0;
+#if 0
+static CORE_ADDR cache_ovly_region_table_base = 0;
+#endif
+enum ovly_index { VMA, SIZE, LMA, MAPPED};
+#define TARGET_LONG_BYTES (TARGET_LONG_BIT / TARGET_CHAR_BIT)
+
+/* Throw away the cached copy of _ovly_table */
+static void
+simple_free_overlay_table ()
+{
+ if (cache_ovly_table)
+ free(cache_ovly_table);
+ cache_novlys = 0;
+ cache_ovly_table = NULL;
+ cache_ovly_table_base = 0;
+}
+
+#if 0
+/* Throw away the cached copy of _ovly_region_table */
+static void
+simple_free_overlay_region_table ()
+{
+ if (cache_ovly_region_table)
+ free(cache_ovly_region_table);
+ cache_novly_regions = 0;
+ cache_ovly_region_table = NULL;
+ cache_ovly_region_table_base = 0;
+}
+#endif
+
+/* Read an array of ints from the target into a local buffer.
+ Convert to host order. int LEN is number of ints */
+static void
+read_target_long_array (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ unsigned int *myaddr;
+ int len;
+{
+ char *buf = alloca (len * TARGET_LONG_BYTES);
+ int i;
+
+ read_memory (memaddr, buf, len * TARGET_LONG_BYTES);
+ for (i = 0; i < len; i++)
+ myaddr[i] = extract_unsigned_integer (TARGET_LONG_BYTES * i + buf,
+ TARGET_LONG_BYTES);
+}
+
+/* Find and grab a copy of the target _ovly_table
+ (and _novlys, which is needed for the table's size) */
+static int
+simple_read_overlay_table ()
+{
+ struct minimal_symbol *msym;
+
+ simple_free_overlay_table ();
+ msym = lookup_minimal_symbol ("_novlys", 0, 0);
+ if (msym != NULL)
+ cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
+ else
+ return 0; /* failure */
+ cache_ovly_table = (void *) xmalloc (cache_novlys * sizeof(*cache_ovly_table));
+ if (cache_ovly_table != NULL)
+ {
+ msym = lookup_minimal_symbol ("_ovly_table", 0, 0);
+ if (msym != NULL)
+ {
+ cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (msym);
+ read_target_long_array (cache_ovly_table_base,
+ (int *) cache_ovly_table,
+ cache_novlys * 4);
+ }
+ else
+ return 0; /* failure */
+ }
+ else
+ return 0; /* failure */
+ return 1; /* SUCCESS */
+}
+
+#if 0
+/* Find and grab a copy of the target _ovly_region_table
+ (and _novly_regions, which is needed for the table's size) */
+static int
+simple_read_overlay_region_table ()
+{
+ struct minimal_symbol *msym;
+
+ simple_free_overlay_region_table ();
+ msym = lookup_minimal_symbol ("_novly_regions", 0, 0);
+ if (msym != NULL)
+ cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
+ else
+ return 0; /* failure */
+ cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12);
+ if (cache_ovly_region_table != NULL)
+ {
+ msym = lookup_minimal_symbol ("_ovly_region_table", 0, 0);
+ if (msym != NULL)
+ {
+ cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym);
+ read_target_long_array (cache_ovly_region_table_base,
+ (int *) cache_ovly_region_table,
+ cache_novly_regions * 3);
+ }
+ else
+ return 0; /* failure */
+ }
+ else
+ return 0; /* failure */
+ return 1; /* SUCCESS */
+}
+#endif
+
+/* Function: simple_overlay_update_1
+ A helper function for simple_overlay_update. Assuming a cached copy
+ of _ovly_table exists, look through it to find an entry whose vma,
+ lma and size match those of OSECT. Re-read the entry and make sure
+ it still matches OSECT (else the table may no longer be valid).
+ Set OSECT's mapped state to match the entry. Return: 1 for
+ success, 0 for failure. */
+
+static int
+simple_overlay_update_1 (osect)
+ struct obj_section *osect;
+{
+ int i, size;
+
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
+ cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
+ cache_ovly_table[i][SIZE] == size */)
+ {
+ read_target_long_array (cache_ovly_table_base + i * TARGET_LONG_BYTES,
+ (int *) cache_ovly_table[i], 4);
+ if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
+ cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
+ cache_ovly_table[i][SIZE] == size */)
+ {
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ return 1;
+ }
+ else /* Warning! Warning! Target's ovly table has changed! */
+ return 0;
+ }
+ return 0;
+}
+
+/* Function: simple_overlay_update
+ If OSECT is NULL, then update all sections' mapped state
+ (after re-reading the entire target _ovly_table).
+ If OSECT is non-NULL, then try to find a matching entry in the
+ cached ovly_table and update only OSECT's mapped state.
+ If a cached entry can't be found or the cache isn't valid, then
+ re-read the entire cache, and go ahead and update all sections. */
+
+static void
+simple_overlay_update (osect)
+ struct obj_section *osect;
+{
+ struct objfile *objfile;
+
+ /* Were we given an osect to look up? NULL means do all of them. */
+ if (osect)
+ /* Have we got a cached copy of the target's overlay table? */
+ if (cache_ovly_table != NULL)
+ /* Does its cached location match what's currently in the symtab? */
+ if (cache_ovly_table_base ==
+ SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", 0, 0)))
+ /* Then go ahead and try to look up this single section in the cache */
+ if (simple_overlay_update_1 (osect))
+ /* Found it! We're done. */
+ return;
+
+ /* Cached table no good: need to read the entire table anew.
+ Or else we want all the sections, in which case it's actually
+ more efficient to read the whole table in one block anyway. */
+
+ if (simple_read_overlay_table () == 0) /* read failed? No table? */
+ {
+ warning ("Failed to read the target overlay mapping table.");
+ return;
+ }
+ /* Now may as well update all sections, even if only one was requested. */
+ ALL_OBJSECTIONS (objfile, osect)
+ if (section_is_overlay (osect->the_bfd_section))
+ {
+ int i, size;
+
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
+ cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
+ cache_ovly_table[i][SIZE] == size */)
+ { /* obj_section matches i'th entry in ovly_table */
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ break; /* finished with inner for loop: break out */
+ }
+ }
+}
+
+
void
_initialize_symfile ()
{
@@ -1771,4 +2982,40 @@ for access from GDB.", &cmdlist);
&setlist),
&showlist);
+ add_prefix_cmd ("overlay", class_support, overlay_command,
+ "Commands for debugging overlays.", &overlaylist,
+ "overlay ", 0, &cmdlist);
+
+ add_com_alias ("ovly", "overlay", class_alias, 1);
+ add_com_alias ("ov", "overlay", class_alias, 1);
+
+ add_cmd ("map-overlay", class_support, map_overlay_command,
+ "Assert that an overlay section is mapped.", &overlaylist);
+
+ add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
+ "Assert that an overlay section is unmapped.", &overlaylist);
+
+ add_cmd ("list-overlays", class_support, list_overlays_command,
+ "List mappings of overlay sections.", &overlaylist);
+
+ add_cmd ("manual", class_support, overlay_manual_command,
+ "Enable overlay debugging.", &overlaylist);
+ add_cmd ("off", class_support, overlay_off_command,
+ "Disable overlay debugging.", &overlaylist);
+ add_cmd ("auto", class_support, overlay_auto_command,
+ "Enable automatic overlay debugging.", &overlaylist);
+ add_cmd ("load-target", class_support, overlay_load_command,
+ "Read the overlay mapping state from the target.", &overlaylist);
+
+ /* Filename extension to source language lookup table: */
+ init_filename_language_table ();
+ c = add_set_cmd ("extension-language", class_files, var_string_noescape,
+ (char *) &ext_args,
+ "Set mapping between filename extension and source language.\n\
+Usage: set extension-language .foo bar",
+ &setlist);
+ c->function.cfunc = set_ext_lang_command;
+
+ add_info ("extensions", info_ext_lang_command,
+ "All filename extensions associated with a source language.");
}
diff --git a/contrib/gdb/gdb/symfile.h b/contrib/gdb/gdb/symfile.h
index d173f4e..0363e1e 100644
--- a/contrib/gdb/gdb/symfile.h
+++ b/contrib/gdb/gdb/symfile.h
@@ -32,9 +32,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
to the single saved instance. */
struct psymbol_allocation_list {
- struct partial_symbol **list; /* Pointer to first partial symbol pointer*/
- struct partial_symbol **next; /* Pointer to next avail storage for pointer */
- int size; /* Number of symbols */
+
+ /* Pointer to beginning of dynamically allocated array of pointers to
+ partial symbols. The array is dynamically expanded as necessary to
+ accommodate more pointers. */
+
+ struct partial_symbol **list;
+
+ /* Pointer to next available slot in which to store a pointer to a partial
+ symbol. */
+
+ struct partial_symbol **next;
+
+ /* Number of allocated pointer slots in current dynamic array (not the
+ number of bytes of storage). The "next" pointer will always point
+ somewhere between list[0] and list[size], and when at list[size] the
+ array will be expanded on the next attempt to store a pointer. */
+
+ int size;
};
/* Structure to keep track of symbol reading functions for various
@@ -94,6 +109,13 @@ struct sym_fns {
};
+/* The default version of sym_fns.sym_offsets for readers that don't
+ do anything special. */
+
+extern struct section_offsets *
+default_symfile_offsets PARAMS ((struct objfile *objfile, CORE_ADDR addr));
+
+
extern void
extend_psymbol_list PARAMS ((struct psymbol_allocation_list *,
struct objfile *));
@@ -107,6 +129,14 @@ add_psymbol_to_list PARAMS ((char *, int, namespace_enum, enum address_class,
struct psymbol_allocation_list *, long, CORE_ADDR,
enum language, struct objfile *));
+extern void
+add_psymbol_with_dem_name_to_list PARAMS ((char *, int, char *, int, namespace_enum,
+ enum address_class,
+ struct psymbol_allocation_list *,
+ long, CORE_ADDR,
+ enum language, struct objfile *));
+
+
extern void init_psymbol_list PARAMS ((struct objfile *, int));
extern void
@@ -163,26 +193,90 @@ obconcat PARAMS ((struct obstack *obstackp, const char *, const char *,
/* Variables */
-/* whether to auto load solibs at startup time: 0/1. */
+/* whether to auto load solibs at startup time: 0/1.
+
+ On all platforms, 0 means "don't auto load".
+
+ On HP-UX, > 0 means a threshhold, in megabytes, of symbol table which will
+ be auto loaded. When the cumulative size of solib symbol table exceeds
+ this threshhold, solibs' symbol tables will not be loaded.
+
+ On other platforms, > 0 means, "always auto load".
+ */
extern int auto_solib_add;
/* From symfile.c */
+extern CORE_ADDR
+entry_point_address PARAMS ((void));
+
extern struct partial_symtab *
allocate_psymtab PARAMS ((char *, struct objfile *));
+extern void
+discard_psymtab PARAMS ((struct partial_symtab *));
+
extern void find_lowest_section PARAMS ((bfd *, asection *, PTR));
+extern bfd * symfile_bfd_open PARAMS ((char *));
+
/* Remote targets may wish to use this as their load function. */
extern void generic_load PARAMS ((char *name, int from_tty));
+/* Utility functions for overlay sections: */
+extern int overlay_debugging;
+extern int overlay_cache_invalid;
+
+/* return the "mapped" overlay section containing the PC */
+extern asection *
+find_pc_mapped_section PARAMS ((CORE_ADDR));
+
+/* return any overlay section containing the PC (even in its LMA region) */
+extern asection *
+find_pc_overlay PARAMS ((CORE_ADDR));
+
+/* return true if the section is an overlay */
+extern int
+section_is_overlay PARAMS ((asection *));
+
+/* return true if the overlay section is currently "mapped" */
+extern int
+section_is_mapped PARAMS ((asection *));
+
+/* return true if pc belongs to section's VMA */
+extern CORE_ADDR
+pc_in_mapped_range PARAMS ((CORE_ADDR, asection *));
+
+/* return true if pc belongs to section's LMA */
+extern CORE_ADDR
+pc_in_unmapped_range PARAMS ((CORE_ADDR, asection *));
+
+/* map an address from a section's LMA to its VMA */
+extern CORE_ADDR
+overlay_mapped_address PARAMS ((CORE_ADDR, asection *));
+
+/* map an address from a section's VMA to its LMA */
+extern CORE_ADDR
+overlay_unmapped_address PARAMS ((CORE_ADDR, asection *));
+
+/* convert an address in an overlay section (force into VMA range) */
+extern CORE_ADDR
+symbol_overlayed_address PARAMS ((CORE_ADDR, asection *));
+
/* From dwarfread.c */
extern void
dwarf_build_psymtabs PARAMS ((struct objfile *, struct section_offsets *, int,
file_ptr, unsigned int, file_ptr, unsigned int));
+/* From dwarf2read.c */
+
+extern int dwarf2_has_info PARAMS ((bfd *abfd));
+
+extern void dwarf2_build_psymtabs PARAMS ((struct objfile *,
+ struct section_offsets *,
+ int));
/* From mdebugread.c */
/* Hack to force structures to exist before use in parameter list. */
@@ -203,9 +297,4 @@ elfmdebug_build_psymtabs PARAMS ((struct objfile *,
asection *,
struct section_offsets *));
-/* From demangle.c */
-
-extern void
-set_demangling_style PARAMS ((char *));
-
#endif /* !defined(SYMFILE_H) */
diff --git a/contrib/gdb/gdb/symmisc.c b/contrib/gdb/gdb/symmisc.c
index db58cdd..97d2f6e 100644
--- a/contrib/gdb/gdb/symmisc.c
+++ b/contrib/gdb/gdb/symmisc.c
@@ -1,5 +1,5 @@
/* Do various things to symbol tables (other than lookup), for GDB.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -48,23 +48,24 @@ FILE *std_err;
/* Prototypes for local functions */
-static void
-dump_symtab PARAMS ((struct objfile *, struct symtab *, GDB_FILE *));
+static void dump_symtab PARAMS ((struct objfile *, struct symtab *,
+ GDB_FILE *));
-static void
-dump_psymtab PARAMS ((struct objfile *, struct partial_symtab *, GDB_FILE *));
+static void dump_psymtab PARAMS ((struct objfile *, struct partial_symtab *,
+ GDB_FILE *));
-static void
-dump_msymbols PARAMS ((struct objfile *, GDB_FILE *));
+static void dump_msymbols PARAMS ((struct objfile *, GDB_FILE *));
-static void
-dump_objfile PARAMS ((struct objfile *));
+static void dump_objfile PARAMS ((struct objfile *));
-static int
-block_depth PARAMS ((struct block *));
+static int block_depth PARAMS ((struct block *));
-static void
-print_partial_symbols PARAMS ((struct partial_symbol **, int, char *, GDB_FILE *));
+static void print_partial_symbols PARAMS ((struct partial_symbol **, int,
+ char *, GDB_FILE *));
+
+static void free_symtab_block PARAMS ((struct objfile *, struct block *));
+
+void _initialize_symmisc PARAMS ((void));
struct print_symbol_args {
struct symbol *symbol;
@@ -72,7 +73,7 @@ struct print_symbol_args {
GDB_FILE *outfile;
};
-static int print_symbol PARAMS ((char *));
+static int print_symbol PARAMS ((PTR));
static void
free_symtab_block PARAMS ((struct objfile *, struct block *));
@@ -148,6 +149,8 @@ free_symtab (s)
mfree (s -> objfile -> md, (PTR) s -> line_charpos);
if (s -> fullname != NULL)
mfree (s -> objfile -> md, s -> fullname);
+ if (s -> debugformat != NULL)
+ mfree (s -> objfile -> md, s -> debugformat);
mfree (s -> objfile -> md, (PTR) s);
}
@@ -180,16 +183,16 @@ print_objfile_statistics ()
printf_filtered (" Number of \"stab\" symbols read: %d\n",
OBJSTAT (objfile, n_stabs));
if (OBJSTAT (objfile, n_minsyms) > 0)
- printf_filtered (" Number of \"minimal symbols read: %d\n",
+ printf_filtered (" Number of \"minimal\" symbols read: %d\n",
OBJSTAT (objfile, n_minsyms));
if (OBJSTAT (objfile, n_psyms) > 0)
- printf_filtered (" Number of \"partial symbols read: %d\n",
+ printf_filtered (" Number of \"partial\" symbols read: %d\n",
OBJSTAT (objfile, n_psyms));
if (OBJSTAT (objfile, n_syms) > 0)
- printf_filtered (" Number of \"full symbols read: %d\n",
+ printf_filtered (" Number of \"full\" symbols read: %d\n",
OBJSTAT (objfile, n_syms));
if (OBJSTAT (objfile, n_types) > 0)
- printf_filtered (" Number of \"types defined: %d\n",
+ printf_filtered (" Number of \"types\" defined: %d\n",
OBJSTAT (objfile, n_types));
if (OBJSTAT (objfile, sz_strtab) > 0)
printf_filtered (" Space used by a.out string tables: %d\n",
@@ -314,8 +317,13 @@ dump_msymbols (objfile, outfile)
ms_type = '?';
break;
}
- fprintf_filtered (outfile, "[%2d] %c %#10lx %s", index, ms_type,
- SYMBOL_VALUE_ADDRESS (msymbol), SYMBOL_NAME (msymbol));
+ fprintf_filtered (outfile, "[%2d] %c ", index, ms_type);
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (msymbol), 1, outfile);
+ fprintf_filtered (outfile, " %s", SYMBOL_NAME (msymbol));
+ if (SYMBOL_BFD_SECTION (msymbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name (objfile->obfd,
+ SYMBOL_BFD_SECTION (msymbol)));
if (SYMBOL_DEMANGLED_NAME (msymbol) != NULL)
{
fprintf_filtered (outfile, " %s", SYMBOL_DEMANGLED_NAME (msymbol));
@@ -417,10 +425,13 @@ dump_symtab (objfile, symtab, outfile)
int depth;
fprintf_filtered (outfile, "\nSymtab for file %s\n", symtab->filename);
+ if (symtab->dirname)
+ fprintf_filtered (outfile, "Compilation directory is %s\n",
+ symtab->dirname);
fprintf_filtered (outfile, "Read from object file %s (", objfile->name);
gdb_print_address (objfile, outfile);
fprintf_filtered (outfile, ")\n");
- fprintf_filtered (outfile, "Language: %s\n", language_str (symtab -> language));
+ fprintf_filtered (outfile, "Language: %s\n", language_str (symtab->language));
/* First print the line table. */
l = LINETABLE (symtab);
@@ -435,53 +446,59 @@ dump_symtab (objfile, symtab, outfile)
fprintf_filtered (outfile, "\n");
}
}
- /* Now print the block info. */
- fprintf_filtered (outfile, "\nBlockvector:\n\n");
- bv = BLOCKVECTOR (symtab);
- len = BLOCKVECTOR_NBLOCKS (bv);
- for (i = 0; i < len; i++)
+ /* Now print the block info, but only for primary symtabs since we will
+ print lots of duplicate info otherwise. */
+ if (symtab -> primary)
{
- b = BLOCKVECTOR_BLOCK (bv, i);
- depth = block_depth (b) * 2;
- print_spaces (depth, outfile);
- fprintf_filtered (outfile, "block #%03d (object ", i);
- gdb_print_address (b, outfile);
- fprintf_filtered (outfile, ") ");
- fprintf_filtered (outfile, "[");
- print_address_numeric (BLOCK_START (b), 1, outfile);
- fprintf_filtered (outfile, "..");
- print_address_numeric (BLOCK_END (b), 1, outfile);
- fprintf_filtered (outfile, "]");
- if (BLOCK_SUPERBLOCK (b))
- {
- fprintf_filtered (outfile, " (under ");
- gdb_print_address (BLOCK_SUPERBLOCK (b), outfile);
- fprintf_filtered (outfile, ")");
- }
- if (BLOCK_FUNCTION (b))
+ fprintf_filtered (outfile, "\nBlockvector:\n\n");
+ bv = BLOCKVECTOR (symtab);
+ len = BLOCKVECTOR_NBLOCKS (bv);
+ for (i = 0; i < len; i++)
{
- fprintf_filtered (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
- if (SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)) != NULL)
+ b = BLOCKVECTOR_BLOCK (bv, i);
+ depth = block_depth (b) * 2;
+ print_spaces (depth, outfile);
+ fprintf_filtered (outfile, "block #%03d, object at ", i);
+ gdb_print_address (b, outfile);
+ if (BLOCK_SUPERBLOCK (b))
+ {
+ fprintf_filtered (outfile, " under ");
+ gdb_print_address (BLOCK_SUPERBLOCK (b), outfile);
+ }
+ blen = BLOCK_NSYMS (b);
+ fprintf_filtered (outfile, ", %d syms in ", blen);
+ print_address_numeric (BLOCK_START (b), 1, outfile);
+ fprintf_filtered (outfile, "..");
+ print_address_numeric (BLOCK_END (b), 1, outfile);
+ if (BLOCK_FUNCTION (b))
{
- fprintf_filtered (outfile, " %s",
- SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)));
+ fprintf_filtered (outfile, ", function %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
+ if (SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)) != NULL)
+ {
+ fprintf_filtered (outfile, ", %s",
+ SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)));
+ }
+ }
+ if (BLOCK_GCC_COMPILED(b))
+ fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED(b));
+ fprintf_filtered (outfile, "\n");
+ /* Now print each symbol in this block */
+ for (j = 0; j < blen; j++)
+ {
+ struct print_symbol_args s;
+ s.symbol = BLOCK_SYM (b, j);
+ s.depth = depth + 1;
+ s.outfile = outfile;
+ catch_errors (print_symbol, &s, "Error printing symbol:\n",
+ RETURN_MASK_ALL);
}
}
- if (BLOCK_GCC_COMPILED(b))
- fprintf_filtered (outfile, " gcc%d compiled", BLOCK_GCC_COMPILED(b));
fprintf_filtered (outfile, "\n");
- blen = BLOCK_NSYMS (b);
- for (j = 0; j < blen; j++)
- {
- struct print_symbol_args s;
- s.symbol = BLOCK_SYM (b, j);
- s.depth = depth + 1;
- s.outfile = outfile;
- catch_errors (print_symbol, &s, "Error printing symbol:\n",
- RETURN_MASK_ALL);
- }
}
- fprintf_filtered (outfile, "\n");
+ else
+ {
+ fprintf_filtered (outfile, "\nBlockvector same as previous symtab\n\n");
+ }
}
void
@@ -508,7 +525,7 @@ Arguments missing: an output file name and an optional symbol file name");
{
nomem (0);
}
- cleanups = make_cleanup (freeargv, (char *) argv);
+ cleanups = make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
if (argv[0] != NULL)
{
@@ -526,7 +543,7 @@ Arguments missing: an output file name and an optional symbol file name");
outfile = gdb_fopen (filename, FOPEN_WT);
if (outfile == 0)
perror_with_name (filename);
- make_cleanup (fclose, (char *) outfile);
+ make_cleanup ((make_cleanup_func) gdb_fclose, (char *) &outfile);
immediate_quit++;
ALL_SYMTABS (objfile, s)
@@ -543,7 +560,7 @@ Arguments missing: an output file name and an optional symbol file name");
static int
print_symbol (args)
- char *args;
+ PTR args;
{
struct symbol *symbol = ((struct print_symbol_args *)args)->symbol;
int depth = ((struct print_symbol_args *)args)->depth;
@@ -554,7 +571,12 @@ print_symbol (args)
{
fprintf_filtered (outfile, "label %s at ", SYMBOL_SOURCE_NAME (symbol));
print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
- fprintf_filtered (outfile, "\n");
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s\n",
+ bfd_section_name (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
+ else
+ fprintf_filtered (outfile, "\n");
return 1;
}
if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
@@ -594,7 +616,7 @@ print_symbol (args)
switch (SYMBOL_CLASS (symbol))
{
case LOC_CONST:
- fprintf_filtered (outfile, "const %ld (0x%lx),",
+ fprintf_filtered (outfile, "const %ld (0x%lx)",
SYMBOL_VALUE (symbol),
SYMBOL_VALUE (symbol));
break;
@@ -608,44 +630,53 @@ print_symbol (args)
for (i = 0; i < TYPE_LENGTH (type); i++)
fprintf_filtered (outfile, " %02x",
(unsigned)SYMBOL_VALUE_BYTES (symbol) [i]);
- fprintf_filtered (outfile, ",");
}
break;
case LOC_STATIC:
fprintf_filtered (outfile, "static at ");
print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1,outfile);
- fprintf_filtered (outfile, ",");
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name
+ (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
+ break;
+
+ case LOC_INDIRECT:
+ fprintf_filtered (outfile, "extern global at *(");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1,outfile);
+ fprintf_filtered (outfile, "),");
break;
case LOC_REGISTER:
- fprintf_filtered (outfile, "register %ld,", SYMBOL_VALUE (symbol));
+ fprintf_filtered (outfile, "register %ld", SYMBOL_VALUE (symbol));
break;
case LOC_ARG:
- fprintf_filtered (outfile, "arg at offset 0x%lx,",
+ fprintf_filtered (outfile, "arg at offset 0x%lx",
SYMBOL_VALUE (symbol));
break;
case LOC_LOCAL_ARG:
- fprintf_filtered (outfile, "arg at offset 0x%lx from fp,",
+ fprintf_filtered (outfile, "arg at offset 0x%lx from fp",
SYMBOL_VALUE (symbol));
break;
case LOC_REF_ARG:
- fprintf_filtered (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol));
+ fprintf_filtered (outfile, "reference arg at 0x%lx", SYMBOL_VALUE (symbol));
break;
case LOC_REGPARM:
- fprintf_filtered (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol));
+ fprintf_filtered (outfile, "parameter register %ld", SYMBOL_VALUE (symbol));
break;
case LOC_REGPARM_ADDR:
- fprintf_filtered (outfile, "address parameter register %ld,", SYMBOL_VALUE (symbol));
+ fprintf_filtered (outfile, "address parameter register %ld", SYMBOL_VALUE (symbol));
break;
case LOC_LOCAL:
- fprintf_filtered (outfile, "local at offset 0x%lx,",
+ fprintf_filtered (outfile, "local at offset 0x%lx",
SYMBOL_VALUE (symbol));
break;
@@ -655,7 +686,7 @@ print_symbol (args)
break;
case LOC_BASEREG_ARG:
- fprintf_filtered (outfile, "arg at 0x%lx from register %d,",
+ fprintf_filtered (outfile, "arg at 0x%lx from register %d",
SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
break;
@@ -665,16 +696,29 @@ print_symbol (args)
case LOC_LABEL:
fprintf_filtered (outfile, "label at ");
print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name
+ (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
break;
case LOC_BLOCK:
- fprintf_filtered (outfile, "block (object ");
+ fprintf_filtered (outfile, "block object ");
gdb_print_address (SYMBOL_BLOCK_VALUE (symbol), outfile);
- fprintf_filtered (outfile, ") starting at ");
+ fprintf_filtered (outfile, ", ");
print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)),
1,
outfile);
- fprintf_filtered (outfile, ",");
+ fprintf_filtered (outfile, "..");
+ print_address_numeric (BLOCK_END (SYMBOL_BLOCK_VALUE (symbol)),
+ 1,
+ outfile);
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name
+ (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
break;
case LOC_UNRESOLVED:
@@ -701,7 +745,7 @@ maintenance_print_psymbols (args, from_tty)
int from_tty;
{
char **argv;
- GDB_FILE *outfile;
+ GDB_FILE *outfile;
struct cleanup *cleanups;
char *symname = NULL;
char *filename = DEV_TTY;
@@ -718,7 +762,7 @@ maintenance_print_psymbols (args, from_tty)
{
nomem (0);
}
- cleanups = make_cleanup (freeargv, (char *) argv);
+ cleanups = make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
if (argv[0] != NULL)
{
@@ -736,7 +780,7 @@ maintenance_print_psymbols (args, from_tty)
outfile = gdb_fopen (filename, FOPEN_WT);
if (outfile == 0)
perror_with_name (filename);
- make_cleanup (fclose, outfile);
+ make_cleanup ((make_cleanup_func) gdb_fclose, &outfile);
immediate_quit++;
ALL_PSYMTABS (objfile, ps)
@@ -791,6 +835,9 @@ print_partial_symbols (p, count, what, outfile)
case LOC_STATIC:
fputs_filtered ("static", outfile);
break;
+ case LOC_INDIRECT:
+ fputs_filtered ("extern global", outfile);
+ break;
case LOC_REGISTER:
fputs_filtered ("register", outfile);
break;
@@ -835,10 +882,8 @@ print_partial_symbols (p, count, what, outfile)
break;
}
fputs_filtered (", ", outfile);
- /* FIXME-32x64: Need to use SYMBOL_VALUE_ADDRESS, etc.; this
- could be 32 bits when some of the other fields in the union
- are 64. */
- fprintf_filtered (outfile, "0x%lx\n", SYMBOL_VALUE (*p));
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (*p), 1, outfile);
+ fprintf_filtered (outfile, "\n");
p++;
}
}
@@ -865,7 +910,7 @@ maintenance_print_msymbols (args, from_tty)
{
nomem (0);
}
- cleanups = make_cleanup (freeargv, argv);
+ cleanups = make_cleanup ((make_cleanup_func) freeargv, argv);
if (argv[0] != NULL)
{
@@ -883,7 +928,7 @@ maintenance_print_msymbols (args, from_tty)
outfile = gdb_fopen (filename, FOPEN_WT);
if (outfile == 0)
perror_with_name (filename);
- make_cleanup (fclose, outfile);
+ make_cleanup ((make_cleanup_func) gdb_fclose, &outfile);
immediate_quit++;
ALL_OBJFILES (objfile)
@@ -970,9 +1015,9 @@ maintenance_check_symtabs (ignore, from_tty)
printf_filtered ("Psymtab ");
puts_filtered (ps->filename);
printf_filtered (" covers bad range ");
- print_address_numeric (ps->textlow, 1, stdout);
+ print_address_numeric (ps->textlow, 1, gdb_stdout);
printf_filtered (" - ");
- print_address_numeric (ps->texthigh, 1, stdout);
+ print_address_numeric (ps->texthigh, 1, gdb_stdout);
printf_filtered ("\n");
continue;
}
@@ -983,13 +1028,13 @@ maintenance_check_symtabs (ignore, from_tty)
printf_filtered ("Psymtab ");
puts_filtered (ps->filename);
printf_filtered (" covers ");
- print_address_numeric (ps->textlow, 1, stdout);
+ print_address_numeric (ps->textlow, 1, gdb_stdout);
printf_filtered (" - ");
- print_address_numeric (ps->texthigh, 1, stdout);
+ print_address_numeric (ps->texthigh, 1, gdb_stdout);
printf_filtered (" but symtab covers only ");
- print_address_numeric (BLOCK_START (b), 1, stdout);
+ print_address_numeric (BLOCK_START (b), 1, gdb_stdout);
printf_filtered (" - ");
- print_address_numeric (BLOCK_END (b), 1, stdout);
+ print_address_numeric (BLOCK_END (b), 1, gdb_stdout);
printf_filtered ("\n");
}
}
diff --git a/contrib/gdb/gdb/symtab.c b/contrib/gdb/gdb/symtab.c
index 41605bc..fb3c8f7 100644
--- a/contrib/gdb/gdb/symtab.c
+++ b/contrib/gdb/gdb/symtab.c
@@ -1,5 +1,5 @@
/* Symbol table lookup for the GNU debugger, GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "expression.h"
#include "language.h"
#include "demangle.h"
+#include "inferior.h"
#include "obstack.h"
@@ -42,52 +43,72 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdb_stat.h"
#include <ctype.h>
-/* Prototypes for local functions */
+/* Prototype for one function in parser-defs.h,
+ instead of including that entire file. */
-extern int
-find_methods PARAMS ((struct type *, char *, struct symbol **));
+extern char * find_template_name_end PARAMS ((char *));
-static void
-completion_list_add_name PARAMS ((char *, char *, int, char *, char *));
+/* Prototypes for local functions */
-static void
-build_canonical_line_spec PARAMS ((struct symtab_and_line *, char *, char ***));
+static int find_methods PARAMS ((struct type *, char *, struct symbol **));
-static struct symtabs_and_lines
-decode_line_2 PARAMS ((struct symbol *[], int, int, char ***));
+static void completion_list_add_name PARAMS ((char *, char *, int, char *,
+ char *));
-static void
-rbreak_command PARAMS ((char *, int));
+static void build_canonical_line_spec PARAMS ((struct symtab_and_line *,
+ char *, char ***));
-static void
-types_info PARAMS ((char *, int));
+static struct symtabs_and_lines decode_line_2 PARAMS ((struct symbol *[],
+ int, int, char ***));
-static void
-functions_info PARAMS ((char *, int));
+static void rbreak_command PARAMS ((char *, int));
-static void
-variables_info PARAMS ((char *, int));
+static void types_info PARAMS ((char *, int));
-static void
-sources_info PARAMS ((char *, int));
+static void functions_info PARAMS ((char *, int));
-static void
-list_symbols PARAMS ((char *, int, int, int));
+static void variables_info PARAMS ((char *, int));
-static void
-output_source_filename PARAMS ((char *, int *));
+static void sources_info PARAMS ((char *, int));
+
+static void output_source_filename PARAMS ((char *, int *));
-static char *
-operator_chars PARAMS ((char *, char **));
+char *operator_chars PARAMS ((char *, char **));
static int find_line_common PARAMS ((struct linetable *, int, int *));
-static struct partial_symbol *
-lookup_partial_symbol PARAMS ((struct partial_symtab *, const char *,
- int, namespace_enum));
+static struct partial_symbol *lookup_partial_symbol PARAMS
+ ((struct partial_symtab *, const char *,
+ int, namespace_enum));
-static struct symtab *
-lookup_symtab_1 PARAMS ((char *));
+static struct partial_symbol *fixup_psymbol_section PARAMS ((struct
+ partial_symbol *, struct objfile *));
+
+static struct symtab *lookup_symtab_1 PARAMS ((char *));
+
+static void cplusplus_hint PARAMS ((char *));
+
+static struct symbol *find_active_alias PARAMS ((struct symbol *sym,
+ CORE_ADDR addr));
+
+/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
+/* Signals the presence of objects compiled by HP compilers */
+int hp_som_som_object_present = 0;
+
+static void fixup_section PARAMS ((struct general_symbol_info *,
+ struct objfile *));
+
+static int file_matches PARAMS ((char *, char **, int));
+
+static void print_symbol_info PARAMS ((namespace_enum,
+ struct symtab *, struct symbol *,
+ int, char *));
+
+static void print_msymbol_info PARAMS ((struct minimal_symbol *));
+
+static void symtab_symbol_info PARAMS ((char *, namespace_enum, int));
+
+void _initialize_symtab PARAMS ((void));
/* */
@@ -106,7 +127,7 @@ char no_symtab_msg[] = "No symbol table is loaded. Use the \"file\" command.";
using the new command completion feature on single quoted demangled C++
symbols. Remove when loose ends are cleaned up. FIXME -fnf */
-void
+static void
cplusplus_hint (name)
char *name;
{
@@ -253,20 +274,22 @@ char *name;
return (NULL);
}
-/* Demangle a GDB method stub type.
- Note that this function is g++ specific. */
+/* Mangle a GDB method stub type. This actually reassembles the pieces of the
+ full method name, which consist of the class name (from T), the unadorned
+ method name from METHOD_ID, and the signature for the specific overload,
+ specified by SIGNATURE_ID. Note that this function is g++ specific. */
char *
-gdb_mangle_name (type, i, j)
+gdb_mangle_name (type, method_id, signature_id)
struct type *type;
- int i, j;
+ int method_id, signature_id;
{
int mangled_name_len;
char *mangled_name;
- struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
- struct fn_field *method = &f[j];
- char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
- char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
+ struct fn_field *method = &f[signature_id];
+ char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
char *newname = type_name_no_tag (type);
/* Does the form of physname indicate that it is the full mangled name
@@ -302,12 +325,11 @@ gdb_mangle_name (type, i, j)
if (len == 0)
{
sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
- if (strcmp(buf, "__") == 0)
- buf[0] = '\0';
}
- else if (newname != NULL && strchr (newname, '<') != NULL)
+ else if (physname[0] == 't' || physname[0] == 'Q')
{
- /* Template methods are fully mangled. */
+ /* The physname for template and qualified methods already includes
+ the class name. */
sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
newname = NULL;
len = 0;
@@ -355,18 +377,24 @@ gdb_mangle_name (type, i, j)
}
-/* Find which partial symtab on contains PC. Return 0 if none. */
+
+/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
struct partial_symtab *
-find_pc_psymtab (pc)
- register CORE_ADDR pc;
+find_pc_sect_psymtab (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register struct partial_symtab *pst;
register struct objfile *objfile;
ALL_PSYMTABS (objfile, pst)
{
+#if defined(HPUXHPPA)
+ if (pc >= pst->textlow && pc <= pst->texthigh)
+#else
if (pc >= pst->textlow && pc < pst->texthigh)
+#endif
{
struct minimal_symbol *msymbol;
struct partial_symtab *tpst;
@@ -375,20 +403,25 @@ find_pc_psymtab (pc)
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
function containing the PC. */
- if (!(objfile->flags & OBJF_REORDERED))
+ if (!(objfile->flags & OBJF_REORDERED) &&
+ section == 0) /* can't validate section this way */
return (pst);
- msymbol = lookup_minimal_symbol_by_pc (pc);
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
if (msymbol == NULL)
return (pst);
for (tpst = pst; tpst != NULL; tpst = tpst->next)
{
+#if defined(HPUXHPPA)
+ if (pc >= tpst->textlow && pc <= tpst->texthigh)
+#else
if (pc >= tpst->textlow && pc < tpst->texthigh)
+#endif
{
struct partial_symbol *p;
- p = find_pc_psymbol (tpst, pc);
+ p = find_pc_sect_psymbol (tpst, pc, section);
if (p != NULL
&& SYMBOL_VALUE_ADDRESS(p)
== SYMBOL_VALUE_ADDRESS (msymbol))
@@ -401,22 +434,35 @@ find_pc_psymtab (pc)
return (NULL);
}
-/* Find which partial symbol within a psymtab contains PC. Return 0
- if none. Check all psymtabs if PSYMTAB is 0. */
+/* Find which partial symtab contains PC. Return 0 if none.
+ Backward compatibility, no section */
+
+struct partial_symtab *
+find_pc_psymtab (pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_psymtab (pc, find_pc_mapped_section (pc));
+}
+
+/* Find which partial symbol within a psymtab matches PC and SECTION.
+ Return 0 if none. Check all psymtabs if PSYMTAB is 0. */
+
struct partial_symbol *
-find_pc_psymbol (psymtab, pc)
+find_pc_sect_psymbol (psymtab, pc, section)
struct partial_symtab *psymtab;
CORE_ADDR pc;
+ asection *section;
{
struct partial_symbol *best = NULL, *p, **pp;
CORE_ADDR best_pc;
if (!psymtab)
- psymtab = find_pc_psymtab (pc);
+ psymtab = find_pc_sect_psymtab (pc, section);
if (!psymtab)
return 0;
- best_pc = psymtab->textlow - 1;
+ /* Cope with programs that start at address 0 */
+ best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
/* Search the global symbols as well as the static symbols, so that
find_pc_partial_function doesn't use a minimal symbol and thus
@@ -430,12 +476,21 @@ find_pc_psymbol (psymtab, pc)
if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
&& SYMBOL_CLASS (p) == LOC_BLOCK
&& pc >= SYMBOL_VALUE_ADDRESS (p)
- && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+ && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+ || (psymtab->textlow == 0
+ && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
{
+ if (section) /* match on a specific section */
+ {
+ fixup_psymbol_section (p, psymtab->objfile);
+ if (SYMBOL_BFD_SECTION (p) != section)
+ continue;
+ }
best_pc = SYMBOL_VALUE_ADDRESS (p);
best = p;
}
}
+
for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
(pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
< psymtab->n_static_syms);
@@ -445,18 +500,82 @@ find_pc_psymbol (psymtab, pc)
if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
&& SYMBOL_CLASS (p) == LOC_BLOCK
&& pc >= SYMBOL_VALUE_ADDRESS (p)
- && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+ && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+ || (psymtab->textlow == 0
+ && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
{
+ if (section) /* match on a specific section */
+ {
+ fixup_psymbol_section (p, psymtab->objfile);
+ if (SYMBOL_BFD_SECTION (p) != section)
+ continue;
+ }
best_pc = SYMBOL_VALUE_ADDRESS (p);
best = p;
}
}
- if (best_pc == psymtab->textlow - 1)
- return 0;
+
return best;
}
+/* Find which partial symbol within a psymtab matches PC. Return 0 if none.
+ Check all psymtabs if PSYMTAB is 0. Backwards compatibility, no section. */
+
+struct partial_symbol *
+find_pc_psymbol (psymtab, pc)
+ struct partial_symtab *psymtab;
+ CORE_ADDR pc;
+{
+ return find_pc_sect_psymbol (psymtab, pc, find_pc_mapped_section (pc));
+}
+/* Debug symbols usually don't have section information. We need to dig that
+ out of the minimal symbols and stash that in the debug symbol. */
+
+static void
+fixup_section (ginfo, objfile)
+ struct general_symbol_info *ginfo;
+ struct objfile *objfile;
+{
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
+
+ if (msym)
+ ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
+}
+
+struct symbol *
+fixup_symbol_section (sym, objfile)
+ struct symbol *sym;
+ struct objfile *objfile;
+{
+ if (!sym)
+ return NULL;
+
+ if (SYMBOL_BFD_SECTION (sym))
+ return sym;
+
+ fixup_section (&sym->ginfo, objfile);
+
+ return sym;
+}
+
+static struct partial_symbol *
+fixup_psymbol_section (psym, objfile)
+ struct partial_symbol *psym;
+ struct objfile *objfile;
+{
+ if (!psym)
+ return NULL;
+
+ if (SYMBOL_BFD_SECTION (psym))
+ return psym;
+
+ fixup_section (&psym->ginfo, objfile);
+
+ return psym;
+}
+
/* Find the definition for a specified symbol name NAME
in namespace NAMESPACE, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
@@ -490,7 +609,7 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
register struct symtab *s = NULL;
register struct partial_symtab *ps;
struct blockvector *bv;
- register struct objfile *objfile;
+ register struct objfile *objfile = NULL;
register struct block *b;
register struct minimal_symbol *msymbol;
@@ -518,7 +637,7 @@ found:
*symtab = s;
}
- return (sym);
+ return fixup_symbol_section (sym, objfile);
}
block = BLOCK_SUPERBLOCK (block);
}
@@ -530,6 +649,16 @@ found:
/* Don't need to mess with the psymtabs; if we have a block,
that file is read in. If we don't, then we deal later with
all the psymtab stuff that needs checking. */
+ /* Note (RT): The following never-executed code looks unnecessary to me also.
+ * If we change the code to use the original (passed-in)
+ * value of 'block', we could cause it to execute, but then what
+ * would it do? The STATIC_BLOCK of the symtab containing the passed-in
+ * 'block' was already searched by the above code. And the STATIC_BLOCK's
+ * of *other* symtabs (those files not containing 'block' lexically)
+ * should not contain 'block' address-wise. So we wouldn't expect this
+ * code to find any 'sym''s that were not found above. I vote for
+ * deleting the following paragraph of code.
+ */
if (namespace == VAR_NAMESPACE && block != NULL)
{
struct block *b;
@@ -547,7 +676,7 @@ found:
block_found = b;
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
}
@@ -566,12 +695,14 @@ found:
*is_a_field_of_this = 1;
if (symtab != NULL)
*symtab = NULL;
- return 0;
+ return NULL;
}
}
/* Now search all global blocks. Do the symtab's first, then
- check the psymtab's */
+ check the psymtab's. If a psymtab indicates the existence
+ of the desired name as a global, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
ALL_SYMTABS (objfile, s)
{
@@ -583,10 +714,12 @@ found:
block_found = block;
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
+#ifndef HPUXHPPA
+
/* Check for the possibility of the symbol being a function or
a mangled variable that is stored in one of the minimal symbol tables.
Eventually, all global symbols might be resolved in this way. */
@@ -596,7 +729,8 @@ found:
msymbol = lookup_minimal_symbol (name, NULL, NULL);
if (msymbol != NULL)
{
- s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+ s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
+ SYMBOL_BFD_SECTION (msymbol));
if (s != NULL)
{
/* This is a function which has a symtab for its address. */
@@ -627,7 +761,7 @@ found:
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
else if (MSYMBOL_TYPE (msymbol) != mst_text
&& MSYMBOL_TYPE (msymbol) != mst_file_text
@@ -635,7 +769,7 @@ found:
{
/* This is a mangled variable, look it up by its
mangled name. */
- return lookup_symbol (SYMBOL_NAME (msymbol), block,
+ return lookup_symbol (SYMBOL_NAME (msymbol), block,
namespace, is_a_field_of_this, symtab);
}
/* There are no debug symbols for this file, or we are looking
@@ -644,6 +778,8 @@ found:
}
}
+#endif
+
ALL_PSYMTABS (objfile, ps)
{
if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))
@@ -653,16 +789,32 @@ found:
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, namespace);
if (!sym)
- error ("Internal: global symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the statics even though the psymtab
+ * claimed the symbol was global. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, namespace);
+ if (!sym)
+ error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
- /* Now search all per-file blocks.
+ /* Now search all static file-level symbols.
Not strictly correct, but more useful than an error.
- Do the symtabs first, then check the psymtabs */
+ Do the symtabs first, then check the psymtabs.
+ If a psymtab indicates the existence
+ of the desired name as a file-level static, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
ALL_SYMTABS (objfile, s)
{
@@ -674,7 +826,7 @@ found:
block_found = block;
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
@@ -687,13 +839,121 @@ found:
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, name, namespace);
if (!sym)
- error ("Internal: static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the globals even though the psymtab
+ * claimed the symbol was static. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, namespace);
+ if (!sym)
+ error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
+
+#ifdef HPUXHPPA
+
+ /* Check for the possibility of the symbol being a function or
+ a global variable that is stored in one of the minimal symbol tables.
+ The "minimal symbol table" is built from linker-supplied info.
+
+ RT: I moved this check to last, after the complete search of
+ the global (p)symtab's and static (p)symtab's. For HP-generated
+ symbol tables, this check was causing a premature exit from
+ lookup_symbol with NULL return, and thus messing up symbol lookups
+ of things like "c::f". It seems to me a check of the minimal
+ symbol table ought to be a last resort in any case. I'm vaguely
+ worried about the comment below which talks about FORTRAN routines "foo_"
+ though... is it saying we need to do the "minsym" check before
+ the static check in this case?
+ */
+
+ if (namespace == VAR_NAMESPACE)
+ {
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ /* OK, we found a minimal symbol in spite of not
+ * finding any symbol. There are various possible
+ * explanations for this. One possibility is the symbol
+ * exists in code not compiled -g. Another possibility
+ * is that the 'psymtab' isn't doing its job.
+ * A third possibility, related to #2, is that we were confused
+ * by name-mangling. For instance, maybe the psymtab isn't
+ * doing its job because it only know about demangled
+ * names, but we were given a mangled name...
+ */
+
+ /* We first use the address in the msymbol to try to
+ * locate the appropriate symtab. Note that find_pc_symtab()
+ * has a side-effect of doing psymtab-to-symtab expansion,
+ * for the found symtab.
+ */
+ s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+ if (s != NULL)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
+ namespace);
+ /* We kept static functions in minimal symbol table as well as
+ in static scope. We want to find them in the symbol table. */
+ if (!sym)
+ {
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
+ namespace);
+ }
+ /* If we found one, return it */
+ if (sym) {
+ if (symtab != NULL)
+ *symtab = s;
+ return sym;
+ }
+
+ /* If we get here with sym == 0, the symbol was
+ found in the minimal symbol table
+ but not in the symtab.
+ Fall through and return 0 to use the msymbol
+ definition of "foo_".
+ (Note that outer code generally follows up a call
+ to this routine with a call to lookup_minimal_symbol(),
+ so a 0 return means we'll just flow into that other routine).
+
+ This happens for Fortran "foo_" symbols,
+ which are "foo" in the symtab.
+
+ This can also happen if "asm" is used to make a
+ regular symbol but not a debugging symbol, e.g.
+ asm(".globl _main");
+ asm("_main:");
+ */
+ }
+
+ /* If the lookup-by-address fails, try repeating the
+ * entire lookup process with the symbol name from
+ * the msymbol (if different from the original symbol name).
+ */
+ else if (MSYMBOL_TYPE (msymbol) != mst_text
+ && MSYMBOL_TYPE (msymbol) != mst_file_text
+ && !STREQ (name, SYMBOL_NAME (msymbol)))
+ {
+ return lookup_symbol (SYMBOL_NAME (msymbol), block,
+ namespace, is_a_field_of_this, symtab);
+ }
}
}
+#endif
+
if (symtab != NULL)
*symtab = NULL;
return 0;
@@ -739,7 +999,10 @@ lookup_partial_symbol (pst, name, global, namespace)
center = bottom + (top - bottom) / 2;
if (!(center < top))
abort ();
- if (!do_linear_search && SYMBOL_LANGUAGE (*center) == language_cplus)
+ if (!do_linear_search
+ && (SYMBOL_LANGUAGE (*center) == language_cplus
+ || SYMBOL_LANGUAGE (*center) == language_java
+ ))
{
do_linear_search = 1;
}
@@ -784,6 +1047,120 @@ lookup_partial_symbol (pst, name, global, namespace)
return (NULL);
}
+/* Look up a type named NAME in the struct_namespace. The type returned
+ must not be opaque -- i.e., must have at least one field defined
+
+ This code was modelled on lookup_symbol -- the parts not relevant to looking
+ up types were just left out. In particular it's assumed here that types
+ are available in struct_namespace and only at file-static or global blocks. */
+
+
+struct type *
+lookup_transparent_type (name)
+ const char *name;
+{
+ register struct symbol *sym;
+ register struct symtab *s = NULL;
+ register struct partial_symtab *ps;
+ struct blockvector *bv;
+ register struct objfile *objfile;
+ register struct block *block;
+ register struct minimal_symbol *msymbol;
+
+ /* Now search all the global symbols. Do the symtab's first, then
+ check the psymtab's. If a psymtab indicates the existence
+ of the desired name as a global, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ {
+ return SYMBOL_TYPE (sym);
+ }
+ }
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE))
+ {
+ s = PSYMTAB_TO_SYMTAB(ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ if (!sym)
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the statics even though the psymtab
+ * claimed the symbol was global. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ if (!sym)
+ error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return SYMBOL_TYPE (sym);
+ }
+ }
+
+ /* Now search the static file-level symbols.
+ Not strictly correct, but more useful than an error.
+ Do the symtab's first, then
+ check the psymtab's. If a psymtab indicates the existence
+ of the desired name as a file-level static, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol.
+ */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ {
+ return SYMBOL_TYPE (sym);
+ }
+ }
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE))
+ {
+ s = PSYMTAB_TO_SYMTAB(ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ if (!sym)
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the globals even though the psymtab
+ * claimed the symbol was static. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ if (!sym)
+ error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return SYMBOL_TYPE (sym);
+ }
+ }
+ return (struct type *) 0;
+}
+
+
/* Find the psymtab containing main(). */
/* FIXME: What about languages without main() or specially linked
executables that have no main() ? */
@@ -852,7 +1229,10 @@ lookup_block_symbol (block, name, namespace)
}
inc = (inc >> 1) + bot;
sym = BLOCK_SYM (block, inc);
- if (!do_linear_search && SYMBOL_LANGUAGE (sym) == language_cplus)
+ if (!do_linear_search
+ && (SYMBOL_LANGUAGE (sym) == language_cplus
+ || SYMBOL_LANGUAGE (sym) == language_java
+ ))
{
do_linear_search = 1;
}
@@ -926,6 +1306,15 @@ lookup_block_symbol (block, name, namespace)
if (SYMBOL_NAMESPACE (sym) == namespace &&
SYMBOL_MATCHES_NAME (sym, name))
{
+ /* If SYM has aliases, then use any alias that is active
+ at the current PC. If no alias is active at the current
+ PC, then use the main symbol.
+
+ ?!? Is checking the current pc correct? Is this routine
+ ever called to look up a symbol from another context? */
+ if (SYMBOL_ALIASES (sym))
+ sym = find_active_alias (sym, read_pc ());
+
sym_found = sym;
if (SYMBOL_CLASS (sym) != LOC_ARG &&
SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
@@ -943,6 +1332,39 @@ lookup_block_symbol (block, name, namespace)
return (sym_found); /* Will be NULL if not found. */
}
+/* Given a main symbol SYM and ADDR, search through the alias
+ list to determine if an alias is active at ADDR and return
+ the active alias.
+
+ If no alias is active, then return SYM. */
+
+static struct symbol *
+find_active_alias (sym, addr)
+ struct symbol *sym;
+ CORE_ADDR addr;
+{
+ struct range_list *r;
+ struct alias_list *aliases;
+
+ /* If we have aliases, check them first. */
+ aliases = SYMBOL_ALIASES (sym);
+
+ while (aliases)
+ {
+ if (!SYMBOL_RANGES (aliases->sym))
+ return aliases->sym;
+ for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next)
+ {
+ if (r->start <= addr && r->end > addr)
+ return aliases->sym;
+ }
+ aliases = aliases->next;
+ }
+
+ /* Nothing found, return the main symbol. */
+ return sym;
+}
+
/* Return the symbol for the function which contains a specified
lexical block, described by a struct block BL. */
@@ -957,12 +1379,13 @@ block_function (bl)
return BLOCK_FUNCTION (bl);
}
-/* Find the symtab associated with PC. Look through the psymtabs and read in
- another symtab if necessary. */
+/* Find the symtab associated with PC and SECTION. Look through the
+ psymtabs and read in another symtab if necessary. */
struct symtab *
-find_pc_symtab (pc)
- register CORE_ADDR pc;
+find_pc_sect_symtab (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register struct block *b;
struct blockvector *bv;
@@ -970,7 +1393,7 @@ find_pc_symtab (pc)
register struct symtab *best_s = NULL;
register struct partial_symtab *ps;
register struct objfile *objfile;
- int distance = 0;
+ CORE_ADDR distance = 0;
/* Search all symtabs for the one whose file contains our address, and which
is the smallest of all the ones containing the address. This is designed
@@ -991,22 +1414,40 @@ find_pc_symtab (pc)
{
bv = BLOCKVECTOR (s);
b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+
if (BLOCK_START (b) <= pc
+#if defined(HPUXHPPA)
+ && BLOCK_END (b) >= pc
+#else
&& BLOCK_END (b) > pc
+#endif
&& (distance == 0
|| BLOCK_END (b) - BLOCK_START (b) < distance))
{
/* For an objfile that has its functions reordered,
find_pc_psymtab will find the proper partial symbol table
and we simply return its corresponding symtab. */
+ /* In order to better support objfiles that contain both
+ stabs and coff debugging info, we continue on if a psymtab
+ can't be found. */
if ((objfile->flags & OBJF_REORDERED) && objfile->psymtabs)
{
- ps = find_pc_psymtab (pc);
+ ps = find_pc_sect_psymtab (pc, section);
if (ps)
- s = PSYMTAB_TO_SYMTAB (ps);
- else
- s = NULL;
- return (s);
+ return PSYMTAB_TO_SYMTAB (ps);
+ }
+ if (section != 0)
+ {
+ int i;
+
+ for (i = 0; i < b->nsyms; i++)
+ {
+ fixup_symbol_section (b->sym[i], objfile);
+ if (section == SYMBOL_BFD_SECTION (b->sym[i]))
+ break;
+ }
+ if (i >= b->nsyms)
+ continue; /* no symbol in this symtab matches section */
}
distance = BLOCK_END (b) - BLOCK_START (b);
best_s = s;
@@ -1017,7 +1458,7 @@ find_pc_symtab (pc)
return(best_s);
s = NULL;
- ps = find_pc_psymtab (pc);
+ ps = find_pc_sect_psymtab (pc, section);
if (ps)
{
if (ps->readin)
@@ -1032,6 +1473,17 @@ find_pc_symtab (pc)
}
return (s);
}
+
+/* Find the symtab associated with PC. Look through the psymtabs and
+ read in another symtab if necessary. Backward compatibility, no section */
+
+struct symtab *
+find_pc_symtab (pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_symtab (pc, find_pc_mapped_section (pc));
+}
+
#if 0
@@ -1082,6 +1534,19 @@ find_addr_symbol (addr, symtabp, symaddrp)
sym_addr = SYMBOL_VALUE_ADDRESS (sym);
break;
+ case LOC_INDIRECT:
+ sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+ /* An indirect symbol really lives at *sym_addr,
+ * so an indirection needs to be done.
+ * However, I am leaving this commented out because it's
+ * expensive, and it's possible that symbolization
+ * could be done without an active process (in
+ * case this read_memory will fail). RT
+ sym_addr = read_memory_unsigned_integer
+ (sym_addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ */
+ break;
+
case LOC_BLOCK:
sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
break;
@@ -1113,7 +1578,7 @@ find_addr_symbol (addr, symtabp, symaddrp)
}
#endif /* 0 */
-/* Find the source file and line number for a given PC value.
+/* Find the source file and line number for a given PC value and section.
Return a structure containing a symtab pointer, a line number,
and a pc range for the entire source line.
The value's .pc field is NOT the specified pc.
@@ -1131,8 +1596,9 @@ find_addr_symbol (addr, symtabp, symaddrp)
/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
-find_pc_line (pc, notcurrent)
+find_pc_sect_line (pc, section, notcurrent)
CORE_ADDR pc;
+ struct sec *section;
int notcurrent;
{
struct symtab *s;
@@ -1142,6 +1608,8 @@ find_pc_line (pc, notcurrent)
register struct linetable_entry *item;
struct symtab_and_line val;
struct blockvector *bv;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *mfunsym;
/* Info on best line seen so far, and where it starts, and its file. */
@@ -1167,15 +1635,89 @@ find_pc_line (pc, notcurrent)
But what we want is the statement containing the instruction.
Fudge the pc to make sure we get that. */
- if (notcurrent) pc -= 1;
+ INIT_SAL (&val); /* initialize to zeroes */
+
+ if (notcurrent)
+ pc -= 1;
- s = find_pc_symtab (pc);
+ /* elz: added this because this function returned the wrong
+ information if the pc belongs to a stub (import/export)
+ to call a shlib function. This stub would be anywhere between
+ two functions in the target, and the line info was erroneously
+ taken to be the one of the line before the pc.
+ */
+ /* RT: Further explanation:
+ *
+ * We have stubs (trampolines) inserted between procedures.
+ *
+ * Example: "shr1" exists in a shared library, and a "shr1" stub also
+ * exists in the main image.
+ *
+ * In the minimal symbol table, we have a bunch of symbols
+ * sorted by start address. The stubs are marked as "trampoline",
+ * the others appear as text. E.g.:
+ *
+ * Minimal symbol table for main image
+ * main: code for main (text symbol)
+ * shr1: stub (trampoline symbol)
+ * foo: code for foo (text symbol)
+ * ...
+ * Minimal symbol table for "shr1" image:
+ * ...
+ * shr1: code for shr1 (text symbol)
+ * ...
+ *
+ * So the code below is trying to detect if we are in the stub
+ * ("shr1" stub), and if so, find the real code ("shr1" trampoline),
+ * and if found, do the symbolization from the real-code address
+ * rather than the stub address.
+ *
+ * Assumptions being made about the minimal symbol table:
+ * 1. lookup_minimal_symbol_by_pc() will return a trampoline only
+ * if we're really in the trampoline. If we're beyond it (say
+ * we're in "foo" in the above example), it'll have a closer
+ * symbol (the "foo" text symbol for example) and will not
+ * return the trampoline.
+ * 2. lookup_minimal_symbol_text() will find a real text symbol
+ * corresponding to the trampoline, and whose address will
+ * be different than the trampoline address. I put in a sanity
+ * check for the address being the same, to avoid an
+ * infinite recursion.
+ */
+ msymbol = lookup_minimal_symbol_by_pc(pc);
+ if (msymbol != NULL)
+ if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ {
+ mfunsym = lookup_minimal_symbol_text (SYMBOL_NAME (msymbol), NULL, NULL);
+ if (mfunsym == NULL)
+ /* I eliminated this warning since it is coming out
+ * in the following situation:
+ * gdb shmain // test program with shared libraries
+ * (gdb) break shr1 // function in shared lib
+ * Warning: In stub for ...
+ * In the above situation, the shared lib is not loaded yet,
+ * so of course we can't find the real func/line info,
+ * but the "break" still works, and the warning is annoying.
+ * So I commented out the warning. RT */
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */;
+ /* fall through */
+ else if (SYMBOL_VALUE(mfunsym) == SYMBOL_VALUE(msymbol))
+ /* Avoid infinite recursion */
+ /* See above comment about why warning is commented out */
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */;
+ /* fall through */
+ else
+ return find_pc_line( SYMBOL_VALUE (mfunsym), 0);
+ }
+
+
+ s = find_pc_sect_symtab (pc, section);
if (!s)
{
- val.symtab = 0;
- val.line = 0;
+ /* if no symbol information, return previous pc */
+ if (notcurrent)
+ pc++;
val.pc = pc;
- val.end = 0;
return val;
}
@@ -1214,7 +1756,8 @@ find_pc_line (pc, notcurrent)
for (i = 0; i < len; i++, item++)
{
- /* Return the last line that did not start after PC. */
+ /* Leave prev pointing to the linetable entry for the last line
+ that started at or before PC. */
if (item->pc > pc)
break;
@@ -1244,11 +1787,8 @@ find_pc_line (pc, notcurrent)
{
if (!alt_symtab)
{ /* If we didn't find any line # info, just
- return zeros. */
- val.symtab = 0;
- val.line = 0;
+ return zeros. */
val.pc = pc;
- val.end = 0;
}
else
{
@@ -1274,27 +1814,43 @@ find_pc_line (pc, notcurrent)
else
val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
}
+ val.section = section;
return val;
}
+
+/* Backward compatibility (no section) */
+
+struct symtab_and_line
+find_pc_line (pc, notcurrent)
+ CORE_ADDR pc;
+ int notcurrent;
+{
+ asection *section;
+
+ section = find_pc_overlay (pc);
+ if (pc_in_unmapped_range (pc, section))
+ pc = overlay_mapped_address (pc, section);
+ return find_pc_sect_line (pc, section, notcurrent);
+}
+
-static int find_line_symtab PARAMS ((struct symtab *, int, struct linetable **,
- int *, int *));
+static struct symtab* find_line_symtab PARAMS ((struct symtab *, int,
+ int *, int *));
/* Find line number LINE in any symtab whose name is the same as
SYMTAB.
- If found, return 1, set *LINETABLE to the linetable in which it was
+ If found, return the symtab that contains the linetable in which it was
found, set *INDEX to the index in the linetable of the best entry
found, and set *EXACT_MATCH nonzero if the value returned is an
exact match.
- If not found, return 0. */
+ If not found, return NULL. */
-static int
-find_line_symtab (symtab, line, linetable, index, exact_match)
+static struct symtab*
+find_line_symtab (symtab, line, index, exact_match)
struct symtab *symtab;
int line;
- struct linetable **linetable;
int *index;
int *exact_match;
{
@@ -1305,9 +1861,11 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
int best_index;
struct linetable *best_linetable;
+ struct symtab *best_symtab;
/* First try looking it up in the given symtab. */
best_linetable = LINETABLE (symtab);
+ best_symtab = symtab;
best_index = find_line_common (best_linetable, line, &exact);
if (best_index < 0 || !exact)
{
@@ -1346,6 +1904,7 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
{
best_index = ind;
best_linetable = l;
+ best_symtab = s;
goto done;
}
if (best == 0 || l->item[ind].line < best)
@@ -1353,39 +1912,47 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
best = l->item[ind].line;
best_index = ind;
best_linetable = l;
+ best_symtab = s;
}
}
}
}
done:
if (best_index < 0)
- return 0;
+ return NULL;
if (index)
*index = best_index;
- if (linetable)
- *linetable = best_linetable;
if (exact_match)
*exact_match = exact;
- return 1;
+
+ return best_symtab;
}
-/* Find the PC value for a given source file and line number.
- Returns zero for invalid line number.
+/* Set the PC value for a given source file and line number and return true.
+ Returns zero for invalid line number (and sets the PC to 0).
The source file is specified with a struct symtab. */
-CORE_ADDR
-find_line_pc (symtab, line)
+int
+find_line_pc (symtab, line, pc)
struct symtab *symtab;
int line;
+ CORE_ADDR *pc;
{
struct linetable *l;
int ind;
+ *pc = 0;
if (symtab == 0)
return 0;
- if (find_line_symtab (symtab, line, &l, &ind, NULL))
- return l->item[ind].pc;
+
+ symtab = find_line_symtab (symtab, line, &ind, NULL);
+ if (symtab != NULL)
+ {
+ l = LINETABLE (symtab);
+ *pc = l->item[ind].pc;
+ return 1;
+ }
else
return 0;
}
@@ -1405,11 +1972,7 @@ find_line_pc_range (sal, startptr, endptr)
struct symtab_and_line found_sal;
startaddr = sal.pc;
- if (startaddr == 0)
- {
- startaddr = find_line_pc (sal.symtab, sal.line);
- }
- if (startaddr == 0)
+ if (startaddr==0 && !find_line_pc (sal.symtab, sal.line, &startaddr))
return 0;
/* This whole function is based on address. For example, if line 10 has
@@ -1419,7 +1982,7 @@ find_line_pc_range (sal, startptr, endptr)
This also insures that we never give a range like "starts at 0x134
and ends at 0x12c". */
- found_sal = find_pc_line (startaddr, 0);
+ found_sal = find_pc_sect_line (startaddr, sal.section, 0);
if (found_sal.line != sal.line)
{
/* The specified line (sal) has zero bytes. */
@@ -1515,12 +2078,23 @@ find_function_start_sal (sym, funfirstline)
struct symtab_and_line sal;
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ fixup_symbol_section (sym, NULL);
if (funfirstline)
- {
+ { /* skip "first line" of function (which is actually its prologue) */
+ asection *section = SYMBOL_BFD_SECTION (sym);
+ /* If function is in an unmapped overlay, use its unmapped LMA
+ address, so that SKIP_PROLOGUE has something unique to work on */
+ if (section_is_overlay (section) &&
+ !section_is_mapped (section))
+ pc = overlay_unmapped_address (pc, section);
+
pc += FUNCTION_START_OFFSET;
SKIP_PROLOGUE (pc);
+
+ /* For overlays, map pc back into its mapped VMA range */
+ pc = overlay_mapped_address (pc, section);
}
- sal = find_pc_line (pc, 0);
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
#ifdef PROLOGUE_FIRSTLINE_OVERLAP
/* Convex: no need to suppress code on first line, if any */
@@ -1535,7 +2109,7 @@ find_function_start_sal (sym, funfirstline)
/* First pc of next line */
pc = sal.end;
/* Recalculate the line number (might not be N+1). */
- sal = find_pc_line (pc, 0);
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
}
sal.pc = pc;
#endif
@@ -1547,7 +2121,7 @@ find_function_start_sal (sym, funfirstline)
some legitimate operator text, return a pointer to the
beginning of the substring of the operator text.
Otherwise, return "". */
-static char *
+char *
operator_chars (p, end)
char *p;
char **end;
@@ -1643,6 +2217,8 @@ total_number_of_methods (type)
int count;
CHECK_TYPEDEF (type);
+ if (TYPE_CPLUS_SPECIFIC (type) == NULL)
+ return 0;
count = TYPE_NFN_FIELDS_TOTAL (type);
for (n = 0; n < TYPE_N_BASECLASSES (type); n++)
@@ -1658,7 +2234,7 @@ total_number_of_methods (type)
a size of total_number_of_methods (T) * sizeof (struct symbol *).
Note that this function is g++ specific. */
-int
+static int
find_methods (t, name, sym_arr)
struct type *t;
char *name;
@@ -1668,6 +2244,7 @@ find_methods (t, name, sym_arr)
int ibase;
struct symbol *sym_class;
char *class_name = type_name_no_tag (t);
+
/* Ignore this class if it doesn't have a name. This is ugly, but
unless we figure out how to get the physname without the name of
the class, then the loop can't do any good. */
@@ -1679,60 +2256,77 @@ find_methods (t, name, sym_arr)
(struct symtab **)NULL)))
{
int method_counter;
+
/* FIXME: Shouldn't this just be CHECK_TYPEDEF (t)? */
t = SYMBOL_TYPE (sym_class);
+
+ /* Loop over each method name. At this level, all overloads of a name
+ are counted as a single name. There is an inner loop which loops over
+ each overload. */
+
for (method_counter = TYPE_NFN_FIELDS (t) - 1;
method_counter >= 0;
--method_counter)
{
int field_counter;
- struct fn_field *f = TYPE_FN_FIELDLIST1 (t, method_counter);
char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);
char dem_opname[64];
- if (strncmp(method_name, "__", 2)==0 ||
- strncmp(method_name, "op", 2)==0 ||
- strncmp(method_name, "type", 4)==0 )
- {
- if (cplus_demangle_opname(method_name, dem_opname, DMGL_ANSI))
+ if (strncmp (method_name, "__", 2) == 0 ||
+ strncmp (method_name, "op", 2) == 0 ||
+ strncmp (method_name, "type", 4) == 0)
+ {
+ if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
method_name = dem_opname;
- else if (cplus_demangle_opname(method_name, dem_opname, 0))
+ else if (cplus_demangle_opname (method_name, dem_opname, 0))
method_name = dem_opname;
- }
+ }
+
if (STREQ (name, method_name))
- /* Find all the fields with that name. */
+ /* Find all the overloaded methods with that name. */
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
field_counter >= 0;
--field_counter)
{
+ struct fn_field *f;
char *phys_name;
+
+ f = TYPE_FN_FIELDLIST1 (t, method_counter);
+
if (TYPE_FN_FIELD_STUB (f, field_counter))
- check_stub_method (t, method_counter, field_counter);
- phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+ {
+ char *tmp_name;
+
+ tmp_name = gdb_mangle_name (t,
+ method_counter,
+ field_counter);
+ phys_name = alloca (strlen (tmp_name) + 1);
+ strcpy (phys_name, tmp_name);
+ free (tmp_name);
+ }
+ else
+ phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+
/* Destructor is handled by caller, dont add it to the list */
if (DESTRUCTOR_PREFIX_P (phys_name))
continue;
- /* FIXME: Why are we looking this up in the
- SYMBOL_BLOCK_VALUE (sym_class)? It is intended as a hook
- for nested types? If so, it should probably hook to the
- type, not the symbol. mipsread.c is the only symbol
- reader which sets the SYMBOL_BLOCK_VALUE for types, and
- this is not documented in symtab.h. -26Aug93. */
-
sym_arr[i1] = lookup_symbol (phys_name,
- SYMBOL_BLOCK_VALUE (sym_class),
- VAR_NAMESPACE,
+ NULL, VAR_NAMESPACE,
(int *) NULL,
(struct symtab **) NULL);
- if (sym_arr[i1]) i1++;
+ if (sym_arr[i1])
+ i1++;
else
{
- fputs_filtered("(Cannot find method ", gdb_stdout);
- fprintf_symbol_filtered (gdb_stdout, phys_name,
- language_cplus,
- DMGL_PARAMS | DMGL_ANSI);
- fputs_filtered(" - possibly inlined.)\n", gdb_stdout);
+ /* This error message gets printed, but the method
+ still seems to be found
+ fputs_filtered("(Cannot find method ", gdb_stdout);
+ fprintf_symbol_filtered (gdb_stdout, phys_name,
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered(" - possibly inlined.)\n", gdb_stdout);
+ */
}
}
}
@@ -1749,11 +2343,10 @@ find_methods (t, name, sym_arr)
rather than hiding without any problem, and gcc 2.4.5 does overload
rather than hiding in this case). */
- if (i1)
- return i1;
- for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
- i1 += find_methods(TYPE_BASECLASS(t, ibase), name,
- sym_arr + i1);
+ if (i1 == 0)
+ for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
+ i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
+
return i1;
}
@@ -1877,7 +2470,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
struct symtab_and_line val;
#endif
register char *p, *p1;
- char *q, *pp;
+ char *q, *pp, *ii, *p2;
#if 0
char *q1;
#endif
@@ -1892,12 +2485,16 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
char *copy;
struct symbol *sym_class;
int i1;
- int is_quoted, has_parens;
+ int is_quoted;
+ int has_parens;
+ int has_if = 0;
struct symbol **sym_arr;
struct type *t;
char *saved_arg = *argptr;
extern char *gdb_completer_quote_characters;
+ INIT_SAL (&val); /* initialize to zeroes */
+
/* Defaults have defaults. */
if (default_symtab == 0)
@@ -1912,77 +2509,157 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
{
(*argptr)++;
pc = parse_and_eval_address_1 (argptr);
+
values.sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
+
values.nelts = 1;
values.sals[0] = find_pc_line (pc, 0);
values.sals[0].pc = pc;
+ values.sals[0].section = find_pc_overlay (pc);
+
return values;
}
+ /* 'has_if' is for the syntax:
+ * (gdb) break foo if (a==b)
+ */
+ if ((ii = strstr(*argptr, " if ")) != NULL ||
+ (ii = strstr(*argptr, "\tif ")) != NULL ||
+ (ii = strstr(*argptr, " if\t")) != NULL ||
+ (ii = strstr(*argptr, "\tif\t")) != NULL ||
+ (ii = strstr(*argptr, " if(")) != NULL ||
+ (ii = strstr(*argptr, "\tif( ")) != NULL)
+ has_if = 1;
+ /* Temporarily zap out "if (condition)" to not
+ * confuse the parenthesis-checking code below.
+ * This is undone below. Do not change ii!!
+ */
+ if (has_if) {
+ *ii = '\0';
+ }
+
+ /* Set various flags.
+ * 'has_parens' is important for overload checking, where
+ * we allow things like:
+ * (gdb) break c::f(int)
+ */
+
/* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
- s = NULL;
is_quoted = (**argptr
&& strchr (gdb_completer_quote_characters, **argptr) != NULL);
+
has_parens = ((pp = strchr (*argptr, '(')) != NULL
&& (pp = strchr (pp, ')')) != NULL);
+ /* Now that we're safely past the has_parens check,
+ * put back " if (condition)" so outer layers can see it
+ */
+ if (has_if)
+ *ii = ' ';
+
+ /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
+ /* May also be CLASS::MEMBER, or NAMESPACE::NAME */
+ /* Look for ':', but ignore inside of <> */
+
+ s = NULL;
for (p = *argptr; *p; p++)
{
if (p[0] == '<')
{
- while(++p && *p != '>');
- if (!p)
+ char * temp_end = find_template_name_end (p);
+ if (!temp_end)
+ error ("malformed template specification in command");
+ p = temp_end;
+ }
+ if (p[0] == ':' || p[0] == ' ' || p[0] == '\t' || !*p)
+ break;
+ if (p[0] == '.' && strchr (p, ':') == NULL) /* Java qualified method. */
+ {
+ /* Find the *last* '.', since the others are package qualifiers. */
+ for (p1 = p; *p1; p1++)
{
- error ("non-matching '<' and '>' in command");
+ if (*p1 == '.')
+ p = p1;
}
+ break;
}
- if (p[0] == ':' || p[0] == ' ' || p[0] == '\t')
- break;
}
while (p[0] == ' ' || p[0] == '\t') p++;
- if ((p[0] == ':') && !has_parens)
+ if ((p[0] == ':' || p[0] == '.') && !has_parens)
{
-
- /* C++ */
+ /* C++ */
+ /* ... or Java */
if (is_quoted) *argptr = *argptr+1;
- if (p[1] ==':')
+ if (p[0] == '.' || p[1] ==':')
{
- /* Extract the class name. */
- p1 = p;
- while (p != *argptr && p[-1] == ' ') --p;
- copy = (char *) alloca (p - *argptr + 1);
- memcpy (copy, *argptr, p - *argptr);
- copy[p - *argptr] = 0;
-
- /* Discard the class name from the arg. */
- p = p1 + 2;
- while (*p == ' ' || *p == '\t') p++;
- *argptr = p;
-
- sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE, 0,
- (struct symtab **)NULL);
+ int ix;
+ char * saved_arg2 = *argptr;
+ char * temp_end;
+ /* First check for "global" namespace specification,
+ of the form "::foo". If found, skip over the colons
+ and jump to normal symbol processing */
+ if ((*argptr == p) || (p[-1] == ' ') || (p[-1] == '\t'))
+ saved_arg2 += 2;
+
+ /* We have what looks like a class or namespace
+ scope specification (A::B), possibly with many
+ levels of namespaces or classes (A::B::C::D).
+
+ Some versions of the HP ANSI C++ compiler (as also possibly
+ other compilers) generate class/function/member names with
+ embedded double-colons if they are inside namespaces. To
+ handle this, we loop a few times, considering larger and
+ larger prefixes of the string as though they were single
+ symbols. So, if the initially supplied string is
+ A::B::C::D::foo, we have to look up "A", then "A::B",
+ then "A::B::C", then "A::B::C::D", and finally
+ "A::B::C::D::foo" as single, monolithic symbols, because
+ A, B, C or D may be namespaces.
+
+ Note that namespaces can nest only inside other
+ namespaces, and not inside classes. So we need only
+ consider *prefixes* of the string; there is no need to look up
+ "B::C" separately as a symbol in the previous example. */
+
+ p2 = p; /* save for restart */
+ while (1)
+ {
+ /* Extract the class name. */
+ p1 = p;
+ while (p != *argptr && p[-1] == ' ') --p;
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = 0;
+
+ /* Discard the class name from the arg. */
+ p = p1 + (p1[0] == ':' ? 2 : 1);
+ while (*p == ' ' || *p == '\t') p++;
+ *argptr = p;
+
+ sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE, 0,
+ (struct symtab **)NULL);
- if (sym_class &&
- (t = check_typedef (SYMBOL_TYPE (sym_class)),
- (TYPE_CODE (t) == TYPE_CODE_STRUCT
- || TYPE_CODE (t) == TYPE_CODE_UNION)))
- {
- /* Arg token is not digits => try it as a function name
- Find the next token(everything up to end or next blank). */
- if (**argptr
- && strchr (gdb_completer_quote_characters, **argptr) != NULL)
- {
- p = skip_quoted(*argptr);
- *argptr = *argptr + 1;
- }
- else
- {
- p = *argptr;
- while (*p && *p!=' ' && *p!='\t' && *p!=',' && *p!=':') p++;
- }
+ if (sym_class &&
+ (t = check_typedef (SYMBOL_TYPE (sym_class)),
+ (TYPE_CODE (t) == TYPE_CODE_STRUCT
+ || TYPE_CODE (t) == TYPE_CODE_UNION)))
+ {
+ /* Arg token is not digits => try it as a function name
+ Find the next token(everything up to end or next blank). */
+ if (**argptr
+ && strchr (gdb_completer_quote_characters, **argptr) != NULL)
+ {
+ p = skip_quoted(*argptr);
+ *argptr = *argptr + 1;
+ }
+ else
+ {
+ p = *argptr;
+ while (*p && *p!=' ' && *p!='\t' && *p!=',' && *p!=':') p++;
+ }
/*
q = operator_chars (*argptr, &q1);
if (q1 - q)
@@ -2005,107 +2682,152 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
}
else
*/
- {
- copy = (char *) alloca (p - *argptr + 1 );
- memcpy (copy, *argptr, p - *argptr);
- copy[p - *argptr] = '\0';
- if (p != *argptr
- && copy[p - *argptr - 1]
- && strchr (gdb_completer_quote_characters,
- copy[p - *argptr - 1]) != NULL)
- copy[p - *argptr - 1] = '\0';
- }
-
- /* no line number may be specified */
- while (*p == ' ' || *p == '\t') p++;
- *argptr = p;
-
- sym = 0;
- i1 = 0; /* counter for the symbol array */
- sym_arr = (struct symbol **) alloca(total_number_of_methods (t)
- * sizeof(struct symbol *));
-
- /* Cfront objects don't have fieldlists. */
- if (destructor_name_p (copy, t) && TYPE_FN_FIELDLISTS (t) != NULL)
- {
- /* destructors are a special case. */
- struct fn_field *f = TYPE_FN_FIELDLIST1 (t, 0);
- int len = TYPE_FN_FIELDLIST_LENGTH (t, 0) - 1;
- /* gcc 1.x puts destructor in last field,
- gcc 2.x puts destructor in first field. */
- char *phys_name = TYPE_FN_FIELD_PHYSNAME (f, len);
- if (!DESTRUCTOR_PREFIX_P (phys_name))
- {
- phys_name = TYPE_FN_FIELD_PHYSNAME (f, 0);
- if (!DESTRUCTOR_PREFIX_P (phys_name))
- phys_name = "";
- }
- sym_arr[i1] =
- lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class),
- VAR_NAMESPACE, 0, (struct symtab **)NULL);
- if (sym_arr[i1]) i1++;
- }
- else
- i1 = find_methods (t, copy, sym_arr);
- if (i1 == 1)
- {
- /* There is exactly one field with that name. */
- sym = sym_arr[0];
-
- if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
- {
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
- values.nelts = 1;
- values.sals[0] = find_function_start_sal (sym,
- funfirstline);
- }
- else
- {
- values.nelts = 0;
- }
- return values;
- }
- if (i1 > 0)
- {
- /* There is more than one field with that name
- (overloaded). Ask the user which one to use. */
- return decode_line_2 (sym_arr, i1, funfirstline, canonical);
- }
- else
- {
- char *tmp;
-
- if (OPNAME_PREFIX_P (copy))
- {
- tmp = (char *)alloca (strlen (copy+3) + 9);
- strcpy (tmp, "operator ");
- strcat (tmp, copy+3);
- }
- else
- tmp = copy;
- error_begin ();
- if (tmp[0] == '~')
- printf_filtered
- ("the class `%s' does not have destructor defined\n",
- SYMBOL_SOURCE_NAME(sym_class));
- else
- printf_filtered
- ("the class %s does not have any method named %s\n",
- SYMBOL_SOURCE_NAME(sym_class), tmp);
- cplusplus_hint (saved_arg);
- return_to_top_level (RETURN_ERROR);
- }
- }
- else
- {
- error_begin ();
- /* The quotes are important if copy is empty. */
- printf_filtered
- ("can't find class, struct, or union named \"%s\"\n", copy);
- cplusplus_hint (saved_arg);
- return_to_top_level (RETURN_ERROR);
- }
- }
+ {
+ copy = (char *) alloca (p - *argptr + 1 );
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\0';
+ if (p != *argptr
+ && copy[p - *argptr - 1]
+ && strchr (gdb_completer_quote_characters,
+ copy[p - *argptr - 1]) != NULL)
+ copy[p - *argptr - 1] = '\0';
+ }
+
+ /* no line number may be specified */
+ while (*p == ' ' || *p == '\t') p++;
+ *argptr = p;
+
+ sym = 0;
+ i1 = 0; /* counter for the symbol array */
+ sym_arr = (struct symbol **) alloca(total_number_of_methods (t)
+ * sizeof(struct symbol *));
+
+ if (destructor_name_p (copy, t))
+ {
+ /* Destructors are a special case. */
+ int m_index, f_index;
+
+ if (get_destructor_fn_field (t, &m_index, &f_index))
+ {
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index);
+
+ sym_arr[i1] =
+ lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index),
+ NULL, VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **)NULL);
+ if (sym_arr[i1])
+ i1++;
+ }
+ }
+ else
+ i1 = find_methods (t, copy, sym_arr);
+ if (i1 == 1)
+ {
+ /* There is exactly one field with that name. */
+ sym = sym_arr[0];
+
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.nelts = 1;
+ values.sals[0] = find_function_start_sal (sym,
+ funfirstline);
+ }
+ else
+ {
+ values.nelts = 0;
+ }
+ return values;
+ }
+ if (i1 > 0)
+ {
+ /* There is more than one field with that name
+ (overloaded). Ask the user which one to use. */
+ return decode_line_2 (sym_arr, i1, funfirstline, canonical);
+ }
+ else
+ {
+ char *tmp;
+
+ if (OPNAME_PREFIX_P (copy))
+ {
+ tmp = (char *)alloca (strlen (copy+3) + 9);
+ strcpy (tmp, "operator ");
+ strcat (tmp, copy+3);
+ }
+ else
+ tmp = copy;
+ error_begin ();
+ if (tmp[0] == '~')
+ printf_filtered
+ ("the class `%s' does not have destructor defined\n",
+ SYMBOL_SOURCE_NAME(sym_class));
+ else
+ printf_filtered
+ ("the class %s does not have any method named %s\n",
+ SYMBOL_SOURCE_NAME(sym_class), tmp);
+ cplusplus_hint (saved_arg);
+ return_to_top_level (RETURN_ERROR);
+ }
+ }
+
+ /* Move pointer up to next possible class/namespace token */
+ p = p2 + 1; /* restart with old value +1 */
+ /* Move pointer ahead to next double-colon */
+ while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')) {
+ if (p[0] == '<') {
+ temp_end = find_template_name_end (p);
+ if (!temp_end)
+ error ("malformed template specification in command");
+ p = temp_end;
+ }
+ else if ((p[0] == ':') && (p[1] == ':'))
+ break; /* found double-colon */
+ else
+ p++;
+ }
+
+ if (*p != ':')
+ break; /* out of the while (1) */
+
+ p2 = p; /* save restart for next time around */
+ *argptr = saved_arg2; /* restore argptr */
+ } /* while (1) */
+
+ /* Last chance attempt -- check entire name as a symbol */
+ /* Use "copy" in preparation for jumping out of this block,
+ to be consistent with usage following the jump target */
+ copy = (char *) alloca (p - saved_arg2 + 1);
+ memcpy (copy, saved_arg2, p - saved_arg2);
+ /* Note: if is_quoted should be true, we snuff out quote here anyway */
+ copy[p-saved_arg2] = '\000';
+ /* Set argptr to skip over the name */
+ *argptr = (*p == '\'') ? p + 1 : p;
+ /* Look up entire name */
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ s = (struct symtab *) 0;
+ /* Prepare to jump: restore the " if (condition)" so outer layers see it */
+ if (has_if)
+ *ii = ' ';
+ /* Symbol was found --> jump to normal symbol processing.
+ Code following "symbol_found" expects "copy" to have the
+ symbol name, "sym" to have the symbol pointer, "s" to be
+ a specified file's symtab, and sym_symtab to be the symbol's
+ symtab. */
+ /* By jumping there we avoid falling through the FILE:LINE and
+ FILE:FUNC processing stuff below */
+ if (sym)
+ goto symbol_found;
+
+ /* Couldn't find any interpretation as classes/namespaces, so give up */
+ error_begin ();
+ /* The quotes are important if copy is empty. */
+ printf_filtered
+ ("Can't find member of namespace, class, struct, or union named \"%s\"\n", copy);
+ cplusplus_hint (saved_arg);
+ return_to_top_level (RETURN_ERROR);
+ }
/* end of C++ */
@@ -2130,6 +2852,34 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
while (*p == ' ' || *p == '\t') p++;
*argptr = p;
}
+ else {
+ /* Check if what we have till now is a symbol name */
+
+ /* We may be looking at a template instantiation such
+ as "foo<int>". Check here whether we know about it,
+ instead of falling through to the code below which
+ handles ordinary function names, because that code
+ doesn't like seeing '<' and '>' in a name -- the
+ skip_quoted call doesn't go past them. So see if we
+ can figure it out right now. */
+
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\000';
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ if (sym) {
+ /* Yes, we have a symbol; jump to symbol processing */
+ /* Code after symbol_found expects S, SYM_SYMTAB, SYM,
+ and COPY to be set correctly */
+ if (has_if)
+ *ii = ' ';
+ *argptr = (*p == '\'') ? p + 1 : p;
+ s = (struct symtab *) 0;
+ goto symbol_found;
+ }
+ /* Otherwise fall out from here and go to file/line spec
+ processing, etc. */
+ }
/* S is specified file's symtab, or 0 if no file specified.
arg no longer contains the file name. */
@@ -2190,9 +2940,17 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
*argptr = q;
if (s == 0)
s = default_symtab;
- val.symtab = s;
+
+ /* It is possible that this source file has more than one symtab,
+ and that the new line number specification has moved us from the
+ default (in s) to a new one. */
+ val.symtab = find_line_symtab (s, val.line, NULL, NULL);
+ if (val.symtab == 0)
+ val.symtab = s;
+
val.pc = 0;
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
values.sals[0] = val;
values.nelts = 1;
if (need_canonical)
@@ -2203,8 +2961,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
/* Arg token is not digits => try it as a variable name
Find the next token (everything up to end or next whitespace). */
- if (**argptr == '$') /* Convenience variable */
- p = skip_quoted (*argptr + 1);
+ if (**argptr == '$') /* May be a convenience variable */
+ p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); /* One or two $ chars possible */
else if (is_quoted)
{
p = skip_quoted (*argptr);
@@ -2234,17 +2992,58 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
while (*p == ' ' || *p == '\t') p++;
*argptr = p;
- /* See if it's a convenience variable */
+ /* If it starts with $: may be a legitimate variable or routine name
+ (e.g. HP-UX millicode routines such as $$dyncall), or it may
+ be history value, or it may be a convenience variable */
if (*copy == '$')
{
value_ptr valx;
- int need_canonical = (s == 0) ? 1 : 0;
-
- valx = value_of_internalvar (lookup_internalvar (copy + 1));
- if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
- error ("Convenience variables used in line specs must have integer values.");
+ int index = 0;
+ int need_canonical = 0;
+
+ p = (copy[1] == '$') ? copy + 2 : copy + 1;
+ while (*p >= '0' && *p <= '9')
+ p++;
+ if (!*p) /* reached end of token without hitting non-digit */
+ {
+ /* We have a value history reference */
+ sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index);
+ valx = access_value_history ((copy[1] == '$') ? -index : index);
+ if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+ error ("History values used in line specs must have integer values.");
+ }
+ else
+ {
+ /* Not all digits -- may be user variable/function or a
+ convenience variable */
+
+ /* Look up entire name as a symbol first */
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ s = (struct symtab *) 0;
+ need_canonical = 1;
+ /* Symbol was found --> jump to normal symbol processing.
+ Code following "symbol_found" expects "copy" to have the
+ symbol name, "sym" to have the symbol pointer, "s" to be
+ a specified file's symtab, and sym_symtab to be the symbol's
+ symtab. */
+ if (sym)
+ goto symbol_found;
+
+ /* If symbol was not found, look in minimal symbol tables */
+ msymbol = lookup_minimal_symbol (copy, 0, 0);
+ /* Min symbol was found --> jump to minsym processing. */
+ if (msymbol)
+ goto minimal_symbol_found;
+
+ /* Not a user variable or function -- must be convenience variable */
+ need_canonical = (s == 0) ? 1 : 0;
+ valx = value_of_internalvar (lookup_internalvar (copy + 1));
+ if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+ error ("Convenience variables used in line specs must have integer values.");
+ }
+ /* Either history value or convenience value from above, in valx */
val.symtab = s ? s : default_symtab;
val.line = value_as_long (valx);
val.pc = 0;
@@ -2267,13 +3066,17 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
(s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
: get_selected_block ()),
VAR_NAMESPACE, 0, &sym_symtab);
+
+symbol_found: /* We also jump here from inside the C++ class/namespace
+ code on finding a symbol of the form "A::B::C" */
if (sym != NULL)
{
if (SYMBOL_CLASS (sym) == LOC_BLOCK)
{
/* Arg is the name of a function */
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
values.sals[0] = find_function_start_sal (sym, funfirstline);
values.nelts = 1;
@@ -2318,18 +3121,22 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
}
msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+
+minimal_symbol_found: /* We also jump here from the case for variables
+ that begin with '$' */
+
if (msymbol != NULL)
{
- val.symtab = 0;
- val.line = 0;
- val.pc = SYMBOL_VALUE_ADDRESS (msymbol);
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = find_pc_sect_line ( SYMBOL_VALUE_ADDRESS (msymbol),
+ (struct sec *)0,0 );
+ values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
if (funfirstline)
{
- val.pc += FUNCTION_START_OFFSET;
- SKIP_PROLOGUE (val.pc);
+ values.sals[0].pc += FUNCTION_START_OFFSET;
+ SKIP_PROLOGUE (values.sals[0].pc);
}
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
- values.sals[0] = val;
values.nelts = 1;
return values;
}
@@ -2378,8 +3185,10 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
struct cleanup *old_chain;
char **canonical_arr = (char **)NULL;
- values.sals = (struct symtab_and_line *) alloca (nelts * sizeof(struct symtab_and_line));
- return_values.sals = (struct symtab_and_line *) xmalloc (nelts * sizeof(struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ alloca (nelts * sizeof(struct symtab_and_line));
+ return_values.sals = (struct symtab_and_line *)
+ xmalloc (nelts * sizeof(struct symtab_and_line));
old_chain = make_cleanup (free, return_values.sals);
if (canonical)
@@ -2394,6 +3203,8 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
printf_unfiltered("[0] cancel\n[1] all\n");
while (i < nelts)
{
+ INIT_SAL (&return_values.sals[i]); /* initialize to zeroes */
+ INIT_SAL (&values.sals[i]);
if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
{
values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
@@ -2410,12 +3221,9 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
if ((prompt = getenv ("PS2")) == NULL)
{
- prompt = ">";
+ prompt = "> ";
}
- printf_unfiltered("%s ",prompt);
- gdb_flush(gdb_stdout);
-
- args = command_line_input ((char *) NULL, 0, "overload-choice");
+ args = command_line_input (prompt, 0, "overload-choice");
if (args == 0 || *args == 0)
error_no_arg ("one or more choice numbers");
@@ -2454,7 +3262,7 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
return return_values;
}
- if (num > nelts + 2)
+ if (num >= nelts + 2)
{
printf_unfiltered ("No choice number %d.\n", num);
}
@@ -2583,37 +3391,75 @@ sources_info (ignore, from_tty)
printf_filtered ("\n");
}
-/* List all symbols (if REGEXP is NULL) or all symbols matching REGEXP.
- If CLASS is zero, list all symbols except functions, type names, and
- constants (enums).
- If CLASS is 1, list only functions.
- If CLASS is 2, list only type names.
- If CLASS is 3, list only method names.
+static int
+file_matches (file, files, nfiles)
+ char *file;
+ char *files[];
+ int nfiles;
+{
+ int i;
- BPT is non-zero if we should set a breakpoint at the functions
- we find. */
+ if (file != NULL && nfiles != 0)
+ {
+ for (i = 0; i < nfiles; i++)
+ {
+ if (strcmp (files[i], basename (file)) == 0)
+ return 1;
+ }
+ }
+ else if (nfiles == 0)
+ return 1;
+ return 0;
+}
-static void
-list_symbols (regexp, class, bpt, from_tty)
+/* Free any memory associated with a search. */
+void
+free_search_symbols (symbols)
+ struct symbol_search *symbols;
+{
+ struct symbol_search *p;
+ struct symbol_search *next;
+
+ for (p = symbols; p != NULL; p = next)
+ {
+ next = p->next;
+ free (p);
+ }
+}
+
+/* Search the symbol table for matches to the regular expression REGEXP,
+ returning the results in *MATCHES.
+
+ Only symbols of KIND are searched:
+ FUNCTIONS_NAMESPACE - search all functions
+ TYPES_NAMESPACE - search all type names
+ METHODS_NAMESPACE - search all methods NOT IMPLEMENTED
+ VARIABLES_NAMESPACE - search all symbols, excluding functions, type names,
+ and constants (enums)
+
+ free_search_symbols should be called when *MATCHES is no longer needed.
+*/
+void
+search_symbols (regexp, kind, nfiles, files, matches)
char *regexp;
- int class;
- int bpt;
- int from_tty;
+ namespace_enum kind;
+ int nfiles;
+ char *files[];
+ struct symbol_search **matches;
+
{
register struct symtab *s;
register struct partial_symtab *ps;
register struct blockvector *bv;
struct blockvector *prev_bv = 0;
register struct block *b;
- register int i, j;
+ register int i = 0;
+ register int j;
register struct symbol *sym;
struct partial_symbol **psym;
struct objfile *objfile;
struct minimal_symbol *msymbol;
char *val;
- static char *classnames[]
- = {"variable", "function", "type", "method"};
- int found_in_file = 0;
int found_misc = 0;
static enum minimal_symbol_type types[]
= {mst_data, mst_text, mst_abs, mst_unknown};
@@ -2623,45 +3469,60 @@ list_symbols (regexp, class, bpt, from_tty)
= {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
static enum minimal_symbol_type types4[]
= {mst_file_bss, mst_text, mst_abs, mst_unknown};
- enum minimal_symbol_type ourtype = types[class];
- enum minimal_symbol_type ourtype2 = types2[class];
- enum minimal_symbol_type ourtype3 = types3[class];
- enum minimal_symbol_type ourtype4 = types4[class];
+ enum minimal_symbol_type ourtype;
+ enum minimal_symbol_type ourtype2;
+ enum minimal_symbol_type ourtype3;
+ enum minimal_symbol_type ourtype4;
+ struct symbol_search *sr;
+ struct symbol_search *psr;
+ struct symbol_search *tail;
+ struct cleanup *old_chain = NULL;
+
+ if (kind < LABEL_NAMESPACE)
+ error ("must search on specific namespace");
+
+ ourtype = types[(int) (kind - LABEL_NAMESPACE)];
+ ourtype2 = types2[(int) (kind - LABEL_NAMESPACE)];
+ ourtype3 = types3[(int) (kind - LABEL_NAMESPACE)];
+ ourtype4 = types4[(int) (kind - LABEL_NAMESPACE)];
+
+ sr = *matches = NULL;
+ tail = NULL;
if (regexp != NULL)
{
/* Make sure spacing is right for C++ operators.
- This is just a courtesy to make the matching less sensitive
- to how many spaces the user leaves between 'operator'
- and <TYPENAME> or <OPERATOR>. */
+ This is just a courtesy to make the matching less sensitive
+ to how many spaces the user leaves between 'operator'
+ and <TYPENAME> or <OPERATOR>. */
char *opend;
char *opname = operator_chars (regexp, &opend);
if (*opname)
- {
+ {
int fix = -1; /* -1 means ok; otherwise number of spaces needed. */
- if (isalpha(*opname) || *opname == '_' || *opname == '$')
- {
- /* There should 1 space between 'operator' and 'TYPENAME'. */
- if (opname[-1] != ' ' || opname[-2] == ' ')
- fix = 1;
- }
- else
- {
- /* There should 0 spaces between 'operator' and 'OPERATOR'. */
- if (opname[-1] == ' ')
- fix = 0;
- }
- /* If wrong number of spaces, fix it. */
- if (fix >= 0)
- {
- char *tmp = (char*) alloca(opend-opname+10);
- sprintf(tmp, "operator%.*s%s", fix, " ", opname);
- regexp = tmp;
- }
+ if (isalpha(*opname) || *opname == '_' || *opname == '$')
+ {
+ /* There should 1 space between 'operator' and 'TYPENAME'. */
+ if (opname[-1] != ' ' || opname[-2] == ' ')
+ fix = 1;
+ }
+ else
+ {
+ /* There should 0 spaces between 'operator' and 'OPERATOR'. */
+ if (opname[-1] == ' ')
+ fix = 0;
+ }
+ /* If wrong number of spaces, fix it. */
+ if (fix >= 0)
+ {
+ char *tmp = (char*) alloca(opend-opname+10);
+ sprintf(tmp, "operator%.*s%s", fix, " ", opname);
+ regexp = tmp;
+ }
}
if (0 != (val = re_comp (regexp)))
- error ("Invalid regexp (%s): %s", val, regexp);
+ error ("Invalid regexp (%s): %s", val, regexp);
}
/* Search through the partial symtabs *first* for all symbols
@@ -2672,48 +3533,49 @@ list_symbols (regexp, class, bpt, from_tty)
{
struct partial_symbol **bound, **gbound, **sbound;
int keep_going = 1;
-
+
if (ps->readin) continue;
-
+
gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms;
sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms;
bound = gbound;
/* Go through all of the symbols stored in a partial
- symtab in one loop. */
+ symtab in one loop. */
psym = objfile->global_psymbols.list + ps->globals_offset;
while (keep_going)
- {
- if (psym >= bound)
- {
- if (bound == gbound && ps->n_static_syms != 0)
- {
- psym = objfile->static_psymbols.list + ps->statics_offset;
- bound = sbound;
- }
- else
- keep_going = 0;
- continue;
- }
- else
- {
- QUIT;
-
- /* If it would match (logic taken from loop below)
- load the file and go on to the next one */
- if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
- && ((class == 0 && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
- && SYMBOL_CLASS (*psym) != LOC_BLOCK)
- || (class == 1 && SYMBOL_CLASS (*psym) == LOC_BLOCK)
- || (class == 2 && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
- || (class == 3 && SYMBOL_CLASS (*psym) == LOC_BLOCK)))
- {
- PSYMTAB_TO_SYMTAB(ps);
- keep_going = 0;
- }
- }
- psym++;
- }
+ {
+ if (psym >= bound)
+ {
+ if (bound == gbound && ps->n_static_syms != 0)
+ {
+ psym = objfile->static_psymbols.list + ps->statics_offset;
+ bound = sbound;
+ }
+ else
+ keep_going = 0;
+ continue;
+ }
+ else
+ {
+ QUIT;
+
+ /* If it would match (logic taken from loop below)
+ load the file and go on to the next one */
+ if (file_matches (ps->filename, files, nfiles)
+ && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
+ && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+ || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
+ || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+ {
+ PSYMTAB_TO_SYMTAB(ps);
+ keep_going = 0;
+ }
+ }
+ psym++;
+ }
}
/* Here, we search through the minimal symbol tables for functions
@@ -2729,191 +3591,269 @@ list_symbols (regexp, class, bpt, from_tty)
any matching symbols without debug info.
*/
- if (class == 0 || class == 1)
+ if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE))
{
ALL_MSYMBOLS (objfile, msymbol)
- {
- if (MSYMBOL_TYPE (msymbol) == ourtype ||
- MSYMBOL_TYPE (msymbol) == ourtype2 ||
- MSYMBOL_TYPE (msymbol) == ourtype3 ||
- MSYMBOL_TYPE (msymbol) == ourtype4)
- {
- if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
- {
- if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
- {
- if (class == 1
- || lookup_symbol (SYMBOL_NAME (msymbol),
- (struct block *) NULL,
- VAR_NAMESPACE,
- 0, (struct symtab **) NULL) == NULL)
- found_misc = 1;
- }
- }
- }
- }
+ {
+ if (MSYMBOL_TYPE (msymbol) == ourtype ||
+ MSYMBOL_TYPE (msymbol) == ourtype2 ||
+ MSYMBOL_TYPE (msymbol) == ourtype3 ||
+ MSYMBOL_TYPE (msymbol) == ourtype4)
+ {
+ if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ {
+ if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
+ {
+ if (kind == FUNCTIONS_NAMESPACE
+ || lookup_symbol (SYMBOL_NAME (msymbol),
+ (struct block *) NULL,
+ VAR_NAMESPACE,
+ 0, (struct symtab **) NULL) == NULL)
+ found_misc = 1;
+ }
+ }
+ }
+ }
}
- /* Printout here so as to get after the "Reading in symbols"
- messages which will be generated above. */
- if (!bpt)
- printf_filtered (regexp
- ? "All %ss matching regular expression \"%s\":\n"
- : "All defined %ss:\n",
- classnames[class],
- regexp);
-
ALL_SYMTABS (objfile, s)
{
- found_in_file = 0;
bv = BLOCKVECTOR (s);
/* Often many files share a blockvector.
- Scan each blockvector only once so that
- we don't get every symbol many times.
- It happens that the first symtab in the list
- for any given blockvector is the main file. */
+ Scan each blockvector only once so that
+ we don't get every symbol many times.
+ It happens that the first symtab in the list
+ for any given blockvector is the main file. */
if (bv != prev_bv)
- for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- /* Skip the sort if this block is always sorted. */
- if (!BLOCK_SHOULD_SORT (b))
- sort_block_syms (b);
- for (j = 0; j < BLOCK_NSYMS (b); j++)
- {
- QUIT;
- sym = BLOCK_SYM (b, j);
- if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
- && ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
- && SYMBOL_CLASS (sym) != LOC_BLOCK
- && SYMBOL_CLASS (sym) != LOC_CONST)
- || (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
- || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- || (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
- {
- if (bpt)
- {
- /* Set a breakpoint here, if it's a function */
- if (class == 1)
- {
- /* There may be more than one function with the
- same name but in different files. In order to
- set breakpoints on all of them, we must give
- both the file name and the function name to
- break_command.
- Quoting the symbol name gets rid of problems
- with mangled symbol names that contain
- CPLUS_MARKER characters. */
- char *string =
- (char *) alloca (strlen (s->filename)
- + strlen (SYMBOL_NAME(sym))
- + 4);
- strcpy (string, s->filename);
- strcat (string, ":'");
- strcat (string, SYMBOL_NAME(sym));
- strcat (string, "'");
- break_command (string, from_tty);
- }
- }
- else if (!found_in_file)
- {
- fputs_filtered ("\nFile ", gdb_stdout);
- fputs_filtered (s->filename, gdb_stdout);
- fputs_filtered (":\n", gdb_stdout);
- }
- found_in_file = 1;
-
- if (class != 2 && i == STATIC_BLOCK)
- printf_filtered ("static ");
-
- /* Typedef that is not a C++ class */
- if (class == 2
- && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
- c_typedef_print (SYMBOL_TYPE(sym), sym, gdb_stdout);
- /* variable, func, or typedef-that-is-c++-class */
- else if (class < 2 ||
- (class == 2 &&
- SYMBOL_NAMESPACE(sym) == STRUCT_NAMESPACE))
- {
- type_print (SYMBOL_TYPE (sym),
- (SYMBOL_CLASS (sym) == LOC_TYPEDEF
- ? "" : SYMBOL_SOURCE_NAME (sym)),
- gdb_stdout, 0);
-
- printf_filtered (";\n");
- }
- else
- {
-# if 0 /* FIXME, why is this zapped out? */
- char buf[1024];
- c_type_print_base (TYPE_FN_FIELD_TYPE(t, i),
- gdb_stdout, 0, 0);
- c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i),
- gdb_stdout, 0);
- sprintf (buf, " %s::", type_name_no_tag (t));
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (t, i),
- buf, name, gdb_stdout);
-# endif
- }
- }
- }
- }
+ for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
+ {
+ b = BLOCKVECTOR_BLOCK (bv, i);
+ /* Skip the sort if this block is always sorted. */
+ if (!BLOCK_SHOULD_SORT (b))
+ sort_block_syms (b);
+ for (j = 0; j < BLOCK_NSYMS (b); j++)
+ {
+ QUIT;
+ sym = BLOCK_SYM (b, j);
+ if (file_matches (s->filename, files, nfiles)
+ && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
+ && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (sym) != LOC_BLOCK
+ && SYMBOL_CLASS (sym) != LOC_CONST)
+ || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+ {
+ /* match */
+ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+ psr->block = i;
+ psr->symtab = s;
+ psr->symbol = sym;
+ psr->msymbol = NULL;
+ psr->next = NULL;
+ if (tail == NULL)
+ {
+ sr = psr;
+ old_chain = make_cleanup ((make_cleanup_func)
+ free_search_symbols, sr);
+ }
+ else
+ tail->next = psr;
+ tail = psr;
+ }
+ }
+ }
prev_bv = bv;
}
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols, then print directly from the msymbol_vector. */
- if (found_misc || class != 1)
+ if (found_misc || kind != FUNCTIONS_NAMESPACE)
{
- found_in_file = 0;
ALL_MSYMBOLS (objfile, msymbol)
- {
- if (MSYMBOL_TYPE (msymbol) == ourtype ||
- MSYMBOL_TYPE (msymbol) == ourtype2 ||
- MSYMBOL_TYPE (msymbol) == ourtype3 ||
- MSYMBOL_TYPE (msymbol) == ourtype4)
- {
- if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
- {
- /* Functions: Look up by address. */
- if (class != 1 ||
- (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
- {
- /* Variables/Absolutes: Look up by name */
- if (lookup_symbol (SYMBOL_NAME (msymbol),
- (struct block *) NULL, VAR_NAMESPACE,
- 0, (struct symtab **) NULL) == NULL)
- {
- if (bpt)
+ {
+ if (MSYMBOL_TYPE (msymbol) == ourtype ||
+ MSYMBOL_TYPE (msymbol) == ourtype2 ||
+ MSYMBOL_TYPE (msymbol) == ourtype3 ||
+ MSYMBOL_TYPE (msymbol) == ourtype4)
+ {
+ if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ {
+ /* Functions: Look up by address. */
+ if (kind != FUNCTIONS_NAMESPACE ||
+ (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
+ {
+ /* Variables/Absolutes: Look up by name */
+ if (lookup_symbol (SYMBOL_NAME (msymbol),
+ (struct block *) NULL, VAR_NAMESPACE,
+ 0, (struct symtab **) NULL) == NULL)
+ {
+ /* match */
+ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+ psr->block = i;
+ psr->msymbol = msymbol;
+ psr->symtab = NULL;
+ psr->symbol = NULL;
+ psr->next = NULL;
+ if (tail == NULL)
{
- break_command (SYMBOL_NAME (msymbol), from_tty);
- printf_filtered ("<function, no debug info> %s;\n",
- SYMBOL_SOURCE_NAME (msymbol));
- continue;
+ sr = psr;
+ old_chain = make_cleanup ((make_cleanup_func)
+ free_search_symbols, &sr);
}
- if (!found_in_file)
- {
- printf_filtered ("\nNon-debugging symbols:\n");
- found_in_file = 1;
- }
- printf_filtered (" %08lx %s\n",
- (unsigned long) SYMBOL_VALUE_ADDRESS (msymbol),
- SYMBOL_SOURCE_NAME (msymbol));
- }
- }
- }
- }
- }
+ else
+ tail->next = psr;
+ tail = psr;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ *matches = sr;
+ if (sr != NULL)
+ discard_cleanups (old_chain);
+}
+
+/* Helper function for symtab_symbol_info, this function uses
+ the data returned from search_symbols() to print information
+ regarding the match to gdb_stdout.
+*/
+static void
+print_symbol_info (kind, s, sym, block, last)
+ namespace_enum kind;
+ struct symtab *s;
+ struct symbol *sym;
+ int block;
+ char *last;
+{
+ if (last == NULL || strcmp (last, s->filename) != 0)
+ {
+ fputs_filtered ("\nFile ", gdb_stdout);
+ fputs_filtered (s->filename, gdb_stdout);
+ fputs_filtered (":\n", gdb_stdout);
+ }
+
+ if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK)
+ printf_filtered ("static ");
+
+ /* Typedef that is not a C++ class */
+ if (kind == TYPES_NAMESPACE
+ && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
+ c_typedef_print (SYMBOL_TYPE(sym), sym, gdb_stdout);
+ /* variable, func, or typedef-that-is-c++-class */
+ else if (kind < TYPES_NAMESPACE ||
+ (kind == TYPES_NAMESPACE &&
+ SYMBOL_NAMESPACE(sym) == STRUCT_NAMESPACE))
+ {
+ type_print (SYMBOL_TYPE (sym),
+ (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+ ? "" : SYMBOL_SOURCE_NAME (sym)),
+ gdb_stdout, 0);
+
+ printf_filtered (";\n");
+ }
+ else
+ {
+# if 0
+ /* Tiemann says: "info methods was never implemented." */
+ char *demangled_name;
+ c_type_print_base (TYPE_FN_FIELD_TYPE(t, block),
+ gdb_stdout, 0, 0);
+ c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, block),
+ gdb_stdout, 0);
+ if (TYPE_FN_FIELD_STUB (t, block))
+ check_stub_method (TYPE_DOMAIN_TYPE (type), j, block);
+ demangled_name =
+ cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ fprintf_filtered (stream, "<badly mangled name %s>",
+ TYPE_FN_FIELD_PHYSNAME (t, block));
+ else
+ {
+ fputs_filtered (demangled_name, stream);
+ free (demangled_name);
+ }
+# endif
}
}
+/* This help function for symtab_symbol_info() prints information
+ for non-debugging symbols to gdb_stdout.
+*/
+static void
+print_msymbol_info (msymbol)
+ struct minimal_symbol *msymbol;
+{
+ printf_filtered (" %08lx %s\n",
+ (unsigned long) SYMBOL_VALUE_ADDRESS (msymbol),
+ SYMBOL_SOURCE_NAME (msymbol));
+}
+
+/* This is the guts of the commands "info functions", "info types", and
+ "info variables". It calls search_symbols to find all matches and then
+ print_[m]symbol_info to print out some useful information about the
+ matches.
+*/
+static void
+symtab_symbol_info (regexp, kind, from_tty)
+ char *regexp;
+ namespace_enum kind;
+ int from_tty;
+{
+ static char *classnames[]
+ = {"variable", "function", "type", "method"};
+ struct symbol_search *symbols;
+ struct symbol_search *p;
+ struct cleanup *old_chain;
+ char *last_filename = NULL;
+ int first = 1;
+
+ /* must make sure that if we're interrupted, symbols gets freed */
+ search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
+ old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, symbols);
+
+ printf_filtered (regexp
+ ? "All %ss matching regular expression \"%s\":\n"
+ : "All defined %ss:\n",
+ classnames[(int) (kind - LABEL_NAMESPACE - 1)], regexp);
+
+ for (p = symbols; p != NULL; p = p->next)
+ {
+ QUIT;
+
+ if (p->msymbol != NULL)
+ {
+ if (first)
+ {
+ printf_filtered ("\nNon-debugging symbols:\n");
+ first = 0;
+ }
+ print_msymbol_info (p->msymbol);
+ }
+ else
+ {
+ print_symbol_info (kind,
+ p->symtab,
+ p->symbol,
+ p->block,
+ last_filename);
+ last_filename = p->symtab->filename;
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
static void
variables_info (regexp, from_tty)
char *regexp;
int from_tty;
{
- list_symbols (regexp, 0, 0, from_tty);
+ symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty);
}
static void
@@ -2921,7 +3861,7 @@ functions_info (regexp, from_tty)
char *regexp;
int from_tty;
{
- list_symbols (regexp, 1, 0, from_tty);
+ symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
}
static void
@@ -2929,7 +3869,7 @@ types_info (regexp, from_tty)
char *regexp;
int from_tty;
{
- list_symbols (regexp, 2, 0, from_tty);
+ symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty);
}
#if 0
@@ -2938,7 +3878,7 @@ static void
methods_info (regexp)
char *regexp;
{
- list_symbols (regexp, 3, 0, from_tty);
+ symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty);
}
#endif /* 0 */
@@ -2948,10 +3888,43 @@ rbreak_command (regexp, from_tty)
char *regexp;
int from_tty;
{
- list_symbols (regexp, 1, 1, from_tty);
+ struct symbol_search *ss;
+ struct symbol_search *p;
+ struct cleanup *old_chain;
+
+ search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
+ old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, ss);
+
+ for (p = ss; p != NULL; p = p->next)
+ {
+ if (p->msymbol == NULL)
+ {
+ char *string = (char *) alloca (strlen (p->symtab->filename)
+ + strlen (SYMBOL_NAME (p->symbol))
+ + 4);
+ strcpy (string, p->symtab->filename);
+ strcat (string, ":'");
+ strcat (string, SYMBOL_NAME (p->symbol));
+ strcat (string, "'");
+ break_command (string, from_tty);
+ print_symbol_info (FUNCTIONS_NAMESPACE,
+ p->symtab,
+ p->symbol,
+ p->block,
+ p->symtab->filename);
+ }
+ else
+ {
+ break_command (SYMBOL_NAME (p->msymbol), from_tty);
+ printf_filtered ("<function, no debug info> %s;\n",
+ SYMBOL_SOURCE_NAME (p->msymbol));
+ }
+ }
+
+ do_cleanups (old_chain);
}
-
+
/* Return Nonzero if block a is lexically nested within block b,
or if a and b have the same pc range.
Return zero otherwise. */
@@ -3258,7 +4231,7 @@ make_symbol_completion_list (text, word)
between the first instruction of a function, and the first executable line.
Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
- If non-zero, func_start is where we thing the prologue starts, possibly
+ If non-zero, func_start is where we think the prologue starts, possibly
by previous examination of symbol table information.
*/
@@ -3278,6 +4251,7 @@ in_prologue (pc, func_start)
if (sal.line == 0)
goto nosyms;
+ /* sal.end is the address of the first instruction past sal.line. */
if (sal.end > func_addr
&& sal.end <= func_end) /* Is prologue in function? */
return pc < sal.end; /* Yes, is pc in prologue? */
@@ -3307,12 +4281,203 @@ in_prologue (pc, func_start)
return pc < func_start;
}
+
+/* Begin overload resolution functions */
+/* Helper routine for make_symbol_completion_list. */
+
+static int sym_return_val_size;
+static int sym_return_val_index;
+static struct symbol **sym_return_val;
+
+/* Test to see if the symbol specified by SYMNAME (which is already
+ demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
+ characters. If so, add it to the current completion list. */
+
+static void
+overload_list_add_symbol (sym, oload_name)
+ struct symbol * sym;
+ char * oload_name;
+{
+ int newsize;
+ int i;
+
+ /* Get the demangled name without parameters */
+ char * sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
+ if (!sym_name)
+ {
+ sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
+ strcpy (sym_name, SYMBOL_NAME (sym));
+ }
+
+ /* skip symbols that cannot match */
+ if (strcmp (sym_name, oload_name) != 0)
+ return;
+
+ /* If there is no type information, we can't do anything, so skip */
+ if (SYMBOL_TYPE (sym) == NULL)
+ return;
+
+ /* skip any symbols that we've already considered. */
+ for (i = 0; i < sym_return_val_index; ++i)
+ if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
+ return;
+
+ /* We have a match for an overload instance, so add SYM to the current list
+ * of overload instances */
+ if (sym_return_val_index + 3 > sym_return_val_size)
+ {
+ newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
+ sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize);
+ }
+ sym_return_val[sym_return_val_index++] = sym;
+ sym_return_val[sym_return_val_index] = NULL;
+
+ free (sym_name);
+}
+
+/* Return a null-terminated list of pointers to function symbols that
+ * match name of the supplied symbol FSYM.
+ * This is used in finding all overloaded instances of a function name.
+ * This has been modified from make_symbol_completion_list. */
+
+
+struct symbol **
+make_symbol_overload_list (fsym)
+ struct symbol * fsym;
+{
+ register struct symbol *sym;
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct minimal_symbol *msymbol;
+ register struct objfile *objfile;
+ register struct block *b, *surrounding_static_block = 0;
+ register int i, j;
+ struct partial_symbol **psym;
+ /* The name we are completing on. */
+ char *oload_name = NULL;
+ /* Length of name. */
+ int oload_name_len = 0;
+
+ /* Look for the symbol we are supposed to complete on.
+ * FIXME: This should be language-specific. */
+
+ oload_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_ARM | DMGL_ANSI);
+ if (!oload_name)
+ {
+ oload_name = (char *) xmalloc (strlen (SYMBOL_NAME (fsym)) + 1);
+ strcpy (oload_name, SYMBOL_NAME (fsym));
+ }
+ oload_name_len = strlen (oload_name);
+
+ sym_return_val_size = 100;
+ sym_return_val_index = 0;
+ sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
+ sym_return_val[0] = NULL;
+
+ /* Look through the partial symtabs for all symbols which begin
+ by matching OLOAD_NAME. Add each one that you find to the list. */
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin) continue;
+
+ for (psym = objfile->global_psymbols.list + ps->globals_offset;
+ psym < (objfile->global_psymbols.list + ps->globals_offset
+ + ps->n_global_syms);
+ psym++)
+ {
+ /* If interrupted, then quit. */
+ QUIT;
+ overload_list_add_symbol (*psym, oload_name);
+ }
+
+ for (psym = objfile->static_psymbols.list + ps->statics_offset;
+ psym < (objfile->static_psymbols.list + ps->statics_offset
+ + ps->n_static_syms);
+ psym++)
+ {
+ QUIT;
+ overload_list_add_symbol (*psym, oload_name);
+ }
+ }
+
+ /* At this point scan through the misc symbol vectors and add each
+ symbol you find to the list. Eventually we want to ignore
+ anything that isn't a text symbol (everything else will be
+ handled by the psymtab code above). */
+
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ QUIT;
+ overload_list_add_symbol (msymbol, oload_name);
+ }
+
+ /* Search upwards from currently selected frame (so that we can
+ complete on local vars. */
+
+ for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ {
+ if (!BLOCK_SUPERBLOCK (b))
+ {
+ surrounding_static_block = b; /* For elimination of dups */
+ }
+
+ /* Also catch fields of types defined in this places which match our
+ text string. Only complete on types visible from current context. */
+
+ for (i = 0; i < BLOCK_NSYMS (b); i++)
+ {
+ sym = BLOCK_SYM (b, i);
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ for (i = 0; i < BLOCK_NSYMS (b); i++)
+ {
+ sym = BLOCK_SYM (b, i);
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block) continue;
+ for (i = 0; i < BLOCK_NSYMS (b); i++)
+ {
+ sym = BLOCK_SYM (b, i);
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ free (oload_name);
+
+ return (sym_return_val);
+}
+
+/* End of overload resolution functions */
+
void
_initialize_symtab ()
{
add_info ("variables", variables_info,
"All global and static variable names, or those matching REGEXP.");
+ if (dbx_commands)
+ add_com("whereis", class_info, variables_info,
+ "All global and static variable names, or those matching REGEXP.");
+
add_info ("functions", functions_info,
"All function names, or those matching REGEXP.");
@@ -3337,9 +4502,16 @@ are listed.");
add_info ("sources", sources_info,
"Source files in the program.");
- add_com ("rbreak", no_class, rbreak_command,
+ add_com ("rbreak", class_breakpoint, rbreak_command,
"Set a breakpoint for all functions matching REGEXP.");
+ if (xdb_commands)
+ {
+ add_com ("lf", class_info, sources_info, "Source files in the program");
+ add_com ("lg", class_info, variables_info,
+ "All global and static variable names, or those matching REGEXP.");
+ }
+
/* Initialize the one built-in type that isn't language dependent... */
builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
"<unknown type>", (struct objfile *) NULL);
diff --git a/contrib/gdb/gdb/symtab.h b/contrib/gdb/gdb/symtab.h
index 274d198..67e6bed 100644
--- a/contrib/gdb/gdb/symtab.h
+++ b/contrib/gdb/gdb/symtab.h
@@ -1,5 +1,6 @@
/* Symbol table definitions for GDB.
- Copyright 1986, 1989, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1986, 89, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -85,6 +86,7 @@ struct general_symbol_info
union
{
struct cplus_specific /* For C++ */
+ /* and Java */
{
char *demangled_name;
} cplus_specific;
@@ -108,8 +110,14 @@ struct general_symbol_info
also tries to set it correctly). */
short section;
+
+ /* The bfd section associated with this symbol. */
+
+ asection *bfd_section;
};
+extern CORE_ADDR symbol_overlayed_address PARAMS((CORE_ADDR, asection *));
+
#define SYMBOL_NAME(symbol) (symbol)->ginfo.name
#define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue
#define SYMBOL_VALUE_ADDRESS(symbol) (symbol)->ginfo.value.address
@@ -118,6 +126,7 @@ struct general_symbol_info
#define SYMBOL_VALUE_CHAIN(symbol) (symbol)->ginfo.value.chain
#define SYMBOL_LANGUAGE(symbol) (symbol)->ginfo.language
#define SYMBOL_SECTION(symbol) (symbol)->ginfo.section
+#define SYMBOL_BFD_SECTION(symbol) (symbol)->ginfo.bfd_section
#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \
(symbol)->ginfo.language_specific.cplus_specific.demangled_name
@@ -128,7 +137,9 @@ struct general_symbol_info
#define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
do { \
SYMBOL_LANGUAGE (symbol) = language; \
- if (SYMBOL_LANGUAGE (symbol) == language_cplus) \
+ if (SYMBOL_LANGUAGE (symbol) == language_cplus \
+ || SYMBOL_LANGUAGE (symbol) == language_java \
+ ) \
{ \
SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \
} \
@@ -172,6 +183,23 @@ struct general_symbol_info
SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \
} \
} \
+ if (SYMBOL_LANGUAGE (symbol) == language_java) \
+ { \
+ demangled = \
+ cplus_demangle (SYMBOL_NAME (symbol), \
+ DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); \
+ if (demangled != NULL) \
+ { \
+ SYMBOL_LANGUAGE (symbol) = language_java; \
+ SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = \
+ obsavestring (demangled, strlen (demangled), (obstack)); \
+ free (demangled); \
+ } \
+ else \
+ { \
+ SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \
+ } \
+ } \
if (demangled == NULL \
&& (SYMBOL_LANGUAGE (symbol) == language_chill \
|| SYMBOL_LANGUAGE (symbol) == language_auto)) \
@@ -201,6 +229,7 @@ struct general_symbol_info
#define SYMBOL_DEMANGLED_NAME(symbol) \
(SYMBOL_LANGUAGE (symbol) == language_cplus \
+ || SYMBOL_LANGUAGE (symbol) == language_java \
? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \
: (SYMBOL_LANGUAGE (symbol) == language_chill \
? SYMBOL_CHILL_DEMANGLED_NAME (symbol) \
@@ -274,14 +303,17 @@ struct minimal_symbol
struct general_symbol_info ginfo;
- /* The info field is available for caching machine-specific information that
- The AMD 29000 tdep.c uses it to remember things it has decoded from the
- instructions in the function header, so it doesn't have to rederive the
- info constantly (over a serial line). It is initialized to zero and
- stays that way until target-dependent code sets it. Storage for any data
- pointed to by this field should be allocated on the symbol_obstack for
- the associated objfile. The type would be "void *" except for reasons
- of compatibility with older compilers. This field is optional. */
+ /* The info field is available for caching machine-specific information
+ so it doesn't have to rederive the info constantly (over a serial line).
+ It is initialized to zero and stays that way until target-dependent code
+ sets it. Storage for any data pointed to by this field should be allo-
+ cated on the symbol_obstack for the associated objfile.
+ The type would be "void *" except for reasons of compatibility with older
+ compilers. This field is optional.
+
+ Currently, the AMD 29000 tdep.c uses it to remember things it has decoded
+ from the instructions in the function header, and the MIPS-16 code uses
+ it to identify 16-bit procedures. */
char *info;
@@ -320,7 +352,6 @@ struct minimal_symbol
mst_file_data, /* Static version of mst_data */
mst_file_bss /* Static version of mst_bss */
} type BYTE_BITFIELD;
-
};
#define MSYMBOL_INFO(msymbol) (msymbol)->info
@@ -456,7 +487,24 @@ typedef enum
/* LABEL_NAMESPACE may be used for names of labels (for gotos);
currently it is not used and labels are not recorded at all. */
- LABEL_NAMESPACE
+ LABEL_NAMESPACE,
+
+ /* Searching namespaces. These overlap with VAR_NAMESPACE, providing
+ some granularity with the search_symbols function. */
+
+ /* Everything in VAR_NAMESPACE minus FUNCTIONS_-, TYPES_-, and
+ METHODS_NAMESPACE */
+ VARIABLES_NAMESPACE,
+
+ /* All functions -- for some reason not methods, though. */
+ FUNCTIONS_NAMESPACE,
+
+ /* All defined types */
+ TYPES_NAMESPACE,
+
+ /* All class methods -- why is this separated out? */
+ METHODS_NAMESPACE
+
} namespace_enum;
/* An address-class says where to find the value of a symbol. */
@@ -572,12 +620,44 @@ enum address_class
LOC_UNRESOLVED,
+ /* Value is at a thread-specific location calculated by a
+ target-specific method. */
+
+ LOC_THREAD_LOCAL_STATIC,
+
/* The variable does not actually exist in the program.
The value is ignored. */
- LOC_OPTIMIZED_OUT
+ LOC_OPTIMIZED_OUT,
+
+ /* The variable is static, but actually lives at * (address).
+ * I.e. do an extra indirection to get to it.
+ * This is used on HP-UX to get at globals that are allocated
+ * in shared libraries, where references from images other
+ * than the one where the global was allocated are done
+ * with a level of indirection.
+ */
+
+ LOC_INDIRECT
+
};
+/* Linked list of symbol's live ranges. */
+
+struct range_list
+{
+ CORE_ADDR start;
+ CORE_ADDR end;
+ struct range_list *next;
+};
+
+/* Linked list of aliases for a particular main/primary symbol. */
+struct alias_list
+ {
+ struct symbol *sym;
+ struct alias_list *next;
+ };
+
struct symbol
{
@@ -591,6 +671,11 @@ struct symbol
/* Name space code. */
+#ifdef __MFC4__
+ /* FIXME: don't conflict with C++'s namespace */
+ /* would be safer to do a global change for all namespace identifiers. */
+ #define namespace _namespace
+#endif
namespace_enum namespace BYTE_BITFIELD;
/* Address class */
@@ -612,13 +697,25 @@ struct symbol
short basereg;
}
aux_value;
+
+
+ /* Link to a list of aliases for this symbol.
+ Only a "primary/main symbol may have aliases. */
+ struct alias_list *aliases;
+
+ /* List of ranges where this symbol is active. This is only
+ used by alias symbols at the current time. */
+ struct range_list *ranges;
};
+
#define SYMBOL_NAMESPACE(symbol) (symbol)->namespace
#define SYMBOL_CLASS(symbol) (symbol)->aclass
#define SYMBOL_TYPE(symbol) (symbol)->type
#define SYMBOL_LINE(symbol) (symbol)->line
#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg
+#define SYMBOL_ALIASES(symbol) (symbol)->aliases
+#define SYMBOL_RANGES(symbol) (symbol)->ranges
/* A partial_symbol records the name, namespace, and address class of
symbols whose types we have not parsed yet. For functions, it also
@@ -717,6 +814,13 @@ struct section_offsets
#define ANOFFSET(secoff, whichone) (secoff->offsets[whichone])
+/* The maximum possible size of a section_offsets table. */
+
+#define SIZEOF_SECTION_OFFSETS \
+ (sizeof (struct section_offsets) \
+ + sizeof (((struct section_offsets *) 0)->offsets) * (SECT_OFF_MAX-1))
+
+
/* Each source file or header is represented by a struct symtab.
These objects are chained through the `next' field. */
@@ -789,6 +893,13 @@ struct symtab
enum language language;
+ /* String that identifies the format of the debugging information, such
+ as "stabs", "dwarf 1", "dwarf 2", "coff", etc. This is mostly useful
+ for automated testing of gdb but may also be information that is
+ useful to the user. */
+
+ char *debugformat;
+
/* String of version information. May be zero. */
char *version;
@@ -802,14 +913,6 @@ struct symtab
struct objfile *objfile;
- /* Anything extra for this symtab. This is for target machines
- with special debugging info of some sort (which cannot just
- be represented in a normal symtab). */
-
-#if defined (EXTRA_SYMTAB_INFO)
- EXTRA_SYMTAB_INFO
-#endif
-
};
#define BLOCKVECTOR(symtab) (symtab)->blockvector
@@ -974,17 +1077,27 @@ extern int currently_reading_symtab;
extern int demangle;
extern int asm_demangle;
+/* symtab.c lookup functions */
+
+/* lookup a symbol table by source file name */
+
extern struct symtab *
lookup_symtab PARAMS ((char *));
+/* lookup a symbol by name (optional block, optional symtab) */
+
extern struct symbol *
lookup_symbol PARAMS ((const char *, const struct block *,
const namespace_enum, int *, struct symtab **));
+/* lookup a symbol by name, within a specified block */
+
extern struct symbol *
lookup_block_symbol PARAMS ((const struct block *, const char *,
const namespace_enum));
+/* lookup a [struct, union, enum] by name, within a specified block */
+
extern struct type *
lookup_struct PARAMS ((char *, struct block *));
@@ -994,30 +1107,73 @@ lookup_union PARAMS ((char *, struct block *));
extern struct type *
lookup_enum PARAMS ((char *, struct block *));
+/* lookup the function corresponding to the block */
+
extern struct symbol *
block_function PARAMS ((struct block *));
+/* from blockframe.c: */
+
+/* lookup the function symbol corresponding to the address */
+
extern struct symbol *
find_pc_function PARAMS ((CORE_ADDR));
-extern int find_pc_partial_function
- PARAMS ((CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *));
+/* lookup the function corresponding to the address and section */
+
+extern struct symbol *
+find_pc_sect_function PARAMS ((CORE_ADDR, asection *));
+
+/* lookup function from address, return name, start addr and end addr */
+
+extern int
+find_pc_partial_function PARAMS ((CORE_ADDR, char **,
+ CORE_ADDR *, CORE_ADDR *));
extern void
clear_pc_function_cache PARAMS ((void));
+extern int
+find_pc_sect_partial_function PARAMS ((CORE_ADDR, asection *,
+ char **, CORE_ADDR *, CORE_ADDR *));
+
+/* from symtab.c: */
+
+/* lookup partial symbol table by filename */
+
extern struct partial_symtab *
lookup_partial_symtab PARAMS ((char *));
+/* lookup partial symbol table by address */
+
extern struct partial_symtab *
find_pc_psymtab PARAMS ((CORE_ADDR));
+/* lookup partial symbol table by address and section */
+
+extern struct partial_symtab *
+find_pc_sect_psymtab PARAMS ((CORE_ADDR, asection *));
+
+/* lookup full symbol table by address */
+
extern struct symtab *
find_pc_symtab PARAMS ((CORE_ADDR));
+/* lookup full symbol table by address and section */
+
+extern struct symtab *
+find_pc_sect_symtab PARAMS ((CORE_ADDR, asection *));
+
+/* lookup partial symbol by address */
+
extern struct partial_symbol *
find_pc_psymbol PARAMS ((struct partial_symtab *, CORE_ADDR));
+/* lookup partial symbol by address and section */
+
+extern struct partial_symbol *
+find_pc_sect_psymbol PARAMS ((struct partial_symtab *, CORE_ADDR, asection *));
+
extern int
find_pc_line_pc_range PARAMS ((CORE_ADDR, CORE_ADDR *, CORE_ADDR *));
@@ -1027,6 +1183,10 @@ contained_in PARAMS ((struct block *, struct block *));
extern void
reread_symbols PARAMS ((void));
+extern struct type *
+lookup_transparent_type PARAMS ((const char *));
+
+
/* Macro for name of symbol to indicate a file compiled with gcc. */
#ifndef GCC_COMPILED_FLAG_SYMBOL
#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."
@@ -1048,6 +1208,7 @@ extern struct minimal_symbol *prim_record_minimal_symbol_and_info
PARAMS ((const char *, CORE_ADDR,
enum minimal_symbol_type,
char *info, int section,
+ asection *bfd_section,
struct objfile *));
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
@@ -1071,6 +1232,9 @@ extern struct minimal_symbol *
lookup_minimal_symbol_by_pc PARAMS ((CORE_ADDR));
extern struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section PARAMS ((CORE_ADDR, asection *));
+
+extern struct minimal_symbol *
lookup_solib_trampoline_symbol_by_pc PARAMS ((CORE_ADDR));
extern CORE_ADDR
@@ -1092,7 +1256,7 @@ extern void msymbols_sort PARAMS ((struct objfile *objfile));
struct symtab_and_line
{
struct symtab *symtab;
-
+ asection *section;
/* Line number. Line numbers start at 1 and proceed through symtab->nlines.
0 is never a valid line number; it is used to indicate that line number
information is not available. */
@@ -1102,18 +1266,66 @@ struct symtab_and_line
CORE_ADDR end;
};
+#define INIT_SAL(sal) { \
+ (sal)->symtab = 0; \
+ (sal)->section = 0; \
+ (sal)->line = 0; \
+ (sal)->pc = 0; \
+ (sal)->end = 0; \
+}
+
struct symtabs_and_lines
{
struct symtab_and_line *sals;
int nelts;
};
+
+
+/* Some types and macros needed for exception catchpoints.
+ Can't put these in target.h because symtab_and_line isn't
+ known there. This file will be included by breakpoint.c,
+ hppa-tdep.c, etc. */
+
+/* Enums for exception-handling support */
+enum exception_event_kind {
+ EX_EVENT_THROW,
+ EX_EVENT_CATCH
+};
+
+/* Type for returning info about an exception */
+struct exception_event_record {
+ enum exception_event_kind kind;
+ struct symtab_and_line throw_sal;
+ struct symtab_and_line catch_sal;
+ /* This may need to be extended in the future, if
+ some platforms allow reporting more information,
+ such as point of rethrow, type of exception object,
+ type expected by catch clause, etc. */
+};
+
+#define CURRENT_EXCEPTION_KIND (current_exception_event->kind)
+#define CURRENT_EXCEPTION_CATCH_SAL (current_exception_event->catch_sal)
+#define CURRENT_EXCEPTION_CATCH_LINE (current_exception_event->catch_sal.line)
+#define CURRENT_EXCEPTION_CATCH_FILE (current_exception_event->catch_sal.symtab->filename)
+#define CURRENT_EXCEPTION_CATCH_PC (current_exception_event->catch_sal.pc)
+#define CURRENT_EXCEPTION_THROW_SAL (current_exception_event->throw_sal)
+#define CURRENT_EXCEPTION_THROW_LINE (current_exception_event->throw_sal.line)
+#define CURRENT_EXCEPTION_THROW_FILE (current_exception_event->throw_sal.symtab->filename)
+#define CURRENT_EXCEPTION_THROW_PC (current_exception_event->throw_sal.pc)
+
+
/* Given a pc value, return line number it is in. Second arg nonzero means
if pc is on the boundary use the previous statement's line number. */
extern struct symtab_and_line
find_pc_line PARAMS ((CORE_ADDR, int));
+/* Same function, but specify a section as well as an address */
+
+extern struct symtab_and_line
+find_pc_sect_line PARAMS ((CORE_ADDR, asection *, int));
+
/* Given an address, return the nearest symbol at or below it in memory.
Optionally return the symtab it's from through 2nd arg, and the
address in inferior memory of the symbol through 3rd arg. */
@@ -1123,8 +1335,8 @@ find_addr_symbol PARAMS ((CORE_ADDR, struct symtab **, CORE_ADDR *));
/* Given a symtab and line number, return the pc there. */
-extern CORE_ADDR
-find_line_pc PARAMS ((struct symtab *, int));
+extern int
+find_line_pc PARAMS ((struct symtab *, int, CORE_ADDR *));
extern int
find_line_pc_range PARAMS ((struct symtab_and_line,
@@ -1145,10 +1357,10 @@ decode_line_spec_1 PARAMS ((char *, int));
extern struct symtabs_and_lines
decode_line_1 PARAMS ((char **, int, struct symtab *, int, char ***));
-/* Symmisc.c */
-
#if MAINTENANCE_CMDS
+/* Symmisc.c */
+
void
maintenance_print_symbols PARAMS ((char *, int));
@@ -1164,6 +1376,11 @@ maintenance_print_objfiles PARAMS ((char *, int));
void
maintenance_check_symtabs PARAMS ((char *, int));
+/* maint.c */
+
+void
+maintenance_print_statistics PARAMS ((char *, int));
+
#endif
extern void
@@ -1178,7 +1395,7 @@ extern void
clear_solib PARAMS ((void));
extern struct objfile *
-symbol_file_add PARAMS ((char *, int, CORE_ADDR, int, int, int));
+symbol_file_add PARAMS ((char *, int, CORE_ADDR, int, int, int, int, int));
/* source.c */
@@ -1196,6 +1413,9 @@ select_source_symtab PARAMS ((struct symtab *));
extern char **make_symbol_completion_list PARAMS ((char *, char *));
+extern struct symbol **
+make_symbol_overload_list PARAMS ((struct symbol *));
+
/* symtab.c */
extern struct partial_symtab *
@@ -1206,6 +1426,10 @@ find_main_psymtab PARAMS ((void));
extern struct blockvector *
blockvector_for_pc PARAMS ((CORE_ADDR, int *));
+extern struct blockvector *
+blockvector_for_pc_sect PARAMS ((CORE_ADDR, asection *, int *,
+ struct symtab *));
+
/* symfile.c */
extern void
@@ -1219,4 +1443,35 @@ deduce_language_from_filename PARAMS ((char *));
extern int
in_prologue PARAMS ((CORE_ADDR pc, CORE_ADDR func_start));
+extern struct symbol *
+fixup_symbol_section PARAMS ((struct symbol *, struct objfile *));
+
+/* Symbol searching */
+
+/* When using search_symbols, a list of the following structs is returned.
+ Callers must free the search list using free_symbol_search! */
+struct symbol_search
+{
+ /* The block in which the match was found. Could be, for example,
+ STATIC_BLOCK or GLOBAL_BLOCK. */
+ int block;
+
+ /* Information describing what was found.
+
+ If symtab abd symbol are NOT NULL, then information was found
+ for this match. */
+ struct symtab *symtab;
+ struct symbol *symbol;
+
+ /* If msymbol is non-null, then a match was made on something for
+ which only minimal_symbols exist. */
+ struct minimal_symbol *msymbol;
+
+ /* A link to the next match, or NULL for the end. */
+ struct symbol_search *next;
+};
+
+extern void search_symbols PARAMS ((char *, namespace_enum, int, char **, struct symbol_search **));
+extern void free_search_symbols PARAMS ((struct symbol_search *));
+
#endif /* !defined(SYMTAB_H) */
diff --git a/contrib/gdb/gdb/target.c b/contrib/gdb/gdb/target.c
index fc0dfd9..808eb8f 100644
--- a/contrib/gdb/gdb/target.c
+++ b/contrib/gdb/gdb/target.c
@@ -1,5 +1,5 @@
/* Select target systems and architectures at runtime for GDB.
- Copyright 1990, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1990, 1992-1995, 1998, 1999 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB.
@@ -44,6 +44,9 @@ static void
maybe_kill_then_create_inferior PARAMS ((char *, char *, char **));
static void
+default_clone_and_follow_inferior PARAMS ((int, int *));
+
+static void
maybe_kill_then_attach PARAMS ((char *, int));
static void
@@ -64,8 +67,11 @@ nomemory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
static int
return_zero PARAMS ((void));
-static void
-ignore PARAMS ((void));
+static int
+return_one PARAMS ((void));
+
+void
+target_ignore PARAMS ((void));
static void
target_command PARAMS ((char *, int));
@@ -73,6 +79,103 @@ target_command PARAMS ((char *, int));
static struct target_ops *
find_default_run_target PARAMS ((char *));
+static void
+update_current_target PARAMS ((void));
+
+/* Transfer LEN bytes between target address MEMADDR and GDB address MYADDR.
+ Returns 0 for success, errno code for failure (which includes partial
+ transfers--if you want a more useful response to partial transfers, try
+ target_read_memory_partial). */
+
+static int
+target_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len,
+ int write, asection *bfd_section));
+
+static void init_dummy_target PARAMS ((void));
+
+static void
+debug_to_open PARAMS ((char *, int));
+
+static void
+debug_to_close PARAMS ((int));
+
+static void
+debug_to_attach PARAMS ((char *, int));
+
+static void
+debug_to_detach PARAMS ((char *, int));
+
+static void
+debug_to_resume PARAMS ((int, int, enum target_signal));
+
+static int
+debug_to_wait PARAMS ((int, struct target_waitstatus *));
+
+static void
+debug_to_fetch_registers PARAMS ((int));
+
+static void
+debug_to_store_registers PARAMS ((int));
+
+static void
+debug_to_prepare_to_store PARAMS ((void));
+
+static int
+debug_to_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
+
+static void
+debug_to_files_info PARAMS ((struct target_ops *));
+
+static int
+debug_to_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int
+debug_to_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static void
+debug_to_terminal_init PARAMS ((void));
+
+static void
+debug_to_terminal_inferior PARAMS ((void));
+
+static void
+debug_to_terminal_ours_for_output PARAMS ((void));
+
+static void
+debug_to_terminal_ours PARAMS ((void));
+
+static void
+debug_to_terminal_info PARAMS ((char *, int));
+
+static void
+debug_to_kill PARAMS ((void));
+
+static void
+debug_to_load PARAMS ((char *, int));
+
+static int
+debug_to_lookup_symbol PARAMS ((char *, CORE_ADDR *));
+
+static void
+debug_to_create_inferior PARAMS ((char *, char *, char **));
+
+static void
+debug_to_mourn_inferior PARAMS ((void));
+
+static int
+debug_to_can_run PARAMS ((void));
+
+static void
+debug_to_notice_signals PARAMS ((int));
+
+static int
+debug_to_thread_alive PARAMS ((int));
+
+static void
+debug_to_stop PARAMS ((void));
+
+static int debug_to_query PARAMS ((int/*char*/, char *, char *, int *));
+
/* Pointer to array of target architecture structures; the size of the
array; the current index into the array; the allocated size of the
array. */
@@ -85,48 +188,7 @@ unsigned target_struct_allocsize;
/* The initial current target, so that there is always a semi-valid
current target. */
-struct target_ops dummy_target = {
- "None", /* to_shortname */
- "None", /* to_longname */
- "", /* to_doc */
- 0, /* to_open */
- 0, /* to_close */
- find_default_attach, /* to_attach */
- 0, /* to_detach */
- 0, /* to_resume */
- 0, /* to_wait */
- 0, /* to_fetch_registers */
- 0, /* to_store_registers */
- 0, /* to_prepare_to_store */
- 0, /* to_xfer_memory */
- 0, /* to_files_info */
- 0, /* to_insert_breakpoint */
- 0, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- 0, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- find_default_create_inferior, /* to_create_inferior */
- 0, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- dummy_stratum, /* to_stratum */
- 0, /* to_next */
- 0, /* to_next */
- 0, /* to_has_all_memory */
- 0, /* to_has_memory */
- 0, /* to_has_registers */
- 0, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC, /* to_magic */
-};
+static struct target_ops dummy_target;
/* Top of target stack. */
@@ -202,8 +264,8 @@ information on the arguments for a particular protocol, type\n\
/* Stub functions */
-static void
-ignore ()
+void
+target_ignore ()
{
}
@@ -230,7 +292,7 @@ tcomplain ()
void
noprocess ()
{
- error ("You can't do that without a process to debug");
+ error ("You can't do that without a process to debug.");
}
/* ARGSUSED */
@@ -243,6 +305,17 @@ nosymbol (name, addrp)
}
/* ARGSUSED */
+void
+nosupport_runtime ()
+{
+ if (!inferior_pid)
+ noprocess ();
+ else
+ error ("No run-time support for this");
+}
+
+
+/* ARGSUSED */
static void
default_terminal_info (args, from_tty)
char *args;
@@ -295,6 +368,14 @@ maybe_kill_then_create_inferior (exec, args, env)
target_create_inferior (exec, args, env);
}
+static void
+default_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ target_clone_and_follow_inferior (child_pid, followed_child);
+}
+
/* Clean up a target struct so it no longer has any zero pointers in it.
We default entries, at least to stubs that print error messages. */
@@ -308,34 +389,61 @@ cleanup_target (t)
/* FIELD DEFAULT VALUE */
- de_fault (to_open, (void (*)())tcomplain);
- de_fault (to_close, (void (*)())ignore);
+ de_fault (to_open, (void (*) PARAMS((char *, int))) tcomplain);
+ de_fault (to_close, (void (*) PARAMS((int))) target_ignore);
de_fault (to_attach, maybe_kill_then_attach);
- de_fault (to_detach, (void (*)())ignore);
- de_fault (to_resume, (void (*)())noprocess);
- de_fault (to_wait, (int (*)())noprocess);
- de_fault (to_fetch_registers, (void (*)())ignore);
- de_fault (to_store_registers, (void (*)())noprocess);
- de_fault (to_prepare_to_store, (void (*)())noprocess);
- de_fault (to_xfer_memory, (int (*)())nomemory);
- de_fault (to_files_info, (void (*)())ignore);
+ de_fault (to_post_attach, (void (*) PARAMS ((int))) target_ignore);
+ de_fault (to_require_attach, maybe_kill_then_attach);
+ de_fault (to_detach, (void (*) PARAMS((char *, int))) target_ignore);
+ de_fault (to_require_detach, (void (*) PARAMS((int, char *, int))) target_ignore);
+ de_fault (to_resume, (void (*) PARAMS((int, int, enum target_signal))) noprocess);
+ de_fault (to_wait, (int (*) PARAMS((int, struct target_waitstatus *))) noprocess);
+ de_fault (to_post_wait, (void (*) PARAMS ((int, int))) target_ignore);
+ de_fault (to_fetch_registers, (void (*) PARAMS((int))) target_ignore);
+ de_fault (to_store_registers, (void (*) PARAMS((int))) noprocess);
+ de_fault (to_prepare_to_store, (void (*) PARAMS((void))) noprocess);
+ de_fault (to_xfer_memory, (int (*) PARAMS((CORE_ADDR, char *, int, int, struct target_ops *))) nomemory);
+ de_fault (to_files_info, (void (*) PARAMS((struct target_ops *))) target_ignore);
de_fault (to_insert_breakpoint, memory_insert_breakpoint);
de_fault (to_remove_breakpoint, memory_remove_breakpoint);
- de_fault (to_terminal_init, ignore);
- de_fault (to_terminal_inferior, ignore);
- de_fault (to_terminal_ours_for_output,ignore);
- de_fault (to_terminal_ours, ignore);
+ de_fault (to_terminal_init, (void (*) PARAMS((void))) target_ignore);
+ de_fault (to_terminal_inferior, (void (*) PARAMS ((void))) target_ignore);
+ de_fault (to_terminal_ours_for_output,(void (*) PARAMS ((void))) target_ignore);
+ de_fault (to_terminal_ours, (void (*) PARAMS ((void))) target_ignore);
de_fault (to_terminal_info, default_terminal_info);
- de_fault (to_kill, (void (*)())noprocess);
- de_fault (to_load, (void (*)())tcomplain);
- de_fault (to_lookup_symbol, nosymbol);
+ de_fault (to_kill, (void (*) PARAMS((void))) noprocess);
+ de_fault (to_load, (void (*) PARAMS((char *, int))) tcomplain);
+ de_fault (to_lookup_symbol, (int (*) PARAMS ((char *, CORE_ADDR *))) nosymbol);
de_fault (to_create_inferior, maybe_kill_then_create_inferior);
- de_fault (to_mourn_inferior, (void (*)())noprocess);
+ de_fault (to_post_startup_inferior, (void (*) PARAMS ((int))) target_ignore);
+ de_fault (to_acknowledge_created_inferior, (void (*) PARAMS((int))) target_ignore);
+ de_fault (to_clone_and_follow_inferior, default_clone_and_follow_inferior);
+ de_fault (to_post_follow_inferior_by_clone, (void (*) PARAMS ((void))) target_ignore);
+ de_fault (to_insert_fork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_remove_fork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_insert_vfork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_remove_vfork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_has_forked, (int (*) PARAMS ((int, int *))) return_zero);
+ de_fault (to_has_vforked, (int (*) PARAMS ((int, int *))) return_zero);
+ de_fault (to_can_follow_vfork_prior_to_exec, (int (*) PARAMS ((void ))) return_zero);
+ de_fault (to_post_follow_vfork, (void (*) PARAMS ((int, int, int, int))) target_ignore);
+ de_fault (to_insert_exec_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_remove_exec_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_has_execd, (int (*) PARAMS ((int, char **))) return_zero);
+ de_fault (to_reported_exec_events_per_exec_call, (int (*) PARAMS ((void))) return_one);
+ de_fault (to_has_syscall_event, (int (*) PARAMS ((int, enum target_waitkind *, int *))) return_zero);
+ de_fault (to_has_exited, (int (*) PARAMS ((int, int, int *))) return_zero);
+ de_fault (to_mourn_inferior, (void (*) PARAMS ((void))) noprocess);
de_fault (to_can_run, return_zero);
- de_fault (to_notice_signals, (void (*)())ignore);
- de_fault (to_thread_alive, (int (*)())ignore);
- de_fault (to_stop, (void (*)())ignore);
-
+ de_fault (to_notice_signals, (void (*) PARAMS((int))) target_ignore);
+ de_fault (to_thread_alive, (int (*) PARAMS((int))) target_ignore);
+ de_fault (to_stop, (void (*) PARAMS((void))) target_ignore);
+ de_fault (to_query, (int (*) PARAMS((int/*char*/, char*, char *, int *))) target_ignore);
+ de_fault (to_enable_exception_callback, (struct symtab_and_line * (*) PARAMS((enum exception_event_kind, int))) nosupport_runtime);
+ de_fault (to_get_current_exception_event, (struct exception_event_record * (*) PARAMS((void))) nosupport_runtime);
+
+ de_fault (to_pid_to_exec_file, (char* (*) PARAMS((int))) return_zero);
+ de_fault (to_core_file_to_sym_file, (char* (*) PARAMS ((char *))) return_zero);
#undef de_fault
}
@@ -366,9 +474,13 @@ update_current_target ()
INHERIT (to_open, t);
INHERIT (to_close, t);
INHERIT (to_attach, t);
+ INHERIT (to_post_attach, t);
+ INHERIT (to_require_attach, t);
INHERIT (to_detach, t);
+ INHERIT (to_require_detach, t);
INHERIT (to_resume, t);
INHERIT (to_wait, t);
+ INHERIT (to_post_wait, t);
INHERIT (to_fetch_registers, t);
INHERIT (to_store_registers, t);
INHERIT (to_prepare_to_store, t);
@@ -385,11 +497,34 @@ update_current_target ()
INHERIT (to_load, t);
INHERIT (to_lookup_symbol, t);
INHERIT (to_create_inferior, t);
+ INHERIT (to_post_startup_inferior, t);
+ INHERIT (to_acknowledge_created_inferior, t);
+ INHERIT (to_clone_and_follow_inferior, t);
+ INHERIT (to_post_follow_inferior_by_clone, t);
+ INHERIT (to_insert_fork_catchpoint, t);
+ INHERIT (to_remove_fork_catchpoint, t);
+ INHERIT (to_insert_vfork_catchpoint, t);
+ INHERIT (to_remove_vfork_catchpoint, t);
+ INHERIT (to_has_forked, t);
+ INHERIT (to_has_vforked, t);
+ INHERIT (to_can_follow_vfork_prior_to_exec, t);
+ INHERIT (to_post_follow_vfork, t);
+ INHERIT (to_insert_exec_catchpoint, t);
+ INHERIT (to_remove_exec_catchpoint, t);
+ INHERIT (to_has_execd, t);
+ INHERIT (to_reported_exec_events_per_exec_call, t);
+ INHERIT (to_has_syscall_event, t);
+ INHERIT (to_has_exited, t);
INHERIT (to_mourn_inferior, t);
INHERIT (to_can_run, t);
INHERIT (to_notice_signals, t);
INHERIT (to_thread_alive, t);
INHERIT (to_stop, t);
+ INHERIT (to_query, t);
+ INHERIT (to_enable_exception_callback, t);
+ INHERIT (to_get_current_exception_event, t);
+ INHERIT (to_pid_to_exec_file, t);
+ INHERIT (to_core_file_to_sym_file, t);
INHERIT (to_stratum, t);
INHERIT (DONT_USE, t);
INHERIT (to_has_all_memory, t);
@@ -397,6 +532,7 @@ update_current_target ()
INHERIT (to_has_stack, t);
INHERIT (to_has_registers, t);
INHERIT (to_has_execution, t);
+ INHERIT (to_has_thread_control, t);
INHERIT (to_sections, t);
INHERIT (to_sections_end, t);
INHERIT (to_magic, t);
@@ -445,7 +581,8 @@ push_target (t)
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 (cur->target_ops->to_close)
+ (cur->target_ops->to_close) (0);
if (prev)
prev->next = cur->next; /* Unchain old target_ops */
else
@@ -565,9 +702,18 @@ target_read_string (memaddr, string, len, errnop)
tlen = MIN (len, 4 - (memaddr & 3));
offset = memaddr & 3;
- errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0);
+ errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0, NULL);
if (errcode != 0)
- goto done;
+ {
+ /* The transfer request might have crossed the boundary to an
+ unallocated region of memory. Retry the transfer, requesting
+ a single byte. */
+ tlen = 1;
+ offset = 0;
+ errcode = target_xfer_memory (memaddr, buf, 1, 0, NULL);
+ if (errcode != 0)
+ goto done;
+ }
if (bufptr - buffer + tlen > buffer_allocated)
{
@@ -616,7 +762,17 @@ target_read_memory (memaddr, myaddr, len)
char *myaddr;
int len;
{
- return target_xfer_memory (memaddr, myaddr, len, 0);
+ return target_xfer_memory (memaddr, myaddr, len, 0, NULL);
+}
+
+int
+target_read_memory_section (memaddr, myaddr, len, bfd_section)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ asection *bfd_section;
+{
+ return target_xfer_memory (memaddr, myaddr, len, 0, bfd_section);
}
/* Read LEN bytes of target memory at address MEMADDR, placing the results
@@ -635,7 +791,7 @@ target_read_memory_partial (memaddr, myaddr, len, errnoptr)
int errcode; /* Error from last read. */
/* First try a complete read. */
- errcode = target_xfer_memory (memaddr, myaddr, len, 0);
+ errcode = target_xfer_memory (memaddr, myaddr, len, 0, NULL);
if (errcode == 0)
{
/* Got it all. */
@@ -646,7 +802,7 @@ target_read_memory_partial (memaddr, myaddr, len, errnoptr)
/* Loop, reading one byte at a time until we get as much as we can. */
for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
{
- errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0);
+ errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0, NULL);
}
/* If an error, the last read was unsuccessful, so adjust count. */
if (errcode != 0)
@@ -667,9 +823,15 @@ target_write_memory (memaddr, myaddr, len)
char *myaddr;
int len;
{
- return target_xfer_memory (memaddr, myaddr, len, 1);
+ return target_xfer_memory (memaddr, myaddr, len, 1, NULL);
}
+/* This variable is used to pass section information down to targets. This
+ *should* be done by adding an argument to the target_xfer_memory function
+ of all the targets, but I didn't feel like changing 50+ files. */
+
+asection *target_memory_bfd_section = NULL;
+
/* Move memory to or from the targets. Iterate until all of it has
been moved, if necessary. The top target gets priority; anything
it doesn't want, is offered to the next one down, etc. Note the
@@ -680,18 +842,25 @@ target_write_memory (memaddr, myaddr, len)
Result is 0 or errno value. */
-int
-target_xfer_memory (memaddr, myaddr, len, write)
+static int
+target_xfer_memory (memaddr, myaddr, len, write, bfd_section)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
+ asection *bfd_section;
{
int curlen;
int res;
struct target_ops *t;
struct target_stack_item *item;
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ return 0;
+
+ target_memory_bfd_section = bfd_section;
+
/* to_xfer_memory is not guaranteed to set errno, even when it returns
0. */
errno = 0;
@@ -875,6 +1044,31 @@ find_default_attach (args, from_tty)
}
void
+find_default_require_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct target_ops *t;
+
+ t = find_default_run_target("require_attach");
+ (t->to_require_attach) (args, from_tty);
+ return;
+}
+
+void
+find_default_require_detach (pid, args, from_tty)
+ int pid;
+ char * args;
+ int from_tty;
+{
+ struct target_ops *t;
+
+ t = find_default_run_target("require_detach");
+ (t->to_require_detach) (pid, args, from_tty);
+ return;
+}
+
+void
find_default_create_inferior (exec_file, allargs, env)
char *exec_file;
char *allargs;
@@ -887,12 +1081,30 @@ find_default_create_inferior (exec_file, allargs, env)
return;
}
+void
+find_default_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ struct target_ops *t;
+
+ t = find_default_run_target("run");
+ (t->to_clone_and_follow_inferior) (child_pid, followed_child);
+ return;
+}
+
static int
return_zero ()
{
return 0;
}
+static int
+return_one ()
+{
+ return 1;
+}
+
struct target_ops *
find_core_target ()
{
@@ -924,7 +1136,7 @@ generic_mourn_inferior ()
inferior_pid = 0;
attach_flag = 0;
- breakpoint_init_inferior ();
+ breakpoint_init_inferior (inf_exited);
registers_changed ();
#ifdef CLEAR_DEFERRED_STORES
@@ -990,7 +1202,7 @@ static struct {
{"SIGLWP", "Signal LWP"},
{"SIGDANGER", "Swap space dangerously low"},
{"SIGGRANT", "Monitor mode granted"},
- {"SIGRETRACT", "Need to relinguish monitor mode"},
+ {"SIGRETRACT", "Need to relinquish monitor mode"},
{"SIGMSG", "Monitor mode data available"},
{"SIGSOUND", "Sound completed"},
{"SIGSAK", "Secure attention"},
@@ -1027,6 +1239,15 @@ static struct {
{"SIG62", "Real-time event 62"},
{"SIG63", "Real-time event 63"},
+#if defined(MACH) || defined(__MACH__)
+ /* Mach exceptions */
+ {"EXC_BAD_ACCESS", "Could not access memory"},
+ {"EXC_BAD_INSTRUCTION", "Illegal instruction/operand"},
+ {"EXC_ARITHMETIC", "Arithmetic exception"},
+ {"EXC_EMULATION", "Emulation instruction"},
+ {"EXC_SOFTWARE", "Software generated exception"},
+ {"EXC_BREAKPOINT", "Breakpoint"},
+#endif
{NULL, "Unknown signal"},
{NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"},
@@ -1224,6 +1445,27 @@ target_signal_from_host (hostsig)
#if defined (SIGPRIO)
if (hostsig == SIGPRIO) return TARGET_SIGNAL_PRIO;
#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_ACCESS) return TARGET_EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_INSTRUCTION) return TARGET_EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_ARITHMETIC) return TARGET_EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_EMULATION) return TARGET_EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_SOFTWARE) return TARGET_EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BREAKPOINT) return TARGET_EXC_BREAKPOINT;
+#endif
+
#if defined (REALTIME_LO)
if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
return (enum target_signal)
@@ -1377,6 +1619,27 @@ target_signal_to_host (oursig)
#if defined (SIGPRIO)
case TARGET_SIGNAL_PRIO: return SIGPRIO;
#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ case TARGET_EXC_BAD_ACCESS: return _NSIG + EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ case TARGET_EXC_BAD_INSTRUCTION: return _NSIG + EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ case TARGET_EXC_ARITHMETIC: return _NSIG + EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ case TARGET_EXC_EMULATION: return _NSIG + EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ case TARGET_EXC_SOFTWARE: return _NSIG + EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ case TARGET_EXC_BREAKPOINT: return _NSIG + EXC_BREAKPOINT;
+#endif
+
default:
#if defined (REALTIME_LO)
if (oursig >= TARGET_SIGNAL_REALTIME_33
@@ -1460,12 +1723,50 @@ normal_pid_to_str (pid)
static char buf[30];
if (STREQ (current_target.to_shortname, "remote"))
- sprintf (buf, "thread %d", pid);
+ sprintf (buf, "thread %d\0", pid);
else
- sprintf (buf, "process %d", pid);
+ sprintf (buf, "process %d\0", pid);
return buf;
}
+
+/* Some targets (such as ttrace-based HPUX) don't allow us to request
+ notification of inferior events such as fork and vork immediately
+ after the inferior is created. (This because of how gdb gets an
+ inferior created via invoking a shell to do it. In such a scenario,
+ if the shell init file has commands in it, the shell will fork and
+ exec for each of those commands, and we will see each such fork
+ event. Very bad.)
+
+ This function is used by all targets that allow us to request
+ notification of forks, etc at inferior creation time; e.g., in
+ target_acknowledge_forked_child.
+ */
+void
+normal_target_post_startup_inferior (pid)
+ int pid;
+{
+ /* This space intentionally left blank. */
+}
+
+/* Set up the handful of non-empty slots needed by the dummy target
+ vector. */
+
+static void
+init_dummy_target ()
+{
+ dummy_target.to_shortname = "None";
+ dummy_target.to_longname = "None";
+ dummy_target.to_doc = "";
+ dummy_target.to_attach = find_default_attach;
+ dummy_target.to_require_attach = find_default_require_attach;
+ dummy_target.to_require_detach = find_default_require_detach;
+ dummy_target.to_create_inferior = find_default_create_inferior;
+ dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ dummy_target.to_stratum = dummy_stratum;
+ dummy_target.to_magic = OPS_MAGIC;
+}
+
#ifdef MAINTENANCE_CMDS
static struct target_ops debug_target;
@@ -1477,7 +1778,7 @@ debug_to_open (args, from_tty)
{
debug_target.to_open (args, from_tty);
- fprintf_unfiltered (stderr, "target_open (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_open (%s, %d)\n", args, from_tty);
}
static void
@@ -1486,7 +1787,7 @@ debug_to_close (quitting)
{
debug_target.to_close (quitting);
- fprintf_unfiltered (stderr, "target_close (%d)\n", quitting);
+ fprintf_unfiltered (gdb_stderr, "target_close (%d)\n", quitting);
}
static void
@@ -1496,7 +1797,28 @@ debug_to_attach (args, from_tty)
{
debug_target.to_attach (args, from_tty);
- fprintf_unfiltered (stderr, "target_attach (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_attach (%s, %d)\n", args, from_tty);
+}
+
+
+static void
+debug_to_post_attach (pid)
+ int pid;
+{
+ debug_target.to_post_attach (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_post_attach (%d)\n", pid);
+}
+
+static void
+debug_to_require_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ debug_target.to_require_attach (args, from_tty);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_require_attach (%s, %d)\n", args, from_tty);
}
static void
@@ -1506,7 +1828,19 @@ debug_to_detach (args, from_tty)
{
debug_target.to_detach (args, from_tty);
- fprintf_unfiltered (stderr, "target_detach (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_detach (%s, %d)\n", args, from_tty);
+}
+
+static void
+debug_to_require_detach (pid, args, from_tty)
+ int pid;
+ char * args;
+ int from_tty;
+{
+ debug_target.to_require_detach (pid, args, from_tty);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_require_detach (%d, %s, %d)\n", pid, args, from_tty);
}
static void
@@ -1517,7 +1851,7 @@ debug_to_resume (pid, step, siggnal)
{
debug_target.to_resume (pid, step, siggnal);
- fprintf_unfiltered (stderr, "target_resume (%d, %s, %s)\n", pid,
+ fprintf_unfiltered (gdb_stderr, "target_resume (%d, %s, %s)\n", pid,
step ? "step" : "continue",
target_signal_to_name (siggnal));
}
@@ -1531,29 +1865,40 @@ debug_to_wait (pid, status)
retval = debug_target.to_wait (pid, status);
- fprintf_unfiltered (stderr, "target_wait (%d, status) = %d, ", pid, retval);
- fprintf_unfiltered (stderr, "status->kind = ");
+ fprintf_unfiltered (gdb_stderr,
+ "target_wait (%d, status) = %d, ", pid, retval);
+ fprintf_unfiltered (gdb_stderr, "status->kind = ");
switch (status->kind)
{
case TARGET_WAITKIND_EXITED:
- fprintf_unfiltered (stderr, "exited, status = %d\n", status->value.integer);
+ fprintf_unfiltered (gdb_stderr, "exited, status = %d\n",
+ status->value.integer);
break;
case TARGET_WAITKIND_STOPPED:
- fprintf_unfiltered (stderr, "stopped, signal = %s\n",
+ fprintf_unfiltered (gdb_stderr, "stopped, signal = %s\n",
target_signal_to_name (status->value.sig));
break;
case TARGET_WAITKIND_SIGNALLED:
- fprintf_unfiltered (stderr, "signalled, signal = %s\n",
+ fprintf_unfiltered (gdb_stderr, "signalled, signal = %s\n",
target_signal_to_name (status->value.sig));
break;
case TARGET_WAITKIND_LOADED:
- fprintf_unfiltered (stderr, "loaded\n");
+ fprintf_unfiltered (gdb_stderr, "loaded\n");
+ break;
+ case TARGET_WAITKIND_FORKED:
+ fprintf_unfiltered (gdb_stderr, "forked\n");
+ break;
+ case TARGET_WAITKIND_VFORKED:
+ fprintf_unfiltered (gdb_stderr, "vforked\n");
+ break;
+ case TARGET_WAITKIND_EXECD:
+ fprintf_unfiltered (gdb_stderr, "execd\n");
break;
case TARGET_WAITKIND_SPURIOUS:
- fprintf_unfiltered (stderr, "spurious\n");
+ fprintf_unfiltered (gdb_stderr, "spurious\n");
break;
default:
- fprintf_unfiltered (stderr, "unknown???\n");
+ fprintf_unfiltered (gdb_stderr, "unknown???\n");
break;
}
@@ -1561,17 +1906,29 @@ debug_to_wait (pid, status)
}
static void
+debug_to_post_wait (pid, status)
+ int pid;
+ int status;
+{
+ debug_target.to_post_wait (pid, status);
+
+ fprintf_unfiltered (gdb_stderr, "target_post_wait (%d, %d)\n",
+ pid, status);
+}
+
+static void
debug_to_fetch_registers (regno)
int regno;
{
debug_target.to_fetch_registers (regno);
- fprintf_unfiltered (stderr, "target_fetch_registers (%s)",
- regno != -1 ? reg_names[regno] : "-1");
+ fprintf_unfiltered (gdb_stderr, "target_fetch_registers (%s)",
+ regno != -1 ? REGISTER_NAME (regno) : "-1");
if (regno != -1)
- fprintf_unfiltered (stderr, " = 0x%x %d", read_register (regno),
+ fprintf_unfiltered (gdb_stderr, " = 0x%x %d",
+ (unsigned long) read_register (regno),
read_register (regno));
- fprintf_unfiltered (stderr, "\n");
+ fprintf_unfiltered (gdb_stderr, "\n");
}
static void
@@ -1581,11 +1938,12 @@ debug_to_store_registers (regno)
debug_target.to_store_registers (regno);
if (regno >= 0 && regno < NUM_REGS)
- fprintf_unfiltered (stderr, "target_store_registers (%s) = 0x%x %d\n",
- reg_names[regno], read_register (regno),
- read_register (regno));
+ fprintf_unfiltered (gdb_stderr, "target_store_registers (%s) = 0x%x %d\n",
+ REGISTER_NAME (regno),
+ (unsigned long) read_register (regno),
+ (unsigned long) read_register (regno));
else
- fprintf_unfiltered (stderr, "target_store_registers (%d)\n", regno);
+ fprintf_unfiltered (gdb_stderr, "target_store_registers (%d)\n", regno);
}
static void
@@ -1593,7 +1951,7 @@ debug_to_prepare_to_store ()
{
debug_target.to_prepare_to_store ();
- fprintf_unfiltered (stderr, "target_prepare_to_store ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_prepare_to_store ()\n");
}
static int
@@ -1608,8 +1966,12 @@ debug_to_xfer_memory (memaddr, myaddr, len, write, target)
retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
- fprintf_unfiltered (stderr, "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
- memaddr, len, write ? "write" : "read", retval);
+ fprintf_unfiltered (gdb_stderr,
+ "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
+ (unsigned int) memaddr, /* possable truncate long long */
+ len, write ? "write" : "read", retval);
+
+
if (retval > 0)
{
@@ -1617,7 +1979,11 @@ debug_to_xfer_memory (memaddr, myaddr, len, write, target)
fputs_unfiltered (", bytes =", gdb_stderr);
for (i = 0; i < retval; i++)
- fprintf_unfiltered (stderr, " %02x", myaddr[i] & 0xff);
+ {
+ if ((((long) &(myaddr[i])) & 0xf) == 0)
+ fprintf_unfiltered (gdb_stderr, "\n");
+ fprintf_unfiltered (gdb_stderr, " %02x", myaddr[i] & 0xff);
+ }
}
fputc_unfiltered ('\n', gdb_stderr);
@@ -1631,7 +1997,7 @@ debug_to_files_info (target)
{
debug_target.to_files_info (target);
- fprintf_unfiltered (stderr, "target_files_info (xxx)\n");
+ fprintf_unfiltered (gdb_stderr, "target_files_info (xxx)\n");
}
static int
@@ -1643,8 +2009,9 @@ debug_to_insert_breakpoint (addr, save)
retval = debug_target.to_insert_breakpoint (addr, save);
- fprintf_unfiltered (stderr, "target_insert_breakpoint (0x%x, xxx) = %d\n",
- addr, retval);
+ fprintf_unfiltered (gdb_stderr,
+ "target_insert_breakpoint (0x%x, xxx) = %d\n",
+ (unsigned long) addr, retval);
return retval;
}
@@ -1657,8 +2024,9 @@ debug_to_remove_breakpoint (addr, save)
retval = debug_target.to_remove_breakpoint (addr, save);
- fprintf_unfiltered (stderr, "target_remove_breakpoint (0x%x, xxx) = %d\n",
- addr, retval);
+ fprintf_unfiltered (gdb_stderr,
+ "target_remove_breakpoint (0x%x, xxx) = %d\n",
+ (unsigned long)addr, retval);
return retval;
}
@@ -1667,7 +2035,7 @@ debug_to_terminal_init ()
{
debug_target.to_terminal_init ();
- fprintf_unfiltered (stderr, "target_terminal_init ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_init ()\n");
}
static void
@@ -1675,7 +2043,7 @@ debug_to_terminal_inferior ()
{
debug_target.to_terminal_inferior ();
- fprintf_unfiltered (stderr, "target_terminal_inferior ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_inferior ()\n");
}
static void
@@ -1683,7 +2051,7 @@ debug_to_terminal_ours_for_output ()
{
debug_target.to_terminal_ours_for_output ();
- fprintf_unfiltered (stderr, "target_terminal_ours_for_output ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_ours_for_output ()\n");
}
static void
@@ -1691,7 +2059,7 @@ debug_to_terminal_ours ()
{
debug_target.to_terminal_ours ();
- fprintf_unfiltered (stderr, "target_terminal_ours ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_ours ()\n");
}
static void
@@ -1701,7 +2069,7 @@ debug_to_terminal_info (arg, from_tty)
{
debug_target.to_terminal_info (arg, from_tty);
- fprintf_unfiltered (stderr, "target_terminal_info (%s, %d)\n", arg,
+ fprintf_unfiltered (gdb_stderr, "target_terminal_info (%s, %d)\n", arg,
from_tty);
}
@@ -1710,7 +2078,7 @@ debug_to_kill ()
{
debug_target.to_kill ();
- fprintf_unfiltered (stderr, "target_kill ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_kill ()\n");
}
static void
@@ -1720,7 +2088,7 @@ debug_to_load (args, from_tty)
{
debug_target.to_load (args, from_tty);
- fprintf_unfiltered (stderr, "target_load (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_load (%s, %d)\n", args, from_tty);
}
static int
@@ -1732,7 +2100,7 @@ debug_to_lookup_symbol (name, addrp)
retval = debug_target.to_lookup_symbol (name, addrp);
- fprintf_unfiltered (stderr, "target_lookup_symbol (%s, xxx)\n", name);
+ fprintf_unfiltered (gdb_stderr, "target_lookup_symbol (%s, xxx)\n", name);
return retval;
}
@@ -1745,16 +2113,274 @@ debug_to_create_inferior (exec_file, args, env)
{
debug_target.to_create_inferior (exec_file, args, env);
- fprintf_unfiltered (stderr, "target_create_inferior (%s, %s, xxx)\n",
+ fprintf_unfiltered (gdb_stderr, "target_create_inferior (%s, %s, xxx)\n",
exec_file, args);
}
static void
+debug_to_post_startup_inferior (pid)
+ int pid;
+{
+ debug_target.to_post_startup_inferior (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_post_startup_inferior (%d)\n",
+ pid);
+}
+
+static void
+debug_to_acknowledge_created_inferior (pid)
+ int pid;
+{
+ debug_target.to_acknowledge_created_inferior (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_acknowledge_created_inferior (%d)\n",
+ pid);
+}
+
+static void
+debug_to_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ debug_target.to_clone_and_follow_inferior (child_pid, followed_child);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_clone_and_follow_inferior (%d, %d)\n",
+ child_pid, *followed_child);
+}
+
+static void
+debug_to_post_follow_inferior_by_clone ()
+{
+ debug_target.to_post_follow_inferior_by_clone ();
+
+ fprintf_unfiltered (gdb_stderr, "target_post_follow_inferior_by_clone ()\n");
+}
+
+static int
+debug_to_insert_fork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_insert_fork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_insert_fork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_fork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_remove_fork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_remove_fork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_insert_vfork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_insert_vfork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_insert_vfork_catchpoint (%d)= %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_vfork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_remove_vfork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_remove_vfork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_has_forked (pid, child_pid)
+ int pid;
+ int * child_pid;
+{
+ int has_forked;
+
+ has_forked = debug_target.to_has_forked (pid, child_pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_forked (%d, %d) = %d\n",
+ pid, *child_pid, has_forked);
+
+ return has_forked;
+}
+
+static int
+debug_to_has_vforked (pid, child_pid)
+ int pid;
+ int * child_pid;
+{
+ int has_vforked;
+
+ has_vforked = debug_target.to_has_vforked (pid, child_pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_vforked (%d, %d) = %d\n",
+ pid, *child_pid, has_vforked);
+
+ return has_vforked;
+}
+
+static int
+debug_to_can_follow_vfork_prior_to_exec ()
+{
+ int can_immediately_follow_vfork;
+
+ can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec ();
+
+ fprintf_unfiltered (gdb_stderr, "target_can_follow_vfork_prior_to_exec () = %d\n",
+ can_immediately_follow_vfork);
+
+ return can_immediately_follow_vfork;
+}
+
+static void
+debug_to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child)
+ int parent_pid;
+ int followed_parent;
+ int child_pid;
+ int followed_child;
+{
+ debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_post_follow_vfork (%d, %d, %d, %d)\n",
+ parent_pid, followed_parent, child_pid, followed_child);
+}
+
+static int
+debug_to_insert_exec_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_insert_exec_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_insert_exec_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_exec_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_remove_exec_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_remove_exec_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_has_execd (pid, execd_pathname)
+ int pid;
+ char ** execd_pathname;
+{
+ int has_execd;
+
+ has_execd = debug_target.to_has_execd (pid, execd_pathname);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_execd (%d, %s) = %d\n",
+ pid, *execd_pathname, has_execd);
+
+ return has_execd;
+}
+
+static int
+debug_to_reported_exec_events_per_exec_call ()
+{
+ int reported_exec_events;
+
+ reported_exec_events = debug_target.to_reported_exec_events_per_exec_call ();
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_reported_exec_events_per_exec_call () = %d\n",
+ reported_exec_events);
+
+ return reported_exec_events;
+}
+
+static int
+debug_to_has_syscall_event (pid, kind, syscall_id)
+ int pid;
+ enum target_waitkind * kind;
+ int * syscall_id;
+{
+ int has_syscall_event;
+ char * kind_spelling = "??";
+
+ has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id);
+ if (has_syscall_event)
+ {
+ switch (*kind)
+ {
+ case TARGET_WAITKIND_SYSCALL_ENTRY:
+ kind_spelling = "SYSCALL_ENTRY";
+ break;
+ case TARGET_WAITKIND_SYSCALL_RETURN:
+ kind_spelling = "SYSCALL_RETURN";
+ break;
+ default:
+ break;
+ }
+ }
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_has_syscall_event (%d, %s, %d) = %d\n",
+ pid, kind_spelling, *syscall_id, has_syscall_event);
+
+ return has_syscall_event;
+}
+
+static int
+debug_to_has_exited (pid, wait_status, exit_status)
+ int pid;
+ int wait_status;
+ int * exit_status;
+{
+ int has_exited;
+
+ has_exited = debug_target.to_has_exited (pid, wait_status, exit_status);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_exited (%d, %d, %d) = %d\n",
+ pid, wait_status, *exit_status, has_exited);
+
+ return has_exited;
+}
+
+static void
debug_to_mourn_inferior ()
{
debug_target.to_mourn_inferior ();
- fprintf_unfiltered (stderr, "target_mourn_inferior ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_mourn_inferior ()\n");
}
static int
@@ -1764,7 +2390,7 @@ debug_to_can_run ()
retval = debug_target.to_can_run ();
- fprintf_unfiltered (stderr, "target_can_run () = %d\n", retval);
+ fprintf_unfiltered (gdb_stderr, "target_can_run () = %d\n", retval);
return retval;
}
@@ -1775,17 +2401,21 @@ debug_to_notice_signals (pid)
{
debug_target.to_notice_signals (pid);
- fprintf_unfiltered (stderr, "target_notice_signals (%d)\n", pid);
+ fprintf_unfiltered (gdb_stderr, "target_notice_signals (%d)\n", pid);
}
static int
debug_to_thread_alive (pid)
int pid;
{
- debug_target.to_thread_alive (pid);
+ int retval;
+
+ retval = debug_target.to_thread_alive (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_thread_alive (%d) = %d\n",
+ pid, retval);
- fprintf_unfiltered (stderr, "target_thread_alive (%d)\n", pid);
- return (0);
+ return retval;
}
static void
@@ -1793,7 +2423,71 @@ debug_to_stop ()
{
debug_target.to_stop ();
- fprintf_unfiltered (stderr, "target_stop ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_stop ()\n");
+}
+
+static int
+debug_to_query (type, req, resp, siz)
+ int type;
+ char *req;
+ char *resp;
+ int *siz;
+{
+ int retval;
+
+ retval = debug_target.to_query (type, req, resp, siz);
+
+ fprintf_unfiltered (gdb_stderr, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval);
+
+ return retval;
+}
+
+static struct symtab_and_line *
+debug_to_enable_exception_callback (kind, enable)
+ enum exception_event_kind kind;
+ int enable;
+{
+ debug_target.to_enable_exception_callback (kind, enable);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target get_exception_callback_sal (%d, %d)\n",
+ kind, enable);
+}
+
+static struct exception_event_record *
+debug_to_get_current_exception_event ()
+{
+ debug_target.to_get_current_exception_event();
+
+ fprintf_unfiltered (gdb_stderr, "target get_current_exception_event ()\n");
+}
+
+static char *
+debug_to_pid_to_exec_file (pid)
+ int pid;
+{
+ char * exec_file;
+
+ exec_file = debug_target.to_pid_to_exec_file (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_pid_to_exec_file (%d) = %s\n",
+ pid, exec_file);
+
+ return exec_file;
+}
+
+static char *
+debug_to_core_file_to_sym_file (core)
+ char * core;
+{
+ char * sym_file;
+
+ sym_file = debug_target.to_core_file_to_sym_file (core);
+
+ fprintf_unfiltered (gdb_stderr, "target_core_file_to_sym_file (%s) = %s\n",
+ core, sym_file);
+
+ return sym_file;
}
static void
@@ -1804,9 +2498,13 @@ setup_target_debug ()
current_target.to_open = debug_to_open;
current_target.to_close = debug_to_close;
current_target.to_attach = debug_to_attach;
+ current_target.to_post_attach = debug_to_post_attach;
+ current_target.to_require_attach = debug_to_require_attach;
current_target.to_detach = debug_to_detach;
+ current_target.to_require_detach = debug_to_require_detach;
current_target.to_resume = debug_to_resume;
current_target.to_wait = debug_to_wait;
+ current_target.to_post_wait = debug_to_post_wait;
current_target.to_fetch_registers = debug_to_fetch_registers;
current_target.to_store_registers = debug_to_store_registers;
current_target.to_prepare_to_store = debug_to_prepare_to_store;
@@ -1823,11 +2521,35 @@ setup_target_debug ()
current_target.to_load = debug_to_load;
current_target.to_lookup_symbol = debug_to_lookup_symbol;
current_target.to_create_inferior = debug_to_create_inferior;
+ current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
+ current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior;
+ current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior;
+ current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone;
+ current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
+ current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
+ current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
+ current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
+ current_target.to_has_forked = debug_to_has_forked;
+ current_target.to_has_vforked = debug_to_has_vforked;
+ current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec;
+ current_target.to_post_follow_vfork = debug_to_post_follow_vfork;
+ current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
+ current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
+ current_target.to_has_execd = debug_to_has_execd;
+ current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
+ current_target.to_has_syscall_event = debug_to_has_syscall_event;
+ current_target.to_has_exited = debug_to_has_exited;
current_target.to_mourn_inferior = debug_to_mourn_inferior;
current_target.to_can_run = debug_to_can_run;
current_target.to_notice_signals = debug_to_notice_signals;
current_target.to_thread_alive = debug_to_thread_alive;
current_target.to_stop = debug_to_stop;
+ current_target.to_query = debug_to_query;
+ current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
+ current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
+ current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
+ current_target.to_core_file_to_sym_file = debug_to_core_file_to_sym_file;
+
}
#endif /* MAINTENANCE_CMDS */
@@ -1839,6 +2561,7 @@ core-file, and process, if any), as well as the symbol file name.";
void
initialize_targets ()
{
+ init_dummy_target ();
push_target (&dummy_target);
add_info ("target", target_info, targ_desc);
diff --git a/contrib/gdb/gdb/target.h b/contrib/gdb/gdb/target.h
index fa2291d..21c3bab 100644
--- a/contrib/gdb/gdb/target.h
+++ b/contrib/gdb/gdb/target.h
@@ -1,5 +1,5 @@
/* Interface between GDB and target environments, including files and processes
- Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1990, 91, 92, 93, 94, 1999 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by John Gilmore.
This file is part of GDB.
@@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
stratum. */
#include "bfd.h"
+#include "symtab.h"
enum strata {
dummy_stratum, /* The lowest of the low */
@@ -50,6 +51,12 @@ enum strata {
process_stratum /* Executing processes */
};
+enum thread_control_capabilities {
+ tc_none = 0, /* Default: can't control thread execution. */
+ tc_schedlock = 1, /* Can lock the thread scheduler. */
+ tc_switch = 2 /* Can switch the running thread on demand. */
+};
+
/* Stuff for target_wait. */
/* Generally, what has the program done? */
@@ -68,6 +75,27 @@ enum target_waitkind {
(e.g. it called load(2) on AIX). */
TARGET_WAITKIND_LOADED,
+ /* The program has forked. A "related" process' ID is in value.related_pid.
+ I.e., if the child forks, value.related_pid is the parent's ID.
+ */
+ TARGET_WAITKIND_FORKED,
+
+ /* The program has vforked. A "related" process's ID is in value.related_pid.
+ */
+ TARGET_WAITKIND_VFORKED,
+
+ /* The program has exec'ed a new executable file. The new file's pathname
+ is pointed to by value.execd_pathname.
+ */
+ TARGET_WAITKIND_EXECD,
+
+ /* The program has entered or returned from a system call. On HP-UX, this
+ is used in the hardware watchpoint implementation. The syscall's unique
+ integer ID number is in value.syscall_id;
+ */
+ TARGET_WAITKIND_SYSCALL_ENTRY,
+ TARGET_WAITKIND_SYSCALL_RETURN,
+
/* Nothing happened, but we stopped anyway. This perhaps should be handled
within target_wait, but I'm not sure target_wait should be resuming the
inferior. */
@@ -177,7 +205,15 @@ enum target_signal {
TARGET_SIGNAL_REALTIME_61 = 73,
TARGET_SIGNAL_REALTIME_62 = 74,
TARGET_SIGNAL_REALTIME_63 = 75,
-
+#if defined(MACH) || defined(__MACH__)
+ /* Mach exceptions */
+ TARGET_EXC_BAD_ACCESS = 76,
+ TARGET_EXC_BAD_INSTRUCTION = 77,
+ TARGET_EXC_ARITHMETIC = 78,
+ TARGET_EXC_EMULATION = 79,
+ TARGET_EXC_SOFTWARE = 80,
+ TARGET_EXC_BREAKPOINT = 81,
+#endif
/* Some signal we don't know about. */
TARGET_SIGNAL_UNKNOWN,
@@ -192,10 +228,13 @@ enum target_signal {
struct target_waitstatus {
enum target_waitkind kind;
- /* Exit status or signal number. */
+ /* Forked child pid, execd pathname, exit status or signal number. */
union {
int integer;
enum target_signal sig;
+ int related_pid;
+ char * execd_pathname;
+ int syscall_id;
} value;
};
@@ -207,6 +246,7 @@ extern char *target_signal_to_name PARAMS ((enum target_signal));
/* Given a name (SIGHUP, etc.), return its signal. */
enum target_signal target_signal_from_name PARAMS ((char *));
+
/* If certain kinds of activity happen, target_wait should perform
callbacks. */
@@ -226,9 +266,13 @@ struct target_ops
void (*to_open) PARAMS ((char *, int));
void (*to_close) PARAMS ((int));
void (*to_attach) PARAMS ((char *, int));
+ void (*to_post_attach) PARAMS ((int));
+ void (*to_require_attach) PARAMS ((char *, int));
void (*to_detach) PARAMS ((char *, int));
+ void (*to_require_detach) PARAMS ((int, char *, int));
void (*to_resume) PARAMS ((int, int, enum target_signal));
int (*to_wait) PARAMS ((int, struct target_waitstatus *));
+ void (*to_post_wait) PARAMS ((int, int));
void (*to_fetch_registers) PARAMS ((int));
void (*to_store_registers) PARAMS ((int));
void (*to_prepare_to_store) PARAMS ((void));
@@ -288,11 +332,34 @@ struct target_ops
void (*to_load) PARAMS ((char *, int));
int (*to_lookup_symbol) PARAMS ((char *, CORE_ADDR *));
void (*to_create_inferior) PARAMS ((char *, char *, char **));
+ void (*to_post_startup_inferior) PARAMS ((int));
+ void (*to_acknowledge_created_inferior) PARAMS ((int));
+ void (*to_clone_and_follow_inferior) PARAMS ((int, int *));
+ void (*to_post_follow_inferior_by_clone) PARAMS ((void));
+ int (*to_insert_fork_catchpoint) PARAMS ((int));
+ int (*to_remove_fork_catchpoint) PARAMS ((int));
+ int (*to_insert_vfork_catchpoint) PARAMS ((int));
+ int (*to_remove_vfork_catchpoint) PARAMS ((int));
+ int (*to_has_forked) PARAMS ((int, int *));
+ int (*to_has_vforked) PARAMS ((int, int *));
+ int (*to_can_follow_vfork_prior_to_exec) PARAMS ((void));
+ void (*to_post_follow_vfork) PARAMS ((int, int, int, int));
+ int (*to_insert_exec_catchpoint) PARAMS ((int));
+ int (*to_remove_exec_catchpoint) PARAMS ((int));
+ int (*to_has_execd) PARAMS ((int, char **));
+ int (*to_reported_exec_events_per_exec_call) PARAMS ((void));
+ int (*to_has_syscall_event) PARAMS ((int, enum target_waitkind *, int *));
+ int (*to_has_exited) PARAMS ((int, int, int *));
void (*to_mourn_inferior) PARAMS ((void));
int (*to_can_run) PARAMS ((void));
void (*to_notice_signals) PARAMS ((int pid));
int (*to_thread_alive) PARAMS ((int pid));
void (*to_stop) PARAMS ((void));
+ int (*to_query) PARAMS ((int/*char*/, char *, char *, int *));
+ struct symtab_and_line * (*to_enable_exception_callback) PARAMS ((enum exception_event_kind, int));
+ struct exception_event_record * (*to_get_current_exception_event) PARAMS ((void));
+ char * (*to_pid_to_exec_file) PARAMS ((int pid));
+ char * (*to_core_file_to_sym_file) PARAMS ((char *));
enum strata to_stratum;
struct target_ops
*DONT_USE; /* formerly to_next */
@@ -301,6 +368,7 @@ struct target_ops
int to_has_stack;
int to_has_registers;
int to_has_execution;
+ int to_has_thread_control; /* control thread execution */
struct section_table
*to_sections;
struct section_table
@@ -365,6 +433,26 @@ extern struct target_stack_item *target_stack;
#define target_attach(args, from_tty) \
(*current_target.to_attach) (args, from_tty)
+/* The target_attach operation places a process under debugger control,
+ and stops the process.
+
+ This operation provides a target-specific hook that allows the
+ necessary bookkeeping to be performed after an attach completes.
+ */
+#define target_post_attach(pid) \
+ (*current_target.to_post_attach) (pid)
+
+/* Attaches to a process on the target side, if not already attached.
+ (If already attached, takes no action.)
+
+ This operation can be used to follow the child process of a fork.
+ On some targets, such child processes of an original inferior process
+ are automatically under debugger control, and thus do not require an
+ actual attach operation. */
+
+#define target_require_attach(args, from_tty) \
+ (*current_target.to_require_attach) (args, from_tty)
+
/* Takes a program previously attached to and detaches it.
The program may resume execution (some targets do, some don't) and will
no longer stop on signals, etc. We better not have left any breakpoints
@@ -375,6 +463,21 @@ extern struct target_stack_item *target_stack;
extern void
target_detach PARAMS ((char *, int));
+/* Detaches from a process on the target side, if not already dettached.
+ (If already detached, takes no action.)
+
+ This operation can be used to follow the parent process of a fork.
+ On some targets, such child processes of an original inferior process
+ are automatically under debugger control, and thus do require an actual
+ detach operation.
+
+ PID is the process id of the child to detach from.
+ ARGS is arguments typed by the user (e.g. a signal to send the process).
+ FROM_TTY says whether to be verbose or not. */
+
+#define target_require_detach(pid, args, from_tty) \
+ (*current_target.to_require_detach) (pid, args, from_tty)
+
/* Resume execution of the target process PID. STEP says whether to
single-step or to run free; SIGGNAL is the signal to be given to
the target, or TARGET_SIGNAL_0 for no signal. The caller may not
@@ -394,6 +497,20 @@ target_detach PARAMS ((char *, int));
#define target_wait(pid, status) \
(*current_target.to_wait) (pid, status)
+/* The target_wait operation waits for a process event to occur, and
+ thereby stop the process.
+
+ On some targets, certain events may happen in sequences. gdb's
+ correct response to any single event of such a sequence may require
+ knowledge of what earlier events in the sequence have been seen.
+
+ This operation provides a target-specific hook that allows the
+ necessary bookkeeping to be performed to track such sequences.
+ */
+
+#define target_post_wait(pid, status) \
+ (*current_target.to_post_wait) (pid, status)
+
/* Fetch register REGNO, or all regs if regno == -1. No result. */
#define target_fetch_registers(regno) \
@@ -418,7 +535,11 @@ target_detach PARAMS ((char *, int));
extern int target_read_string PARAMS ((CORE_ADDR, char **, int, int *));
extern int
-target_read_memory PARAMS ((CORE_ADDR, char *, int));
+target_read_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+
+extern int
+target_read_memory_section PARAMS ((CORE_ADDR memaddr, char *myaddr, int len,
+ asection *bfd_section));
extern int
target_read_memory_partial PARAMS ((CORE_ADDR, char *, int, int *));
@@ -432,13 +553,79 @@ xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
extern int
child_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
-/* Transfer LEN bytes between target address MEMADDR and GDB address MYADDR.
- Returns 0 for success, errno code for failure (which includes partial
- transfers--if you want a more useful response to partial transfers, try
- target_read_memory_partial). */
+extern char *
+child_pid_to_exec_file PARAMS ((int));
+
+extern char *
+child_core_file_to_sym_file PARAMS ((char *));
+
+#if defined(CHILD_POST_ATTACH)
+extern void
+child_post_attach PARAMS ((int));
+#endif
+
+extern void
+child_post_wait PARAMS ((int, int));
+
+extern void
+child_post_startup_inferior PARAMS ((int));
+
+extern void
+child_acknowledge_created_inferior PARAMS ((int));
+
+extern void
+child_clone_and_follow_inferior PARAMS ((int, int *));
+
+extern void
+child_post_follow_inferior_by_clone PARAMS ((void));
+
+extern int
+child_insert_fork_catchpoint PARAMS ((int));
+
+extern int
+child_remove_fork_catchpoint PARAMS ((int));
+
+extern int
+child_insert_vfork_catchpoint PARAMS ((int));
+
+extern int
+child_remove_vfork_catchpoint PARAMS ((int));
+
+extern int
+child_has_forked PARAMS ((int, int *));
+
+extern int
+child_has_vforked PARAMS ((int, int *));
+
+extern void
+child_acknowledge_created_inferior PARAMS ((int));
+
+extern int
+child_can_follow_vfork_prior_to_exec PARAMS ((void));
+
+extern void
+child_post_follow_vfork PARAMS ((int, int, int, int));
+
+extern int
+child_insert_exec_catchpoint PARAMS ((int));
+
+extern int
+child_remove_exec_catchpoint PARAMS ((int));
+
+extern int
+child_has_execd PARAMS ((int, char **));
+
+extern int
+child_reported_exec_events_per_exec_call PARAMS ((void));
+
+extern int
+child_has_syscall_event PARAMS ((int, enum target_waitkind *, int *));
+
+extern int
+child_has_exited PARAMS ((int, int, int *));
-extern int target_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
- int len, int write));
+extern int
+child_thread_alive PARAMS ((int));
/* From exec.c */
@@ -535,6 +722,149 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
#define target_create_inferior(exec_file, args, env) \
(*current_target.to_create_inferior) (exec_file, args, env)
+
+/* Some targets (such as ttrace-based HPUX) don't allow us to request
+ notification of inferior events such as fork and vork immediately
+ after the inferior is created. (This because of how gdb gets an
+ inferior created via invoking a shell to do it. In such a scenario,
+ if the shell init file has commands in it, the shell will fork and
+ exec for each of those commands, and we will see each such fork
+ event. Very bad.)
+
+ Such targets will supply an appropriate definition for this function.
+ */
+#define target_post_startup_inferior(pid) \
+ (*current_target.to_post_startup_inferior) (pid)
+
+/* On some targets, the sequence of starting up an inferior requires
+ some synchronization between gdb and the new inferior process, PID.
+ */
+#define target_acknowledge_created_inferior(pid) \
+ (*current_target.to_acknowledge_created_inferior) (pid)
+
+/* An inferior process has been created via a fork() or similar
+ system call. This function will clone the debugger, then ensure
+ that CHILD_PID is attached to by that debugger.
+
+ FOLLOWED_CHILD is set TRUE on return *for the clone debugger only*,
+ and FALSE otherwise. (The original and clone debuggers can use this
+ to determine which they are, if need be.)
+
+ (This is not a terribly useful feature without a GUI to prevent
+ the two debuggers from competing for shell input.)
+ */
+#define target_clone_and_follow_inferior(child_pid,followed_child) \
+ (*current_target.to_clone_and_follow_inferior) (child_pid, followed_child)
+
+/* This operation is intended to be used as the last in a sequence of
+ steps taken when following both parent and child of a fork. This
+ is used by a clone of the debugger, which will follow the child.
+
+ The original debugger has detached from this process, and the
+ clone has attached to it.
+
+ On some targets, this requires a bit of cleanup to make it work
+ correctly.
+ */
+#define target_post_follow_inferior_by_clone() \
+ (*current_target.to_post_follow_inferior_by_clone) ()
+
+/* On some targets, we can catch an inferior fork or vfork event when it
+ occurs. These functions insert/remove an already-created catchpoint for
+ such events.
+ */
+#define target_insert_fork_catchpoint(pid) \
+ (*current_target.to_insert_fork_catchpoint) (pid)
+
+#define target_remove_fork_catchpoint(pid) \
+ (*current_target.to_remove_fork_catchpoint) (pid)
+
+#define target_insert_vfork_catchpoint(pid) \
+ (*current_target.to_insert_vfork_catchpoint) (pid)
+
+#define target_remove_vfork_catchpoint(pid) \
+ (*current_target.to_remove_vfork_catchpoint) (pid)
+
+/* Returns TRUE if PID has invoked the fork() system call. And,
+ also sets CHILD_PID to the process id of the other ("child")
+ inferior process that was created by that call.
+ */
+#define target_has_forked(pid,child_pid) \
+ (*current_target.to_has_forked) (pid,child_pid)
+
+/* Returns TRUE if PID has invoked the vfork() system call. And,
+ also sets CHILD_PID to the process id of the other ("child")
+ inferior process that was created by that call.
+ */
+#define target_has_vforked(pid,child_pid) \
+ (*current_target.to_has_vforked) (pid,child_pid)
+
+/* Some platforms (such as pre-10.20 HP-UX) don't allow us to do
+ anything to a vforked child before it subsequently calls exec().
+ On such platforms, we say that the debugger cannot "follow" the
+ child until it has vforked.
+
+ This function should be defined to return 1 by those targets
+ which can allow the debugger to immediately follow a vforked
+ child, and 0 if they cannot.
+ */
+#define target_can_follow_vfork_prior_to_exec() \
+ (*current_target.to_can_follow_vfork_prior_to_exec) ()
+
+/* An inferior process has been created via a vfork() system call.
+ The debugger has followed the parent, the child, or both. The
+ process of setting up for that follow may have required some
+ target-specific trickery to track the sequence of reported events.
+ If so, this function should be defined by those targets that
+ require the debugger to perform cleanup or initialization after
+ the vfork follow.
+ */
+#define target_post_follow_vfork(parent_pid,followed_parent,child_pid,followed_child) \
+ (*current_target.to_post_follow_vfork) (parent_pid,followed_parent,child_pid,followed_child)
+
+/* On some targets, we can catch an inferior exec event when it
+ occurs. These functions insert/remove an already-created catchpoint
+ for such events.
+ */
+#define target_insert_exec_catchpoint(pid) \
+ (*current_target.to_insert_exec_catchpoint) (pid)
+
+#define target_remove_exec_catchpoint(pid) \
+ (*current_target.to_remove_exec_catchpoint) (pid)
+
+/* Returns TRUE if PID has invoked a flavor of the exec() system call.
+ And, also sets EXECD_PATHNAME to the pathname of the executable file
+ that was passed to exec(), and is now being executed.
+ */
+#define target_has_execd(pid,execd_pathname) \
+ (*current_target.to_has_execd) (pid,execd_pathname)
+
+/* Returns the number of exec events that are reported when a process
+ invokes a flavor of the exec() system call on this target, if exec
+ events are being reported.
+ */
+#define target_reported_exec_events_per_exec_call() \
+ (*current_target.to_reported_exec_events_per_exec_call) ()
+
+/* Returns TRUE if PID has reported a syscall event. And, also sets
+ KIND to the appropriate TARGET_WAITKIND_, and sets SYSCALL_ID to
+ the unique integer ID of the syscall.
+ */
+#define target_has_syscall_event(pid,kind,syscall_id) \
+ (*current_target.to_has_syscall_event) (pid,kind,syscall_id)
+
+/* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the
+ exit code of PID, if any.
+ */
+#define target_has_exited(pid,wait_status,exit_status) \
+ (*current_target.to_has_exited) (pid,wait_status,exit_status)
+
+/* The debugger has completed a blocking wait() call. There is now
+ some process event that must be processed. This function should
+ be defined by those targets that require the debugger to perform
+ cleanup or internal state changes in response to the process event.
+ */
+
/* The inferior process has died. Do what is right. */
#define target_mourn_inferior() \
@@ -559,7 +889,32 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
should act like SIGSTOP). This function is normally used by GUIs to
implement a stop button. */
-#define target_stop() current_target.to_stop ()
+#define target_stop current_target.to_stop
+
+/* Queries the target side for some information. The first argument is a
+ letter specifying the type of the query, which is used to determine who
+ should process it. The second argument is a string that specifies which
+ information is desired and the third is a buffer that carries back the
+ response from the target side. The fourth parameter is the size of the
+ output buffer supplied. */
+
+#define target_query(query_type, query, resp_buffer, bufffer_size) \
+ (*current_target.to_query) (query_type, query, resp_buffer, bufffer_size)
+
+/* Get the symbol information for a breakpointable routine called when
+ an exception event occurs.
+ Intended mainly for C++, and for those
+ platforms/implementations where such a callback mechanism is available,
+ e.g. HP-UX with ANSI C++ (aCC). Some compilers (e.g. g++) support
+ different mechanisms for debugging exceptions. */
+
+#define target_enable_exception_callback(kind, enable) \
+ (*current_target.to_enable_exception_callback) (kind, enable)
+
+/* Get the current exception event kind -- throw or catch, etc. */
+
+#define target_get_current_exception_event() \
+ (*current_target.to_get_current_exception_event) ()
/* Pointer to next target in the chain, e.g. a core file and an exec file. */
@@ -599,6 +954,16 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
#define target_has_execution \
(current_target.to_has_execution)
+/* Can the target support the debugger control of thread execution?
+ a) Can it lock the thread scheduler?
+ b) Can it switch the currently running thread? */
+
+#define target_can_lock_scheduler \
+ (current_target.to_has_thread_control & tc_schedlock)
+
+#define target_can_switch_threads \
+ (current_target.to_has_thread_control & tc_switch)
+
extern void target_link PARAMS ((char *, CORE_ADDR *));
/* Converts a process id to a string. Usually, the string just contains
@@ -611,6 +976,38 @@ extern void target_link PARAMS ((char *, CORE_ADDR *));
extern char *normal_pid_to_str PARAMS ((int pid));
#endif
+#ifndef target_tid_to_str
+#define target_tid_to_str(PID) \
+ normal_pid_to_str (PID)
+extern char *normal_pid_to_str PARAMS ((int pid));
+#endif
+
+
+#ifndef target_new_objfile
+#define target_new_objfile(OBJFILE)
+#endif
+
+#ifndef target_pid_or_tid_to_str
+#define target_pid_or_tid_to_str(ID) \
+ normal_pid_to_str (ID)
+#endif
+
+/* Attempts to find the pathname of the executable file
+ that was run to create a specified process.
+
+ The process PID must be stopped when this operation is used.
+
+ If the executable file cannot be determined, NULL is returned.
+
+ Else, a pointer to a character string containing the pathname
+ is returned. This string should be copied into a buffer by
+ the client if the string will not be immediately used, or if
+ it must persist.
+ */
+
+#define target_pid_to_exec_file(pid) \
+ (current_target.to_pid_to_exec_file) (pid)
+
/* Hook to call target-dependant code after reading in a new symbol table. */
#ifndef TARGET_SYMFILE_POSTREAD
@@ -633,6 +1030,18 @@ extern char *normal_pid_to_str PARAMS ((int pid));
#define STOPPED_BY_WATCHPOINT(w) 0
#endif
+/* HP-UX supplies these operations, which respectively disable and enable
+ the memory page-protections that are used to implement hardware watchpoints
+ on that platform. See wait_for_inferior's use of these.
+ */
+#if !defined(TARGET_DISABLE_HW_WATCHPOINTS)
+#define TARGET_DISABLE_HW_WATCHPOINTS(pid)
+#endif
+
+#if !defined(TARGET_ENABLE_HW_WATCHPOINTS)
+#define TARGET_ENABLE_HW_WATCHPOINTS(pid)
+#endif
+
/* Provide defaults for systems that don't support hardware watchpoints. */
#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
@@ -644,9 +1053,26 @@ extern char *normal_pid_to_str PARAMS ((int pid));
#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
-/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes. TYPE is 1
- for read and 2 for read/write accesses. Returns 0 for success, non-zero for
- failure. */
+#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
+ (LONGEST)(byte_count) <= REGISTER_SIZE
+#endif
+
+/* However, some addresses may not be profitable to use hardware to watch,
+ or may be difficult to understand when the addressed object is out of
+ scope, and hence should be unwatched. On some targets, this may have
+ severe performance penalties, such that we might as well use regular
+ watchpoints, and save (possibly precious) hardware watchpoints for other
+ locations.
+ */
+#if !defined(TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT)
+#define TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT(pid,start,len) 0
+#endif
+
+
+/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes. TYPE is 0
+ for write, 1 for read, and 2 for read/write accesses. Returns 0 for
+ success, non-zero for failure. */
#define target_remove_watchpoint(ADDR,LEN,TYPE) -1
#define target_insert_watchpoint(ADDR,LEN,TYPE) -1
@@ -669,6 +1095,38 @@ extern char *normal_pid_to_str PARAMS ((int pid));
#define DECR_PC_AFTER_HW_BREAK 0
#endif
+/* Sometimes gdb may pick up what appears to be a valid target address
+ from a minimal symbol, but the value really means, essentially,
+ "This is an index into a table which is populated when the inferior
+ is run. Therefore, do not attempt to use this as a PC."
+ */
+#if !defined(PC_REQUIRES_RUN_BEFORE_USE)
+#define PC_REQUIRES_RUN_BEFORE_USE(pc) (0)
+#endif
+
+/* This will only be defined by a target that supports catching vfork events,
+ such as HP-UX.
+
+ On some targets (such as HP-UX 10.20 and earlier), resuming a newly vforked
+ child process after it has exec'd, causes the parent process to resume as
+ well. To prevent the parent from running spontaneously, such targets should
+ define this to a function that prevents that from happening.
+ */
+#if !defined(ENSURE_VFORKING_PARENT_REMAINS_STOPPED)
+#define ENSURE_VFORKING_PARENT_REMAINS_STOPPED(PID) (0)
+#endif
+
+/* This will only be defined by a target that supports catching vfork events,
+ such as HP-UX.
+
+ On some targets (such as HP-UX 10.20 and earlier), a newly vforked child
+ process must be resumed when it delivers its exec event, before the parent
+ vfork event will be delivered to us.
+ */
+#if !defined(RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK)
+#define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK() (0)
+#endif
+
/* Routines for maintenance of the target structures...
add_target: Add a target to the list of all possible targets.
@@ -721,24 +1179,40 @@ build_section_table PARAMS ((bfd *, struct section_table **,
/* From mem-break.c */
-extern int
-memory_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+extern int memory_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+extern int memory_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+extern breakpoint_from_pc_fn memory_breakpoint_from_pc;
+#ifndef BREAKPOINT_FROM_PC
+#define BREAKPOINT_FROM_PC(pcptr, lenptr) memory_breakpoint_from_pc (pcptr, lenptr)
+#endif
-extern int
-memory_insert_breakpoint PARAMS ((CORE_ADDR, char *));
/* From target.c */
-void
+extern void
+initialize_targets PARAMS ((void));
+
+extern void
noprocess PARAMS ((void));
-void
+extern void
find_default_attach PARAMS ((char *, int));
void
+find_default_require_attach PARAMS ((char *, int));
+
+void
+find_default_require_detach PARAMS ((int, char *, int));
+
+extern void
find_default_create_inferior PARAMS ((char *, char *, char **));
-struct target_ops *
+void
+find_default_clone_and_follow_inferior PARAMS ((int, int *));
+
+extern struct target_ops *
find_core_target PARAMS ((void));
/* Stuff that should be shared among the various remote targets. */
@@ -749,6 +1223,10 @@ extern int remote_debug;
/* Speed in bits per second, or -1 which means don't mess with the speed. */
extern int baud_rate;
+/* Timeout limit for response from target. */
+extern int remote_timeout;
+
+extern asection *target_memory_bfd_section;
/* Functions for helping to write a native target. */
@@ -762,4 +1240,25 @@ extern int target_signal_to_host PARAMS ((enum target_signal));
/* Convert from a number used in a GDB command to an enum target_signal. */
extern enum target_signal target_signal_from_command PARAMS ((int));
+/* Any target can call this to switch to remote protocol (in remote.c). */
+extern void push_remote_target PARAMS ((char *name, int from_tty));
+
+/* Imported from machine dependent code */
+
+#ifndef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P 0
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) abort ()
+#endif /* SOFTWARE_SINGLE_STEP_P */
+
+/* Blank target vector entries are initialized to target_ignore. */
+void target_ignore PARAMS ((void));
+
+/* Macro for getting target's idea of a frame pointer.
+ FIXME: GDB's whole scheme for dealing with "frames" and
+ "frame pointers" needs a serious shakedown. */
+#ifndef TARGET_VIRTUAL_FRAME_POINTER
+#define TARGET_VIRTUAL_FRAME_POINTER(ADDR, REGP, OFFP) \
+ do { *(REGP) = FP_REGNUM; *(OFFP) = 0; } while (0)
+#endif /* TARGET_VIRTUAL_FRAME_POINTER */
+
#endif /* !defined (TARGET_H) */
diff --git a/contrib/gdb/gdb/terminal.h b/contrib/gdb/gdb/terminal.h
index 9cae179..e7fb2cb 100644
--- a/contrib/gdb/gdb/terminal.h
+++ b/contrib/gdb/gdb/terminal.h
@@ -34,20 +34,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if !defined (HAVE_TERMIOS) && !defined(HAVE_TERMIO) && !defined(HAVE_SGTTY)
#if defined(HAVE_TERMIOS_H)
#define HAVE_TERMIOS
-#elif defined(HAVE_TERMIO_H)
+#else /* ! defined (HAVE_TERMIOS_H) */
+#if defined(HAVE_TERMIO_H)
#define HAVE_TERMIO
-#elif defined(HAVE_SGTTY_H)
+#else /* ! defined (HAVE_TERMIO_H) */
+#if defined(HAVE_SGTTY_H)
#define HAVE_SGTTY
-#endif
-#endif
-#endif
+#endif /* ! defined (HAVE_SGTTY_H) */
+#endif /* ! defined (HAVE_TERMIO_H) */
+#endif /* ! defined (HAVE_TERMIOS_H) */
+#endif /* !defined (HAVE_TERMIOS) && !defined(HAVE_TERMIO) && !defined(HAVE_SGTTY) */
+#endif /* ! defined (__GO32__) */
#if defined(HAVE_TERMIOS)
#include <termios.h>
#endif
-
-#if !defined(__GO32__) && !defined(__WIN32__) && !defined (HAVE_TERMIOS)
+#if !defined(__GO32__) && !defined(_WIN32) && !defined (HAVE_TERMIOS)
/* Define a common set of macros -- BSD based -- and redefine whatever
the system offers to make it look like that. FIXME: serial.h and
diff --git a/contrib/gdb/gdb/thread.c b/contrib/gdb/gdb/thread.c
index d3ed393..6a7ab09 100644
--- a/contrib/gdb/gdb/thread.c
+++ b/contrib/gdb/gdb/thread.c
@@ -1,5 +1,5 @@
/* Multi-process/thread control for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1993
+ Copyright 1986, 1987, 1988, 1993, 1998
Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
Free Software Foundation, Inc.
@@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "environ.h"
#include "value.h"
#include "target.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "command.h"
#include "gdbcmd.h"
@@ -53,18 +53,110 @@ struct thread_info
int trap_expected;
int handling_longjmp;
int another_trap;
+
+ /* This is set TRUE when a catchpoint of a shared library event
+ triggers. Since we don't wish to leave the inferior in the
+ solib hook when we report the event, we step the inferior
+ back to user code before stopping and reporting the event.
+ */
+ int stepping_through_solib_after_catch;
+
+ /* When stepping_through_solib_after_catch is TRUE, this is a
+ list of the catchpoints that should be reported as triggering
+ when we finally do stop stepping.
+ */
+ bpstat stepping_through_solib_catchpoints;
+
+ /* This is set to TRUE when this thread is in a signal handler
+ trampoline and we're single-stepping through it */
+ int stepping_through_sigtramp;
+
};
+/* Prototypes for exported functions. */
+
+void _initialize_thread PARAMS ((void));
+
+/* Prototypes for local functions. */
+
+#if !defined(FIND_NEW_THREADS)
+#define FIND_NEW_THREADS target_find_new_threads
+#endif
+
static struct thread_info *thread_list = NULL;
static int highest_thread_num;
-static void thread_command PARAMS ((char * tidstr, int from_tty));
+static struct thread_info * find_thread_id PARAMS ((int num));
+static void thread_command PARAMS ((char * tidstr, int from_tty));
+static void thread_apply_all_command PARAMS ((char *, int));
+static int thread_alive PARAMS ((struct thread_info *));
+static void info_threads_command PARAMS ((char *, int));
+static void thread_apply_command PARAMS ((char *, int));
+static void restore_current_thread PARAMS ((int));
+static void switch_to_thread PARAMS ((int pid));
static void prune_threads PARAMS ((void));
-static void thread_switch PARAMS ((int pid));
+/* If the host has threads, the host machine definition may set this
+ macro. But, for remote thread debugging, it gets more complex and
+ setting macros does not bind to the various target dependent
+ methods well. So, we use the vector target_thread_functions */
-static struct thread_info * find_thread_id PARAMS ((int num));
+static struct target_thread_vector *target_thread_functions;
+
+int
+target_find_new_threads ()
+{
+ int retval = 0;
+ if (target_thread_functions &&
+ target_thread_functions->find_new_threads)
+ retval = (*(target_thread_functions->find_new_threads)) ();
+ return retval; /* no support */
+}
+
+
+int
+target_get_thread_info PARAMS ((gdb_threadref * ref,
+ int selection, /* FIXME: Selection */
+ struct gdb_ext_thread_info * info));
+
+int
+target_get_thread_info (ref, selection, info)
+
+ gdb_threadref *ref;
+ int selection;
+ /* FIXME: Selection */
+ struct gdb_ext_thread_info *info;
+
+{
+ int retval = 0;
+ if (target_thread_functions
+ && target_thread_functions->get_thread_info)
+ retval = (*(target_thread_functions->get_thread_info)) (ref, selection, info);
+ return retval;
+}
+
+
+/* It is possible that these bind and unbinf functions implement a
+ stack the interface allows it, but its not implemented that way
+ */
+
+
+void
+bind_target_thread_vector (vec)
+ struct target_thread_vector *vec;
+{
+ target_thread_functions = vec;
+}
+
+struct target_thread_vector *
+unbind_target_thread_vector ()
+{
+ struct target_thread_vector *retval;
+ retval = target_thread_functions;
+ target_thread_functions = 0;
+ return retval;
+} /* unbind_target_thread-vector */
void
init_thread_list ()
@@ -105,10 +197,38 @@ add_thread (pid)
tp->handling_longjmp = 0;
tp->trap_expected = 0;
tp->another_trap = 0;
+ tp->stepping_through_solib_after_catch = 0;
+ tp->stepping_through_solib_catchpoints = NULL;
+ tp->stepping_through_sigtramp = 0;
tp->next = thread_list;
thread_list = tp;
}
+void
+delete_thread (pid)
+ int pid;
+{
+ struct thread_info *tp, *tpprev;
+
+ tpprev = NULL;
+
+ for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
+ if (tp->pid == pid)
+ break;
+
+ if (!tp)
+ return;
+
+ if (tpprev)
+ tpprev->next = tp->next;
+ else
+ thread_list = tp->next;
+
+ free (tp);
+
+ return;
+}
+
static struct thread_info *
find_thread_id (num)
int num;
@@ -149,6 +269,17 @@ pid_to_thread_id (pid)
}
int
+thread_id_to_pid (num)
+ int num;
+{
+ struct thread_info *thread = find_thread_id (num);
+ if (thread)
+ return thread->pid;
+ else
+ return -1;
+}
+
+int
in_thread_list (pid)
int pid;
{
@@ -167,7 +298,10 @@ void load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
trap_expected, step_resume_breakpoint,
through_sigtramp_breakpoint, step_range_start,
step_range_end, step_frame_address,
- handling_longjmp, another_trap)
+ handling_longjmp, another_trap,
+ stepping_through_solib_after_catch,
+ stepping_through_solib_catchpoints,
+ stepping_through_sigtramp)
int pid;
CORE_ADDR *prev_pc;
CORE_ADDR *prev_func_start;
@@ -180,6 +314,9 @@ void load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
CORE_ADDR *step_frame_address;
int *handling_longjmp;
int *another_trap;
+ int * stepping_through_solib_after_catch;
+ bpstat * stepping_through_solib_catchpoints;
+ int * stepping_through_sigtramp;
{
struct thread_info *tp;
@@ -200,6 +337,9 @@ void load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
*handling_longjmp = tp->handling_longjmp;
*trap_expected = tp->trap_expected;
*another_trap = tp->another_trap;
+ *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
+ *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
+ *stepping_through_sigtramp = tp->stepping_through_sigtramp;
}
/* Save infrun state for the thread PID. */
@@ -208,7 +348,10 @@ void save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
trap_expected, step_resume_breakpoint,
through_sigtramp_breakpoint, step_range_start,
step_range_end, step_frame_address,
- handling_longjmp, another_trap)
+ handling_longjmp, another_trap,
+ stepping_through_solib_after_catch,
+ stepping_through_solib_catchpoints,
+ stepping_through_sigtramp)
int pid;
CORE_ADDR prev_pc;
CORE_ADDR prev_func_start;
@@ -221,6 +364,9 @@ void save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
CORE_ADDR step_frame_address;
int handling_longjmp;
int another_trap;
+ int stepping_through_solib_after_catch;
+ bpstat stepping_through_solib_catchpoints;
+ int stepping_through_sigtramp;
{
struct thread_info *tp;
@@ -241,30 +387,54 @@ void save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
tp->handling_longjmp = handling_longjmp;
tp->trap_expected = trap_expected;
tp->another_trap = another_trap;
+ tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
+ tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
+ tp->stepping_through_sigtramp = stepping_through_sigtramp;
+}
+
+/* Return true if TP is an active thread. */
+static int
+thread_alive (tp)
+ struct thread_info *tp;
+{
+ if (tp->pid == -1)
+ return 0;
+ if (! target_thread_alive (tp->pid))
+ {
+ tp->pid = -1; /* Mark it as dead */
+ return 0;
+ }
+ return 1;
}
static void
prune_threads ()
{
- struct thread_info *tp, *tpprev;
+ struct thread_info *tp, *tpprev, *next;
tpprev = 0;
-
- for (tp = thread_list; tp; tp = tp->next)
- if (tp->pid == -1)
- {
- if (tpprev)
- tpprev->next = tp->next;
- else
- thread_list = NULL;
-
- free (tp);
- }
- else
- tpprev = tp;
+ for (tp = thread_list; tp; tp = next)
+ {
+ next = tp->next;
+ if (!thread_alive (tp))
+ {
+ if (tpprev)
+ tpprev->next = next;
+ else
+ thread_list = next;
+ free (tp);
+ }
+ else
+ tpprev = tp;
+ }
}
-/* Print information about currently known threads */
+/* Print information about currently known threads
+ *
+ * Note: this has the drawback that it _really_ switches
+ * threads, which frees the frame cache. A no-side
+ * effects info-threads command would be nicer.
+ */
static void
info_threads_command (arg, from_tty)
@@ -272,39 +442,68 @@ info_threads_command (arg, from_tty)
int from_tty;
{
struct thread_info *tp;
- int current_pid = inferior_pid;
+ int current_pid;
+ struct frame_info *cur_frame;
+ int saved_frame_level = selected_frame_level;
+ int counter;
/* Avoid coredumps which would happen if we tried to access a NULL
selected_frame. */
if (!target_has_stack) error ("No stack.");
+ prune_threads ();
+#if defined(FIND_NEW_THREADS)
+ FIND_NEW_THREADS ();
+#endif
+ current_pid = inferior_pid;
for (tp = thread_list; tp; tp = tp->next)
{
- if (! target_thread_alive (tp->pid))
- {
- tp->pid = -1; /* Mark it as dead */
- continue;
- }
-
if (tp->pid == current_pid)
printf_filtered ("* ");
else
printf_filtered (" ");
+#ifdef HPUXHPPA
+ printf_filtered ("%d %s ", tp->num, target_tid_to_str (tp->pid));
+#else
printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
+#endif
+ switch_to_thread (tp->pid);
+ if (selected_frame)
+ print_only_stack_frame (selected_frame, -1, 0);
+ else
+ printf_filtered ("[No stack.]\n");
+ }
- thread_switch (tp->pid);
+ switch_to_thread (current_pid);
+
+ /* Code below copied from "up_silently_base" in "stack.c".
+ * It restores the frame set by the user before the "info threads"
+ * command. We have finished the info-threads display by switching
+ * back to the current thread. That switch has put us at the top
+ * of the stack (leaf frame).
+ */
+ counter = saved_frame_level;
+ cur_frame = find_relative_frame(selected_frame, &counter);
+ if (counter != 0)
+ {
+ /* Ooops, can't restore, tell user where we are. */
+ warning ("Couldn't restore frame in current thread, at frame 0");
print_stack_frame (selected_frame, -1, 0);
}
+ else
+ {
+ select_frame(cur_frame, saved_frame_level);
+ }
- thread_switch (current_pid);
- prune_threads ();
+ /* re-show current frame. */
+ show_stack_frame(cur_frame);
}
/* Switch from one thread to another. */
static void
-thread_switch (pid)
+switch_to_thread (pid)
int pid;
{
if (pid == inferior_pid)
@@ -321,8 +520,11 @@ static void
restore_current_thread (pid)
int pid;
{
- if (pid != inferior_pid)
- thread_switch (pid);
+ if (pid != inferior_pid)
+ {
+ switch_to_thread (pid);
+ print_stack_frame( get_current_frame(), 0, -1);
+ }
}
/* Apply a GDB command to a list of threads. List syntax is a whitespace
@@ -345,15 +547,23 @@ thread_apply_all_command (cmd, from_tty)
if (cmd == NULL || *cmd == '\000')
error ("Please specify a command following the thread ID list");
- old_chain = make_cleanup (restore_current_thread, inferior_pid);
+ old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
+ (void *) inferior_pid);
for (tp = thread_list; tp; tp = tp->next)
- {
- thread_switch (tp->pid);
- printf_filtered ("\nThread %d (%s):\n", tp->num,
- target_pid_to_str (inferior_pid));
- execute_command (cmd, from_tty);
- }
+ if (thread_alive (tp))
+ {
+ switch_to_thread (tp->pid);
+#ifdef HPUXHPPA
+ printf_filtered ("\nThread %d (%s):\n",
+ tp->num,
+ target_tid_to_str (inferior_pid));
+#else
+ printf_filtered ("\nThread %d (%s):\n", tp->num,
+ target_pid_to_str (inferior_pid));
+#endif
+ execute_command (cmd, from_tty);
+ }
}
static void
@@ -373,7 +583,8 @@ thread_apply_command (tidlist, from_tty)
if (*cmd == '\000')
error ("Please specify a command following the thread ID list");
- old_chain = make_cleanup (restore_current_thread, inferior_pid);
+ old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
+ (void *) inferior_pid);
while (tidlist < cmd)
{
@@ -407,15 +618,21 @@ thread_apply_command (tidlist, from_tty)
tp = find_thread_id (start);
if (!tp)
+ warning ("Unknown thread %d.", start);
+ else if (!thread_alive (tp))
+ warning ("Thread %d has terminated.", start);
+ else
{
- warning ("Unknown thread %d.", start);
- continue;
+ switch_to_thread (tp->pid);
+#ifdef HPUXHPPA
+ printf_filtered ("\nThread %d (%s):\n", tp->num,
+ target_tid_to_str (inferior_pid));
+#else
+ printf_filtered ("\nThread %d (%s):\n", tp->num,
+ target_pid_to_str (inferior_pid));
+#endif
+ execute_command (cmd, from_tty);
}
-
- thread_switch (tp->pid);
- printf_filtered ("\nThread %d (%s):\n", tp->num,
- target_pid_to_str (inferior_pid));
- execute_command (cmd, from_tty);
}
}
}
@@ -432,9 +649,21 @@ thread_command (tidstr, from_tty)
struct thread_info *tp;
if (!tidstr)
- error ("Please specify a thread ID. Use the \"info threads\" command to\n\
-see the IDs of currently known threads.");
-
+ {
+ /* Don't generate an error, just say which thread is current. */
+ if (target_has_stack)
+ printf_filtered ("[Current thread is %d (%s)]\n",
+ pid_to_thread_id(inferior_pid),
+#if defined(HPUXHPPA)
+ target_tid_to_str(inferior_pid)
+#else
+ target_pid_to_str(inferior_pid)
+#endif
+ );
+ else
+ error ("No stack.");
+ return;
+ }
num = atoi (tidstr);
tp = find_thread_id (num);
@@ -443,16 +672,31 @@ see the IDs of currently known threads.");
error ("Thread ID %d not known. Use the \"info threads\" command to\n\
see the IDs of currently known threads.", num);
- thread_switch (tp->pid);
+ if (!thread_alive (tp))
+ error ("Thread ID %d has terminated.\n", num);
+
+ switch_to_thread (tp->pid);
- printf_filtered ("[Switching to %s]\n", target_pid_to_str (inferior_pid));
+ if (context_hook)
+ context_hook (num);
+
+ printf_filtered ("[Switching to thread %d (%s)]\n",
+ pid_to_thread_id (inferior_pid),
+#if defined(HPUXHPPA)
+ target_tid_to_str (inferior_pid)
+#else
+ target_pid_to_str (inferior_pid)
+#endif
+ );
print_stack_frame (selected_frame, selected_frame_level, 1);
}
+/* Commands with a prefix of `thread'. */
+struct cmd_list_element *thread_cmd_list = NULL;
+
void
_initialize_thread ()
{
- static struct cmd_list_element *thread_cmd_list = NULL;
static struct cmd_list_element *thread_apply_list = NULL;
extern struct cmd_list_element *cmdlist;
@@ -472,5 +716,6 @@ The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
"Apply a command to all threads.",
&thread_apply_list);
- add_com_alias ("t", "thread", class_run, 1);
+ if (!xdb_commands)
+ add_com_alias ("t", "thread", class_run, 1);
}
diff --git a/contrib/gdb/gdb/top.c b/contrib/gdb/gdb/top.c
index 088bcd9..189e3c3 100644
--- a/contrib/gdb/gdb/top.c
+++ b/contrib/gdb/gdb/top.c
@@ -1,5 +1,5 @@
/* Top level stuff for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -36,8 +36,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "top.h"
/* readline include files */
-#include "readline.h"
-#include "history.h"
+#include <readline/readline.h>
+#include <readline/history.h>
/* readline defines this. */
#undef savestring
@@ -48,19 +48,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif
#include "gdb_string.h"
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
-#include <sys/param.h>
#include "gdb_stat.h"
#include <ctype.h>
-extern void initialize_targets PARAMS ((void));
-
extern void initialize_utils PARAMS ((void));
/* Prototypes for local functions */
+static void dont_repeat_command PARAMS ((char *, int));
+
+static void source_cleanup_lines PARAMS ((PTR));
+
+static void user_defined_command PARAMS ((char *, int));
+
+static void init_signals PARAMS ((void));
+
+#ifdef STOP_SIGNAL
+static void stop_sig PARAMS ((int));
+#endif
+
static char * line_completion_function PARAMS ((char *, int, char *, int));
static char * readline_line_completion_function PARAMS ((char *, int));
@@ -102,20 +108,6 @@ static void init_signals PARAMS ((void));
static void set_verbose PARAMS ((char *, int, struct cmd_list_element *));
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-static void set_endian PARAMS ((char *, int));
-
-static void set_endian_big PARAMS ((char *, int));
-
-static void set_endian_little PARAMS ((char *, int));
-
-static void set_endian_auto PARAMS ((char *, int));
-
-static void show_endian PARAMS ((char *, int));
-
-#endif
-
static void show_history PARAMS ((char *, int));
static void set_history PARAMS ((char *, int));
@@ -147,9 +139,11 @@ static void complete_command PARAMS ((char *, int));
static void do_nothing PARAMS ((int));
-static int quit_cover PARAMS ((char *));
+#ifdef SIGHUP
+static int quit_cover PARAMS ((PTR));
static void disconnect PARAMS ((int));
+#endif
static void source_cleanup PARAMS ((FILE *));
@@ -209,6 +203,14 @@ struct cmd_list_element *enablelist;
struct cmd_list_element *disablelist;
+/* Chain containing all defined toggle subcommands. */
+
+struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+struct cmd_list_element *stoplist;
+
/* Chain containing all defined delete subcommands. */
struct cmd_list_element *deletelist;
@@ -229,12 +231,6 @@ struct cmd_list_element *unsetlist;
struct cmd_list_element *showlist;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-/* Chain containing the \"set endian\" commands. */
-
-struct cmd_list_element *endianlist;
-#endif
-
/* Chain containing all defined \"set history\". */
struct cmd_list_element *sethistlist;
@@ -275,7 +271,7 @@ struct cmd_list_element *showchecklist;
/* stdio stream that command input is being read from. Set to stdin normally.
Set by source_command to the file we are sourcing. Set to NULL if we are
- executing a user-defined command. */
+ executing a user-defined command or interacting via a GUI. */
FILE *instream;
@@ -319,6 +315,10 @@ int server_command;
int baud_rate = -1;
+/* Timeout limit for response from target. */
+
+int remote_timeout = 20; /* Set default to 20 */
+
/* Non-zero tells remote* modules to output debugging info. */
int remote_debug = 0;
@@ -366,7 +366,10 @@ static void stop_sig PARAMS ((int));
/* Called after most modules have been initialized, but before taking users
command file. */
-void (*init_ui_hook) PARAMS ((void));
+void (*init_ui_hook) PARAMS ((char *argv0));
+#ifdef __CYGWIN32__
+void (*ui_loop_hook) PARAMS ((int));
+#endif
/* Called instead of command_loop at top level. Can be invoked via
return_to_top_level. */
@@ -376,7 +379,7 @@ void (*command_loop_hook) PARAMS ((void));
/* Called instead of fputs for all output. */
-void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream));
+void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE *stream));
/* Called when the target says something to the host, which may
want to appear in a different window. */
@@ -389,11 +392,30 @@ void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
int stopline, int noerror));
/* Replaces most of query. */
-int (*query_hook) PARAMS (());
+int (*query_hook) PARAMS ((const char *, va_list));
+
+/* Replaces most of warning. */
+
+void (*warning_hook) PARAMS ((const char *, va_list));
/* Called from gdb_flush to flush output. */
-void (*flush_hook) PARAMS ((FILE *stream));
+void (*flush_hook) PARAMS ((GDB_FILE *stream));
+
+/* These three functions support getting lines of text from the user. They
+ are used in sequence. First readline_begin_hook is called with a text
+ string that might be (for example) a message for the user to type in a
+ sequence of commands to be executed at a breakpoint. If this function
+ calls back to a GUI, it might take this opportunity to pop up a text
+ interaction window with this message. Next, readline_hook is called
+ with a prompt that is emitted prior to collecting the user input.
+ It can be called multiple times. Finally, readline_end_hook is called
+ to notify the GUI that we are done with the interaction window and it
+ can close it. */
+
+void (*readline_begin_hook) PARAMS ((char *, ...));
+char * (*readline_hook) PARAMS ((char *));
+void (*readline_end_hook) PARAMS ((void));
/* Called as appropriate to notify the interface of the specified breakpoint
conditions. */
@@ -412,6 +434,14 @@ void (*interactive_hook) PARAMS ((void));
void (*registers_changed_hook) PARAMS ((void));
+/* Tell the GUI someone changed the register REGNO. -1 means
+ that the caller does not know which register changed or
+ that several registers have changed (see value_assign).*/
+void (*register_changed_hook) PARAMS ((int regno));
+
+/* Tell the GUI someone changed LEN bytes of memory at ADDR */
+void (*memory_changed_hook) PARAMS ((CORE_ADDR addr, int len));
+
/* Called when going to wait for the target. Usually allows the GUI to run
while waiting for target events. */
@@ -423,17 +453,20 @@ int (*target_wait_hook) PARAMS ((int pid, struct target_waitstatus *status));
void (*call_command_hook) PARAMS ((struct cmd_list_element *c, char *cmd,
int from_tty));
+/* Called when the current thread changes. Argument is thread id. */
+
+void (*context_hook) PARAMS ((int id));
/* Takes control from error (). Typically used to prevent longjmps out of the
middle of the GUI. Usually used in conjunction with a catch routine. */
-NORETURN void (*error_hook) PARAMS (()) ATTR_NORETURN;
+NORETURN void (*error_hook) PARAMS ((void)) ATTR_NORETURN;
/* Where to go for return_to_top_level (RETURN_ERROR). */
-jmp_buf error_return;
+SIGJMP_BUF error_return;
/* Where to go for return_to_top_level (RETURN_QUIT). */
-jmp_buf quit_return;
+SIGJMP_BUF quit_return;
/* Return for reason REASON. This generally gets back to the command
loop, but can be caught via catch_errors. */
@@ -463,7 +496,7 @@ return_to_top_level (reason)
break;
}
- (NORETURN void) longjmp
+ (NORETURN void) SIGLONGJMP
(reason == RETURN_ERROR ? error_return : quit_return, 1);
}
@@ -488,14 +521,14 @@ return_to_top_level (reason)
int
catch_errors (func, args, errstring, mask)
- int (*func) PARAMS ((char *));
+ catch_errors_ftype *func;
PTR args;
char *errstring;
return_mask mask;
{
- jmp_buf saved_error;
- jmp_buf saved_quit;
- jmp_buf tmp_jmp;
+ SIGJMP_BUF saved_error;
+ SIGJMP_BUF saved_quit;
+ SIGJMP_BUF tmp_jmp;
int val;
struct cleanup *saved_cleanup_chain;
char *saved_error_pre_print;
@@ -507,21 +540,21 @@ catch_errors (func, args, errstring, mask)
if (mask & RETURN_MASK_ERROR)
{
- memcpy ((char *)saved_error, (char *)error_return, sizeof (jmp_buf));
+ memcpy ((char *)saved_error, (char *)error_return, sizeof (SIGJMP_BUF));
error_pre_print = errstring;
}
if (mask & RETURN_MASK_QUIT)
{
- memcpy (saved_quit, quit_return, sizeof (jmp_buf));
+ memcpy (saved_quit, quit_return, sizeof (SIGJMP_BUF));
quit_pre_print = errstring;
}
- if (setjmp (tmp_jmp) == 0)
+ if (SIGSETJMP (tmp_jmp) == 0)
{
if (mask & RETURN_MASK_ERROR)
- memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
+ memcpy (error_return, tmp_jmp, sizeof (SIGJMP_BUF));
if (mask & RETURN_MASK_QUIT)
- memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
+ memcpy (quit_return, tmp_jmp, sizeof (SIGJMP_BUF));
val = (*func) (args);
}
else
@@ -531,12 +564,12 @@ catch_errors (func, args, errstring, mask)
if (mask & RETURN_MASK_ERROR)
{
- memcpy (error_return, saved_error, sizeof (jmp_buf));
+ memcpy (error_return, saved_error, sizeof (SIGJMP_BUF));
error_pre_print = saved_error_pre_print;
}
if (mask & RETURN_MASK_QUIT)
{
- memcpy (quit_return, saved_quit, sizeof (jmp_buf));
+ memcpy (quit_return, saved_quit, sizeof (SIGJMP_BUF));
quit_pre_print = saved_quit_pre_print;
}
return val;
@@ -544,6 +577,7 @@ catch_errors (func, args, errstring, mask)
/* Handler for SIGHUP. */
+#ifdef SIGHUP
static void
disconnect (signo)
int signo;
@@ -558,13 +592,14 @@ int signo;
static int
quit_cover (s)
-char *s;
+ PTR s;
{
caution = 0; /* Throw caution to the wind -- we're exiting.
This prevents asking the user dumb questions. */
quit_command((char *)0, 0);
return 0;
}
+#endif /* defined SIGHUP */
/* Line number we are currently in in a file which is being sourced. */
static int source_line_number;
@@ -599,18 +634,19 @@ read_command_file (stream)
{
struct cleanup *cleanups;
- cleanups = make_cleanup (source_cleanup, instream);
+ cleanups = make_cleanup ((make_cleanup_func) source_cleanup, instream);
instream = stream;
command_loop ();
do_cleanups (cleanups);
}
-extern void init_proc ();
+extern void init_proc PARAMS ((void));
void (*pre_init_ui_hook) PARAMS ((void));
void
-gdb_init ()
+gdb_init (argv0)
+ char *argv0;
{
if (pre_init_ui_hook)
pre_init_ui_hook ();
@@ -636,7 +672,7 @@ gdb_init ()
expected_language = current_language; /* don't warn about the change. */
if (init_ui_hook)
- init_ui_hook ();
+ init_ui_hook (argv0);
}
/* Allocate, initialize a new command line structure for one of the
@@ -679,7 +715,7 @@ get_command_line (type, arg)
/* Allocate and build a new command line structure. */
cmd = build_command_line (type, arg);
- old_chain = make_cleanup (free_command_lines, &cmd);
+ old_chain = make_cleanup ((make_cleanup_func) free_command_lines, &cmd);
/* Read in the body of this command. */
if (recurse_read_control_structure (cmd) == invalid_control)
@@ -784,6 +820,7 @@ execute_control_command (cmd)
struct command_line *current;
struct cleanup *old_chain = 0;
value_ptr val;
+ value_ptr val_mark;
int loop;
enum command_control_type ret;
char *new_line;
@@ -795,7 +832,8 @@ execute_control_command (cmd)
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &new_line);
execute_command (new_line, 0);
ret = cmd->control_type;
break;
@@ -813,9 +851,10 @@ execute_control_command (cmd)
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &new_line);
expr = parse_expression (new_line);
- make_cleanup (free_current_contents, &expr);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expr);
ret = simple_control;
loop = 1;
@@ -823,11 +862,18 @@ execute_control_command (cmd)
/* Keep iterating so long as the expression is true. */
while (loop == 1)
{
+ int cond_result;
+
+ QUIT;
+
/* Evaluate the expression. */
+ val_mark = value_mark ();
val = evaluate_expression (expr);
+ cond_result = value_true (val);
+ value_free_to_mark (val_mark);
/* If the value is false, then break out of the loop. */
- if (!value_true (val))
+ if (!cond_result)
break;
/* Execute the body of the while statement. */
@@ -866,15 +912,17 @@ execute_control_command (cmd)
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &new_line);
/* Parse the conditional for the if statement. */
expr = parse_expression (new_line);
- make_cleanup (free_current_contents, &expr);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expr);
current = NULL;
ret = simple_control;
/* Evaluate the conditional. */
+ val_mark = value_mark ();
val = evaluate_expression (expr);
/* Choose which arm to take commands from based on the value of the
@@ -883,6 +931,7 @@ execute_control_command (cmd)
current = *cmd->body_list;
else if (cmd->body_count == 2)
current = *(cmd->body_list + 1);
+ value_free_to_mark (val_mark);
/* Execute commands in the given arm. */
while (current)
@@ -980,7 +1029,7 @@ setup_user_args (p)
args->next = user_args;
user_args = args;
- old_chain = make_cleanup (arg_cleanup, 0);
+ old_chain = make_cleanup ((make_cleanup_func) arg_cleanup, 0);
if (p == NULL)
return old_chain;
@@ -988,6 +1037,9 @@ setup_user_args (p)
while (*p)
{
char *start_arg;
+ int squote = 0;
+ int dquote = 0;
+ int bsquote = 0;
if (arg_count >= MAXUSERARGS)
{
@@ -1005,8 +1057,36 @@ setup_user_args (p)
user_args->a[arg_count].arg = p;
/* Get to the end of this argument. */
- while (*p && *p != ' ' && *p != '\t')
- p++;
+ while (*p)
+ {
+ if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote)
+ break;
+ else
+ {
+ if (bsquote)
+ bsquote = 0;
+ else if (*p == '\\')
+ bsquote = 1;
+ else if (squote)
+ {
+ if (*p == '\'')
+ squote = 0;
+ }
+ else if (dquote)
+ {
+ if (*p == '"')
+ dquote = 0;
+ }
+ else
+ {
+ if (*p == '\'')
+ squote = 1;
+ else if (*p == '"')
+ dquote = 1;
+ }
+ p++;
+ }
+ }
user_args->a[arg_count].len = p - start_arg;
arg_count++;
@@ -1113,7 +1193,7 @@ execute_user_command (c, args)
/* Set the instream to 0, indicating execution of a
user-defined function. */
- old_chain = make_cleanup (source_cleanup, instream);
+ old_chain = make_cleanup ((make_cleanup_func) source_cleanup, instream);
instream = (FILE *) 0;
while (cmdlines)
{
@@ -1139,16 +1219,20 @@ execute_command (p, from_tty)
register struct cmd_list_element *c;
register enum language flang;
static int warned = 0;
- extern FILE *serial_logfp;
+ /* FIXME: These should really be in an appropriate header file */
+ extern void serial_log_command PARAMS ((const char *));
free_all_values ();
+ /* Force cleanup of any alloca areas if using C alloca instead of
+ a builtin alloca. */
+ alloca (0);
+
/* This can happen when command_line_input hits end of file. */
if (p == NULL)
return;
- if (serial_logfp != NULL)
- serial_log_command (p);
+ serial_log_command (p);
while (*p == ' ' || *p == '\t') p++;
if (*p)
@@ -1230,22 +1314,39 @@ command_loop ()
int stdin_is_tty = ISATTY (stdin);
long time_at_cmd_start;
#ifdef HAVE_SBRK
- long space_at_cmd_start;
+ long space_at_cmd_start = 0;
#endif
extern int display_time;
extern int display_space;
- while (!feof (instream))
+ while (instream && !feof (instream))
{
+#if defined(TUI)
+ extern int insert_mode;
+#endif
if (window_hook && instream == stdin)
(*window_hook) (instream, prompt);
quit_flag = 0;
if (instream == stdin && stdin_is_tty)
reinitialize_more_filter ();
- old_chain = make_cleanup (command_loop_marker, 0);
+ old_chain = make_cleanup ((make_cleanup_func) command_loop_marker, 0);
+
+#if defined(TUI)
+ /* A bit of paranoia: I want to make sure the "insert_mode" global
+ * is clear except when it is being used for command-line editing
+ * (see tuiIO.c, utils.c); otherwise normal output will
+ * get messed up in the TUI. So clear it before/after
+ * the command-line-input call. - RT
+ */
+ insert_mode = 0;
+#endif
+ /* Get a command-line. This calls the readline package. */
command = command_line_input (instream == stdin ? prompt : (char *) NULL,
instream == stdin, "prompt");
+#if defined(TUI)
+ insert_mode = 0;
+#endif
if (command == 0)
return;
@@ -1356,7 +1457,15 @@ gdb_readline (prrompt)
}
if (c == '\n')
+#ifndef CRLF_SOURCE_FILES
break;
+#else
+ {
+ if (input_index > 0 && result[input_index - 1] == '\r')
+ input_index--;
+ break;
+ }
+#endif
result[input_index++] = c;
while (input_index >= result_size)
@@ -1428,7 +1537,7 @@ filename_completer (text, word)
char *word;
{
/* From readline. */
- extern char *filename_completion_function ();
+ extern char *filename_completion_function PARAMS ((char *, int));
int subsequent_name;
char **return_val;
int return_val_used;
@@ -1839,6 +1948,13 @@ static void
do_nothing (signo)
int signo;
{
+ /* Under System V the default disposition of a signal is reinstated after
+ the signal is caught and delivered to an application process. On such
+ systems one must restore the replacement signal handler if one wishes
+ to continue handling the signal in one's program. On BSD systems this
+ is not needed but it is harmless, and it simplifies the code to just do
+ it unconditionally. */
+ signal (signo, do_nothing);
}
static void
@@ -1861,8 +1977,10 @@ init_signals ()
a handler for SIGQUIT, when we call exec it will set the signal
to SIG_DFL for us. */
signal (SIGQUIT, do_nothing);
+#ifdef SIGHUP
if (signal (SIGHUP, do_nothing) != SIG_IGN)
signal (SIGHUP, disconnect);
+#endif
signal (SIGFPE, float_handler);
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
@@ -1960,11 +2078,18 @@ command_line_input (prrompt, repeat, annotation_suffix)
}
/* Don't use fancy stuff if not talking to stdin. */
- if (command_editing_p && instream == stdin
- && ISATTY (instream))
- rl = readline (local_prompt);
+ if (readline_hook && instream == NULL)
+ {
+ rl = (*readline_hook) (local_prompt);
+ }
+ else if (command_editing_p && instream == stdin && ISATTY (instream))
+ {
+ rl = readline (local_prompt);
+ }
else
- rl = gdb_readline (local_prompt);
+ {
+ rl = gdb_readline (local_prompt);
+ }
if (annotation_level > 1 && instream == stdin)
{
@@ -2136,7 +2261,7 @@ read_next_line (command)
error ("Control nesting too deep!\n");
/* Set a prompt based on the nesting of the control commands. */
- if (instream == stdin)
+ if (instream == stdin || (instream == 0 && readline_hook != NULL))
{
for (i = 0; i < control_level; i++)
control_prompt[i] = ' ';
@@ -2181,7 +2306,7 @@ read_next_line (command)
*command = build_command_line (while_control, p + 6);
else if (p1 - p > 2 && !strncmp (p, "if", 2))
*command = build_command_line (if_control, p + 3);
- else if (p1 - p == 5 && !strncmp (p, "loop_break", 5))
+ else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
{
*command = (struct command_line *)
xmalloc (sizeof (struct command_line));
@@ -2191,7 +2316,7 @@ read_next_line (command)
(*command)->body_count = 0;
(*command)->body_list = NULL;
}
- else if (p1 - p == 8 && !strncmp (p, "loop_continue", 8))
+ else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13))
{
*command = (struct command_line *)
xmalloc (sizeof (struct command_line));
@@ -2218,7 +2343,7 @@ read_next_line (command)
}
/* Recursively read in the control structures and create a command_line
- tructure from them.
+ structure from them.
The parent_control parameter is the control structure in which the
following commands are nested. */
@@ -2329,19 +2454,34 @@ recurse_read_control_structure (current_cmd)
return ret;
}
+/* Read lines from the input stream and accumulate them in a chain of
+ struct command_line's, which is then returned. For input from a
+ terminal, the special command "end" is used to mark the end of the
+ input, and is not included in the returned chain of commands. */
-/* Read lines from the input stream
- and accumulate them in a chain of struct command_line's
- which is then returned. */
+#define END_MESSAGE "End with a line saying just \"end\"."
struct command_line *
-read_command_lines ()
+read_command_lines (prompt, from_tty)
+char *prompt;
+int from_tty;
{
struct command_line *head, *tail, *next;
struct cleanup *old_chain;
enum command_control_type ret;
enum misc_command_type val;
+ if (readline_begin_hook)
+ {
+ /* Note - intentional to merge messages with no newline */
+ (*readline_begin_hook) ("%s %s\n", prompt, END_MESSAGE);
+ }
+ else if (from_tty && input_from_terminal_p ())
+ {
+ printf_unfiltered ("%s\n%s\n", prompt, END_MESSAGE);
+ gdb_flush (gdb_stdout);
+ }
+
head = tail = NULL;
old_chain = NULL;
@@ -2383,7 +2523,8 @@ read_command_lines ()
else
{
head = next;
- old_chain = make_cleanup (free_command_lines, &head);
+ old_chain = make_cleanup ((make_cleanup_func) free_command_lines,
+ &head);
}
tail = next;
}
@@ -2395,13 +2536,16 @@ read_command_lines ()
if (ret != invalid_control)
{
discard_cleanups (old_chain);
- return head;
}
else
do_cleanups (old_chain);
}
- return NULL;
+ if (readline_end_hook)
+ {
+ (*readline_end_hook) ();
+ }
+ return (head);
}
/* Free a chain of struct command_line's. */
@@ -2577,6 +2721,7 @@ define_command (comname, from_tty)
register struct command_line *cmds;
register struct cmd_list_element *c, *newc, *hookc = 0;
char *tem = comname;
+ char tmpbuf[128];
#define HOOK_STRING "hook-"
#define HOOK_LEN 5
@@ -2624,15 +2769,9 @@ define_command (comname, from_tty)
for (tem = comname; *tem; tem++)
if (isupper(*tem)) *tem = tolower(*tem);
- if (from_tty)
- {
- printf_unfiltered ("Type commands for definition of \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
- gdb_flush (gdb_stdout);
- }
-
control_level = 0;
- cmds = read_command_lines ();
+ sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
+ cmds = read_command_lines (tmpbuf, from_tty);
if (c && c->class == class_user)
free_command_lines (&c->user_commands);
@@ -2659,6 +2798,7 @@ document_command (comname, from_tty)
struct command_line *doclines;
register struct cmd_list_element *c;
char *tem = comname;
+ char tmpbuf[128];
validate_comname (comname);
@@ -2667,11 +2807,8 @@ document_command (comname, from_tty)
if (c->class != class_user)
error ("Command \"%s\" is built-in.", comname);
- if (from_tty)
- printf_unfiltered ("Type documentation for \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
-
- doclines = read_command_lines ();
+ sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
+ doclines = read_command_lines (tmpbuf, from_tty);
if (c->doc) free (c->doc);
@@ -2696,29 +2833,44 @@ End with a line saying just \"end\".\n", comname);
free_command_lines (&doclines);
}
-void
-print_gnu_advertisement ()
-{
- printf_unfiltered ("\
-GDB is free software and you are welcome to distribute copies of it\n\
- under certain conditions; type \"show copying\" to see the conditions.\n\
-There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
-");
-}
-
+/* Print the GDB banner. */
void
print_gdb_version (stream)
GDB_FILE *stream;
{
+ /* From GNU coding standards, first line is meant to be easy for a
+ program to parse, and is just canonical program name and version
+ number, which starts after last space. */
+
+ fprintf_filtered (stream, "GNU gdb %s\n", version);
+
+ /* Second line is a copyright notice. */
+
+ fprintf_filtered (stream, "Copyright 1998 Free Software Foundation, Inc.\n");
+
+ /* Following the copyright is a brief statement that the program is
+ free software, that users are free to copy and change it on
+ certain conditions, that it is covered by the GNU GPL, and that
+ there is no warranty. */
+
fprintf_filtered (stream, "\
-GDB %s (%s", version, host_name);
+GDB is free software, covered by the GNU General Public License, and you are\n\
+welcome to change it and/or distribute copies of it under certain conditions.\n\
+Type \"show copying\" to see the conditions.\n\
+There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n");
- if (!STREQ (host_name, target_name))
- fprintf_filtered (stream, " --target %s", target_name);
+ /* After the required info we print the configuration information. */
- fprintf_filtered (stream, "), ");
- wrap_here("");
- fprintf_filtered (stream, "Copyright 1996 Free Software Foundation, Inc.");
+ fprintf_filtered (stream, "This GDB was configured as \"");
+ if (!STREQ (host_name, target_name))
+ {
+ fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name);
+ }
+ else
+ {
+ fprintf_filtered (stream, "%s", host_name);
+ }
+ fprintf_filtered (stream, "\".");
}
/* ARGSUSED */
@@ -2728,7 +2880,6 @@ show_version (args, from_tty)
int from_tty;
{
immediate_quit++;
- print_gnu_advertisement ();
print_gdb_version (gdb_stdout);
printf_filtered ("\n");
immediate_quit--;
@@ -2743,9 +2894,59 @@ print_prompt ()
printf_unfiltered ("%s", prompt);
gdb_flush (gdb_stdout);
}
+
+/* This replaces the above for the frontends: it returns a pointer
+ to the prompt. */
+char *
+get_prompt ()
+{
+ return prompt;
+}
+
+void
+set_prompt (s)
+ char *s;
+{
+/* ??rehrauer: I don't know why this fails, since it looks as though
+ assignments to prompt are wrapped in calls to savestring...
+ if (prompt != NULL)
+ free (prompt);
+*/
+ prompt = savestring (s, strlen (s));
+}
+
+/* If necessary, make the user confirm that we should quit. Return
+ non-zero if we should quit, zero if we shouldn't. */
+
+int
+quit_confirm ()
+{
+ if (inferior_pid != 0 && target_has_execution)
+ {
+ char *s;
+
+ /* This is something of a hack. But there's no reliable way to
+ see if a GUI is running. The `use_windows' variable doesn't
+ cut it. */
+ if (init_ui_hook)
+ s = "A debugging session is active.\nDo you still want to close the debugger?";
+ else if (attach_flag)
+ s = "The program is running. Quit anyway (and detach it)? ";
+ else
+ s = "The program is running. Exit anyway? ";
+
+ if (! query (s))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Quit without asking for confirmation. */
+
void
-quit_command (args, from_tty)
+quit_force (args, from_tty)
char *args;
int from_tty;
{
@@ -2763,20 +2964,11 @@ quit_command (args, from_tty)
if (inferior_pid != 0 && target_has_execution)
{
if (attach_flag)
- {
- if (query ("The program is running. Quit anyway (and detach it)? "))
- target_detach (args, from_tty);
- else
- error ("Not confirmed.");
- }
+ target_detach (args, from_tty);
else
- {
- if (query ("The program is running. Quit anyway (and kill it)? "))
- target_kill ();
- else
- error ("Not confirmed.");
- }
+ target_kill ();
}
+
/* UDI wants this, to kill the TIP. */
target_close (1);
@@ -2784,9 +2976,33 @@ quit_command (args, from_tty)
if (write_history_p && history_filename)
write_history (history_filename);
+ do_final_cleanups(ALL_CLEANUPS); /* Do any final cleanups before exiting */
+
+#if defined(TUI)
+ /* tuiDo((TuiOpaqueFuncPtr)tuiCleanUp); */
+ /* The above does not need to be inside a tuiDo(), since
+ * it is not manipulating the curses screen, but rather,
+ * it is tearing it down.
+ */
+ if (tui_version)
+ tuiCleanUp();
+#endif
+
exit (exit_code);
}
+/* Handle the quit command. */
+
+void
+quit_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (! quit_confirm ())
+ error ("Not confirmed.");
+ quit_force (args, from_tty);
+}
+
/* Returns whether GDB is running on a terminal and whether the user
desires that questions be asked of them on that terminal. */
@@ -2934,10 +3150,13 @@ source_command (args, from_tty)
old_cleanups = make_cleanup (free, file);
stream = fopen (file, FOPEN_RT);
- if (stream == 0)
- perror_with_name (file);
+ if (!stream)
+ if (from_tty)
+ perror_with_name (file);
+ else
+ return;
- make_cleanup (fclose, stream);
+ make_cleanup ((make_cleanup_func) fclose, stream);
old_lines.old_line = source_line_number;
old_lines.old_file = source_file_name;
@@ -3012,103 +3231,6 @@ dont_repeat_command (ignored, from_tty)
necessarily reading from stdin. */
}
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-/* Functions to manipulate the endianness of the target. */
-
-#ifndef TARGET_BYTE_ORDER_DEFAULT
-#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN
-#endif
-
-int target_byte_order = TARGET_BYTE_ORDER_DEFAULT;
-
-static int target_byte_order_auto = 1;
-
-/* Called if the user enters ``set endian'' without an argument. */
-static void
-set_endian (args, from_tty)
- char *args;
- int from_tty;
-{
- printf_unfiltered ("\"set endian\" must be followed by \"auto\", \"big\" or \"little\".\n");
- show_endian (args, from_tty);
-}
-
-/* Called by ``set endian big''. */
-static void
-set_endian_big (args, from_tty)
- char *args;
- int from_tty;
-{
- target_byte_order = BIG_ENDIAN;
- target_byte_order_auto = 0;
-}
-
-/* Called by ``set endian little''. */
-static void
-set_endian_little (args, from_tty)
- char *args;
- int from_tty;
-{
- target_byte_order = LITTLE_ENDIAN;
- target_byte_order_auto = 0;
-}
-
-/* Called by ``set endian auto''. */
-static void
-set_endian_auto (args, from_tty)
- char *args;
- int from_tty;
-{
- target_byte_order_auto = 1;
-}
-
-/* Called by ``show endian''. */
-static void
-show_endian (args, from_tty)
- char *args;
- int from_tty;
-{
- const char *msg =
- (target_byte_order_auto
- ? "The target endianness is set automatically (currently %s endian)\n"
- : "The target is assumed to be %s endian\n");
- printf_unfiltered ((char *) msg, TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-}
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
-/* Set the endianness from a BFD. */
-void
-set_endian_from_file (abfd)
- bfd *abfd;
-{
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
- int want;
-
- if (bfd_big_endian (abfd))
- want = BIG_ENDIAN;
- else
- want = LITTLE_ENDIAN;
- if (target_byte_order_auto)
- target_byte_order = want;
- else if (target_byte_order != want)
- warning ("%s endian file does not match %s endian target.",
- want == BIG_ENDIAN ? "big" : "little",
- TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-
-#else /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
- if (bfd_big_endian (abfd)
- ? TARGET_BYTE_ORDER != BIG_ENDIAN
- : TARGET_BYTE_ORDER == BIG_ENDIAN)
- warning ("%s endian file does not match %s endian target.",
- bfd_big_endian (abfd) ? "big" : "little",
- TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-
-#endif /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
-}
-
/* Functions to manipulate command line editing control variables. */
/* Number of commands to print in each call to show_commands. */
@@ -3273,14 +3395,13 @@ init_cmd_lists ()
infolist = NULL;
enablelist = NULL;
disablelist = NULL;
+ togglelist = NULL;
+ stoplist = NULL;
deletelist = NULL;
enablebreaklist = NULL;
setlist = NULL;
unsetlist = NULL;
showlist = NULL;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
- endianlist = NULL;
-#endif
sethistlist = NULL;
showhistlist = NULL;
unsethistlist = NULL;
@@ -3331,22 +3452,6 @@ init_main ()
{
struct cmd_list_element *c;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
- add_prefix_cmd ("endian", class_support, set_endian,
- "Set endianness of target.",
- &endianlist, "set endian ", 0, &setlist);
- add_cmd ("big", class_support, set_endian_big,
- "Set target as being big endian.", &endianlist);
- add_cmd ("little", class_support, set_endian_little,
- "Set target as being little endian.", &endianlist);
- add_cmd ("auto", class_support, set_endian_auto,
- "Select target endianness automatically.", &endianlist);
- add_cmd ("endian", class_support, show_endian,
- "Show endianness of target.", &showlist);
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
#ifdef DEFAULT_PROMPT
prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
#else
@@ -3379,7 +3484,8 @@ well documented as user commands.",
The commands in this class are those defined by the user.\n\
Use the \"define\" command to define a command.", &cmdlist);
add_cmd ("support", class_support, NO_FUNCTION, "Support facilities.", &cmdlist);
- add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
+ if (!dbx_commands)
+ add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
add_cmd ("files", class_files, NO_FUNCTION, "Specifying and examining files.", &cmdlist);
add_cmd ("breakpoints", class_breakpoint, NO_FUNCTION, "Making program stop at certain points.", &cmdlist);
add_cmd ("data", class_vars, NO_FUNCTION, "Examining data.", &cmdlist);
@@ -3459,7 +3565,7 @@ hitting return.");
add_show_from_set
(add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p,
"Set editing of command lines as they are typed.\n\
-Use \"on\" to enable to enable the editing, and \"off\" to disable it.\n\
+Use \"on\" to enable the editing, and \"off\" to disable it.\n\
Without an argument, command line editing is enabled. To edit, use\n\
EMACS-like or VI-like commands like control-P or ESC.", &setlist),
&showlist);
@@ -3480,7 +3586,7 @@ Without an argument, history expansion is enabled.", &sethistlist),
add_show_from_set
(add_set_cmd ("save", no_class, var_boolean, (char *)&write_history_p,
"Set saving of the history record on exit.\n\
-Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\
+Use \"on\" to enable the saving, and \"off\" to disable it.\n\
Without an argument, saving is enabled.", &sethistlist),
&showhistlist);
@@ -3554,4 +3660,18 @@ using remote targets.", &setlist),
When enabled, each packet sent or received with the remote target\n\
is displayed.", &setlist),
&showlist);
+
+ add_show_from_set (
+ add_set_cmd ("remotetimeout", no_class, var_integer, (char *)&remote_timeout,
+ "Set timeout limit to wait for target to respond.\n\
+This value is used to set the time limit for gdb to wait for a response\n\
+from the target.", &setlist),
+ &showlist);
+
+ c = add_set_cmd ("annotate", class_obscure, var_zinteger,
+ (char *)&annotation_level, "Set annotation_level.\n\
+0 == normal; 1 == fullname (for use when running under emacs)\n\
+2 == output annotated suitably for use by programs that control GDB.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
}
diff --git a/contrib/gdb/gdb/top.h b/contrib/gdb/gdb/top.h
index 661f4ef..fe7002b 100644
--- a/contrib/gdb/gdb/top.h
+++ b/contrib/gdb/gdb/top.h
@@ -29,19 +29,38 @@ extern char gdbinit[];
/* Generally one should use catch_errors rather than manipulating these
directly. The exception is main(). */
-extern jmp_buf error_return;
-extern jmp_buf quit_return;
+#if defined(HAVE_SIGSETJMP)
+#define SIGJMP_BUF sigjmp_buf
+#define SIGSETJMP(buf) sigsetjmp(buf, 1)
+#define SIGLONGJMP(buf,val) siglongjmp(buf,val)
+#else
+#define SIGJMP_BUF jmp_buf
+#define SIGSETJMP(buf) setjmp(buf)
+#define SIGLONGJMP(buf,val) longjmp(buf,val)
+#endif
+
+extern SIGJMP_BUF error_return;
+extern SIGJMP_BUF quit_return;
extern void print_gdb_version PARAMS ((GDB_FILE *));
-extern void print_gnu_advertisement PARAMS ((void));
extern void source_command PARAMS ((char *, int));
extern void cd_command PARAMS ((char *, int));
extern void read_command_file PARAMS ((FILE *));
extern void init_history PARAMS ((void));
extern void command_loop PARAMS ((void));
+extern int quit_confirm PARAMS ((void));
+extern void quit_force PARAMS ((char *, int));
extern void quit_command PARAMS ((char *, int));
+/* This function returns a pointer to the string that is used
+ by gdb for its command prompt. */
+extern char *get_prompt PARAMS((void));
+
+/* This function copies the specified string into the string that
+ is used by gdb for its command prompt. */
+extern void set_prompt PARAMS ((char *));
+
/* From random places. */
extern int mapped_symbol_files;
extern int readnow_symbol_files;
diff --git a/contrib/gdb/gdb/tracepoint.c b/contrib/gdb/gdb/tracepoint.c
new file mode 100644
index 0000000..9f03617
--- /dev/null
+++ b/contrib/gdb/gdb/tracepoint.c
@@ -0,0 +1,2780 @@
+/* Tracing functionality for remote targets in custom GDB protocol
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "symtab.h"
+#include "frame.h"
+#include "tracepoint.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "gdbcmd.h"
+#include "value.h"
+#include "target.h"
+#include "language.h"
+#include "gdb_string.h"
+
+#include "ax.h"
+#include "ax-gdb.h"
+
+/* readline include files */
+#include <readline/readline.h>
+#include <readline/history.h>
+
+/* readline defines this. */
+#undef savestring
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* maximum length of an agent aexpression.
+ this accounts for the fact that packets are limited to 400 bytes
+ (which includes everything -- including the checksum), and assumes
+ the worst case of maximum length for each of the pieces of a
+ continuation packet.
+
+ NOTE: expressions get mem2hex'ed otherwise this would be twice as
+ large. (400 - 31)/2 == 184 */
+#define MAX_AGENT_EXPR_LEN 184
+
+
+extern int info_verbose;
+extern void (*readline_begin_hook) PARAMS ((char *, ...));
+extern char * (*readline_hook) PARAMS ((char *));
+extern void (*readline_end_hook) PARAMS ((void));
+extern void x_command PARAMS ((char *, int));
+extern int addressprint; /* Print machine addresses? */
+
+/* If this definition isn't overridden by the header files, assume
+ that isatty and fileno exist on this system. */
+#ifndef ISATTY
+#define ISATTY(FP) (isatty (fileno (FP)))
+#endif
+
+/*
+ Tracepoint.c:
+
+ This module defines the following debugger commands:
+ trace : set a tracepoint on a function, line, or address.
+ info trace : list all debugger-defined tracepoints.
+ delete trace : delete one or more tracepoints.
+ enable trace : enable one or more tracepoints.
+ disable trace : disable one or more tracepoints.
+ actions : specify actions to be taken at a tracepoint.
+ passcount : specify a pass count for a tracepoint.
+ tstart : start a trace experiment.
+ tstop : stop a trace experiment.
+ tstatus : query the status of a trace experiment.
+ tfind : find a trace frame in the trace buffer.
+ tdump : print everything collected at the current tracepoint.
+ save-tracepoints : write tracepoint setup into a file.
+
+ This module defines the following user-visible debugger variables:
+ $trace_frame : sequence number of trace frame currently being debugged.
+ $trace_line : source line of trace frame currently being debugged.
+ $trace_file : source file of trace frame currently being debugged.
+ $tracepoint : tracepoint number of trace frame currently being debugged.
+ */
+
+
+/* ======= Important global variables: ======= */
+
+/* Chain of all tracepoints defined. */
+struct tracepoint *tracepoint_chain;
+
+/* Number of last tracepoint made. */
+static int tracepoint_count;
+
+/* Number of last traceframe collected. */
+static int traceframe_number;
+
+/* Tracepoint for last traceframe collected. */
+static int tracepoint_number;
+
+/* Symbol for function for last traceframe collected */
+static struct symbol *traceframe_fun;
+
+/* Symtab and line for last traceframe collected */
+static struct symtab_and_line traceframe_sal;
+
+/* Tracing command lists */
+static struct cmd_list_element *tfindlist;
+
+/* ======= Important command functions: ======= */
+static void trace_command PARAMS ((char *, int));
+static void tracepoints_info PARAMS ((char *, int));
+static void delete_trace_command PARAMS ((char *, int));
+static void enable_trace_command PARAMS ((char *, int));
+static void disable_trace_command PARAMS ((char *, int));
+static void trace_pass_command PARAMS ((char *, int));
+static void trace_actions_command PARAMS ((char *, int));
+static void trace_start_command PARAMS ((char *, int));
+static void trace_stop_command PARAMS ((char *, int));
+static void trace_status_command PARAMS ((char *, int));
+static void trace_find_command PARAMS ((char *, int));
+static void trace_find_pc_command PARAMS ((char *, int));
+static void trace_find_tracepoint_command PARAMS ((char *, int));
+static void trace_find_line_command PARAMS ((char *, int));
+static void trace_find_range_command PARAMS ((char *, int));
+static void trace_find_outside_command PARAMS ((char *, int));
+static void tracepoint_save_command PARAMS ((char *, int));
+static void trace_dump_command PARAMS ((char *, int));
+
+/* support routines */
+static void trace_mention PARAMS ((struct tracepoint *));
+
+struct collection_list;
+static void add_aexpr PARAMS ((struct collection_list *, struct agent_expr *));
+static unsigned char *mem2hex(unsigned char *, unsigned char *, int);
+
+/* Utility: returns true if "target remote" */
+static int
+target_is_remote ()
+{
+ if (current_target.to_shortname &&
+ strcmp (current_target.to_shortname, "remote") == 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* Utility: generate error from an incoming stub packet. */
+static void
+trace_error (buf)
+ char *buf;
+{
+ if (*buf++ != 'E')
+ return; /* not an error msg */
+ switch (*buf)
+ {
+ case '1': /* malformed packet error */
+ if (*++buf == '0') /* general case: */
+ error ("tracepoint.c: error in outgoing packet.");
+ else
+ error ("tracepoint.c: error in outgoing packet at field #%d.",
+ strtol (buf, NULL, 16));
+ case '2':
+ error ("trace API error 0x%s.", ++buf);
+ default:
+ error ("Target returns error code '%s'.", buf);
+ }
+}
+
+/* Utility: wait for reply from stub, while accepting "O" packets */
+static char *
+remote_get_noisy_reply (buf)
+ char *buf;
+{
+ do /* loop on reply from remote stub */
+ {
+ QUIT; /* allow user to bail out with ^C */
+ getpkt (buf, 0);
+ if (buf[0] == 0)
+ error ("Target does not support this command.");
+ else if (buf[0] == 'E')
+ trace_error (buf);
+ else if (buf[0] == 'O' &&
+ buf[1] != 'K')
+ remote_console_output (buf + 1); /* 'O' message from stub */
+ else
+ return buf; /* here's the actual reply */
+ } while (1);
+}
+
+/* Set tracepoint count to NUM. */
+static void
+set_tracepoint_count (num)
+ int num;
+{
+ tracepoint_count = num;
+ set_internalvar (lookup_internalvar ("tpnum"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Set traceframe number to NUM. */
+static void
+set_traceframe_num (num)
+ int num;
+{
+ traceframe_number = num;
+ set_internalvar (lookup_internalvar ("trace_frame"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Set tracepoint number to NUM. */
+static void
+set_tracepoint_num (num)
+ int num;
+{
+ tracepoint_number = num;
+ set_internalvar (lookup_internalvar ("tracepoint"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Set externally visible debug variables for querying/printing
+ the traceframe context (line, function, file) */
+
+static void
+set_traceframe_context (trace_pc)
+ CORE_ADDR trace_pc;
+{
+ static struct type *func_string, *file_string;
+ static struct type *func_range, *file_range;
+ static value_ptr func_val, file_val;
+ static struct type *charstar;
+ int len;
+
+ if (charstar == (struct type *) NULL)
+ charstar = lookup_pointer_type (builtin_type_char);
+
+ if (trace_pc == -1) /* cease debugging any trace buffers */
+ {
+ traceframe_fun = 0;
+ traceframe_sal.pc = traceframe_sal.line = 0;
+ traceframe_sal.symtab = NULL;
+ set_internalvar (lookup_internalvar ("trace_func"),
+ value_from_longest (charstar, (LONGEST) 0));
+ set_internalvar (lookup_internalvar ("trace_file"),
+ value_from_longest (charstar, (LONGEST) 0));
+ set_internalvar (lookup_internalvar ("trace_line"),
+ value_from_longest (builtin_type_int, (LONGEST) -1));
+ return;
+ }
+
+ /* save as globals for internal use */
+ traceframe_sal = find_pc_line (trace_pc, 0);
+ traceframe_fun = find_pc_function (trace_pc);
+
+ /* save linenumber as "$trace_line", a debugger variable visible to users */
+ set_internalvar (lookup_internalvar ("trace_line"),
+ value_from_longest (builtin_type_int,
+ (LONGEST) traceframe_sal.line));
+
+ /* save func name as "$trace_func", a debugger variable visible to users */
+ if (traceframe_fun == NULL ||
+ SYMBOL_NAME (traceframe_fun) == NULL)
+ set_internalvar (lookup_internalvar ("trace_func"),
+ value_from_longest (charstar, (LONGEST) 0));
+ else
+ {
+ len = strlen (SYMBOL_NAME (traceframe_fun));
+ func_range = create_range_type (func_range,
+ builtin_type_int, 0, len - 1);
+ func_string = create_array_type (func_string,
+ builtin_type_char, func_range);
+ func_val = allocate_value (func_string);
+ VALUE_TYPE (func_val) = func_string;
+ memcpy (VALUE_CONTENTS_RAW (func_val),
+ SYMBOL_NAME (traceframe_fun),
+ len);
+ func_val->modifiable = 0;
+ set_internalvar (lookup_internalvar ("trace_func"), func_val);
+ }
+
+ /* save file name as "$trace_file", a debugger variable visible to users */
+ if (traceframe_sal.symtab == NULL ||
+ traceframe_sal.symtab->filename == NULL)
+ set_internalvar (lookup_internalvar ("trace_file"),
+ value_from_longest (charstar, (LONGEST) 0));
+ else
+ {
+ len = strlen (traceframe_sal.symtab->filename);
+ file_range = create_range_type (file_range,
+ builtin_type_int, 0, len - 1);
+ file_string = create_array_type (file_string,
+ builtin_type_char, file_range);
+ file_val = allocate_value (file_string);
+ VALUE_TYPE (file_val) = file_string;
+ memcpy (VALUE_CONTENTS_RAW (file_val),
+ traceframe_sal.symtab->filename,
+ len);
+ file_val->modifiable = 0;
+ set_internalvar (lookup_internalvar ("trace_file"), file_val);
+ }
+}
+
+/* Low level routine to set a tracepoint.
+ Returns the tracepoint object so caller can set other things.
+ Does not set the tracepoint number!
+ Does not print anything.
+
+ ==> This routine should not be called if there is a chance of later
+ error(); otherwise it leaves a bogus tracepoint on the chain. Validate
+ your arguments BEFORE calling this routine! */
+
+static struct tracepoint *
+set_raw_tracepoint (sal)
+ struct symtab_and_line sal;
+{
+ register struct tracepoint *t, *tc;
+ struct cleanup *old_chain;
+
+ t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
+ old_chain = make_cleanup (free, t);
+ memset (t, 0, sizeof (*t));
+ t->address = sal.pc;
+ if (sal.symtab == NULL)
+ t->source_file = NULL;
+ else
+ t->source_file = savestring (sal.symtab->filename,
+ strlen (sal.symtab->filename));
+
+ t->section = sal.section;
+ t->language = current_language->la_language;
+ t->input_radix = input_radix;
+ t->line_number = sal.line;
+ t->enabled = enabled;
+ t->next = 0;
+ t->step_count = 0;
+ t->pass_count = 0;
+ t->addr_string = NULL;
+
+ /* Add this tracepoint to the end of the chain
+ so that a list of tracepoints will come out in order
+ of increasing numbers. */
+
+ tc = tracepoint_chain;
+ if (tc == 0)
+ tracepoint_chain = t;
+ else
+ {
+ while (tc->next)
+ tc = tc->next;
+ tc->next = t;
+ }
+ discard_cleanups (old_chain);
+ return t;
+}
+
+/* Set a tracepoint according to ARG (function, linenum or *address) */
+static void
+trace_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ char **canonical = (char **)NULL;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct tracepoint *t;
+ char *addr_start = 0, *addr_end = 0;
+ int i;
+
+ if (!arg || !*arg)
+ error ("trace command requires an argument");
+
+ if (from_tty && info_verbose)
+ printf_filtered ("TRACE %s\n", arg);
+
+ addr_start = arg;
+ sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, &canonical);
+ addr_end = arg;
+ if (! sals.nelts)
+ return; /* ??? Presumably decode_line_1 has already warned? */
+
+ /* Resolve all line numbers to PC's */
+ for (i = 0; i < sals.nelts; i++)
+ resolve_sal_pc (&sals.sals[i]);
+
+ /* Now set all the tracepoints. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ sal = sals.sals[i];
+
+ t = set_raw_tracepoint (sal);
+ set_tracepoint_count (tracepoint_count + 1);
+ t->number = tracepoint_count;
+
+ /* If a canonical line spec is needed use that instead of the
+ command string. */
+ if (canonical != (char **)NULL && canonical[i] != NULL)
+ t->addr_string = canonical[i];
+ else if (addr_start)
+ t->addr_string = savestring (addr_start, addr_end - addr_start);
+
+ trace_mention (t);
+
+ /* Let the UI know of any additions */
+ if (create_tracepoint_hook)
+ create_tracepoint_hook (t);
+ }
+
+ if (sals.nelts > 1)
+ {
+ printf_filtered ("Multiple tracepoints were set.\n");
+ printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
+ }
+}
+
+/* Tell the user we have just set a tracepoint TP. */
+
+static void
+trace_mention (tp)
+ struct tracepoint *tp;
+{
+ printf_filtered ("Tracepoint %d", tp->number);
+
+ if (addressprint || (tp->source_file == NULL))
+ {
+ printf_filtered (" at ");
+ print_address_numeric (tp->address, 1, gdb_stdout);
+ }
+ if (tp->source_file)
+ printf_filtered (": file %s, line %d.",
+ tp->source_file, tp->line_number);
+
+ printf_filtered ("\n");
+}
+
+/* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
+
+static void
+tracepoints_info (tpnum_exp, from_tty)
+ char *tpnum_exp;
+ int from_tty;
+{
+ struct tracepoint *t;
+ struct action_line *action;
+ int found_a_tracepoint = 0;
+ char wrap_indent[80];
+ struct symbol *sym;
+ int tpnum = -1;
+
+ if (tpnum_exp)
+ tpnum = parse_and_eval_address (tpnum_exp);
+
+ ALL_TRACEPOINTS (t)
+ if (tpnum == -1 || tpnum == t->number)
+ {
+ extern int addressprint; /* print machine addresses? */
+
+ if (!found_a_tracepoint++)
+ {
+ printf_filtered ("Num Enb ");
+ if (addressprint)
+ printf_filtered ("Address ");
+ printf_filtered ("PassC StepC What\n");
+ }
+ strcpy (wrap_indent, " ");
+ if (addressprint)
+ strcat (wrap_indent, " ");
+
+ printf_filtered ("%-3d %-3s ", t->number,
+ t->enabled == enabled ? "y" : "n");
+ if (addressprint)
+ printf_filtered ("%s ",
+ local_hex_string_custom ((unsigned long) t->address,
+ "08l"));
+ printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count);
+
+ if (t->source_file)
+ {
+ sym = find_pc_sect_function (t->address, t->section);
+ if (sym)
+ {
+ fputs_filtered ("in ", gdb_stdout);
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
+ wrap_here (wrap_indent);
+ fputs_filtered (" at ", gdb_stdout);
+ }
+ fputs_filtered (t->source_file, gdb_stdout);
+ printf_filtered (":%d", t->line_number);
+ }
+ else
+ print_address_symbolic (t->address, gdb_stdout, demangle, " ");
+
+ printf_filtered ("\n");
+ if (t->actions)
+ {
+ printf_filtered (" Actions for tracepoint %d: \n", t->number);
+ for (action = t->actions; action; action = action->next)
+ {
+ printf_filtered ("\t%s\n", action->action);
+ }
+ }
+ }
+ if (!found_a_tracepoint)
+ {
+ if (tpnum == -1)
+ printf_filtered ("No tracepoints.\n");
+ else
+ printf_filtered ("No tracepoint number %d.\n", tpnum);
+ }
+}
+
+/* Optimization: the code to parse an enable, disable, or delete TP command
+ is virtually identical except for whether it performs an enable, disable,
+ or delete. Therefore I've combined them into one function with an opcode.
+ */
+enum tracepoint_opcode
+{
+ enable,
+ disable,
+ delete
+};
+
+/* This function implements enable, disable and delete. */
+static void
+tracepoint_operation (t, from_tty, opcode)
+ struct tracepoint *t;
+ int from_tty;
+ enum tracepoint_opcode opcode;
+{
+ struct tracepoint *t2;
+
+ switch (opcode) {
+ case enable:
+ t->enabled = enabled;
+ if (modify_tracepoint_hook)
+ modify_tracepoint_hook (t);
+ break;
+ case disable:
+ t->enabled = disabled;
+ if (modify_tracepoint_hook)
+ modify_tracepoint_hook (t);
+ break;
+ case delete:
+ if (tracepoint_chain == t)
+ tracepoint_chain = t->next;
+
+ ALL_TRACEPOINTS (t2)
+ if (t2->next == t)
+ {
+ t2->next = t->next;
+ break;
+ }
+
+ /* Let the UI know of any deletions */
+ if (delete_tracepoint_hook)
+ delete_tracepoint_hook (t);
+
+ if (t->addr_string)
+ free (t->addr_string);
+ if (t->source_file)
+ free (t->source_file);
+ if (t->actions)
+ free_actions (t);
+
+ free (t);
+ break;
+ }
+}
+
+/* Utility: parse a tracepoint number and look it up in the list. */
+struct tracepoint *
+get_tracepoint_by_number (arg)
+ char **arg;
+{
+ struct tracepoint *t;
+ char *end, *copy;
+ value_ptr val;
+ int tpnum;
+
+ if (arg == 0)
+ error ("Bad tracepoint argument");
+
+ if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */
+ tpnum = tracepoint_count;
+ else if (**arg == '$') /* handle convenience variable */
+ {
+ /* Make a copy of the name, so we can null-terminate it
+ to pass to lookup_internalvar(). */
+ end = *arg + 1;
+ while (isalnum(*end) || *end == '_')
+ end++;
+ copy = (char *) alloca (end - *arg);
+ strncpy (copy, *arg + 1, (end - *arg - 1));
+ copy[end - *arg - 1] = '\0';
+ *arg = end;
+
+ val = value_of_internalvar (lookup_internalvar (copy));
+ if (TYPE_CODE( VALUE_TYPE (val)) != TYPE_CODE_INT)
+ error ("Convenience variable must have integral type.");
+ tpnum = (int) value_as_long (val);
+ }
+ else /* handle tracepoint number */
+ {
+ tpnum = strtol (*arg, arg, 0);
+ if (tpnum == 0) /* possible strtol failure */
+ while (**arg && !isspace (**arg))
+ (*arg)++; /* advance to next white space, if any */
+ }
+ ALL_TRACEPOINTS (t)
+ if (t->number == tpnum)
+ {
+ return t;
+ }
+ printf_unfiltered ("No tracepoint number %d.\n", tpnum);
+ return NULL;
+}
+
+/* Utility: parse a list of tracepoint numbers, and call a func for each. */
+static void
+map_args_over_tracepoints (args, from_tty, opcode)
+ char *args;
+ int from_tty;
+ enum tracepoint_opcode opcode;
+{
+ struct tracepoint *t, *tmp;
+ int tpnum;
+ char *cp;
+
+ if (args == 0 || *args == 0) /* do them all */
+ ALL_TRACEPOINTS_SAFE (t, tmp)
+ tracepoint_operation (t, from_tty, opcode);
+ else
+ while (*args)
+ {
+ QUIT; /* give user option to bail out with ^C */
+ if (t = get_tracepoint_by_number (&args))
+ tracepoint_operation (t, from_tty, opcode);
+ while (*args == ' ' || *args == '\t')
+ args++;
+ }
+}
+
+/* The 'enable trace' command enables tracepoints. Not supported by all targets. */
+static void
+enable_trace_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ dont_repeat ();
+ map_args_over_tracepoints (args, from_tty, enable);
+}
+
+/* The 'disable trace' command enables tracepoints. Not supported by all targets. */
+static void
+disable_trace_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ dont_repeat ();
+ map_args_over_tracepoints (args, from_tty, disable);
+}
+
+/* Remove a tracepoint (or all if no argument) */
+static void
+delete_trace_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ dont_repeat ();
+ if (!args || !*args) /* No args implies all tracepoints; */
+ if (from_tty) /* confirm only if from_tty... */
+ if (tracepoint_chain) /* and if there are tracepoints to delete! */
+ if (!query ("Delete all tracepoints? "))
+ return;
+
+ map_args_over_tracepoints (args, from_tty, delete);
+}
+
+/* Set passcount for tracepoint.
+
+ First command argument is passcount, second is tracepoint number.
+ If tracepoint number omitted, apply to most recently defined.
+ Also accepts special argument "all". */
+
+static void
+trace_pass_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
+ unsigned long count;
+
+ if (args == 0 || *args == 0)
+ error ("PASS command requires an argument (count + optional TP num)");
+
+ count = strtoul (args, &args, 10); /* count comes first, then TP num */
+
+ while (*args && isspace (*args))
+ args++;
+
+ if (*args && strncasecmp (args, "all", 3) == 0)
+ args += 3; /* skip special argument "all" */
+ else
+ t1 = get_tracepoint_by_number (&args);
+
+ if (*args)
+ error ("Junk at end of arguments.");
+
+ if (t1 == NULL)
+ return; /* error, bad tracepoint number */
+
+ ALL_TRACEPOINTS (t2)
+ if (t1 == (struct tracepoint *) -1 || t1 == t2)
+ {
+ t2->pass_count = count;
+ if (modify_tracepoint_hook)
+ modify_tracepoint_hook (t2);
+ if (from_tty)
+ printf_filtered ("Setting tracepoint %d's passcount to %d\n",
+ t2->number, count);
+ }
+}
+
+/* ACTIONS functions: */
+
+/* Prototypes for action-parsing utility commands */
+static void read_actions PARAMS((struct tracepoint *));
+static char *parse_and_eval_memrange PARAMS ((char *,
+ CORE_ADDR,
+ long *,
+ bfd_signed_vma *,
+ long *));
+
+/* The three functions:
+ collect_pseudocommand,
+ while_stepping_pseudocommand, and
+ end_actions_pseudocommand
+ are placeholders for "commands" that are actually ONLY to be used
+ within a tracepoint action list. If the actual function is ever called,
+ it means that somebody issued the "command" at the top level,
+ which is always an error. */
+
+static void
+end_actions_pseudocommand (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ error ("This command cannot be used at the top level.");
+}
+
+static void
+while_stepping_pseudocommand (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ error ("This command can only be used in a tracepoint actions list.");
+}
+
+static void
+collect_pseudocommand (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ error ("This command can only be used in a tracepoint actions list.");
+}
+
+/* Enter a list of actions for a tracepoint. */
+static void
+trace_actions_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct tracepoint *t;
+ char *actions;
+ char tmpbuf[128];
+ char *end_msg = "End with a line saying just \"end\".";
+
+ if (t = get_tracepoint_by_number (&args))
+ {
+ sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
+ t->number);
+
+ if (from_tty)
+ {
+ if (readline_begin_hook)
+ (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
+ else if (input_from_terminal_p ())
+ printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
+ }
+
+ free_actions (t);
+ t->step_count = 0; /* read_actions may set this */
+ read_actions (t);
+
+ if (readline_end_hook)
+ (*readline_end_hook) ();
+
+ /* tracepoints_changed () */
+ }
+ /* else error, just return; */
+}
+
+/* worker function */
+static void
+read_actions (t)
+ struct tracepoint *t;
+{
+ char *line;
+ char *prompt1 = "> ", *prompt2 = " > ";
+ char *prompt = prompt1;
+ enum actionline_type linetype;
+ extern FILE *instream;
+ struct action_line *next = NULL, *temp;
+ struct cleanup *old_chain;
+
+ /* Control-C quits instantly if typed while in this loop
+ since it should not wait until the user types a newline. */
+ immediate_quit++;
+#ifdef STOP_SIGNAL
+ if (job_control)
+ signal (STOP_SIGNAL, stop_sig);
+#endif
+ old_chain = make_cleanup ((make_cleanup_func) free_actions, (void *) t);
+ while (1)
+ {
+ /* Make sure that all output has been output. Some machines may let
+ you get away with leaving out some of the gdb_flush, but not all. */
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ if (readline_hook && instream == NULL)
+ line = (*readline_hook) (prompt);
+ else if (instream == stdin && ISATTY (instream))
+ {
+ line = readline (prompt);
+ if (line && *line) /* add it to command history */
+ add_history (line);
+ }
+ else
+ line = gdb_readline (0);
+
+ linetype = validate_actionline (&line, t);
+ if (linetype == BADLINE)
+ continue; /* already warned -- collect another line */
+
+ temp = xmalloc (sizeof (struct action_line));
+ temp->next = NULL;
+ temp->action = line;
+
+ if (next == NULL) /* first action for this tracepoint? */
+ t->actions = next = temp;
+ else
+ {
+ next->next = temp;
+ next = temp;
+ }
+
+ if (linetype == STEPPING) /* begin "while-stepping" */
+ if (prompt == prompt2)
+ {
+ warning ("Already processing 'while-stepping'");
+ continue;
+ }
+ else
+ prompt = prompt2; /* change prompt for stepping actions */
+ else if (linetype == END)
+ if (prompt == prompt2)
+ {
+ prompt = prompt1; /* end of single-stepping actions */
+ }
+ else
+ { /* end of actions */
+ if (t->actions->next == NULL)
+ {
+ /* an "end" all by itself with no other actions means
+ this tracepoint has no actions. Discard empty list. */
+ free_actions (t);
+ }
+ break;
+ }
+ }
+#ifdef STOP_SIGNAL
+ if (job_control)
+ signal (STOP_SIGNAL, SIG_DFL);
+#endif
+ immediate_quit = 0;
+ discard_cleanups (old_chain);
+}
+
+/* worker function */
+enum actionline_type
+validate_actionline (line, t)
+ char **line;
+ struct tracepoint *t;
+{
+ struct cmd_list_element *c;
+ struct expression *exp = NULL;
+ value_ptr temp, temp2;
+ struct cleanup *old_chain = NULL;
+ char *p;
+
+ for (p = *line; isspace (*p); )
+ p++;
+
+ /* symbol lookup etc. */
+ if (*p == '\0') /* empty line: just prompt for another line. */
+ return BADLINE;
+
+ if (*p == '#') /* comment line */
+ return GENERIC;
+
+ c = lookup_cmd (&p, cmdlist, "", -1, 1);
+ if (c == 0)
+ {
+ warning ("'%s' is not an action that I know, or is ambiguous.", p);
+ return BADLINE;
+ }
+
+ if (c->function.cfunc == collect_pseudocommand)
+ {
+ struct agent_expr *aexpr;
+ struct agent_reqs areqs;
+
+ do { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ while (isspace (*p))
+ p++;
+
+ if (*p == '$') /* look for special pseudo-symbols */
+ {
+ long typecode, size;
+ bfd_signed_vma offset;
+
+ if ((0 == strncasecmp ("reg", p + 1, 3)) ||
+ (0 == strncasecmp ("arg", p + 1, 3)) ||
+ (0 == strncasecmp ("loc", p + 1, 3)))
+ {
+ p = strchr (p, ',');
+ continue;
+ }
+ /* else fall thru, treat p as an expression and parse it! */
+ }
+ exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &exp);
+
+ if (exp->elts[0].opcode == OP_VAR_VALUE)
+ if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
+ {
+ warning ("%s is constant (value %d): will not be collected.",
+ SYMBOL_NAME (exp->elts[2].symbol),
+ SYMBOL_VALUE (exp->elts[2].symbol));
+ return BADLINE;
+ }
+ else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
+ {
+ warning ("%s is optimized away and cannot be collected.",
+ SYMBOL_NAME (exp->elts[2].symbol));
+ return BADLINE;
+ }
+
+ /* we have something to collect, make sure that the expr to
+ bytecode translator can handle it and that it's not too long */
+ aexpr = gen_trace_for_expr (t->address, exp);
+ (void) make_cleanup ((make_cleanup_func) free_agent_expr, aexpr);
+
+ if (aexpr->len > MAX_AGENT_EXPR_LEN)
+ error ("expression too complicated, try simplifying");
+
+ ax_reqs(aexpr, &areqs);
+ (void) make_cleanup (free, areqs.reg_mask);
+
+ if (areqs.flaw != agent_flaw_none)
+ error ("malformed expression");
+
+ if (areqs.min_height < 0)
+ error ("gdb: Internal error: expression has min height < 0");
+
+ if (areqs.max_height > 20)
+ error ("expression too complicated, try simplifying");
+
+ do_cleanups (old_chain);
+ } while (p && *p++ == ',');
+ return GENERIC;
+ }
+ else if (c->function.cfunc == while_stepping_pseudocommand)
+ {
+ char *steparg; /* in case warning is necessary */
+
+ while (isspace (*p))
+ p++;
+ steparg = p;
+
+ if (*p == '\0' ||
+ (t->step_count = strtol (p, &p, 0)) == 0)
+ {
+ warning ("bad step-count: command ignored.", *line);
+ return BADLINE;
+ }
+ return STEPPING;
+ }
+ else if (c->function.cfunc == end_actions_pseudocommand)
+ return END;
+ else
+ {
+ warning ("'%s' is not a supported tracepoint action.", *line);
+ return BADLINE;
+ }
+}
+
+/* worker function */
+void
+free_actions (t)
+ struct tracepoint *t;
+{
+ struct action_line *line, *next;
+
+ for (line = t->actions; line; line = next)
+ {
+ next = line->next;
+ if (line->action)
+ free (line->action);
+ free (line);
+ }
+ t->actions = NULL;
+}
+
+struct memrange {
+ int type; /* 0 for absolute memory range, else basereg number */
+ bfd_signed_vma start;
+ bfd_signed_vma end;
+};
+
+struct collection_list {
+ unsigned char regs_mask[8]; /* room for up to 256 regs */
+ long listsize;
+ long next_memrange;
+ struct memrange *list;
+ long aexpr_listsize; /* size of array pointed to by expr_list elt */
+ long next_aexpr_elt;
+ struct agent_expr **aexpr_list;
+
+} tracepoint_list, stepping_list;
+
+/* MEMRANGE functions: */
+
+static int memrange_cmp PARAMS ((const void *, const void *));
+
+/* compare memranges for qsort */
+static int
+memrange_cmp (va, vb)
+ const void *va;
+ const void *vb;
+{
+ const struct memrange *a = va, *b = vb;
+
+ if (a->type < b->type)
+ return -1;
+ if (a->type > b->type)
+ return 1;
+ if (a->type == 0)
+ {
+ if ((bfd_vma) a->start < (bfd_vma) b->start) return -1;
+ if ((bfd_vma) a->start > (bfd_vma) b->start) return 1;
+ }
+ else
+ {
+ if (a->start < b->start)
+ return -1;
+ if (a->start > b->start)
+ return 1;
+ }
+ return 0;
+}
+
+/* Sort the memrange list using qsort, and merge adjacent memranges */
+static void
+memrange_sortmerge (memranges)
+ struct collection_list *memranges;
+{
+ int a, b;
+
+ qsort (memranges->list, memranges->next_memrange,
+ sizeof (struct memrange), memrange_cmp);
+ if (memranges->next_memrange > 0)
+ {
+ for (a = 0, b = 1; b < memranges->next_memrange; b++)
+ {
+ if (memranges->list[a].type == memranges->list[b].type &&
+ memranges->list[b].start - memranges->list[a].end <=
+ MAX_REGISTER_VIRTUAL_SIZE)
+ {
+ /* memrange b starts before memrange a ends; merge them. */
+ if (memranges->list[b].end > memranges->list[a].end)
+ memranges->list[a].end = memranges->list[b].end;
+ continue; /* next b, same a */
+ }
+ a++; /* next a */
+ if (a != b)
+ memcpy (&memranges->list[a], &memranges->list[b],
+ sizeof (struct memrange));
+ }
+ memranges->next_memrange = a + 1;
+ }
+}
+
+/* Add a register to a collection list */
+void
+add_register (collection, regno)
+ struct collection_list *collection;
+ unsigned long regno;
+{
+ if (info_verbose)
+ printf_filtered ("collect register %d\n", regno);
+ if (regno > (8 * sizeof (collection->regs_mask)))
+ error ("Internal: register number %d too large for tracepoint",
+ regno);
+ collection->regs_mask [regno / 8] |= 1 << (regno % 8);
+}
+
+/* Add a memrange to a collection list */
+static void
+add_memrange (memranges, type, base, len)
+ struct collection_list *memranges;
+ int type;
+ bfd_signed_vma base;
+ unsigned long len;
+{
+ if (info_verbose)
+ printf_filtered ("(%d,0x%x,%d)\n", type, base, len);
+ /* type: 0 == memory, n == basereg */
+ memranges->list[memranges->next_memrange].type = type;
+ /* base: addr if memory, offset if reg relative. */
+ memranges->list[memranges->next_memrange].start = base;
+ /* len: we actually save end (base + len) for convenience */
+ memranges->list[memranges->next_memrange].end = base + len;
+ memranges->next_memrange++;
+ if (memranges->next_memrange >= memranges->listsize)
+ {
+ memranges->listsize *= 2;
+ memranges->list = xrealloc (memranges->list,
+ memranges->listsize);
+ }
+
+ if (type != -1) /* better collect the base register! */
+ add_register (memranges, type);
+}
+
+/* Add a symbol to a collection list */
+static void
+collect_symbol (collect, sym, frame_regno, frame_offset)
+ struct collection_list *collect;
+ struct symbol *sym;
+ long frame_regno;
+ long frame_offset;
+{
+ unsigned long len;
+ unsigned long reg;
+ bfd_signed_vma offset;
+
+ len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
+ switch (SYMBOL_CLASS (sym)) {
+ default:
+ printf_filtered ("%s: don't know symbol class %d\n",
+ SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
+ break;
+ case LOC_CONST:
+ printf_filtered ("%s is constant, value is %d: will not be collected.\n",
+ SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
+ break;
+ case LOC_STATIC:
+ offset = SYMBOL_VALUE_ADDRESS (sym);
+ if (info_verbose)
+ printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
+ SYMBOL_NAME (sym), len, offset);
+ add_memrange (collect, -1, offset, len); /* 0 == memory */
+ break;
+ case LOC_REGISTER:
+ case LOC_REGPARM:
+ reg = SYMBOL_VALUE (sym);
+ if (info_verbose)
+ printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
+ add_register (collect, reg);
+ /* check for doubles stored in two registers */
+ /* FIXME: how about larger types stored in 3 or more regs? */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
+ len > REGISTER_RAW_SIZE (reg))
+ add_register (collect, reg + 1);
+ break;
+ case LOC_REF_ARG:
+ printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
+ printf_filtered (" (will not collect %s)\n",
+ SYMBOL_NAME (sym));
+ break;
+ case LOC_ARG:
+ reg = frame_regno;
+ offset = frame_offset + SYMBOL_VALUE (sym);
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
+ SYMBOL_NAME (sym), len);
+ printf_filtered (" %d from frame ptr reg %d\n", offset, reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_REGPARM_ADDR:
+ reg = SYMBOL_VALUE (sym);
+ offset = 0;
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset",
+ SYMBOL_NAME (sym), len);
+ printf_filtered (" %d from reg %d\n", offset, reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ reg = frame_regno;
+ offset = frame_offset + SYMBOL_VALUE (sym);
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
+ SYMBOL_NAME (sym), len);
+ printf_filtered (" %d from frame ptr reg %d\n", offset, reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ reg = SYMBOL_BASEREG (sym);
+ offset = SYMBOL_VALUE (sym);
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
+ SYMBOL_NAME (sym), len, offset, reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_UNRESOLVED:
+ printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
+ break;
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("%s has been optimized out of existance.\n",
+ SYMBOL_NAME (sym));
+ break;
+ }
+}
+
+/* Add all locals (or args) symbols to collection list */
+static void
+add_local_symbols (collect, pc, frame_regno, frame_offset, type)
+ struct collection_list *collect;
+ CORE_ADDR pc;
+ long frame_regno;
+ long frame_offset;
+ int type;
+{
+ struct symbol *sym;
+ struct block *block;
+ int i, nsyms, count = 0;
+
+ block = block_for_pc (pc);
+ while (block != 0)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ nsyms = BLOCK_NSYMS (block);
+ for (i = 0; i < nsyms; i++)
+ {
+ sym = BLOCK_SYM (block, i);
+ switch (SYMBOL_CLASS (sym)) {
+ case LOC_LOCAL:
+ case LOC_STATIC:
+ case LOC_REGISTER:
+ case LOC_BASEREG:
+ if (type == 'L') /* collecting Locals */
+ {
+ count++;
+ collect_symbol (collect, sym, frame_regno, frame_offset);
+ }
+ break;
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ if (type == 'A') /* collecting Arguments */
+ {
+ count++;
+ collect_symbol (collect, sym, frame_regno, frame_offset);
+ }
+ }
+ }
+ if (BLOCK_FUNCTION (block))
+ break;
+ else
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ if (count == 0)
+ warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
+}
+
+/* worker function */
+static void
+clear_collection_list (list)
+ struct collection_list *list;
+{
+ int ndx;
+
+ list->next_memrange = 0;
+ for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
+ {
+ free_agent_expr(list->aexpr_list[ndx]);
+ list->aexpr_list[ndx] = NULL;
+ }
+ list->next_aexpr_elt = 0;
+ memset (list->regs_mask, 0, sizeof (list->regs_mask));
+}
+
+/* reduce a collection list to string form (for gdb protocol) */
+static char **
+stringify_collection_list (list, string)
+ struct collection_list *list;
+ char *string;
+{
+ char temp_buf[2048];
+ int count;
+ int ndx = 0;
+ char *(*str_list)[];
+ char *end;
+ long i;
+
+ count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
+ str_list = (char *(*)[])xmalloc(count * sizeof (char *));
+
+ for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
+ if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
+ break;
+ if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
+ {
+ if (info_verbose)
+ printf_filtered ("\nCollecting registers (mask): 0x");
+ end = temp_buf;
+ *end++='R';
+ for (; i >= 0; i--)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (info_verbose)
+ printf_filtered ("%02X", list->regs_mask[i]);
+ sprintf (end, "%02X", list->regs_mask[i]);
+ end += 2;
+ }
+ (*str_list)[ndx] = savestring(temp_buf, end - temp_buf);
+ ndx++;
+ }
+ if (info_verbose)
+ printf_filtered ("\n");
+ if (list->next_memrange > 0 && info_verbose)
+ printf_filtered ("Collecting memranges: \n");
+ for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (info_verbose)
+ printf_filtered ("(%d, 0x%x, %d)\n",
+ list->list[i].type,
+ list->list[i].start,
+ list->list[i].end - list->list[i].start);
+ if (count + 27 > MAX_AGENT_EXPR_LEN)
+ {
+ (*str_list)[ndx] = savestring(temp_buf, count);
+ ndx++;
+ count = 0;
+ end = temp_buf;
+ }
+ sprintf (end, "M%X,%X,%X",
+ list->list[i].type,
+ list->list[i].start,
+ list->list[i].end - list->list[i].start);
+ count += strlen (end);
+ end += strlen (end);
+ }
+
+ for (i = 0; i < list->next_aexpr_elt; i++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
+ {
+ (*str_list)[ndx] = savestring(temp_buf, count);
+ ndx++;
+ count = 0;
+ end = temp_buf;
+ }
+ sprintf (end, "X%08X,", list->aexpr_list[i]->len);
+ end += 10; /* 'X' + 8 hex digits + ',' */
+ count += 10;
+
+ end = mem2hex(list->aexpr_list[i]->buf, end, list->aexpr_list[i]->len);
+ count += 2 * list->aexpr_list[i]->len;
+ }
+
+ if (count != 0)
+ {
+ (*str_list)[ndx] = savestring(temp_buf, count);
+ ndx++;
+ count = 0;
+ end = temp_buf;
+ }
+ (*str_list)[ndx] = NULL;
+
+ if (ndx == 0)
+ return NULL;
+ else
+ return *str_list;
+}
+
+void
+free_actions_list(actions_list)
+ char **actions_list;
+{
+ int ndx;
+
+ if (actions_list == 0)
+ return;
+
+ for (ndx = 0; actions_list[ndx]; ndx++)
+ free(actions_list[ndx]);
+
+ free(actions_list);
+}
+
+/* render all actions into gdb protocol */
+static void
+encode_actions (t, tdp_actions, stepping_actions)
+ struct tracepoint *t;
+ char ***tdp_actions;
+ char ***stepping_actions;
+{
+ static char tdp_buff[2048], step_buff[2048];
+ char *action_exp;
+ struct expression *exp = NULL;
+ struct action_line *action;
+ bfd_signed_vma offset;
+ long i;
+ value_ptr tempval;
+ struct collection_list *collect;
+ struct cmd_list_element *cmd;
+ struct agent_expr *aexpr;
+ long frame_reg, frame_offset;
+
+
+ clear_collection_list (&tracepoint_list);
+ clear_collection_list (&stepping_list);
+ collect = &tracepoint_list;
+
+ *tdp_actions = NULL;
+ *stepping_actions = NULL;
+
+ TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
+
+ for (action = t->actions; action; action = action->next)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ action_exp = action->action;
+ while (isspace (*action_exp))
+ action_exp++;
+
+ if (*action_exp == '#') /* comment line */
+ return;
+
+ cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+ if (cmd == 0)
+ error ("Bad action list item: %s", action_exp);
+
+ if (cmd->function.cfunc == collect_pseudocommand)
+ {
+ do { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ while (isspace (*action_exp))
+ action_exp++;
+
+ if (0 == strncasecmp ("$reg", action_exp, 4))
+ {
+ for (i = 0; i < NUM_REGS; i++)
+ add_register (collect, i);
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
+ else if (0 == strncasecmp ("$arg", action_exp, 4))
+ {
+ add_local_symbols (collect,
+ t->address,
+ frame_reg,
+ frame_offset,
+ 'A');
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
+ else if (0 == strncasecmp ("$loc", action_exp, 4))
+ {
+ add_local_symbols (collect,
+ t->address,
+ frame_reg,
+ frame_offset,
+ 'L');
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
+ else
+ {
+ unsigned long addr, len;
+ struct cleanup *old_chain = NULL;
+ struct cleanup *old_chain1 = NULL;
+ struct agent_reqs areqs;
+
+ exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
+ old_chain = make_cleanup ((make_cleanup_func)
+ free_current_contents, &exp);
+
+ switch (exp->elts[0].opcode) {
+ case OP_REGISTER:
+ i = exp->elts[1].longconst;
+ if (info_verbose)
+ printf_filtered ("OP_REGISTER: ");
+ add_register (collect, i);
+ break;
+
+ case UNOP_MEMVAL:
+ /* safe because we know it's a simple expression */
+ tempval = evaluate_expression (exp);
+ addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
+ len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
+ add_memrange (collect, -1, addr, len);
+ break;
+
+ case OP_VAR_VALUE:
+ collect_symbol (collect,
+ exp->elts[2].symbol,
+ frame_reg,
+ frame_offset);
+ break;
+
+ default: /* full-fledged expression */
+ aexpr = gen_trace_for_expr (t->address, exp);
+
+ old_chain1 = make_cleanup ((make_cleanup_func)
+ free_agent_expr, aexpr);
+
+ ax_reqs (aexpr, &areqs);
+ if (areqs.flaw != agent_flaw_none)
+ error ("malformed expression");
+
+ if (areqs.min_height < 0)
+ error ("gdb: Internal error: expression has min height < 0");
+ if (areqs.max_height > 20)
+ error ("expression too complicated, try simplifying");
+
+ discard_cleanups (old_chain1);
+ add_aexpr (collect, aexpr);
+
+ /* take care of the registers */
+ if (areqs.reg_mask_len > 0)
+ {
+ int ndx1;
+ int ndx2;
+
+ for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (areqs.reg_mask[ndx1] != 0)
+ {
+ /* assume chars have 8 bits */
+ for (ndx2 = 0; ndx2 < 8; ndx2++)
+ if (areqs.reg_mask[ndx1] & (1 << ndx2))
+ /* it's used -- record it */
+ add_register (collect, ndx1 * 8 + ndx2);
+ }
+ }
+ }
+ break;
+ } /* switch */
+ do_cleanups (old_chain);
+ } /* do */
+ } while (action_exp && *action_exp++ == ',');
+ } /* if */
+ else if (cmd->function.cfunc == while_stepping_pseudocommand)
+ {
+ collect = &stepping_list;
+ }
+ else if (cmd->function.cfunc == end_actions_pseudocommand)
+ {
+ if (collect == &stepping_list) /* end stepping actions */
+ collect = &tracepoint_list;
+ else
+ break; /* end tracepoint actions */
+ }
+ } /* for */
+ memrange_sortmerge (&tracepoint_list);
+ memrange_sortmerge (&stepping_list);
+
+ *tdp_actions = stringify_collection_list (&tracepoint_list, &tdp_buff);
+ *stepping_actions = stringify_collection_list (&stepping_list, &step_buff);
+}
+
+static void
+add_aexpr(collect, aexpr)
+ struct collection_list *collect;
+ struct agent_expr *aexpr;
+{
+ if (collect->next_aexpr_elt >= collect->aexpr_listsize)
+ {
+ collect->aexpr_list =
+ xrealloc (collect->aexpr_list,
+ 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
+ collect->aexpr_listsize *= 2;
+ }
+ collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
+ collect->next_aexpr_elt++;
+}
+
+static char target_buf[2048];
+
+/* Set "transparent" memory ranges
+
+ Allow trace mechanism to treat text-like sections
+ (and perhaps all read-only sections) transparently,
+ i.e. don't reject memory requests from these address ranges
+ just because they haven't been collected. */
+
+static void
+remote_set_transparent_ranges (void)
+{
+ extern bfd *exec_bfd;
+ asection *s;
+ bfd_size_type size;
+ bfd_vma lma;
+ int anysecs = 0;
+
+ if (!exec_bfd)
+ return; /* no information to give. */
+
+ strcpy (target_buf, "QTro");
+ for (s = exec_bfd->sections; s; s = s->next)
+ {
+ char tmp[40];
+
+ if ((s->flags & SEC_LOAD) == 0 ||
+ /* (s->flags & SEC_CODE) == 0 || */
+ (s->flags & SEC_READONLY) == 0)
+ continue;
+
+ anysecs = 1;
+ lma = s->lma;
+ size = bfd_get_section_size_before_reloc (s);
+ sprintf (tmp, ":%x,%x", lma, lma + size);
+ strcat (target_buf, tmp);
+ }
+ if (anysecs)
+ {
+ putpkt (target_buf);
+ getpkt (target_buf, 0);
+ }
+}
+
+/* tstart command:
+
+ Tell target to clear any previous trace experiment.
+ Walk the list of tracepoints, and send them (and their actions)
+ to the target. If no errors,
+ Tell target to start a new trace experiment. */
+
+static void
+trace_start_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM MOSTLY_IMPLEMENTED */
+ struct tracepoint *t;
+ char buf[2048];
+ char **tdp_actions;
+ char **stepping_actions;
+ int ndx;
+ struct cleanup *old_chain = NULL;
+
+ dont_repeat (); /* like "run", dangerous to repeat accidentally */
+
+ if (target_is_remote ())
+ {
+ putpkt ("QTinit");
+ remote_get_noisy_reply (target_buf);
+ if (strcmp (target_buf, "OK"))
+ error ("Target does not support this command.");
+
+ ALL_TRACEPOINTS (t)
+ {
+ int ss_count; /* if actions include singlestepping */
+ int disable_mask; /* ??? */
+ int enable_mask; /* ??? */
+
+ sprintf (buf, "QTDP:%x:%x:%c:%x:%x", t->number, t->address,
+ t->enabled == enabled ? 'E' : 'D',
+ t->step_count, t->pass_count);
+
+ if (t->actions)
+ strcat (buf, "-");
+ putpkt (buf);
+ remote_get_noisy_reply (target_buf);
+ if (strcmp (target_buf, "OK"))
+ error ("Target does not support tracepoints.");
+
+ if (t->actions)
+ {
+ encode_actions (t, &tdp_actions, &stepping_actions);
+ old_chain = make_cleanup (free_actions_list, tdp_actions);
+ (void) make_cleanup (free_actions_list, stepping_actions);
+
+ /* do_single_steps (t); */
+ if (tdp_actions)
+ {
+ for (ndx = 0; tdp_actions[ndx]; ndx++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ sprintf (buf, "QTDP:-%x:%x:%s%c",
+ t->number, t->address,
+ tdp_actions[ndx],
+ ((tdp_actions[ndx+1] || stepping_actions)
+ ? '-' : 0));
+ putpkt (buf);
+ remote_get_noisy_reply (target_buf);
+ if (strcmp (target_buf, "OK"))
+ error ("Error on target while setting tracepoints.");
+ }
+ }
+ if (stepping_actions)
+ {
+ for (ndx = 0; stepping_actions[ndx]; ndx++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ sprintf (buf, "QTDP:-%x:%x:%s%s%s",
+ t->number, t->address,
+ ((ndx == 0) ? "S" : ""),
+ stepping_actions[ndx],
+ (stepping_actions[ndx+1] ? "-" : ""));
+ putpkt (buf);
+ remote_get_noisy_reply (target_buf);
+ if (strcmp (target_buf, "OK"))
+ error ("Error on target while setting tracepoints.");
+ }
+ }
+
+ do_cleanups (old_chain);
+ }
+ }
+ /* Tell target to treat text-like sections as transparent */
+ remote_set_transparent_ranges ();
+ /* Now insert traps and begin collecting data */
+ putpkt ("QTStart");
+ remote_get_noisy_reply (target_buf);
+ if (strcmp (target_buf, "OK"))
+ error ("Bogus reply from target: %s", target_buf);
+ set_traceframe_num (-1); /* all old traceframes invalidated */
+ set_tracepoint_num (-1);
+ set_traceframe_context(-1);
+ trace_running_p = 1;
+ if (trace_start_stop_hook)
+ trace_start_stop_hook(1, from_tty);
+
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tstop command */
+static void
+trace_stop_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM IS_IMPLEMENTED */
+ if (target_is_remote ())
+ {
+ putpkt ("QTStop");
+ remote_get_noisy_reply (target_buf);
+ if (strcmp (target_buf, "OK"))
+ error ("Bogus reply from target: %s", target_buf);
+ trace_running_p = 0;
+ if (trace_start_stop_hook)
+ trace_start_stop_hook(0, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+unsigned long trace_running_p;
+
+/* tstatus command */
+static void
+trace_status_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM IS_IMPLEMENTED */
+ if (target_is_remote ())
+ {
+ putpkt ("qTStatus");
+ remote_get_noisy_reply (target_buf);
+
+ if (target_buf[0] != 'T' ||
+ (target_buf[1] != '0' && target_buf[1] != '1'))
+ error ("Bogus reply from target: %s", target_buf);
+
+ /* exported for use by the GUI */
+ trace_running_p = (target_buf[1] == '1');
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* Worker function for the various flavors of the tfind command */
+static void
+finish_tfind_command (msg, from_tty)
+ char *msg;
+ int from_tty;
+{
+ int target_frameno = -1, target_tracept = -1;
+ CORE_ADDR old_frame_addr;
+ struct symbol *old_func;
+ char *reply;
+
+ old_frame_addr = FRAME_FP (get_current_frame ());
+ old_func = find_pc_function (read_pc ());
+
+ putpkt (msg);
+ reply = remote_get_noisy_reply (msg);
+
+ while (reply && *reply)
+ switch (*reply) {
+ case 'F':
+ if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
+ {
+ /* A request for a non-existant trace frame has failed.
+ Our response will be different, depending on FROM_TTY:
+
+ If FROM_TTY is true, meaning that this command was
+ typed interactively by the user, then give an error
+ and DO NOT change the state of traceframe_number etc.
+
+ However if FROM_TTY is false, meaning that we're either
+ in a script, a loop, or a user-defined command, then
+ DON'T give an error, but DO change the state of
+ traceframe_number etc. to invalid.
+
+ The rationalle is that if you typed the command, you
+ might just have committed a typo or something, and you'd
+ like to NOT lose your current debugging state. However
+ if you're in a user-defined command or especially in a
+ loop, then you need a way to detect that the command
+ failed WITHOUT aborting. This allows you to write
+ scripts that search thru the trace buffer until the end,
+ and then continue on to do something else. */
+
+ if (from_tty)
+ error ("Target failed to find requested trace frame.");
+ else
+ {
+ if (info_verbose)
+ printf_filtered ("End of trace buffer.\n");
+ /* The following will not recurse, since it's special-cased */
+ trace_find_command ("-1", from_tty);
+ reply = NULL; /* break out of loop,
+ (avoid recursive nonsense) */
+ }
+ }
+ break;
+ case 'T':
+ if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
+ error ("Target failed to find requested trace frame.");
+ break;
+ case 'O': /* "OK"? */
+ if (reply[1] == 'K' && reply[2] == '\0')
+ reply += 2;
+ else
+ error ("Bogus reply from target: %s", reply);
+ break;
+ default:
+ error ("Bogus reply from target: %s", reply);
+ }
+
+ flush_cached_frames ();
+ registers_changed ();
+ select_frame (get_current_frame (), 0);
+ set_traceframe_num (target_frameno);
+ set_tracepoint_num (target_tracept);
+ if (target_frameno == -1)
+ set_traceframe_context (-1);
+ else
+ set_traceframe_context (read_pc ());
+
+ if (from_tty)
+ {
+ int source_only;
+
+ /* NOTE: in immitation of the step command, try to determine
+ whether we have made a transition from one function to another.
+ If so, we'll print the "stack frame" (ie. the new function and
+ it's arguments) -- otherwise we'll just show the new source line.
+
+ This determination is made by checking (1) whether the current
+ function has changed, and (2) whether the current FP has changed.
+ Hack: if the FP wasn't collected, either at the current or the
+ previous frame, assume that the FP has NOT changed. */
+
+ if (old_func == find_pc_function (read_pc ()) &&
+ (old_frame_addr == 0 ||
+ FRAME_FP (get_current_frame ()) == 0 ||
+ old_frame_addr == FRAME_FP (get_current_frame ())))
+ source_only = -1;
+ else
+ source_only = 1;
+
+ print_stack_frame (selected_frame, selected_frame_level, source_only);
+ do_displays ();
+ }
+}
+
+/* trace_find_command takes a trace frame number n,
+ sends "QTFrame:<n>" to the target,
+ and accepts a reply that may contain several optional pieces
+ of information: a frame number, a tracepoint number, and an
+ indication of whether this is a trap frame or a stepping frame.
+
+ The minimal response is just "OK" (which indicates that the
+ target does not give us a frame number or a tracepoint number).
+ Instead of that, the target may send us a string containing
+ any combination of:
+ F<hexnum> (gives the selected frame number)
+ T<hexnum> (gives the selected tracepoint number)
+ */
+
+/* tfind command */
+static void
+trace_find_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM PART_IMPLEMENTED */
+ /* this should only be called with a numeric argument */
+ int frameno = -1;
+ char *tmp;
+
+ if (target_is_remote ())
+ {
+ if (trace_find_hook)
+ trace_find_hook (args, from_tty);
+
+ if (args == 0 || *args == 0)
+ { /* TFIND with no args means find NEXT trace frame. */
+ if (traceframe_number == -1)
+ frameno = 0; /* "next" is first one */
+ else
+ frameno = traceframe_number + 1;
+ }
+ else if (0 == strcmp (args, "-"))
+ {
+ if (traceframe_number == -1)
+ error ("not debugging trace buffer");
+ else if (from_tty && traceframe_number == 0)
+ error ("already at start of trace buffer");
+
+ frameno = traceframe_number - 1;
+ }
+ else
+ frameno = parse_and_eval_address (args);
+
+ if (frameno < -1)
+ error ("invalid input (%d is less than zero)", frameno);
+
+ sprintf (target_buf, "QTFrame:%x", frameno);
+ finish_tfind_command (target_buf, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind end */
+static void
+trace_find_end_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ trace_find_command ("-1", from_tty);
+}
+
+/* tfind none */
+static void
+trace_find_none_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ trace_find_command ("-1", from_tty);
+}
+
+/* tfind start */
+static void
+trace_find_start_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ trace_find_command ("0", from_tty);
+}
+
+/* tfind pc command */
+static void
+trace_find_pc_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM PART_IMPLEMENTED */
+ CORE_ADDR pc;
+ char *tmp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ pc = read_pc (); /* default is current pc */
+ else
+ pc = parse_and_eval_address (args);
+
+ sprintf (target_buf, "QTFrame:pc:%x", pc);
+ finish_tfind_command (target_buf, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind tracepoint command */
+static void
+trace_find_tracepoint_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM PART_IMPLEMENTED */
+ int tdp;
+ char buf[40], *tmp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ if (tracepoint_number == -1)
+ error ("No current tracepoint -- please supply an argument.");
+ else
+ tdp = tracepoint_number; /* default is current TDP */
+ else
+ tdp = parse_and_eval_address (args);
+
+ sprintf (target_buf, "QTFrame:tdp:%x", tdp);
+ finish_tfind_command (target_buf, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* TFIND LINE command:
+
+ This command will take a sourceline for argument, just like BREAK
+ or TRACE (ie. anything that "decode_line_1" can handle).
+
+ With no argument, this command will find the next trace frame
+ corresponding to a source line OTHER THAN THE CURRENT ONE. */
+
+static void
+trace_find_line_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM PART_IMPLEMENTED */
+ static CORE_ADDR start_pc, end_pc;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ char *tmp;
+ struct cleanup *old_chain;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ {
+ sal = find_pc_line ((get_current_frame ())->pc, 0);
+ sals.nelts = 1;
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ sals.sals[0] = sal;
+ }
+ else
+ {
+ sals = decode_line_spec (args, 1);
+ sal = sals.sals[0];
+ }
+
+ old_chain = make_cleanup (free, sals.sals);
+ if (sal.symtab == 0)
+ {
+ printf_filtered ("TFIND: No line number information available");
+ if (sal.pc != 0)
+ {
+ /* This is useful for "info line *0x7f34". If we can't tell the
+ user about a source line, at least let them have the symbolic
+ address. */
+ printf_filtered (" for address ");
+ wrap_here (" ");
+ print_address (sal.pc, gdb_stdout);
+ printf_filtered (";\n -- will attempt to find by PC. \n");
+ }
+ else
+ {
+ printf_filtered (".\n");
+ return; /* no line, no PC; what can we do? */
+ }
+ }
+ else if (sal.line > 0
+ && find_line_pc_range (sal, &start_pc, &end_pc))
+ {
+ if (start_pc == end_pc)
+ {
+ printf_filtered ("Line %d of \"%s\"",
+ sal.line, sal.symtab->filename);
+ wrap_here (" ");
+ printf_filtered (" is at address ");
+ print_address (start_pc, gdb_stdout);
+ wrap_here (" ");
+ printf_filtered (" but contains no code.\n");
+ sal = find_pc_line (start_pc, 0);
+ if (sal.line > 0 &&
+ find_line_pc_range (sal, &start_pc, &end_pc) &&
+ start_pc != end_pc)
+ printf_filtered ("Attempting to find line %d instead.\n",
+ sal.line);
+ else
+ error ("Cannot find a good line.");
+ }
+ }
+ else
+ /* Is there any case in which we get here, and have an address
+ which the user would want to see? If we have debugging symbols
+ and no line numbers? */
+ error ("Line number %d is out of range for \"%s\".\n",
+ sal.line, sal.symtab->filename);
+
+ if (args && *args) /* find within range of stated line */
+ sprintf (target_buf, "QTFrame:range:%x:%x", start_pc, end_pc - 1);
+ else /* find OUTSIDE OF range of CURRENT line */
+ sprintf (target_buf, "QTFrame:outside:%x:%x", start_pc, end_pc - 1);
+ finish_tfind_command (target_buf, from_tty);
+ do_cleanups (old_chain);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind range command */
+static void
+trace_find_range_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM PART_IMPLEMENTED */
+ static CORE_ADDR start, stop;
+ char *tmp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ { /* XXX FIXME: what should default behavior be? */
+ printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
+ return;
+ }
+
+ if (0 != (tmp = strchr (args, ',' )))
+ {
+ *tmp++ = '\0'; /* terminate start address */
+ while (isspace (*tmp))
+ tmp++;
+ start = parse_and_eval_address (args);
+ stop = parse_and_eval_address (tmp);
+ }
+ else
+ { /* no explicit end address? */
+ start = parse_and_eval_address (args);
+ stop = start + 1; /* ??? */
+ }
+
+ sprintf (target_buf, "QTFrame:range:%x:%x", start, stop);
+ finish_tfind_command (target_buf, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind outside command */
+static void
+trace_find_outside_command (args, from_tty)
+ char *args;
+ int from_tty;
+{ /* STUB_COMM PART_IMPLEMENTED */
+ CORE_ADDR start, stop;
+ char *tmp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ { /* XXX FIXME: what should default behavior be? */
+ printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
+ return;
+ }
+
+ if (0 != (tmp = strchr (args, ',' )))
+ {
+ *tmp++ = '\0'; /* terminate start address */
+ while (isspace (*tmp))
+ tmp++;
+ start = parse_and_eval_address (args);
+ stop = parse_and_eval_address (tmp);
+ }
+ else
+ { /* no explicit end address? */
+ start = parse_and_eval_address (args);
+ stop = start + 1; /* ??? */
+ }
+
+ sprintf (target_buf, "QTFrame:outside:%x:%x", start, stop);
+ finish_tfind_command (target_buf, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* save-tracepoints command */
+static void
+tracepoint_save_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct tracepoint *tp;
+ struct action_line *line;
+ FILE *fp;
+ char *i1 = " ", *i2 = " ";
+ char *indent, *actionline;
+
+ if (args == 0 || *args == 0)
+ error ("Argument required (file name in which to save tracepoints");
+
+ if (tracepoint_chain == 0)
+ {
+ warning ("save-tracepoints: no tracepoints to save.\n");
+ return;
+ }
+
+ if (!(fp = fopen (args, "w")))
+ error ("Unable to open file '%s' for saving tracepoints");
+
+ ALL_TRACEPOINTS (tp)
+ {
+ if (tp->addr_string)
+ fprintf (fp, "trace %s\n", tp->addr_string);
+ else
+ fprintf (fp, "trace *0x%x\n", tp->address);
+
+ if (tp->pass_count)
+ fprintf (fp, " passcount %d\n", tp->pass_count);
+
+ if (tp->actions)
+ {
+ fprintf (fp, " actions\n");
+ indent = i1;
+ for (line = tp->actions; line; line = line->next)
+ {
+ struct cmd_list_element *cmd;
+
+ QUIT; /* allow user to bail out with ^C */
+ actionline = line->action;
+ while (isspace(*actionline))
+ actionline++;
+
+ fprintf (fp, "%s%s\n", indent, actionline);
+ if (*actionline != '#') /* skip for comment lines */
+ {
+ cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
+ if (cmd == 0)
+ error ("Bad action list item: %s", actionline);
+ if (cmd->function.cfunc == while_stepping_pseudocommand)
+ indent = i2;
+ else if (cmd->function.cfunc == end_actions_pseudocommand)
+ indent = i1;
+ }
+ }
+ }
+ }
+ fclose (fp);
+ if (from_tty)
+ printf_filtered ("Tracepoints saved to file '%s'.\n", args);
+ return;
+}
+
+/* info scope command: list the locals for a scope. */
+static void
+scope_info (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct symtab_and_line sal;
+ struct symtabs_and_lines sals;
+ struct symbol *sym;
+ struct minimal_symbol *msym;
+ struct block *block;
+ char **canonical, *symname, *save_args = args;
+ int i, j, nsyms, count = 0;
+
+ if (args == 0 || *args == 0)
+ error ("requires an argument (function, line or *addr) to define a scope");
+
+ sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
+ if (sals.nelts == 0)
+ return; /* presumably decode_line_1 has already warned */
+
+ /* Resolve line numbers to PC */
+ resolve_sal_pc (&sals.sals[0]);
+ block = block_for_pc (sals.sals[0].pc);
+
+ while (block != 0)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ nsyms = BLOCK_NSYMS (block);
+ for (i = 0; i < nsyms; i++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (count == 0)
+ printf_filtered ("Scope for %s:\n", save_args);
+ count++;
+ sym = BLOCK_SYM (block, i);
+ symname = SYMBOL_NAME (sym);
+ if (symname == NULL || *symname == '\0')
+ continue; /* probably botched, certainly useless */
+
+ printf_filtered ("Symbol %s is ", symname);
+ switch (SYMBOL_CLASS (sym)) {
+ default:
+ case LOC_UNDEF: /* messed up symbol? */
+ printf_filtered ("a bogus symbol, class %d.\n",
+ SYMBOL_CLASS (sym));
+ count--; /* don't count this one */
+ continue;
+ case LOC_CONST:
+ printf_filtered ("a constant with value %d (0x%x)",
+ SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
+ break;
+ case LOC_CONST_BYTES:
+ printf_filtered ("constant bytes: ");
+ if (SYMBOL_TYPE (sym))
+ for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
+ fprintf_filtered (gdb_stdout, " %02x",
+ (unsigned) SYMBOL_VALUE_BYTES (sym) [j]);
+ break;
+ case LOC_STATIC:
+ printf_filtered ("in static storage at address ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
+ break;
+ case LOC_REGISTER:
+ printf_filtered ("a local variable in register $%s",
+ REGISTER_NAME (SYMBOL_VALUE (sym)));
+ break;
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ printf_filtered ("an argument at stack/frame offset %ld",
+ SYMBOL_VALUE (sym));
+ break;
+ case LOC_LOCAL:
+ printf_filtered ("a local variable at frame offset %ld",
+ SYMBOL_VALUE (sym));
+ break;
+ case LOC_REF_ARG:
+ printf_filtered ("a reference argument at offset %ld",
+ SYMBOL_VALUE (sym));
+ break;
+ case LOC_REGPARM:
+ printf_filtered ("an argument in register $%s",
+ REGISTER_NAME (SYMBOL_VALUE (sym)));
+ break;
+ case LOC_REGPARM_ADDR:
+ printf_filtered ("the address of an argument, in register $%s",
+ REGISTER_NAME (SYMBOL_VALUE (sym)));
+ break;
+ case LOC_TYPEDEF:
+ printf_filtered ("a typedef.\n");
+ continue;
+ case LOC_LABEL:
+ printf_filtered ("a label at address ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
+ break;
+ case LOC_BLOCK:
+ printf_filtered ("a function at address ");
+ print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
+ gdb_stdout);
+ break;
+ case LOC_BASEREG:
+ printf_filtered ("a variable at offset %d from register $%s",
+ SYMBOL_VALUE (sym),
+ REGISTER_NAME (SYMBOL_BASEREG (sym)));
+ break;
+ case LOC_BASEREG_ARG:
+ printf_filtered ("an argument at offset %d from register $%s",
+ SYMBOL_VALUE (sym),
+ REGISTER_NAME (SYMBOL_BASEREG (sym)));
+ break;
+ case LOC_UNRESOLVED:
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
+ if (msym == NULL)
+ printf_filtered ("Unresolved Static");
+ else
+ {
+ printf_filtered ("static storage at address ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
+ gdb_stdout);
+ }
+ break;
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("optimized out.\n");
+ continue;
+ }
+ if (SYMBOL_TYPE (sym))
+ printf_filtered (", length %d.\n",
+ TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
+ }
+ if (BLOCK_FUNCTION (block))
+ break;
+ else
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ if (count <= 0)
+ printf_filtered ("Scope for %s contains no locals or arguments.\n",
+ save_args);
+}
+
+/* worker function (cleanup) */
+static void
+replace_comma (comma)
+ char *comma;
+{
+ *comma = ',';
+}
+
+/* tdump command */
+static void
+trace_dump_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct tracepoint *t;
+ struct action_line *action;
+ char *action_exp, *next_comma;
+ struct cleanup *old_cleanups;
+ int stepping_actions = 0;
+ int stepping_frame = 0;
+
+ if (!target_is_remote ())
+ {
+ error ("Trace can only be run on remote targets.");
+ return;
+ }
+
+ if (tracepoint_number == -1)
+ {
+ warning ("No current trace frame.");
+ return;
+ }
+
+ ALL_TRACEPOINTS (t)
+ if (t->number == tracepoint_number)
+ break;
+
+ if (t == NULL)
+ error ("No known tracepoint matches 'current' tracepoint #%d.",
+ tracepoint_number);
+
+ old_cleanups = make_cleanup (null_cleanup, NULL);
+
+ printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
+ tracepoint_number, traceframe_number);
+
+ /* The current frame is a trap frame if the frame PC is equal
+ to the tracepoint PC. If not, then the current frame was
+ collected during single-stepping. */
+
+ stepping_frame = (t->address != read_pc());
+
+ for (action = t->actions; action; action = action->next)
+ {
+ struct cmd_list_element *cmd;
+
+ QUIT; /* allow user to bail out with ^C */
+ action_exp = action->action;
+ while (isspace (*action_exp))
+ action_exp++;
+
+ /* The collection actions to be done while stepping are
+ bracketed by the commands "while-stepping" and "end". */
+
+ if (*action_exp == '#') /* comment line */
+ continue;
+
+ cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+ if (cmd == 0)
+ error ("Bad action list item: %s", action_exp);
+
+ if (cmd->function.cfunc == while_stepping_pseudocommand)
+ stepping_actions = 1;
+ else if (cmd->function.cfunc == end_actions_pseudocommand)
+ stepping_actions = 0;
+ else if (cmd->function.cfunc == collect_pseudocommand)
+ {
+ /* Display the collected data.
+ For the trap frame, display only what was collected at the trap.
+ Likewise for stepping frames, display only what was collected
+ while stepping. This means that the two boolean variables,
+ STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
+ if (stepping_frame == stepping_actions)
+ {
+ do { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ if (*action_exp == ',')
+ action_exp++;
+ while (isspace (*action_exp))
+ action_exp++;
+
+ next_comma = strchr (action_exp, ',');
+
+ if (0 == strncasecmp (action_exp, "$reg", 4))
+ registers_info (NULL, from_tty);
+ else if (0 == strncasecmp (action_exp, "$loc", 4))
+ locals_info (NULL, from_tty);
+ else if (0 == strncasecmp (action_exp, "$arg", 4))
+ args_info (NULL, from_tty);
+ else
+ { /* variable */
+ if (next_comma)
+ {
+ make_cleanup (replace_comma, next_comma);
+ *next_comma = '\0';
+ }
+ printf_filtered ("%s = ", action_exp);
+ output_command (action_exp, from_tty);
+ printf_filtered ("\n");
+ }
+ if (next_comma)
+ *next_comma = ',';
+ action_exp = next_comma;
+ } while (action_exp && *action_exp == ',');
+ }
+ }
+ }
+ discard_cleanups (old_cleanups);
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null)
+ * "stolen" from sparc-stub.c
+ */
+
+static const char hexchars[]="0123456789abcdef";
+
+static unsigned char *
+mem2hex(mem, buf, count)
+ unsigned char *mem;
+ unsigned char *buf;
+ int count;
+{
+ unsigned char ch;
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ return buf;
+}
+
+int get_traceframe_number()
+{
+ return traceframe_number;
+}
+
+
+/* module initialization */
+void
+_initialize_tracepoint ()
+{
+ tracepoint_chain = 0;
+ tracepoint_count = 0;
+ traceframe_number = -1;
+ tracepoint_number = -1;
+
+ set_internalvar (lookup_internalvar ("tpnum"),
+ value_from_longest (builtin_type_int, (LONGEST) 0));
+ set_internalvar (lookup_internalvar ("trace_frame"),
+ value_from_longest (builtin_type_int, (LONGEST) -1));
+
+ if (tracepoint_list.list == NULL)
+ {
+ tracepoint_list.listsize = 128;
+ tracepoint_list.list = xmalloc
+ (tracepoint_list.listsize * sizeof (struct memrange));
+ }
+ if (tracepoint_list.aexpr_list == NULL)
+ {
+ tracepoint_list.aexpr_listsize = 128;
+ tracepoint_list.aexpr_list = xmalloc
+ (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
+ }
+
+ if (stepping_list.list == NULL)
+ {
+ stepping_list.listsize = 128;
+ stepping_list.list = xmalloc
+ (stepping_list.listsize * sizeof (struct memrange));
+ }
+
+ if (stepping_list.aexpr_list == NULL)
+ {
+ stepping_list.aexpr_listsize = 128;
+ stepping_list.aexpr_list = xmalloc
+ (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
+ }
+
+ add_info ("scope", scope_info,
+ "List the variables local to a scope");
+
+ add_cmd ("tracepoints", class_trace, NO_FUNCTION,
+ "Tracing of program execution without stopping the program.",
+ &cmdlist);
+
+ add_info ("tracepoints", tracepoints_info,
+ "Status of tracepoints, or tracepoint number NUMBER.\n\
+Convenience variable \"$tpnum\" contains the number of the\n\
+last tracepoint set.");
+
+ add_info_alias ("tp", "tracepoints", 1);
+
+ add_com ("save-tracepoints", class_trace, tracepoint_save_command,
+ "Save current tracepoint definitions as a script.\n\
+Use the 'source' command in another debug session to restore them.");
+
+ add_com ("tdump", class_trace, trace_dump_command,
+ "Print everything collected at the current tracepoint.");
+
+ add_prefix_cmd ("tfind", class_trace, trace_find_command,
+ "Select a trace frame;\n\
+No argument means forward by one frame; '-' meand backward by one frame.",
+ &tfindlist, "tfind ", 1, &cmdlist);
+
+ add_cmd ("outside", class_trace, trace_find_outside_command,
+ "Select a trace frame whose PC is outside the given \
+range.\nUsage: tfind outside addr1, addr2",
+ &tfindlist);
+
+ add_cmd ("range", class_trace, trace_find_range_command,
+ "Select a trace frame whose PC is in the given range.\n\
+Usage: tfind range addr1,addr2",
+ &tfindlist);
+
+ add_cmd ("line", class_trace, trace_find_line_command,
+ "Select a trace frame by source line.\n\
+Argument can be a line number (with optional source file), \n\
+a function name, or '*' followed by an address.\n\
+Default argument is 'the next source line that was traced'.",
+ &tfindlist);
+
+ add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
+ "Select a trace frame by tracepoint number.\n\
+Default is the tracepoint for the current trace frame.",
+ &tfindlist);
+
+ add_cmd ("pc", class_trace, trace_find_pc_command,
+ "Select a trace frame by PC.\n\
+Default is the current PC, or the PC of the current trace frame.",
+ &tfindlist);
+
+ add_cmd ("end", class_trace, trace_find_end_command,
+ "Synonym for 'none'.\n\
+De-select any trace frame and resume 'live' debugging.",
+ &tfindlist);
+
+ add_cmd ("none", class_trace, trace_find_none_command,
+ "De-select any trace frame and resume 'live' debugging.",
+ &tfindlist);
+
+ add_cmd ("start", class_trace, trace_find_start_command,
+ "Select the first trace frame in the trace buffer.",
+ &tfindlist);
+
+ add_com ("tstatus", class_trace, trace_status_command,
+ "Display the status of the current trace data collection.");
+
+ add_com ("tstop", class_trace, trace_stop_command,
+ "Stop trace data collection.");
+
+ add_com ("tstart", class_trace, trace_start_command,
+ "Start trace data collection.");
+
+ add_com ("passcount", class_trace, trace_pass_command,
+ "Set the passcount for a tracepoint.\n\
+The trace will end when the tracepoint has been passed 'count' times.\n\
+Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
+if TPNUM is omitted, passcount refers to the last tracepoint defined.");
+
+ add_com ("end", class_trace, end_actions_pseudocommand,
+ "Ends a list of commands or actions.\n\
+Several GDB commands allow you to enter a list of commands or actions.\n\
+Entering \"end\" on a line by itself is the normal way to terminate\n\
+such a list.\n\n\
+Note: the \"end\" command cannot be used at the gdb prompt.");
+
+ add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
+ "Specify single-stepping behavior at a tracepoint.\n\
+Argument is number of instructions to trace in single-step mode\n\
+following the tracepoint. This command is normally followed by\n\
+one or more \"collect\" commands, to specify what to collect\n\
+while single-stepping.\n\n\
+Note: this command can only be used in a tracepoint \"actions\" list.");
+
+ add_com_alias ("ws", "while-stepping", class_alias, 0);
+ add_com_alias ("stepping", "while-stepping", class_alias, 0);
+
+ add_com ("collect", class_trace, collect_pseudocommand,
+ "Specify one or more data items to be collected at a tracepoint.\n\
+Accepts a comma-separated list of (one or more) expressions. GDB will\n\
+collect all data (variables, registers) referenced by that expression.\n\
+Also accepts the following special arguments:\n\
+ $regs -- all registers.\n\
+ $args -- all function arguments.\n\
+ $locals -- all variables local to the block/function scope.\n\
+Note: this command can only be used in a tracepoint \"actions\" list.");
+
+ add_com ("actions", class_trace, trace_actions_command,
+ "Specify the actions to be taken at a tracepoint.\n\
+Tracepoint actions may include collecting of specified data, \n\
+single-stepping, or enabling/disabling other tracepoints, \n\
+depending on target's capabilities.");
+
+ add_cmd ("tracepoints", class_trace, delete_trace_command,
+ "Delete specified tracepoints.\n\
+Arguments are tracepoint numbers, separated by spaces.\n\
+No argument means delete all tracepoints.",
+ &deletelist);
+
+ add_cmd ("tracepoints", class_trace, disable_trace_command,
+ "Disable specified tracepoints.\n\
+Arguments are tracepoint numbers, separated by spaces.\n\
+No argument means disable all tracepoints.",
+ &disablelist);
+
+ add_cmd ("tracepoints", class_trace, enable_trace_command,
+ "Enable specified tracepoints.\n\
+Arguments are tracepoint numbers, separated by spaces.\n\
+No argument means enable all tracepoints.",
+ &enablelist);
+
+ add_com ("trace", class_trace, trace_command,
+ "Set a tracepoint at a specified line or function or address.\n\
+Argument may be a line number, function name, or '*' plus an address.\n\
+For a line number or function, trace at the start of its code.\n\
+If an address is specified, trace at that exact address.\n\n\
+Do \"help tracepoints\" for info on other tracepoint commands.");
+
+ add_com_alias ("tp", "trace", class_alias, 0);
+ add_com_alias ("tr", "trace", class_alias, 1);
+ add_com_alias ("tra", "trace", class_alias, 1);
+ add_com_alias ("trac", "trace", class_alias, 1);
+}
+
diff --git a/contrib/gdb/gdb/tracepoint.h b/contrib/gdb/gdb/tracepoint.h
new file mode 100644
index 0000000..4c1ee82
--- /dev/null
+++ b/contrib/gdb/gdb/tracepoint.h
@@ -0,0 +1,137 @@
+/* Data structures associated with tracepoints in GDB.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if !defined (TRACEPOINT_H)
+#define TRACEPOINT_H 1
+
+#if !defined (BREAKPOINT_H)
+enum enable { disabled, enabled };
+#endif
+/* The data structure for an action: */
+struct action_line
+{
+ struct action_line *next;
+ char *action;
+};
+
+/* The data structure for a tracepoint: */
+
+struct tracepoint
+{
+ struct tracepoint *next;
+
+ enum enable enabled;
+
+#if 0
+ /* Type of tracepoint (MVS FIXME: needed?). */
+ enum tptype type;
+
+ /* What to do with this tracepoint after we hit it MVS FIXME: needed?). */
+ enum tpdisp disposition;
+#endif
+ /* Number assigned to distinguish tracepoints. */
+ int number;
+
+ /* Address to trace at, or NULL if not an instruction tracepoint (MVS ?). */
+ CORE_ADDR address;
+
+ /* Line number of this address. Only matters if address is non-NULL. */
+ int line_number;
+
+ /* Source file name of this address. Only matters if address is non-NULL. */
+ char *source_file;
+
+ /* Number of times this tracepoint should single-step
+ and collect additional data */
+ long step_count;
+
+ /* Number of times this tracepoint should be hit before disabling/ending. */
+ int pass_count;
+
+ /* Chain of action lines to execute when this tracepoint is hit. */
+ struct action_line *actions;
+
+ /* Conditional (MVS ?). */
+ struct expression *cond;
+
+ /* String we used to set the tracepoint (malloc'd). Only matters if
+ address is non-NULL. */
+ char *addr_string;
+
+ /* Language we used to set the tracepoint. */
+ enum language language;
+
+ /* Input radix we used to set the tracepoint. */
+ int input_radix;
+
+ /* Count of the number of times this tracepoint was taken, dumped
+ with the info, but not used for anything else. Useful for
+ seeing how many times you hit a tracepoint prior to the program
+ aborting, so you can back up to just before the abort. */
+ int hit_count;
+
+ /* Thread number for thread-specific tracepoint, or -1 if don't care */
+ int thread;
+
+ /* BFD section, in case of overlays:
+ no, I don't know if tracepoints are really gonna work with overlays. */
+ asection *section;
+};
+
+enum actionline_type
+{
+ BADLINE = -1,
+ GENERIC = 0,
+ END = 1,
+ STEPPING = 2
+};
+
+
+/* The tracepont chain of all tracepoints */
+
+extern struct tracepoint *tracepoint_chain;
+
+extern unsigned long trace_running_p;
+
+/* A hook used to notify the UI of tracepoint operations */
+
+void (*create_tracepoint_hook) PARAMS ((struct tracepoint *));
+void (*delete_tracepoint_hook) PARAMS ((struct tracepoint *));
+void (*modify_tracepoint_hook) PARAMS ((struct tracepoint *));
+void (*trace_find_hook) PARAMS ((char *arg, int from_tty));
+void (*trace_start_stop_hook) PARAMS ((int start, int from_tty));
+
+struct tracepoint *get_tracepoint_by_number PARAMS ((char **));
+int get_traceframe_number PARAMS ((void));
+void free_actions PARAMS((struct tracepoint *));
+enum actionline_type validate_actionline PARAMS((char **,
+ struct tracepoint *));
+
+
+/* Walk the following statement or block through all tracepoints.
+ ALL_TRACEPOINTS_SAFE does so even if the statment deletes the current
+ breakpoint. */
+
+#define ALL_TRACEPOINTS(t) for (t = tracepoint_chain; t; t = t->next)
+
+#define ALL_TRACEPOINTS_SAFE(t,tmp) \
+ for (t = tracepoint_chain; \
+ t ? (tmp = t->next, 1) : 0;\
+ t = tmp)
+#endif /* TRACEPOINT_H */
diff --git a/contrib/gdb/gdb/tui/ChangeLog b/contrib/gdb/gdb/tui/ChangeLog
new file mode 100644
index 0000000..7dc1bf6
--- /dev/null
+++ b/contrib/gdb/gdb/tui/ChangeLog
@@ -0,0 +1,121 @@
+1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * tui.h: Include stdarg.h instead of varargs.h if we're on an ISO Cish
+ system.
+
+Thu Dec 31 12:08:32 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Jim Blandy <jimb@cygnus.com>,
+ Edith Epstein <eepstein@cygnus.com>, Elena Zannoni
+ <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David
+ Taylor <taylor@cygnus.com>, as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * Makefile.in: New file; we're merging HP's changes into GDB, and
+ we've moved the TUI files into a subdirectory, so we need a new
+ Makefile.
+
+ * tui.c:
+ #include <term.h>, if we have it, to get declarations for
+ the termcap functions on Solaris.
+ (tgoto): Add external K&R declaration for this; Solaris doesn't
+ bother to actually declare it in their header files.
+ (_tuiReset): Ignore the #definition of TIOCGETC if USG is defined;
+ we'd rather use the USG mechanisms than the Berkeley mechanisms
+ (TIOCGETC is one of the Berkeley terminal control ioctls).
+ Apologies if this causes trouble later; this should all be handled
+ by autoconf...
+ (strcat_to_buf, strcat_to_buf_with_fmt): New functions, moved here
+ from ../utils.h.
+ (tuiFree): replace safe_free with free.
+ (strcat_to_buf): new function, copied from utils.c.
+ (tuiInit): Add ignored `argv0' argument, to match the type that
+ init_ui_hook expects; updated declaration. Call the
+ initialize_tui_files function constructed above. Initialize
+ flush_hook to NULL.
+ (tuiInitWindows): Call tuiSetLocatorContent, to get the first
+ element of the locator window's content allocated. This seems
+ wrong, because it must have been initialized somehow in HP's
+ sources, and we should do it the same way now. But we do get
+ further before it segfaults. [Postscript: HP didn't bother to
+ initialize it; they compile
+ (va_catch_errors, vcatch_errors): Functions moved here from
+ ../utils.c in HP's sources. They're not used anywhere else.
+ (xdb_style): Delete this variable, and remove all references to
+ it. It's always true.
+ (tuiInit, _tui_vDo): References removed.
+
+ * tui.h: Add prototypes.
+ Don't #include "gendefs.h"; it's only used in the TUI.
+ Integrate its contents into this file:
+ #include <ansidecl.h> here.
+ (Opaque, OpaqueFuncPtr): Typedefs moved to here.
+
+ * tuiCommand.c: #include "defs.h", so we get the appropriate
+ definition of GDB_FILE.
+
+ * tuiData.c
+ (freeWindow): replace safe_free with free.
+ (tui_version): don't define it here; it's defined in main.c now.
+
+ * tuiDisassem.c
+ (tuiSetDisassemContent): Call strcat_address_numeric instead of
+ strcat_address. Simplify the control structure. Use predefined
+ GDB function to print asm inst address. Use GDB_FILE to collect
+ output into buffers.
+
+ * tuiIO.c
+ (tgoto): Add external K&R declaration for this here too.
+ (tuiGetc, tuiTermSetup, tuiTermUnsetup): Same.
+ (tuiPuts_unfiltered): change FILE to GDB_FILE.
+ (tui_tputs): fix prototype for 3rd argument.
+
+ * tuiIO.h (tuiPuts_unfiltered): change declaration.
+
+ * tuiLayout.c
+ (_tuiSetLayoutTo): for displaying registers, hook up the HP code
+ that decides which registers to display (i.e. single precision
+ float, double precision float, general, special). Previously,
+ only handled TUI_GENERAL_REGS. Now that the code is hooked up,
+ compiling with -z poses a problem. When the first layout command
+ is 'layout regs', dataWin->detail is a NULL pointer, and gdb
+ core dumps.
+
+ * tuiLayout.c (_tuiSetLayoutTo): replace safe_free with free.
+
+ * tuiRegs.c #include "defs.h" earlier, to avoid problems in
+ <stdarg.h>. No idea exactly what's conflicting with what, but the
+ errors went away...
+ (_tuiRegisterFormat): Change so that function creates a GDB_FILE
+ object, calls pa_do_strcat_registers_info, copies the register
+ info into a buffer, and deallocates the GDB_FILE object. Remove
+ some code that is not executed. Also, call to
+ pa_do_strcat_registers_info has an additional parameter,
+ precision. This code requires some new per-target functions that
+ we don't want to merge. Dyke it out, with #ifdef
+ TUI_EXTENDED_FORMATTERS.
+ (_tuiSetSpecialRegsContent): this function was ifdefed out.
+ Hooked this up.
+ (_tuiSetGeneralAndSpecialRegsContent): this function was ifdefed
+ out. Hooked it up.
+ (IS_64BIT): Just define this to be zero; we're not merging in the
+ 64-bit support.
+ (tuiShowRegisters): Comment out all references to the "special"
+ regs; we don't have a distinction between the "special" and
+ "non-special" regs in most of our machine descriptions. This code
+ is PA-specific in other ways as well, and needs to be redesigned
+ to be portable to other processors.
+
+ * tuiWin.c: #include <string.h>, to get a declaration for
+ strchr.
+
+ * tui.c, tuiCommand.c, tuiData.c, tuiDataWin.c, tuiDisassem.c,
+ tuiGeneralWin.c, tuiIO.c, tuiLayout.c, tuiRegs.c, tuiSource.c,
+ tuiSourceWin.c, tuiStack.c, tuiWin.c: New files (from HP). Changed
+ bool to int throughout. Re-indented, GNU style.
+
+ * tui.h, tuiCommand.h, tuiData.h, tuiDataWin.h, tuiDisassem.h,
+ tuiGeneralWin.h, tuiIO.h, tuiLayout.h, tuiRegs.h, tuiSource.h,
+ tuiSourceWin.h, tuiStack.h, tuiWin.h: new files (from HP).
+ Changed bool to int throughout.
diff --git a/contrib/gdb/gdb/tui/Makefile b/contrib/gdb/gdb/tui/Makefile
new file mode 100644
index 0000000..ed89c6e
--- /dev/null
+++ b/contrib/gdb/gdb/tui/Makefile
@@ -0,0 +1,182 @@
+# Generated automatically from Makefile.in by configure.
+# Copyright 1998 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+all: libtui.a
+
+srcdir=.
+
+SHELL = /bin/sh
+
+CC=gcc
+CFLAGS=-g -O2
+AR=ar
+RANLIB=ranlib
+
+# Host and target-dependent makefile fragments come in here.
+
+# Host: Sun 4 or Sparcstation, running SunOS 4
+XDEPFILES= ser-tcp.o
+XM_FILE= xm-sun4os4.h
+NAT_FILE= nm-sun4os4.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o
+HOST_IPC=-DBSD_IPC
+GDBSERVER_DEPFILES= low-sparc.o
+# Setting XM_CLIBS=-lresolv would let us use the DNS, but that would screw
+# anyone who wants to use NIS, which includes at least one Cygnus customer
+# (PR 3593). So leave it this way until/unless we find a resolver which can
+# get names from either DNS or NIS from the same GDB binary.
+
+# Target: Sun 4 or Sparcstation, running SunOS 4
+TDEPFILES= sparc-tdep.o solib.o
+TM_FILE= tm-sun4os4.h
+# End of host and target-dependent makefile fragments
+
+# Where is our "include" directory? Typically $(srcdir)/../include.
+# This is essentially the header file directory for the library
+# routines in libiberty.
+INCLUDE_DIR = $(srcdir)/../../include
+INCLUDE_CFLAGS = -I$(INCLUDE_DIR)
+
+# Configured by the --with-mmalloc option to configure.
+MMALLOC =
+MMALLOC_CFLAGS =
+
+# Where is the BFD library? Typically in ../bfd.
+BFD_DIR = ../../bfd
+BFD_SRC = $(srcdir)/$(BFD_DIR)
+BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
+
+# Where is the READLINE library? Typically in ../readline.
+READLINE_DIR = ../../readline
+READLINE_SRC = $(srcdir)/$(READLINE_DIR)
+READLINE_CFLAGS = -I$(READLINE_SRC)
+
+# Where is the INTL library? Typically in ../intl.
+INTL_DIR = ../../intl
+INTL_SRC = $(srcdir)/$(INTL_DIR)
+INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC)
+
+# Where is the TCL library? Typically in ../tcl.
+TCL_CFLAGS = @TCLHDIR@
+
+# Where is the TK library? Typically in ../tk.
+TK_CFLAGS = @TKHDIR@ @TK_BUILD_INCLUDES@
+
+# Where is Itcl? Typically in ../itcl.
+ITCL_CFLAGS = @ITCLHDIR@
+
+# Where is Tix? Typically in ../tix.
+TIX_CFLAGS = @TIXHDIR@
+
+X11_CFLAGS = @TK_XINCLUDES@
+
+ENABLE_IDE= @ENABLE_IDE@
+
+GUI_CFLAGS_X = -I$(srcdir)/../../libgui/src
+
+IDE_CFLAGS_X = -I$(srcdir)/../../libidetcl/src -I$(srcdir)/../../libide/src \
+ `if [ x"$(ENABLE_IDE)" != x ] ; then \
+ echo -DIDE -I$(srcdir)/../../ilu/runtime/mainloop;\
+ fi`
+
+IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X)
+
+ENABLE_CFLAGS=
+
+# -I. for config files.
+# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also.
+# -I$(srcdir)/config for more generic config files.
+
+# It is also possible that you will need to add -I/usr/include/sys if
+# your system doesn't have fcntl.h in /usr/include (which is where it
+# should be according to Posix).
+DEFS = -DHAVE_CONFIG_H
+GDB_CFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config $(DEFS)
+
+# M{H,T}_CFLAGS, if defined, have host- and target-dependent CFLAGS
+# from the config directory.
+GLOBAL_CFLAGS = $(MT_CFLAGS) $(MH_CFLAGS)
+#PROFILE_CFLAGS = -pg
+
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
+ $(GDB_CFLAGS) $(READLINE_CFLAGS) $(BFD_CFLAGS) \
+ $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(INTL_CFLAGS) \
+ $(ENABLE_CFLAGS)
+
+HEADERS = tuiIO.h tuiData.h tuiGeneralWin.h tuiLayout.h tuiStack.h \
+ tuiSource.h tuiCommand.h tuiWin.h tuiDisassem.h \
+ tuiSourceWin.h tuiRegs.h tuiDataWin.h
+
+SOURCES = tui.c tuiData.c tuiSource.c tuiStack.c tuiIO.c \
+ tuiGeneralWin.c tuiLayout.c tuiWin.c tuiCommand.c \
+ tuiDisassem.c tuiSourceWin.c tuiRegs.c tuiDataWin.c
+
+OBJECTS = tui.o tuiData.o tuiSource.o tuiStack.o tuiIO.o \
+ tuiGeneralWin.o tuiLayout.o tuiWin.o tuiCommand.o \
+ tuiDisassem.o tuiSourceWin.o tuiRegs.o tuiDataWin.o \
+ tuiInit.o
+
+
+# Prevent Sun make from putting in the machine type. Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+ $(CC) -c $(INTERNAL_CFLAGS) $<
+.SUFFIXES: .cpp
+.c.cpp:
+ $(CC) -E $(INTERNAL_CFLAGS) $< > $@
+
+libtui.a: $(OBJECTS)
+ rm -f libtui.a
+ $(AR) rc libtui.a $(OBJECTS)
+ $(RANLIB) libtui.a
+
+tui.o: tui.c tui.h tuiData.h tuiLayout.h tuiIO.h tuiRegs.h tuiWin.h
+tuiCommand.o: tui.h tuiData.h tuiWin.h tuiIO.h
+tuiData.o: tui.h tuiData.h
+tuiDataWin.o: tui.h tuiData.h tuiRegs.h
+tuiDisassem.o: tui.h tuiData.h tuiLayout.h tuiSourceWin.h tuiStack.h
+tuiGeneralWin.o: tui.h tuiData.h tuiGeneralWin.h
+tuiIO.o: tui.h tuiData.h tuiIO.h tuiCommand.h tuiWin.h
+tuiLayout.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiRegs.h \
+ tuiDisassem.h
+tuiRegs.o: tui.h tuiData.h tuiLayout.h tuiWin.h
+tuiSource.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h
+tuiSourceWin.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h \
+ tuiDisassem.h
+tuiStack.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h
+tuiWin.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiSourceWin.h \
+ tuiDataWin.h
+
+tuiInit.o: tuiInit.c
+tuiInit.c: $(SOURCES)
+ @echo Making tuiInit.c
+ @rm -f init.c-tmp
+ @echo '/* Do not modify this file. */' >init.c-tmp
+ @echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
+ @echo '#include "ansidecl.h"' >>init.c-tmp
+ @echo 'extern void initialize_tui_files PARAMS ((void));' >>init.c-tmp
+ @echo 'void initialize_tui_files PARAMS ((void)) {' >>init.c-tmp
+ @-( cd $(srcdir) ; grep '^_initialize_[a-z_0-9A-Z]* *(' $(SOURCES) ) 2>/dev/null \
+ | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp
+ @echo '}' >>init.c-tmp
+ @mv init.c-tmp tuiInit.c
+
+clean:
+ rm -f *.o *.a
diff --git a/contrib/gdb/gdb/tui/Makefile.in b/contrib/gdb/gdb/tui/Makefile.in
new file mode 100644
index 0000000..256464b
--- /dev/null
+++ b/contrib/gdb/gdb/tui/Makefile.in
@@ -0,0 +1,168 @@
+# Copyright 1998 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+all: libtui.a
+
+srcdir=@srcdir@
+VPATH = @srcdir@
+
+SHELL = @SHELL@
+
+CC=@CC@
+CFLAGS=@CFLAGS@
+AR=@AR@
+RANLIB=@RANLIB@
+
+# Host and target-dependent makefile fragments come in here.
+@host_makefile_frag@
+@target_makefile_frag@
+# End of host and target-dependent makefile fragments
+
+# Where is our "include" directory? Typically $(srcdir)/../include.
+# This is essentially the header file directory for the library
+# routines in libiberty.
+INCLUDE_DIR = $(srcdir)/../../include
+INCLUDE_CFLAGS = -I$(INCLUDE_DIR)
+
+# Configured by the --with-mmalloc option to configure.
+MMALLOC = @MMALLOC@
+MMALLOC_CFLAGS = @MMALLOC_CFLAGS@
+
+# Where is the BFD library? Typically in ../bfd.
+BFD_DIR = ../../bfd
+BFD_SRC = $(srcdir)/$(BFD_DIR)
+BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
+
+# Where is the READLINE library? Typically in ../readline.
+READLINE_DIR = ../../readline
+READLINE_SRC = $(srcdir)/$(READLINE_DIR)
+READLINE_CFLAGS = -I$(READLINE_SRC)
+
+# Where is the INTL library? Typically in ../intl.
+INTL_DIR = ../../intl
+INTL_SRC = $(srcdir)/$(INTL_DIR)
+INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC)
+
+# Where is the TCL library? Typically in ../tcl.
+TCL_CFLAGS = @TCLHDIR@
+
+# Where is the TK library? Typically in ../tk.
+TK_CFLAGS = @TKHDIR@ @TK_BUILD_INCLUDES@
+
+# Where is Itcl? Typically in ../itcl.
+ITCL_CFLAGS = @ITCLHDIR@
+
+# Where is Tix? Typically in ../tix.
+TIX_CFLAGS = @TIXHDIR@
+
+X11_CFLAGS = @TK_XINCLUDES@
+
+ENABLE_IDE= @ENABLE_IDE@
+
+GUI_CFLAGS_X = -I$(srcdir)/../../libgui/src
+
+IDE_CFLAGS_X = -I$(srcdir)/../../libidetcl/src -I$(srcdir)/../../libide/src \
+ `if [ x"$(ENABLE_IDE)" != x ] ; then \
+ echo -DIDE -I$(srcdir)/../../ilu/runtime/mainloop;\
+ fi`
+
+IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X)
+
+ENABLE_CFLAGS= @ENABLE_CFLAGS@
+
+# -I. for config files.
+# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also.
+# -I$(srcdir)/config for more generic config files.
+
+# It is also possible that you will need to add -I/usr/include/sys if
+# your system doesn't have fcntl.h in /usr/include (which is where it
+# should be according to Posix).
+DEFS = @DEFS@
+GDB_CFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config $(DEFS)
+
+# M{H,T}_CFLAGS, if defined, have host- and target-dependent CFLAGS
+# from the config directory.
+GLOBAL_CFLAGS = $(MT_CFLAGS) $(MH_CFLAGS)
+#PROFILE_CFLAGS = -pg
+
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
+ $(GDB_CFLAGS) $(READLINE_CFLAGS) $(BFD_CFLAGS) \
+ $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(INTL_CFLAGS) \
+ $(ENABLE_CFLAGS)
+
+HEADERS = tuiIO.h tuiData.h tuiGeneralWin.h tuiLayout.h tuiStack.h \
+ tuiSource.h tuiCommand.h tuiWin.h tuiDisassem.h \
+ tuiSourceWin.h tuiRegs.h tuiDataWin.h
+
+SOURCES = tui.c tuiData.c tuiSource.c tuiStack.c tuiIO.c \
+ tuiGeneralWin.c tuiLayout.c tuiWin.c tuiCommand.c \
+ tuiDisassem.c tuiSourceWin.c tuiRegs.c tuiDataWin.c
+
+OBJECTS = tui.o tuiData.o tuiSource.o tuiStack.o tuiIO.o \
+ tuiGeneralWin.o tuiLayout.o tuiWin.o tuiCommand.o \
+ tuiDisassem.o tuiSourceWin.o tuiRegs.o tuiDataWin.o \
+ tuiInit.o
+
+
+# Prevent Sun make from putting in the machine type. Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+ $(CC) -c $(INTERNAL_CFLAGS) $<
+.SUFFIXES: .cpp
+.c.cpp:
+ $(CC) -E $(INTERNAL_CFLAGS) $< > $@
+
+libtui.a: $(OBJECTS)
+ rm -f libtui.a
+ $(AR) rc libtui.a $(OBJECTS)
+ $(RANLIB) libtui.a
+
+tui.o: tui.c tui.h tuiData.h tuiLayout.h tuiIO.h tuiRegs.h tuiWin.h
+tuiCommand.o: tui.h tuiData.h tuiWin.h tuiIO.h
+tuiData.o: tui.h tuiData.h
+tuiDataWin.o: tui.h tuiData.h tuiRegs.h
+tuiDisassem.o: tui.h tuiData.h tuiLayout.h tuiSourceWin.h tuiStack.h
+tuiGeneralWin.o: tui.h tuiData.h tuiGeneralWin.h
+tuiIO.o: tui.h tuiData.h tuiIO.h tuiCommand.h tuiWin.h
+tuiLayout.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiRegs.h \
+ tuiDisassem.h
+tuiRegs.o: tui.h tuiData.h tuiLayout.h tuiWin.h
+tuiSource.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h
+tuiSourceWin.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h tuiSource.h \
+ tuiDisassem.h
+tuiStack.o: tui.h tuiData.h tuiStack.h tuiSourceWin.h
+tuiWin.o: tui.h tuiData.h tuiGeneralWin.h tuiStack.h tuiSourceWin.h \
+ tuiDataWin.h
+
+tuiInit.o: tuiInit.c
+tuiInit.c: $(SOURCES)
+ @echo Making tuiInit.c
+ @rm -f init.c-tmp
+ @echo '/* Do not modify this file. */' >init.c-tmp
+ @echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
+ @echo '#include "ansidecl.h"' >>init.c-tmp
+ @echo 'extern void initialize_tui_files PARAMS ((void));' >>init.c-tmp
+ @echo 'void initialize_tui_files PARAMS ((void)) {' >>init.c-tmp
+ @-( cd $(srcdir) ; grep '^_initialize_[a-z_0-9A-Z]* *(' $(SOURCES) ) 2>/dev/null \
+ | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp
+ @echo '}' >>init.c-tmp
+ @mv init.c-tmp tuiInit.c
+
+clean:
+ rm -f *.o *.a
diff --git a/contrib/gdb/gdb/tui/tui.c b/contrib/gdb/gdb/tui/tui.c
new file mode 100644
index 0000000..f64db44
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tui.c
@@ -0,0 +1,830 @@
+/*
+** tui.c
+** General functions for the WDB TUI
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <curses.h>
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+#include <signal.h>
+#include <fcntl.h>
+#include <termio.h>
+#include <setjmp.h>
+#include "defs.h"
+#include "gdbcmd.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiLayout.h"
+#include "tuiIO.h"
+#include "tuiRegs.h"
+#include "tuiWin.h"
+
+/* The Solaris header files seem to provide no declaration for this at
+ all when __STDC__ is defined. This shouldn't conflict with
+ anything. */
+extern char *tgoto ();
+
+/***********************
+** Local Definitions
+************************/
+#define FILEDES 2
+/* Solaris <sys/termios.h> defines CTRL. */
+#ifndef CTRL
+#define CTRL(x) (x & ~0140)
+#endif
+#define CHK(val, dft) (val<=0 ? dft : val)
+
+#define TOGGLE_USAGE "Usage:toggle breakpoints"
+#define TUI_TOGGLE_USAGE "Usage:\ttoggle $fregs\n\ttoggle breakpoints"
+
+/*****************************
+** Local static forward decls
+******************************/
+static void _tuiReset PARAMS ((void));
+static void _toggle_command PARAMS ((char *, int));
+static void _tui_vToggle_command PARAMS ((va_list));
+static Opaque _tui_vDo PARAMS ((TuiOpaqueFuncPtr, va_list));
+
+
+
+/***********************
+** Public Functions
+************************/
+
+/*
+** tuiInit().
+*/
+void
+#ifdef __STDC__
+tuiInit (char *argv0)
+#else
+tuiInit (argv0)
+ char *argv0;
+#endif
+{
+ extern void init_page_info ();
+ extern void initialize_tui_files PARAMS ((void));
+
+ initialize_tui_files ();
+ initializeStaticData ();
+ initscr ();
+ refresh ();
+ setTermHeightTo (LINES);
+ setTermWidthTo (COLS);
+ tuiInitWindows ();
+ wrefresh (cmdWin->generic.handle);
+ init_page_info ();
+ /* Don't hook debugger output if doing command-window
+ * the XDB way. However, one thing we do want to do in
+ * XDB style is set up the scrolling region to be
+ * the bottom of the screen (tuiTermUnsetup()).
+ */
+ fputs_unfiltered_hook = NULL;
+ flush_hook = NULL;
+ rl_initialize (); /* need readline initialization to
+ * create termcap sequences
+ */
+ tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch);
+
+ return;
+} /* tuiInit */
+
+
+/*
+** tuiInitWindows().
+*/
+void
+#ifdef __STDC__
+tuiInitWindows (void)
+#else
+tuiInitWindows ()
+#endif
+{
+ TuiWinType type;
+
+ tuiSetLocatorContent (0);
+ showLayout (SRC_COMMAND);
+ keypad (cmdWin->generic.handle, TRUE);
+ echo ();
+ crmode ();
+ nl ();
+ tuiSetWinFocusTo (srcWin);
+
+ return;
+} /* tuiInitWindows */
+
+
+/*
+** tuiCleanUp().
+** Kill signal handler and cleanup termination method
+*/
+void
+#ifdef __STDC__
+tuiResetScreen (void)
+#else
+tuiResetScreen ()
+#endif
+{
+ TuiWinType type = SRC_WIN;
+
+ keypad (cmdWin->generic.handle, FALSE);
+ for (; type < MAX_MAJOR_WINDOWS; type++)
+ {
+ if (m_winPtrNotNull (winList[type]) &&
+ winList[type]->generic.type != UNDEFINED_WIN &&
+ !winList[type]->generic.isVisible)
+ tuiDelWindow (winList[type]);
+ }
+ endwin ();
+ initscr ();
+ refresh ();
+ echo ();
+ crmode ();
+ nl ();
+
+ return;
+} /* tuiResetScreen */
+
+
+/*
+** tuiCleanUp().
+** Kill signal handler and cleanup termination method
+*/
+void
+#ifdef __STDC__
+tuiCleanUp (void)
+#else
+tuiCleanUp ()
+#endif
+{
+ char *buffer;
+ extern char *term_cursor_move;
+
+ signal (SIGINT, SIG_IGN);
+ tuiTermSetup (0); /* Restore scrolling region to whole screen */
+ keypad (cmdWin->generic.handle, FALSE);
+ freeAllWindows ();
+ endwin ();
+ buffer = tgoto (term_cursor_move, 0, termHeight ());
+ tputs (buffer, 1, putchar);
+ _tuiReset ();
+
+ return;
+} /* tuiCleanUp */
+
+
+/*
+** tuiError().
+*/
+void
+#ifdef __STDC__
+tuiError (
+ char *string,
+ int exitGdb)
+#else
+tuiError (string, exitGdb)
+ char *string;
+ int exitGdb;
+#endif
+{
+ puts_unfiltered (string);
+ if (exitGdb)
+ {
+ tuiCleanUp ();
+ exit (-1);
+ }
+
+ return;
+} /* tuiError */
+
+
+/*
+** tui_vError()
+** tuiError with args in a va_list.
+*/
+void
+#ifdef __STDC__
+tui_vError (
+ va_list args)
+#else
+tui_vError (args)
+ va_list args;
+#endif
+{
+ char *string;
+ int exitGdb;
+
+ string = va_arg (args, char *);
+ exitGdb = va_arg (args, int);
+
+ tuiError (string, exitGdb);
+
+ return;
+} /* tui_vError */
+
+
+/*
+** tuiFree()
+** Wrapper on top of free() to ensure that input address is greater than 0x0
+*/
+void
+#ifdef __STDC__
+tuiFree (
+ char *ptr)
+#else
+tuiFree (ptr)
+ char *ptr;
+#endif
+{
+ if (ptr != (char *) NULL)
+ {
+ free (ptr);
+ }
+
+ return;
+} /* tuiFree */
+
+
+/* tuiGetLowDisassemblyAddress().
+** Determine what the low address will be to display in the TUI's
+** disassembly window. This may or may not be the same as the
+** low address input.
+*/
+Opaque
+#ifdef __STDC__
+tuiGetLowDisassemblyAddress (
+ Opaque low,
+ Opaque pc)
+#else
+tuiGetLowDisassemblyAddress (low, pc)
+ Opaque low;
+ Opaque pc;
+#endif
+{
+ int line;
+ Opaque newLow;
+
+ /*
+ ** Determine where to start the disassembly so that the pc is about in the
+ ** middle of the viewport.
+ */
+ for (line = 0, newLow = pc;
+ (newLow > low &&
+ line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
+ DISASSEM_COMMAND) / 2));)
+ {
+ bfd_byte buffer[4];
+
+ newLow -= sizeof (bfd_getb32 (buffer));
+ line++;
+ }
+
+ return newLow;
+} /* tuiGetLowDisassemblyAddress */
+
+
+/* tui_vGetLowDisassemblyAddress().
+** Determine what the low address will be to display in the TUI's
+** disassembly window with args in a va_list.
+*/
+Opaque
+#ifdef __STDC__
+tui_vGetLowDisassemblyAddress (
+ va_list args)
+#else
+tui_vGetLowDisassemblyAddress (args)
+ va_list args;
+#endif
+{
+ int line;
+ Opaque newLow;
+ Opaque low;
+ Opaque pc;
+
+ low = va_arg (args, Opaque);
+ pc = va_arg (args, Opaque);
+
+ return (tuiGetLowDisassemblyAddress (low, pc));
+
+} /* tui_vGetLowDisassemblyAddress */
+
+
+/*
+** tuiDo().
+** General purpose function to execute a tui function. Transitions
+** between curses and the are handled here. This function is called
+** by non-tui gdb functions.
+**
+** Errors are caught here.
+** If there is no error, the value returned by 'func' is returned.
+** If there is an error, then zero is returned.
+**
+** Must not be called with immediate_quit in effect (bad things might
+** happen, say we got a signal in the middle of a memcpy to quit_return).
+** This is an OK restriction; with very few exceptions immediate_quit can
+** be replaced by judicious use of QUIT.
+*/
+Opaque
+#ifdef __STDC__
+tuiDo (
+ TuiOpaqueFuncPtr func,...)
+#else
+tuiDo (func, va_alist)
+ TuiOpaqueFuncPtr func;
+ va_dcl
+#endif
+{
+ extern int terminal_is_ours;
+
+ Opaque ret = (Opaque) NULL;
+
+ /* It is an error to be tuiDo'ing if we
+ * don't own the terminal.
+ */
+ if (!terminal_is_ours)
+ return ret;
+
+ if (tui_version)
+ {
+ va_list args;
+
+#ifdef __STDC__
+ va_start (args, func);
+#else
+ va_start (args);
+#endif
+ ret = _tui_vDo (func, args);
+ va_end (args);
+ }
+
+ return ret;
+} /* tuiDo */
+
+
+/*
+** tuiDoAndReturnToTop().
+** General purpose function to execute a tui function. Transitions
+** between curses and the are handled here. This function is called
+** by non-tui gdb functions who wish to reset gdb to the top level.
+** After the tuiDo is performed, a return to the top level occurs.
+**
+** Errors are caught here.
+** If there is no error, the value returned by 'func' is returned.
+** If there is an error, then zero is returned.
+**
+** Must not be called with immediate_quit in effect (bad things might
+** happen, say we got a signal in the middle of a memcpy to quit_return).
+** This is an OK restriction; with very few exceptions immediate_quit can
+** be replaced by judicious use of QUIT.
+**
+*/
+Opaque
+#ifdef __STDC__
+tuiDoAndReturnToTop (
+ TuiOpaqueFuncPtr func,...)
+#else
+tuiDoAndReturnToTop (func, va_alist)
+ TuiOpaqueFuncPtr func;
+ va_dcl
+#endif
+{
+ extern int terminal_is_ours;
+
+ Opaque ret = (Opaque) NULL;
+
+ /* It is an error to be tuiDo'ing if we
+ * don't own the terminal.
+ */
+ if (!terminal_is_ours)
+ return ret;
+
+ if (tui_version)
+ {
+ va_list args;
+
+#ifdef __STDC__
+ va_start (args, func);
+#else
+ va_start (args);
+#endif
+ ret = _tui_vDo (func, args);
+
+ /* force a return to the top level */
+ return_to_top_level (RETURN_ERROR);
+ }
+
+ return ret;
+} /* tuiDoAndReturnToTop */
+
+
+void
+#ifdef __STDC__
+tui_vSelectSourceSymtab (
+ va_list args)
+#else
+tui_vSelectSourceSymtab (args)
+ va_list args;
+#endif
+{
+ struct symtab *s = va_arg (args, struct symtab *);
+
+ select_source_symtab (s);
+ return;
+} /* tui_vSelectSourceSymtab */
+
+
+/*
+** _initialize_tui().
+** Function to initialize gdb commands, for tui window manipulation.
+*/
+void
+_initialize_tui ()
+{
+#if 0
+ if (tui_version)
+ {
+ add_com ("toggle", class_tui, _toggle_command,
+ "Toggle Terminal UI Features\n\
+Usage: Toggle $fregs\n\
+\tToggles between single and double precision floating point registers.\n");
+ }
+#endif
+ char *helpStr;
+
+ if (tui_version)
+ helpStr = "Toggle Specified Features\n\
+Usage:\ttoggle $fregs\n\ttoggle breakpoints";
+ else
+ helpStr = "Toggle Specified Features\nUsage:toggle breakpoints";
+ add_abbrev_prefix_cmd ("toggle",
+ class_tui,
+ _toggle_command,
+ helpStr,
+ &togglelist,
+ "toggle ",
+ 1,
+ &cmdlist);
+} /* _initialize_tui*/
+
+
+/*
+** va_catch_errors().
+** General purpose function to execute a function, catching errors.
+** If there is no error, the value returned by 'func' is returned.
+** If there is error, then zero is returned.
+** Note that 'func' must take a variable argument list as well.
+**
+** Must not be called with immediate_quit in effect (bad things might
+** happen, say we got a signal in the middle of a memcpy to quit_return).
+** This is an OK restriction; with very few exceptions immediate_quit can
+** be replaced by judicious use of QUIT.
+*/
+Opaque
+#ifdef __STDC__
+va_catch_errors (
+ TuiOpaqueFuncPtr func,
+ va_list args)
+#else
+va_catch_errors (func, args)
+ TuiOpaqueFuncPtr func;
+ va_list args;
+#endif
+{
+ Opaque ret = (Opaque) NULL;
+
+ /*
+ ** We could have used catch_errors(), but it doesn't handle variable args.
+ ** Also, for the tui, we always want to catch all errors, so we don't
+ ** need to pass a mask, or an error string.
+ */
+ jmp_buf saved_error;
+ jmp_buf saved_quit;
+ jmp_buf tmp_jmp;
+ struct cleanup *saved_cleanup_chain;
+ char *saved_error_pre_print;
+ char *saved_quit_pre_print;
+ extern jmp_buf error_return;
+ extern jmp_buf quit_return;
+
+ saved_cleanup_chain = save_cleanups ();
+ saved_error_pre_print = error_pre_print;
+ saved_quit_pre_print = quit_pre_print;
+
+ memcpy ((char *) saved_error, (char *) error_return, sizeof (jmp_buf));
+ error_pre_print = "";
+ memcpy (saved_quit, quit_return, sizeof (jmp_buf));
+ quit_pre_print = "";
+
+ if (setjmp (tmp_jmp) == 0)
+ {
+ va_list argList = args;
+ memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
+ memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
+ ret = func (argList);
+ }
+ restore_cleanups (saved_cleanup_chain);
+ memcpy (error_return, saved_error, sizeof (jmp_buf));
+ error_pre_print = saved_error_pre_print;
+ memcpy (quit_return, saved_quit, sizeof (jmp_buf));
+ quit_pre_print = saved_quit_pre_print;
+
+ return ret;
+}
+
+/*
+** vcatch_errors().
+** Catch errors occurring in tui or non tui function, handling
+** variable param lists. Note that 'func' must take a variable
+** argument list as well.
+*/
+Opaque
+#ifdef __STDC__
+vcatch_errors (
+ OpaqueFuncPtr func,...)
+#else
+vcatch_errors (va_alist)
+ va_dcl
+/*
+vcatch_errors(func, va_alist)
+ OpaqueFuncPtr func;
+ va_dcl
+*/
+#endif
+{
+ Opaque ret = (Opaque) NULL;
+ va_list args;
+#ifdef __STDC__
+ va_start (args, func);
+/*
+ va_arg(args, OpaqueFuncPtr);
+*/
+#else
+ OpaqueFuncPtr func;
+
+ va_start (args);
+ func = va_arg (args, OpaqueFuncPtr);
+#endif
+ ret = va_catch_errors (func, args);
+ va_end (args);
+
+ return ret;
+}
+
+
+void
+#ifdef __STDC__
+strcat_to_buf (
+ char *buf,
+ int buflen,
+ char *itemToAdd)
+#else
+strcat_to_buf (buf, buflen, itemToAdd)
+ char *buf;
+ int buflen;
+ char *itemToAdd;
+#endif
+{
+ if (itemToAdd != (char *) NULL && buf != (char *) NULL)
+ {
+ if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
+ strcat (buf, itemToAdd);
+ else
+ strncat (buf, itemToAdd, (buflen - strlen (buf)));
+ }
+
+ return;
+} /* strcat_to_buf */
+
+/* VARARGS */
+void
+#ifdef ANSI_PROTOTYPES
+strcat_to_buf_with_fmt (
+ char *buf,
+ int bufLen,
+ char *format,...)
+#else
+strcat_to_buf_with_fmt (va_alist)
+ va_dcl
+#endif
+{
+ char *linebuffer;
+ struct cleanup *old_cleanups;
+ va_list args;
+#ifdef ANSI_PROTOTYPES
+ va_start (args, format);
+#else
+ char *buf;
+ int bufLen;
+ char *format;
+
+ va_start (args);
+ buf = va_arg (args, char *);
+ bufLen = va_arg (args, int);
+ format = va_arg (args, char *);
+#endif
+ vasprintf (&linebuffer, format, args);
+ old_cleanups = make_cleanup (free, linebuffer);
+ strcat_to_buf (buf, bufLen, linebuffer);
+ do_cleanups (old_cleanups);
+ va_end (args);
+}
+
+
+
+
+
+/***********************
+** Static Functions
+************************/
+
+
+/*
+** _tui_vDo().
+** General purpose function to execute a tui function. Transitions
+** between curses and the are handled here. This function is called
+** by non-tui gdb functions.
+**
+** Errors are caught here.
+** If there is no error, the value returned by 'func' is returned.
+** If there is an error, then zero is returned.
+**
+** Must not be called with immediate_quit in effect (bad things might
+** happen, say we got a signal in the middle of a memcpy to quit_return).
+** This is an OK restriction; with very few exceptions immediate_quit can
+** be replaced by judicious use of QUIT.
+*/
+static Opaque
+#ifdef __STDC__
+_tui_vDo (
+ TuiOpaqueFuncPtr func,
+ va_list args)
+#else
+_tui_vDo (func, args)
+ TuiOpaqueFuncPtr func;
+ va_list args;
+#endif
+{
+ extern int terminal_is_ours;
+
+ Opaque ret = (Opaque) NULL;
+
+ /* It is an error to be tuiDo'ing if we
+ * don't own the terminal.
+ */
+ if (!terminal_is_ours)
+ return ret;
+
+ if (tui_version)
+ {
+ /* If doing command window the "XDB way" (command window
+ * is unmanaged by curses...
+ */
+ /* Set up terminal for TUI */
+ tuiTermSetup (1);
+
+ ret = va_catch_errors (func, args);
+
+ /* Set up terminal for command window */
+ tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch);
+ }
+
+ return ret;
+} /* _tui_vDo */
+
+
+static void
+#ifdef __STDC__
+_toggle_command (
+ char *arg,
+ int fromTTY)
+#else
+_toggle_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ printf_filtered ("Specify feature to toggle.\n%s\n",
+ (tui_version) ? TUI_TOGGLE_USAGE : TOGGLE_USAGE);
+/*
+ tuiDo((TuiOpaqueFuncPtr)_Toggle_command, arg, fromTTY);
+*/
+}
+
+/*
+** _tui_vToggle_command().
+*/
+static void
+#ifdef __STDC__
+_tui_vToggle_command (
+ va_list args)
+#else
+_tui_vToggle_command (args)
+ va_list args;
+#endif
+{
+ char *arg;
+ int fromTTY;
+
+ arg = va_arg (args, char *);
+
+ if (arg == (char *) NULL)
+ printf_filtered (TOGGLE_USAGE);
+ else
+ {
+ char *ptr = (char *) tuiStrDup (arg);
+ int i;
+
+ for (i = 0; (ptr[i]); i++)
+ ptr[i] = toupper (arg[i]);
+
+ if (subsetCompare (ptr, TUI_FLOAT_REGS_NAME))
+ tuiToggleFloatRegs ();
+/* else if (subsetCompare(ptr, "ANOTHER TOGGLE OPTION"))
+ ...
+*/
+ else
+ printf_filtered (TOGGLE_USAGE);
+ tuiFree (ptr);
+ }
+
+ return;
+} /* _tuiToggle_command */
+
+
+static void
+#ifdef __STDC__
+_tuiReset (void)
+#else
+_tuiReset ()
+#endif
+{
+ struct termio mode;
+
+ /*
+ ** reset the teletype mode bits to a sensible state.
+ ** Copied tset.c
+ */
+#if ! defined (USG) && defined (TIOCGETC)
+ struct tchars tbuf;
+#endif /* !USG && TIOCGETC */
+#ifdef UCB_NTTY
+ struct ltchars ltc;
+
+ if (ldisc == NTTYDISC)
+ {
+ ioctl (FILEDES, TIOCGLTC, &ltc);
+ ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
+ ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
+ ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
+ ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
+ ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
+ ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
+ ioctl (FILEDES, TIOCSLTC, &ltc);
+ }
+#endif /* UCB_NTTY */
+#ifndef USG
+#ifdef TIOCGETC
+ ioctl (FILEDES, TIOCGETC, &tbuf);
+ tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
+ tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
+ tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
+ tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
+ tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
+ /* brkc is left alone */
+ ioctl (FILEDES, TIOCSETC, &tbuf);
+#endif /* TIOCGETC */
+ mode.sg_flags &= ~(RAW
+#ifdef CBREAK
+ | CBREAK
+#endif /* CBREAK */
+ | VTDELAY | ALLDELAY);
+ mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
+#else /*USG*/
+ ioctl (FILEDES, TCGETA, &mode);
+ mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
+ mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
+ mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
+
+ mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
+ mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
+ mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
+ NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
+ mode.c_oflag |= (OPOST | ONLCR);
+ mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
+#ifndef hp9000s800
+ mode.c_cflag |= (CS8 | CREAD);
+#else /*hp9000s800*/
+ mode.c_cflag |= (CS8 | CSTOPB | CREAD);
+#endif /* hp9000s800 */
+ mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
+ mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
+ ioctl (FILEDES, TCSETAW, &mode);
+#endif /* USG */
+
+ return;
+} /* _tuiReset */
diff --git a/contrib/gdb/gdb/tui/tui.h b/contrib/gdb/gdb/tui/tui.h
new file mode 100644
index 0000000..bc9fb31
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tui.h
@@ -0,0 +1,120 @@
+/* External/Public TUI Header File */
+
+#ifndef TUI_H
+#define TUI_H
+#include <curses.h>
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include "ansidecl.h"
+
+#if defined(reg)
+#undef reg
+#endif
+#if defined(chtype)
+#undef chtype
+#endif
+
+/* Opaque data type */
+typedef char *Opaque;
+typedef Opaque (*OpaqueFuncPtr) PARAMS ((va_list));
+typedef char **OpaqueList;
+typedef OpaqueList OpaquePtr;
+
+/* Generic function pointer */
+typedef void (*TuiVoidFuncPtr) PARAMS ((va_list));
+typedef int (*TuiIntFuncPtr) PARAMS ((va_list));
+/*
+typedef Opaque (*TuiOpaqueFuncPtr) PARAMS ((va_list));
+*/
+typedef OpaqueFuncPtr TuiOpaqueFuncPtr;
+
+extern Opaque vcatch_errors PARAMS ((OpaqueFuncPtr, ...));
+extern Opaque va_catch_errors PARAMS ((OpaqueFuncPtr, va_list));
+
+extern void strcat_to_buf PARAMS ((char *, int, char *));
+extern void strcat_to_buf_with_fmt PARAMS ((char *, int, char *, ...));
+
+/* Types of error returns */
+typedef enum {
+ TUI_SUCCESS,
+ TUI_FAILURE
+} TuiStatus, *TuiStatusPtr;
+
+/* Types of windows */
+typedef enum {
+ SRC_WIN = 0,
+ DISASSEM_WIN,
+ DATA_WIN,
+ CMD_WIN,
+ /* This must ALWAYS be AFTER the major windows last */
+ MAX_MAJOR_WINDOWS,
+ /* auxillary windows */
+ LOCATOR_WIN,
+ EXEC_INFO_WIN,
+ DATA_ITEM_WIN,
+ /* This must ALWAYS be next to last */
+ MAX_WINDOWS,
+ UNDEFINED_WIN /* LAST */
+} TuiWinType, *TuiWinTypePtr;
+
+/* This is a point definition */
+typedef struct _TuiPoint {
+ int x, y;
+} TuiPoint, *TuiPointPtr;
+
+/* Generic window information */
+typedef struct _TuiGenWinInfo {
+ WINDOW *handle; /* window handle */
+ TuiWinType type; /* type of window */
+ int width; /* window width */
+ int height; /* window height */
+ TuiPoint origin; /* origin of window */
+ OpaquePtr content; /* content of window */
+ int contentSize; /* Size of content (# of elements) */
+ int contentInUse; /* Can it be used, or is it already used? */
+ int viewportHeight; /* viewport height */
+ int lastVisibleLine; /* index of last visible line */
+ int isVisible; /* whether the window is visible or not */
+} TuiGenWinInfo, *TuiGenWinInfoPtr;
+
+/* GENERAL TUI FUNCTIONS */
+/* tui.c */
+extern void tuiInit PARAMS ((char *argv0));
+extern void tuiInitWindows PARAMS ((void));
+extern void tuiResetScreen PARAMS ((void));
+extern void tuiCleanUp PARAMS ((void));
+extern void tuiError PARAMS ((char *, int));
+extern void tui_vError PARAMS ((va_list));
+extern void tuiFree PARAMS ((char *));
+extern Opaque tuiDo PARAMS ((TuiOpaqueFuncPtr, ...));
+extern Opaque tuiDoAndReturnToTop PARAMS ((TuiOpaqueFuncPtr, ...));
+extern Opaque tuiGetLowDisassemblyAddress PARAMS ((Opaque, Opaque));
+extern Opaque tui_vGetLowDisassemblyAddress PARAMS ((va_list));
+extern void tui_vSelectSourceSymtab PARAMS ((va_list));
+
+/* tuiDataWin.c */
+extern void tui_vCheckDataValues PARAMS ((va_list));
+
+/* tuiIO.c */
+extern void tui_vStartNewLines PARAMS ((va_list));
+
+/* tuiLayout.c */
+extern void tui_vAddWinToLayout PARAMS ((va_list));
+extern TuiStatus tui_vSetLayoutTo PARAMS ((va_list));
+
+/* tuiSourceWin.c */
+extern void tuiDisplayMainFunction PARAMS ((void));
+extern void tuiUpdateAllExecInfos PARAMS ((void));
+extern void tuiUpdateOnEnd PARAMS ((void));
+extern void tui_vAllSetHasBreakAt PARAMS ((va_list));
+extern void tui_vUpdateSourceWindowsWithAddr PARAMS ((va_list));
+
+/* tuiStack.c */
+extern void tui_vShowFrameInfo PARAMS ((va_list));
+extern void tui_vUpdateLocatorFilename PARAMS ((va_list));
+#endif /* TUI_H */
diff --git a/contrib/gdb/gdb/tui/tuiCommand.c b/contrib/gdb/gdb/tui/tuiCommand.c
new file mode 100644
index 0000000..454dc62
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiCommand.c
@@ -0,0 +1,215 @@
+/*
+** tuiCommand.c
+** This module contains functions specific to command window processing.
+*/
+
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiWin.h"
+#include "tuiIO.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*
+** tuiDispatchCtrlChar().
+** Dispatch the correct tui function based upon the control character.
+*/
+unsigned int
+#ifdef __STDC__
+tuiDispatchCtrlChar (
+ unsigned int ch)
+#else
+tuiDispatchCtrlChar (ch)
+ unsigned int ch;
+#endif
+{
+ TuiWinInfoPtr winInfo = tuiWinWithFocus ();
+
+ /*
+ ** If the command window has the logical focus, or no-one does
+ ** assume it is the command window; in this case, pass the
+ ** character on through and do nothing here.
+ */
+ if (winInfo == (TuiWinInfoPtr) NULL || winInfo == cmdWin)
+ return ch;
+ else
+ {
+ unsigned int c = 0, chCopy = ch;
+ register int i;
+ char *term;
+
+ /* If this is an xterm, page next/prev keys aren't returned
+ ** by keypad as a single char, so we must handle them here.
+ ** Seems like a bug in the curses library?
+ */
+ term = (char *) getenv ("TERM");
+ for (i = 0; (term && term[i]); i++)
+ term[i] = toupper (term[i]);
+ if ((strcmp (term, "XTERM") == 0) && m_isStartSequence (ch))
+ {
+ unsigned int pageCh = 0, tmpChar;
+
+ tmpChar = 0;
+ while (!m_isEndSequence (tmpChar))
+ {
+ tmpChar = (int) wgetch (cmdWin->generic.handle);
+ if (!tmpChar)
+ break;
+ if (tmpChar == 53)
+ pageCh = KEY_PPAGE;
+ else if (tmpChar == 54)
+ pageCh = KEY_NPAGE;
+ }
+ chCopy = pageCh;
+ }
+
+ switch (chCopy)
+ {
+ case KEY_NPAGE:
+ tuiScrollForward (winInfo, 0);
+ break;
+ case KEY_PPAGE:
+ tuiScrollBackward (winInfo, 0);
+ break;
+ case KEY_DOWN:
+ case KEY_SF:
+ tuiScrollForward (winInfo, 1);
+ break;
+ case KEY_UP:
+ case KEY_SR:
+ tuiScrollBackward (winInfo, 1);
+ break;
+ case KEY_RIGHT:
+ tuiScrollLeft (winInfo, 1);
+ break;
+ case KEY_LEFT:
+ tuiScrollRight (winInfo, 1);
+ break;
+ case '\f':
+ tuiRefreshAll ();
+ break;
+ default:
+ c = chCopy;
+ break;
+ }
+ return c;
+ }
+} /* tuiDispatchCtrlChar */
+
+
+/*
+** tuiIncrCommandCharCountBy()
+** Increment the current character count in the command window,
+** checking for overflow. Returns the new value of the char count.
+*/
+int
+#ifdef __STDC__
+tuiIncrCommandCharCountBy (
+ int count)
+#else
+tuiIncrCommandCharCountBy (count)
+ int count;
+#endif
+{
+ if (tui_version)
+ {
+ if ((count + cmdWin->detail.commandInfo.curch) >= cmdWin->generic.width)
+ cmdWin->detail.commandInfo.curch =
+ (count + cmdWin->detail.commandInfo.curch) - cmdWin->generic.width;
+ else
+ cmdWin->detail.commandInfo.curch += count;
+ }
+
+ return cmdWin->detail.commandInfo.curch;
+} /* tuiIncrCommandCharCountBy */
+
+
+/*
+** tuiDecrCommandCharCountBy()
+** Decrement the current character count in the command window,
+** checking for overflow. Returns the new value of the char count.
+*/
+int
+#ifdef __STDC__
+tuiDecrCommandCharCountBy (
+ int count)
+#else
+tuiDecrCommandCharCountBy (count)
+ int count;
+#endif
+{
+ if (tui_version)
+ {
+ if ((cmdWin->detail.commandInfo.curch - count) < 0)
+ cmdWin->detail.commandInfo.curch =
+ cmdWin->generic.width + (cmdWin->detail.commandInfo.curch - count);
+ else
+ cmdWin->detail.commandInfo.curch -= count;
+ }
+
+ return cmdWin->detail.commandInfo.curch;
+} /* tuiDecrCommandCharCountBy */
+
+
+/*
+** tuiSetCommandCharCountTo()
+** Set the character count to count.
+*/
+int
+#ifdef __STDC__
+tuiSetCommandCharCountTo (
+ int count)
+#else
+tuiSetCommandCharCountTo (count)
+ int count;
+#endif
+{
+ if (tui_version)
+ {
+ if (count > cmdWin->generic.width - 1)
+ {
+ cmdWin->detail.commandInfo.curch = 0;
+ tuiIncrCommandCharCountBy (count);
+ }
+ else
+ cmdWin->detail.commandInfo.curch -= count;
+ }
+
+ return cmdWin->detail.commandInfo.curch;
+} /* tuiSetCommandCharCountTo */
+
+
+
+/*
+** tuiClearCommandCharCount()
+** Clear the character count to count.
+*/
+int
+#ifdef __STDC__
+tuiClearCommandCharCount (void)
+#else
+tuiClearCommandCharCount ()
+#endif
+{
+ if (tui_version)
+ cmdWin->detail.commandInfo.curch = 0;
+
+ return cmdWin->detail.commandInfo.curch;
+} /* tuiClearCommandCharCount */
+
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
diff --git a/contrib/gdb/gdb/tui/tuiCommand.h b/contrib/gdb/gdb/tui/tuiCommand.h
new file mode 100644
index 0000000..206d918
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiCommand.h
@@ -0,0 +1,24 @@
+#ifndef _TUI_COMMAND_H
+#define _TUI_COMMAND_H
+/*
+** This header file supports
+*/
+
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+
+extern unsigned int tuiDispatchCtrlChar PARAMS ((unsigned int));
+extern int tuiIncrCommandCharCountBy PARAMS ((int));
+extern int tuiDecrCommandCharCountBy PARAMS ((int));
+extern int tuiSetCommandCharCountTo PARAMS ((int));
+extern int tuiClearCommandCharCount PARAMS ((void));
+
+#endif /*_TUI_COMMAND_H*/
diff --git a/contrib/gdb/gdb/tui/tuiData.c b/contrib/gdb/gdb/tui/tuiData.c
new file mode 100644
index 0000000..758a6cd
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiData.c
@@ -0,0 +1,1624 @@
+/*
+** tuiData.c
+** This module contains functions for manipulating the data
+** structures used by the TUI
+*/
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+
+/****************************
+** GLOBAL DECLARATIONS
+****************************/
+TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS];
+
+/***************************
+** Private Definitions
+****************************/
+#define FILE_WIDTH 30
+#define PROC_WIDTH 40
+#define LINE_WIDTH 4
+#define PC_WIDTH 8
+
+/***************************
+** Private data
+****************************/
+static char *_tuiNullStr = TUI_NULL_STR;
+static char *_tuiBlankStr = " ";
+static char *_tuiLocationStr = " >";
+static char *_tuiBreakStr = " * ";
+static char *_tuiBreakLocationStr = " *>";
+static TuiLayoutType _currentLayout = UNDEFINED_LAYOUT;
+static int _termHeight, _termWidth;
+static int _historyLimit = DEFAULT_HISTORY_COUNT;
+static TuiGenWinInfo _locator;
+static TuiGenWinInfo _execInfo[2];
+static TuiWinInfoPtr _srcWinList[2];
+static TuiList _sourceWindows =
+{(OpaqueList) _srcWinList, 0};
+static int _defaultTabLen = DEFAULT_TAB_LEN;
+static TuiWinInfoPtr _winWithFocus = (TuiWinInfoPtr) NULL;
+static TuiLayoutDef _layoutDef =
+{SRC_WIN, /* displayMode */
+ FALSE, /* split */
+ TUI_UNDEFINED_REGS, /* regsDisplayType */
+ TUI_SFLOAT_REGS}; /* floatRegsDisplayType */
+static int _winResized = FALSE;
+
+
+/*********************************
+** Static function forward decls
+**********************************/
+static void freeContent PARAMS ((TuiWinContent, int, TuiWinType));
+static void freeContentElements PARAMS ((TuiWinContent, int, TuiWinType));
+
+
+
+/*********************************
+** PUBLIC FUNCTIONS
+**********************************/
+
+/******************************************
+** ACCESSORS & MUTATORS FOR PRIVATE DATA
+******************************************/
+
+/*
+** tuiWinResized().
+** Answer a whether the terminal window has been resized or not
+*/
+int
+#ifdef __STDC__
+tuiWinResized (void)
+#else
+tuiWinResized ()
+#endif
+{
+ return _winResized;
+} /* tuiWinResized */
+
+
+/*
+** tuiSetWinResized().
+** Set a whether the terminal window has been resized or not
+*/
+void
+#ifdef __STDC__
+tuiSetWinResizedTo (
+ int resized)
+#else
+tuiSetWinResizedTo (resized)
+ int resized;
+#endif
+{
+ _winResized = resized;
+
+ return;
+} /* tuiSetWinResizedTo */
+
+
+/*
+** tuiLayoutDef().
+** Answer a pointer to the current layout definition
+*/
+TuiLayoutDefPtr
+#ifdef __STDC__
+tuiLayoutDef (void)
+#else
+tuiLayoutDef ()
+#endif
+{
+ return &_layoutDef;
+} /* tuiLayoutDef */
+
+
+/*
+** tuiWinWithFocus().
+** Answer the window with the logical focus
+*/
+TuiWinInfoPtr
+#ifdef __STDC__
+tuiWinWithFocus (void)
+#else
+tuiWinWithFocus ()
+#endif
+{
+ return _winWithFocus;
+} /* tuiWinWithFocus */
+
+
+/*
+** tuiSetWinWithFocus().
+** Set the window that has the logical focus
+*/
+void
+#ifdef __STDC__
+tuiSetWinWithFocus (
+ TuiWinInfoPtr winInfo)
+#else
+tuiSetWinWithFocus (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ _winWithFocus = winInfo;
+
+ return;
+} /* tuiSetWinWithFocus */
+
+
+/*
+** tuiDefaultTabLen().
+** Answer the length in chars, of tabs
+*/
+int
+#ifdef __STDC__
+tuiDefaultTabLen (void)
+#else
+tuiDefaultTabLen ()
+#endif
+{
+ return _defaultTabLen;
+} /* tuiDefaultTabLen */
+
+
+/*
+** tuiSetDefaultTabLen().
+** Set the length in chars, of tabs
+*/
+void
+#ifdef __STDC__
+tuiSetDefaultTabLen (
+ int len)
+#else
+tuiSetDefaultTabLen (len)
+ int len;
+#endif
+{
+ _defaultTabLen = len;
+
+ return;
+} /* tuiSetDefaultTabLen */
+
+
+/*
+** currentSourceWin()
+** Accessor for the current source window. Usually there is only
+** one source window (either source or disassembly), but both can
+** be displayed at the same time.
+*/
+TuiListPtr
+#ifdef __STDC__
+sourceWindows (void)
+#else
+sourceWindows ()
+#endif
+{
+ return &_sourceWindows;
+} /* currentSourceWindows */
+
+
+/*
+** clearSourceWindows()
+** Clear the list of source windows. Usually there is only one
+** source window (either source or disassembly), but both can be
+** displayed at the same time.
+*/
+void
+#ifdef __STDC__
+clearSourceWindows (void)
+#else
+clearSourceWindows ()
+#endif
+{
+ _sourceWindows.list[0] = (Opaque) NULL;
+ _sourceWindows.list[1] = (Opaque) NULL;
+ _sourceWindows.count = 0;
+
+ return;
+} /* currentSourceWindows */
+
+
+/*
+** clearSourceWindowsDetail()
+** Clear the pertinant detail in the source windows.
+*/
+void
+#ifdef __STDC__
+clearSourceWindowsDetail (void)
+#else
+clearSourceWindowsDetail ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ clearWinDetail ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* currentSourceWindows */
+
+
+/*
+** addSourceWindowToList().
+** Add a window to the list of source windows. Usually there is
+** only one source window (either source or disassembly), but
+** both can be displayed at the same time.
+*/
+void
+#ifdef __STDC__
+addToSourceWindows (
+ TuiWinInfoPtr winInfo)
+#else
+addToSourceWindows (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (_sourceWindows.count < 2)
+ _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo;
+
+ return;
+} /* addToSourceWindows */
+
+
+/*
+** clearWinDetail()
+** Clear the pertinant detail in the windows.
+*/
+void
+#ifdef __STDC__
+clearWinDetail (
+ TuiWinInfoPtr winInfo)
+#else
+clearWinDetail (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ winInfo->detail.sourceInfo.startLineOrAddr.addr = (Opaque) NULL;
+ winInfo->detail.sourceInfo.horizontalOffset = 0;
+ break;
+ case CMD_WIN:
+ winInfo->detail.commandInfo.curLine =
+ winInfo->detail.commandInfo.curch = 0;
+ break;
+ case DATA_WIN:
+ winInfo->detail.dataDisplayInfo.dataContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.dataContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.regsContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsDisplayType =
+ TUI_UNDEFINED_REGS;
+ winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
+ winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return;
+} /* clearWinDetail */
+
+
+/*
+** blankStr()
+** Accessor for the blank string.
+*/
+char *
+#ifdef __STDC__
+blankStr (void)
+#else
+blankStr ()
+#endif
+{
+ return _tuiBlankStr;
+} /* blankStr */
+
+
+/*
+** locationStr()
+** Accessor for the location string.
+*/
+char *
+#ifdef __STDC__
+locationStr (void)
+#else
+locationStr ()
+#endif
+{
+ return _tuiLocationStr;
+} /* locationStr */
+
+
+/*
+** breakStr()
+** Accessor for the break string.
+*/
+char *
+#ifdef __STDC__
+breakStr (void)
+#else
+breakStr ()
+#endif
+{
+ return _tuiBreakStr;
+} /* breakStr */
+
+
+/*
+** breakLocationStr()
+** Accessor for the breakLocation string.
+*/
+char *
+#ifdef __STDC__
+breakLocationStr (void)
+#else
+breakLocationStr ()
+#endif
+{
+ return _tuiBreakLocationStr;
+} /* breakLocationStr */
+
+
+/*
+** nullStr()
+** Accessor for the null string.
+*/
+char *
+#ifdef __STDC__
+nullStr (void)
+#else
+nullStr ()
+#endif
+{
+ return _tuiNullStr;
+} /* nullStr */
+
+
+/*
+** sourceExecInfoPtr().
+** Accessor for the source execution info ptr.
+*/
+TuiGenWinInfoPtr
+#ifdef __STDC__
+sourceExecInfoWinPtr (void)
+#else
+sourceExecInfoWinPtr ()
+#endif
+{
+ return &_execInfo[0];
+} /* sourceExecInfoWinPtr */
+
+
+/*
+** disassemExecInfoPtr().
+** Accessor for the disassem execution info ptr.
+*/
+TuiGenWinInfoPtr
+#ifdef __STDC__
+disassemExecInfoWinPtr (void)
+#else
+disassemExecInfoWinPtr ()
+#endif
+{
+ return &_execInfo[1];
+} /* disassemExecInfoWinPtr */
+
+
+/*
+** locatorWinInfoPtr().
+** Accessor for the locator win info. Answers a pointer to the
+** static locator win info struct.
+*/
+TuiGenWinInfoPtr
+#ifdef __STDC__
+locatorWinInfoPtr (void)
+#else
+locatorWinInfoPtr ()
+#endif
+{
+ return &_locator;
+} /* locatorWinInfoPtr */
+
+
+/*
+** historyLimit().
+** Accessor for the history limit
+*/
+int
+#ifdef __STDC__
+historyLimit (void)
+#else
+historyLimit ()
+#endif
+{
+ return _historyLimit;
+} /* historyLimit */
+
+
+/*
+** setHistoryLimitTo().
+** Mutator for the history limit
+*/
+void
+#ifdef __STDC__
+setHistoryLimitTo (
+ int h)
+#else
+setHistoryLimitTo (h)
+ int h;
+#endif
+{
+ _historyLimit = h;
+
+ return;
+} /* setHistoryLimitTo */
+
+/*
+** termHeight().
+** Accessor for the termHeight
+*/
+int
+#ifdef __STDC__
+termHeight (void)
+#else
+termHeight ()
+#endif
+{
+ return _termHeight;
+} /* termHeight */
+
+
+/*
+** setTermHeightTo().
+** Mutator for the term height
+*/
+void
+#ifdef __STDC__
+setTermHeightTo (
+ int h)
+#else
+setTermHeightTo (h)
+ int h;
+#endif
+{
+ _termHeight = h;
+
+ return;
+} /* setTermHeightTo */
+
+
+/*
+** termWidth().
+** Accessor for the termWidth
+*/
+int
+#ifdef __STDC__
+termWidth (void)
+#else
+termWidth ()
+#endif
+{
+ return _termWidth;
+} /* termWidth */
+
+
+/*
+** setTermWidth().
+** Mutator for the termWidth
+*/
+void
+#ifdef __STDC__
+setTermWidthTo (
+ int w)
+#else
+setTermWidthTo (w)
+ int w;
+#endif
+{
+ _termWidth = w;
+
+ return;
+} /* setTermWidthTo */
+
+
+/*
+** currentLayout().
+** Accessor for the current layout
+*/
+TuiLayoutType
+#ifdef __STDC__
+currentLayout (void)
+#else
+currentLayout ()
+#endif
+{
+ return _currentLayout;
+} /* currentLayout */
+
+
+/*
+** setCurrentLayoutTo().
+** Mutator for the current layout
+*/
+void
+#ifdef __STDC__
+setCurrentLayoutTo (
+ TuiLayoutType newLayout)
+#else
+setCurrentLayoutTo (newLayout)
+ TuiLayoutType newLayout;
+#endif
+{
+ _currentLayout = newLayout;
+
+ return;
+} /* setCurrentLayoutTo */
+
+
+/*
+** setGenWinOrigin().
+** Set the origin of the window
+*/
+void
+#ifdef __STDC__
+setGenWinOrigin (
+ TuiGenWinInfoPtr winInfo,
+ int x,
+ int y)
+#else
+setGenWinOrigin (winInfo, x, y)
+ TuiGenWinInfoPtr winInfo;
+ int x;
+ int y;
+#endif
+{
+ winInfo->origin.x = x;
+ winInfo->origin.y = y;
+
+ return;
+} /* setGenWinOrigin */
+
+
+/*****************************
+** OTHER PUBLIC FUNCTIONS
+*****************************/
+
+
+/*
+** tuiNextWin().
+** Answer the next window in the list, cycling back to the top
+** if necessary
+*/
+TuiWinInfoPtr
+#ifdef __STDC__
+tuiNextWin (
+ TuiWinInfoPtr curWin)
+#else
+tuiNextWin (curWin)
+ TuiWinInfoPtr curWin;
+#endif
+{
+ TuiWinType type = curWin->generic.type;
+ TuiWinInfoPtr nextWin = (TuiWinInfoPtr) NULL;
+
+ if (curWin->generic.type == CMD_WIN)
+ type = SRC_WIN;
+ else
+ type = curWin->generic.type + 1;
+ while (type != curWin->generic.type && m_winPtrIsNull (nextWin))
+ {
+ if (winList[type]->generic.isVisible)
+ nextWin = winList[type];
+ else
+ {
+ if (type == CMD_WIN)
+ type = SRC_WIN;
+ else
+ type++;
+ }
+ }
+
+ return nextWin;
+} /* tuiNextWin */
+
+
+/*
+** tuiPrevWin().
+** Answer the prev window in the list, cycling back to the bottom
+** if necessary
+*/
+TuiWinInfoPtr
+#ifdef __STDC__
+tuiPrevWin (
+ TuiWinInfoPtr curWin)
+#else
+tuiPrevWin (curWin)
+ TuiWinInfoPtr curWin;
+#endif
+{
+ TuiWinType type = curWin->generic.type;
+ TuiWinInfoPtr prev = (TuiWinInfoPtr) NULL;
+
+ if (curWin->generic.type == SRC_WIN)
+ type = CMD_WIN;
+ else
+ type = curWin->generic.type - 1;
+ while (type != curWin->generic.type && m_winPtrIsNull (prev))
+ {
+ if (winList[type]->generic.isVisible)
+ prev = winList[type];
+ else
+ {
+ if (type == SRC_WIN)
+ type = CMD_WIN;
+ else
+ type--;
+ }
+ }
+
+ return prev;
+} /* tuiPrevWin */
+
+
+/*
+** displayableWinContentOf().
+** Answer a the content at the location indicated by index. Note
+** that if this is a locator window, the string returned should be
+** freed after use.
+*/
+char *
+#ifdef __STDC__
+displayableWinContentOf (
+ TuiGenWinInfoPtr winInfo,
+ TuiWinElementPtr elementPtr)
+#else
+displayableWinContentOf (winInfo, elementPtr)
+ TuiGenWinInfoPtr winInfo;
+ TuiWinElementPtr elementPtr;
+#endif
+{
+
+ char *string = nullStr ();
+
+ if (elementPtr != (TuiWinElementPtr) NULL || winInfo->type == LOCATOR_WIN)
+ {
+ /*
+ ** Now convert the line to a displayable string
+ */
+ switch (winInfo->type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ string = elementPtr->whichElement.source.line;
+ break;
+ case CMD_WIN:
+ string = elementPtr->whichElement.command.line;
+ break;
+ case LOCATOR_WIN:
+ if ((string = (char *) xmalloc (
+ (termWidth () + 1) * sizeof (char))) == (char *) NULL)
+ string = nullStr ();
+ else
+ {
+ char lineNo[50], pc[50], buf[50], *fname, *pname;
+ register int strSize = termWidth (), i, procWidth, fileWidth;
+
+ /*
+ ** First determine the amount of file/proc name width
+ ** we have available
+ */
+ i = strSize - (PC_WIDTH + LINE_WIDTH
+ + 25 /* pc and line labels */
+ + strlen (FILE_PREFIX) + 1 /* file label */
+ + 15 /* procedure label */ );
+ if (i >= FILE_WIDTH + PROC_WIDTH)
+ {
+ fileWidth = FILE_WIDTH;
+ procWidth = PROC_WIDTH;
+ }
+ else
+ {
+ fileWidth = i / 2;
+ procWidth = i - fileWidth;
+ }
+
+ /* Now convert elements to string form */
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ *elementPtr->whichElement.locator.fileName != (char) 0 &&
+ srcWin->generic.isVisible)
+ fname = elementPtr->whichElement.locator.fileName;
+ else
+ fname = "??";
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ *elementPtr->whichElement.locator.procName != (char) 0)
+ pname = elementPtr->whichElement.locator.procName;
+ else
+ pname = "??";
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ elementPtr->whichElement.locator.lineNo > 0)
+ sprintf (lineNo, "%d",
+ elementPtr->whichElement.locator.lineNo);
+ else
+ strcpy (lineNo, "??");
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ elementPtr->whichElement.locator.addr > (Opaque) 0)
+ sprintf (pc, "0x%x",
+ elementPtr->whichElement.locator.addr);
+ else
+ strcpy (pc, "??");
+ /*
+ ** Now create the locator line from the string version
+ ** of the elements. We could use sprintf() here but
+ ** that wouldn't ensure that we don't overrun the size
+ ** of the allocated buffer. strcat_to_buf() will.
+ */
+ *string = (char) 0;
+ /* Filename */
+ strcat_to_buf (string, strSize, " ");
+ strcat_to_buf (string, strSize, FILE_PREFIX);
+ if (strlen (fname) > fileWidth)
+ {
+ strncpy (buf, fname, fileWidth - 1);
+ buf[fileWidth - 1] = '*';
+ buf[fileWidth] = (char) 0;
+ }
+ else
+ strcpy (buf, fname);
+ strcat_to_buf (string, strSize, buf);
+ /* procedure/class name */
+ sprintf (buf, "%15s", PROC_PREFIX);
+ strcat_to_buf (string, strSize, buf);
+ if (strlen (pname) > procWidth)
+ {
+ strncpy (buf, pname, procWidth - 1);
+ buf[procWidth - 1] = '*';
+ buf[procWidth] = (char) 0;
+ }
+ else
+ strcpy (buf, pname);
+ strcat_to_buf (string, strSize, buf);
+ sprintf (buf, "%10s", LINE_PREFIX);
+ strcat_to_buf (string, strSize, buf);
+ strcat_to_buf (string, strSize, lineNo);
+ sprintf (buf, "%10s", PC_PREFIX);
+ strcat_to_buf (string, strSize, buf);
+ strcat_to_buf (string, strSize, pc);
+ for (i = strlen (string); i < strSize; i++)
+ string[i] = ' ';
+ string[strSize] = (char) 0;
+ }
+ break;
+ case EXEC_INFO_WIN:
+ string = elementPtr->whichElement.simpleString;
+ break;
+ default:
+ break;
+ }
+ }
+ return string;
+} /* displayableWinContentOf */
+
+
+/*
+** winContentAt().
+** Answer a the content at the location indicated by index
+*/
+char *
+#ifdef __STDC__
+displayableWinContentAt (
+ TuiGenWinInfoPtr winInfo,
+ int index)
+#else
+displayableWinContentAt (winInfo, index)
+ TuiGenWinInfoPtr winInfo;
+ int index;
+#endif
+{
+ return (displayableWinContentOf (winInfo, (TuiWinElementPtr) winInfo->content[index]));
+} /* winContentAt */
+
+
+/*
+** winElementHeight().
+** Answer the height of the element in lines
+*/
+int
+#ifdef __STDC__
+winElementHeight (
+ TuiGenWinInfoPtr winInfo,
+ TuiWinElementPtr element)
+#else
+winElementHeight (winInfo, element)
+ TuiGenWinInfoPtr winInfo;
+ TuiWinElementPtr element;
+#endif
+{
+ int h;
+
+ if (winInfo->type == DATA_WIN)
+/* FOR NOW SAY IT IS ONLY ONE LINE HIGH */
+ h = 1;
+ else
+ h = 1;
+
+ return h;
+} /* winElementHeight */
+
+
+/*
+** winByName().
+** Answer the window represented by name
+*/
+TuiWinInfoPtr
+#ifdef __STDC__
+winByName (
+ char *name)
+#else
+winByName (name)
+ char *name;
+#endif
+{
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+ int i = 0;
+
+ while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo))
+ {
+ if (strcmp (name, winName (&(winList[i]->generic))) == 0)
+ winInfo = winList[i];
+ i++;
+ }
+
+ return winInfo;
+} /* winByName */
+
+
+/*
+** partialWinByName().
+** Answer the window represented by name
+*/
+TuiWinInfoPtr
+#ifdef __STDC__
+partialWinByName (
+ char *name)
+#else
+partialWinByName (name)
+ char *name;
+#endif
+{
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+
+ if (name != (char *) NULL)
+ {
+ int i = 0;
+
+ while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo))
+ {
+ char *curName = winName (&winList[i]->generic);
+ if (strlen (name) <= strlen (curName) &&
+ strncmp (name, curName, strlen (name)) == 0)
+ winInfo = winList[i];
+ i++;
+ }
+ }
+
+ return winInfo;
+} /* partialWinByName */
+
+
+/*
+** winName().
+** Answer the name of the window
+*/
+char *
+#ifdef __STDC__
+winName (
+ TuiGenWinInfoPtr winInfo)
+#else
+winName (winInfo)
+ TuiGenWinInfoPtr winInfo;
+#endif
+{
+ char *name = (char *) NULL;
+
+ switch (winInfo->type)
+ {
+ case SRC_WIN:
+ name = SRC_NAME;
+ break;
+ case CMD_WIN:
+ name = CMD_NAME;
+ break;
+ case DISASSEM_WIN:
+ name = DISASSEM_NAME;
+ break;
+ case DATA_WIN:
+ name = DATA_NAME;
+ break;
+ default:
+ name = "";
+ break;
+ }
+
+ return name;
+} /* winName */
+
+
+/*
+** initializeStaticData
+*/
+void
+#ifdef __STDC__
+initializeStaticData (void)
+#else
+initializeStaticData ()
+#endif
+{
+ initGenericPart (sourceExecInfoWinPtr ());
+ initGenericPart (disassemExecInfoWinPtr ());
+ initGenericPart (locatorWinInfoPtr ());
+
+ return;
+} /* initializeStaticData */
+
+
+/*
+** allocGenericWinInfo().
+*/
+TuiGenWinInfoPtr
+#ifdef __STDC__
+allocGenericWinInfo (void)
+#else
+allocGenericWinInfo ()
+#endif
+{
+ TuiGenWinInfoPtr win;
+
+ if ((win = (TuiGenWinInfoPtr) xmalloc (
+ sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL)
+ initGenericPart (win);
+
+ return win;
+} /* allocGenericWinInfo */
+
+
+/*
+** initGenericPart().
+*/
+void
+#ifdef __STDC__
+initGenericPart (
+ TuiGenWinInfoPtr win)
+#else
+initGenericPart (win)
+ TuiGenWinInfoPtr win;
+#endif
+{
+ win->width =
+ win->height =
+ win->origin.x =
+ win->origin.y =
+ win->viewportHeight =
+ win->contentSize =
+ win->lastVisibleLine = 0;
+ win->handle = (WINDOW *) NULL;
+ win->content = (OpaquePtr) NULL;
+ win->contentInUse =
+ win->isVisible = FALSE;
+
+ return;
+} /* initGenericPart */
+
+
+/*
+** initContentElement().
+*/
+void
+#ifdef __STDC__
+initContentElement (
+ TuiWinElementPtr element,
+ TuiWinType type)
+#else
+initContentElement (element, type)
+ TuiWinElementPtr element;
+ TuiWinType type;
+#endif
+{
+ element->highlight = FALSE;
+ switch (type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ element->whichElement.source.line = (char *) NULL;
+ element->whichElement.source.lineOrAddr.lineNo = 0;
+ element->whichElement.source.isExecPoint = FALSE;
+ element->whichElement.source.hasBreak = FALSE;
+ break;
+ case DATA_WIN:
+ initGenericPart (&element->whichElement.dataWindow);
+ element->whichElement.dataWindow.type = DATA_ITEM_WIN;
+ ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->content =
+ (OpaquePtr) allocContent (1, DATA_ITEM_WIN);
+ ((TuiGenWinInfoPtr)
+ & element->whichElement.dataWindow)->contentSize = 1;
+ break;
+ case CMD_WIN:
+ element->whichElement.command.line = (char *) NULL;
+ break;
+ case DATA_ITEM_WIN:
+ element->whichElement.data.name = (char *) NULL;
+ element->whichElement.data.type = TUI_REGISTER;
+ element->whichElement.data.itemNo = UNDEFINED_ITEM;
+ element->whichElement.data.value = (Opaque) NULL;
+ element->whichElement.data.highlight = FALSE;
+ break;
+ case LOCATOR_WIN:
+ element->whichElement.locator.fileName[0] =
+ element->whichElement.locator.procName[0] = (char) 0;
+ element->whichElement.locator.lineNo = 0;
+ element->whichElement.locator.addr = 0;
+ break;
+ case EXEC_INFO_WIN:
+ element->whichElement.simpleString = blankStr ();
+ break;
+ default:
+ break;
+ }
+ return;
+} /* initContentElement */
+
+/*
+** initWinInfo().
+*/
+void
+#ifdef __STDC__
+initWinInfo (
+ TuiWinInfoPtr winInfo)
+#else
+initWinInfo (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ initGenericPart (&winInfo->generic);
+ winInfo->canHighlight =
+ winInfo->isHighlighted = FALSE;
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ winInfo->detail.sourceInfo.executionInfo = (TuiGenWinInfoPtr) NULL;
+ winInfo->detail.sourceInfo.hasLocator = FALSE;
+ winInfo->detail.sourceInfo.horizontalOffset = 0;
+ winInfo->detail.sourceInfo.startLineOrAddr.addr = (Opaque) NULL;
+ break;
+ case DATA_WIN:
+ winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.dataContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.regsContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsDisplayType =
+ TUI_UNDEFINED_REGS;
+ winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
+ winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
+ break;
+ case CMD_WIN:
+ winInfo->detail.commandInfo.curLine = 0;
+ winInfo->detail.commandInfo.curch = 0;
+ break;
+ default:
+ winInfo->detail.opaque = (Opaque) NULL;
+ break;
+ }
+
+ return;
+} /* initWinInfo */
+
+
+/*
+** allocWinInfo().
+*/
+TuiWinInfoPtr
+#ifdef __STDC__
+allocWinInfo (
+ TuiWinType type)
+#else
+allocWinInfo (type)
+ TuiWinType type;
+#endif
+{
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+
+ winInfo = (TuiWinInfoPtr) xmalloc (sizeof (TuiWinInfo));
+ if (m_winPtrNotNull (winInfo))
+ {
+ winInfo->generic.type = type;
+ initWinInfo (winInfo);
+ }
+
+ return winInfo;
+} /* allocWinInfo */
+
+
+/*
+** allocContent().
+** Allocates the content and elements in a block.
+*/
+TuiWinContent
+#ifdef __STDC__
+allocContent (
+ int numElements,
+ TuiWinType type)
+#else
+allocContent (numElements, type)
+ int numElements;
+ TuiWinType type;
+#endif
+{
+ TuiWinContent content = (TuiWinContent) NULL;
+ char *elementBlockPtr = (char *) NULL;
+ int i;
+
+ if ((content = (TuiWinContent)
+ xmalloc (sizeof (TuiWinElementPtr) * numElements)) != (TuiWinContent) NULL)
+ { /*
+ ** All windows, except the data window, can allocate the elements
+ ** in a chunk. The data window cannot because items can be
+ ** added/removed from the data display by the user at any time.
+ */
+ if (type != DATA_WIN)
+ {
+ if ((elementBlockPtr = (char *)
+ xmalloc (sizeof (TuiWinElement) * numElements)) != (char *) NULL)
+ {
+ for (i = 0; i < numElements; i++)
+ {
+ content[i] = (TuiWinElementPtr) elementBlockPtr;
+ initContentElement (content[i], type);
+ elementBlockPtr += sizeof (TuiWinElement);
+ }
+ }
+ else
+ {
+ tuiFree ((char *) content);
+ content = (TuiWinContent) NULL;
+ }
+ }
+ }
+
+ return content;
+} /* allocContent */
+
+
+/*
+** addContentElements().
+** Adds the input number of elements to the windows's content. If
+** no content has been allocated yet, allocContent() is called to
+** do this. The index of the first element added is returned,
+** unless there is a memory allocation error, in which case, (-1)
+** is returned.
+*/
+int
+#ifdef __STDC__
+addContentElements (
+ TuiGenWinInfoPtr winInfo,
+ int numElements)
+#else
+addContentElements (winInfo, numElements)
+ TuiGenWinInfoPtr winInfo;
+ int numElements;
+#endif
+{
+ TuiWinElementPtr elementPtr;
+ int i, indexStart;
+
+ if (winInfo->content == (OpaquePtr) NULL)
+ {
+ winInfo->content = (OpaquePtr) allocContent (numElements, winInfo->type);
+ indexStart = 0;
+ }
+ else
+ indexStart = winInfo->contentSize;
+ if (winInfo->content != (OpaquePtr) NULL)
+ {
+ for (i = indexStart; (i < numElements + indexStart); i++)
+ {
+ if ((elementPtr = (TuiWinElementPtr)
+ xmalloc (sizeof (TuiWinElement))) != (TuiWinElementPtr) NULL)
+ {
+ winInfo->content[i] = (Opaque) elementPtr;
+ initContentElement (elementPtr, winInfo->type);
+ winInfo->contentSize++;
+ }
+ else /* things must be really hosed now! We ran out of memory!?*/
+ return (-1);
+ }
+ }
+
+ return indexStart;
+} /* addContentElements */
+
+
+/*
+** tuiDelWindow().
+** Delete all curses windows associated with winInfo, leaving everything
+** else in tact.
+*/
+void
+#ifdef __STDC__
+tuiDelWindow (
+ TuiWinInfoPtr winInfo)
+#else
+tuiDelWindow (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ Opaque detail;
+ int i;
+ TuiGenWinInfoPtr genericWin;
+
+
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ genericWin = locatorWinInfoPtr ();
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ genericWin->isVisible = FALSE;
+ }
+ genericWin = winInfo->detail.sourceInfo.executionInfo;
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ genericWin->isVisible = FALSE;
+ }
+ break;
+ case DATA_WIN:
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ int i;
+
+ tuiDelDataWindows (
+ winInfo->detail.dataDisplayInfo.regsContent,
+ winInfo->detail.dataDisplayInfo.regsContentCount);
+ tuiDelDataWindows (
+ winInfo->detail.dataDisplayInfo.dataContent,
+ winInfo->detail.dataDisplayInfo.dataContentCount);
+ }
+ break;
+ default:
+ break;
+ }
+ if (winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ tuiDelwin (winInfo->generic.handle);
+ winInfo->generic.handle = (WINDOW *) NULL;
+ winInfo->generic.isVisible = FALSE;
+ }
+
+ return;
+} /* tuiDelWindow */
+
+
+/*
+** freeWindow().
+*/
+void
+#ifdef __STDC__
+freeWindow (
+ TuiWinInfoPtr winInfo)
+#else
+freeWindow (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ Opaque detail;
+ int i;
+ TuiGenWinInfoPtr genericWin;
+
+
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ genericWin = locatorWinInfoPtr ();
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ }
+ freeWinContent (genericWin);
+ genericWin = winInfo->detail.sourceInfo.executionInfo;
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ freeWinContent (genericWin);
+ }
+ break;
+ case DATA_WIN:
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ freeDataContent (
+ winInfo->detail.dataDisplayInfo.regsContent,
+ winInfo->detail.dataDisplayInfo.regsContentCount);
+ winInfo->detail.dataDisplayInfo.regsContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.regsContentCount = 0;
+ freeDataContent (
+ winInfo->detail.dataDisplayInfo.dataContent,
+ winInfo->detail.dataDisplayInfo.dataContentCount);
+ winInfo->detail.dataDisplayInfo.dataContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.dataContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsDisplayType =
+ TUI_UNDEFINED_REGS;
+ winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
+ winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
+ winInfo->generic.content = (OpaquePtr) NULL;
+ winInfo->generic.contentSize = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ if (winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ tuiDelwin (winInfo->generic.handle);
+ winInfo->generic.handle = (WINDOW *) NULL;
+ freeWinContent (&winInfo->generic);
+ }
+ free (winInfo);
+
+ return;
+} /* freeWindow */
+
+
+/*
+** freeAllSourceWinsContent().
+*/
+void
+#ifdef __STDC__
+freeAllSourceWinsContent (void)
+#else
+freeAllSourceWinsContent ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ if (m_winPtrNotNull (winInfo))
+ {
+ freeWinContent (&(winInfo->generic));
+ freeWinContent (winInfo->detail.sourceInfo.executionInfo);
+ }
+ }
+
+ return;
+} /* freeAllSourceWinsContent */
+
+
+/*
+** freeWinContent().
+*/
+void
+#ifdef __STDC__
+freeWinContent (
+ TuiGenWinInfoPtr winInfo)
+#else
+freeWinContent (winInfo)
+ TuiGenWinInfoPtr winInfo;
+#endif
+{
+ if (winInfo->content != (OpaquePtr) NULL)
+ {
+ freeContent ((TuiWinContent) winInfo->content,
+ winInfo->contentSize,
+ winInfo->type);
+ winInfo->content = (OpaquePtr) NULL;
+ }
+ winInfo->contentSize = 0;
+
+ return;
+} /* freeWinContent */
+
+
+/*
+** freeAllWindows().
+*/
+void
+#ifdef __STDC__
+freeAllWindows (void)
+#else
+freeAllWindows ()
+#endif
+{
+ TuiWinType type = SRC_WIN;
+
+ for (; type < MAX_MAJOR_WINDOWS; type++)
+ if (m_winPtrNotNull (winList[type]) &&
+ winList[type]->generic.type != UNDEFINED_WIN)
+ freeWindow (winList[type]);
+ return;
+} /* freeAllWindows */
+
+
+void
+#ifdef __STDC__
+tuiDelDataWindows (
+ TuiWinContent content,
+ int contentSize)
+#else
+tuiDelDataWindows (content, contentSize)
+ TuiWinContent content;
+ int contentSize;
+#endif
+{
+ int i;
+
+ /*
+ ** Remember that data window content elements are of type TuiGenWinInfoPtr,
+ ** each of which whose single element is a data element.
+ */
+ for (i = 0; i < contentSize; i++)
+ {
+ TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow;
+
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ genericWin->isVisible = FALSE;
+ }
+ }
+
+ return;
+} /* tuiDelDataWindows */
+
+
+void
+#ifdef __STDC__
+freeDataContent (
+ TuiWinContent content,
+ int contentSize)
+#else
+freeDataContent (content, contentSize)
+ TuiWinContent content;
+ int contentSize;
+#endif
+{
+ int i;
+
+ /*
+ ** Remember that data window content elements are of type TuiGenWinInfoPtr,
+ ** each of which whose single element is a data element.
+ */
+ for (i = 0; i < contentSize; i++)
+ {
+ TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow;
+
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ freeWinContent (genericWin);
+ }
+ }
+ freeContent (content,
+ contentSize,
+ DATA_WIN);
+
+ return;
+} /* freeDataContent */
+
+
+/**********************************
+** LOCAL STATIC FUNCTIONS **
+**********************************/
+
+
+/*
+** freeContent().
+*/
+static void
+#ifdef __STDC__
+freeContent (
+ TuiWinContent content,
+ int contentSize,
+ TuiWinType winType)
+#else
+freeContent (content, contentSize, winType)
+ TuiWinContent content;
+ int contentSize;
+ TuiWinType winType;
+#endif
+{
+ if (content != (TuiWinContent) NULL)
+ {
+ freeContentElements (content, contentSize, winType);
+ tuiFree ((char *) content);
+ }
+
+ return;
+} /* freeContent */
+
+
+/*
+** freeContentElements().
+*/
+static void
+#ifdef __STDC__
+freeContentElements (
+ TuiWinContent content,
+ int contentSize,
+ TuiWinType type)
+#else
+freeContentElements (content, contentSize, type)
+ TuiWinContent content;
+ int contentSize;
+ TuiWinType type;
+#endif
+{
+ if (content != (TuiWinContent) NULL)
+ {
+ int i;
+
+ if (type == SRC_WIN || type == DISASSEM_WIN)
+ {
+ /* free whole source block */
+ if (content[0]->whichElement.source.line != (char *) NULL)
+ tuiFree (content[0]->whichElement.source.line);
+ }
+ else
+ {
+ for (i = 0; i < contentSize; i++)
+ {
+ TuiWinElementPtr element;
+
+ element = content[i];
+ if (element != (TuiWinElementPtr) NULL)
+ {
+ switch (type)
+ {
+ case DATA_WIN:
+ tuiFree ((char *) element);
+ break;
+ case DATA_ITEM_WIN:
+ /*
+ ** Note that data elements are not allocated
+ ** in a single block, but individually, as needed.
+ */
+ if (element->whichElement.data.type != TUI_REGISTER)
+ tuiFree ((char *)
+ element->whichElement.data.name);
+ tuiFree ((char *) element->whichElement.data.value);
+ tuiFree ((char *) element);
+ break;
+ case CMD_WIN:
+ tuiFree ((char *) element->whichElement.command.line);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ if (type != DATA_WIN && type != DATA_ITEM_WIN)
+ tuiFree ((char *) content[0]); /* free the element block */
+ }
+
+ return;
+} /* freeContentElements */
diff --git a/contrib/gdb/gdb/tui/tuiData.h b/contrib/gdb/gdb/tui/tuiData.h
new file mode 100644
index 0000000..bb4d19c
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiData.h
@@ -0,0 +1,302 @@
+#ifndef TUI_DATA_H
+#define TUI_DATA_H
+
+/* Constant definitions */
+#define DEFAULT_TAB_LEN 8
+#define NO_SRC_STRING "[ No Source Available ]"
+#define NO_DISASSEM_STRING "[ No Assembly Available ]"
+#define NO_REGS_STRING "[ Register Values Unavailable ]"
+#define NO_DATA_STRING "[ No Data Values Displayed ]"
+#define MAX_CONTENT_COUNT 100
+#define SRC_NAME "SRC"
+#define CMD_NAME "CMD"
+#define DATA_NAME "REGS"
+#define DISASSEM_NAME "ASM"
+#define TUI_NULL_STR ""
+#define DEFAULT_HISTORY_COUNT 25
+#define BOX_WINDOW TRUE
+#define DONT_BOX_WINDOW FALSE
+#define HILITE TRUE
+#define NO_HILITE FALSE
+#define WITH_LOCATOR TRUE
+#define NO_LOCATOR FALSE
+#define EMPTY_SOURCE_PROMPT TRUE
+#define NO_EMPTY_SOURCE_PROMPT FALSE
+#define UNDEFINED_ITEM -1
+#define MIN_WIN_HEIGHT 3
+#define MIN_CMD_WIN_HEIGHT 3
+
+#define FILE_PREFIX "File: "
+#define PROC_PREFIX "Procedure: "
+#define LINE_PREFIX "Line: "
+#define PC_PREFIX "pc: "
+
+#define TUI_FLOAT_REGS_NAME "$FREGS"
+#define TUI_FLOAT_REGS_NAME_LOWER "$fregs"
+#define TUI_GENERAL_REGS_NAME "$GREGS"
+#define TUI_GENERAL_REGS_NAME_LOWER "$gregs"
+#define TUI_SPECIAL_REGS_NAME "$SREGS"
+#define TUI_SPECIAL_REGS_NAME_LOWER "$sregs"
+#define TUI_GENERAL_SPECIAL_REGS_NAME "$REGS"
+#define TUI_GENERAL_SPECIAL_REGS_NAME_LOWER "$regs"
+
+/* Scroll direction enum */
+typedef enum {
+ FORWARD_SCROLL,
+ BACKWARD_SCROLL,
+ LEFT_SCROLL,
+ RIGHT_SCROLL
+} TuiScrollDirection, *TuiScrollDirectionPtr;
+
+
+/* General list struct */
+typedef struct _TuiList {
+ OpaqueList list;
+ int count;
+} TuiList, *TuiListPtr;
+
+
+/* The kinds of layouts available */
+typedef enum {
+ SRC_COMMAND,
+ DISASSEM_COMMAND,
+ SRC_DISASSEM_COMMAND,
+ SRC_DATA_COMMAND,
+ DISASSEM_DATA_COMMAND,
+ UNDEFINED_LAYOUT
+} TuiLayoutType, *TuiLayoutTypePtr;
+
+/* Basic data types that can be displayed in the data window. */
+typedef enum _TuiDataType {
+ TUI_REGISTER,
+ TUI_SCALAR,
+ TUI_COMPLEX,
+ TUI_STRUCT
+} TuiDataType, TuiDataTypePtr;
+
+/* Types of register displays */
+typedef enum _TuiRegisterDisplayType {
+ TUI_UNDEFINED_REGS,
+ TUI_GENERAL_REGS,
+ TUI_SFLOAT_REGS,
+ TUI_DFLOAT_REGS,
+ TUI_SPECIAL_REGS,
+ TUI_GENERAL_AND_SPECIAL_REGS
+} TuiRegisterDisplayType, *TuiRegisterDisplayTypePtr;
+
+/* Structure describing source line or line address */
+typedef union _TuiLineOrAddress {
+ int lineNo;
+ Opaque addr;
+} TuiLineOrAddress, *TuiLineOrAddressPtr;
+
+/* Current Layout definition */
+typedef struct _TuiLayoutDef {
+ TuiWinType displayMode;
+ int split;
+ TuiRegisterDisplayType regsDisplayType;
+ TuiRegisterDisplayType floatRegsDisplayType;
+} TuiLayoutDef, *TuiLayoutDefPtr;
+
+/* Elements in the Source/Disassembly Window */
+typedef struct _TuiSourceElement
+{
+ char *line;
+ TuiLineOrAddress lineOrAddr;
+ int isExecPoint;
+ int hasBreak;
+} TuiSourceElement, *TuiSourceElementPtr;
+
+
+/* Elements in the data display window content */
+typedef struct _TuiDataElement
+{
+ char *name;
+ int itemNo; /* the register number, or data display number */
+ TuiDataType type;
+ Opaque value;
+ int highlight;
+} TuiDataElement, *TuiDataElementPtr;
+
+
+/* Elements in the command window content */
+typedef struct _TuiCommandElement
+{
+ char *line;
+} TuiCommandElement, *TuiCommandElementPtr;
+
+
+#define MAX_LOCATOR_ELEMENT_LEN 100
+
+/* Elements in the locator window content */
+typedef struct _TuiLocatorElement
+{
+ char fileName[MAX_LOCATOR_ELEMENT_LEN];
+ char procName[MAX_LOCATOR_ELEMENT_LEN];
+ int lineNo;
+ Opaque addr;
+} TuiLocatorElement, *TuiLocatorElementPtr;
+
+
+/* An content element in a window */
+typedef union
+{
+ TuiSourceElement source; /* the source elements */
+ TuiGenWinInfo dataWindow; /* data display elements */
+ TuiDataElement data; /* elements of dataWindow */
+ TuiCommandElement command; /* command elements */
+ TuiLocatorElement locator; /* locator elements */
+ char *simpleString; /* simple char based elements */
+} TuiWhichElement, *TuiWhichElementPtr;
+
+typedef struct _TuiWinElement
+{
+ int highlight;
+ TuiWhichElement whichElement;
+} TuiWinElement, *TuiWinElementPtr;
+
+
+/* This describes the content of the window. */
+typedef TuiWinElementPtr *TuiWinContent;
+
+
+/* This struct defines the specific information about a data display window */
+typedef struct _TuiDataInfo {
+ TuiWinContent dataContent; /* start of data display content */
+ int dataContentCount;
+ TuiWinContent regsContent; /* start of regs display content */
+ int regsContentCount;
+ TuiRegisterDisplayType regsDisplayType;
+ int regsColumnCount;
+ int displayRegs; /* Should regs be displayed at all? */
+} TuiDataInfo, *TuiDataInfoPtr;
+
+
+typedef struct _TuiSourceInfo {
+ int hasLocator; /* Does locator belongs to this window? */
+ TuiGenWinInfoPtr executionInfo; /* execution information window */
+ int horizontalOffset; /* used for horizontal scroll */
+ TuiLineOrAddress startLineOrAddr;
+} TuiSourceInfo, *TuiSourceInfoPtr;
+
+
+typedef struct _TuiCommandInfo {
+ int curLine; /* The current line position */
+ int curch; /* The current cursor position */
+} TuiCommandInfo, *TuiCommandInfoPtr;
+
+
+/* This defines information about each logical window */
+typedef struct _TuiWinInfo {
+ TuiGenWinInfo generic; /* general window information */
+ union {
+ TuiSourceInfo sourceInfo;
+ TuiDataInfo dataDisplayInfo;
+ TuiCommandInfo commandInfo;
+ Opaque opaque;
+ } detail;
+ int canHighlight; /* Can this window ever be highlighted? */
+ int isHighlighted; /* Is this window highlighted? */
+} TuiWinInfo, *TuiWinInfoPtr;
+
+/* MACROS (prefixed with m_) */
+
+/* Testing macros */
+#define m_genWinPtrIsNull(winInfo) \
+ ((winInfo) == (TuiGenWinInfoPtr)NULL)
+#define m_genWinPtrNotNull(winInfo) \
+ ((winInfo) != (TuiGenWinInfoPtr)NULL)
+#define m_winPtrIsNull(winInfo) \
+ ((winInfo) == (TuiWinInfoPtr)NULL)
+#define m_winPtrNotNull(winInfo) \
+ ((winInfo) != (TuiWinInfoPtr)NULL)
+
+#define m_winIsSourceType(type) \
+ (type == SRC_WIN || type == DISASSEM_WIN)
+#define m_winIsAuxillary(winType) \
+ (winType > MAX_MAJOR_WINDOWS)
+#define m_hasLocator(winInfo) \
+ ( ((winInfo) != (TuiWinInfoPtr)NULL) ? \
+ (winInfo->detail.sourceInfo.hasLocator) : \
+ FALSE )
+
+#define m_setWinHighlightOn(winInfo) \
+ if ((winInfo) != (TuiWinInfoPtr)NULL) \
+ (winInfo)->isHighlighted = TRUE
+#define m_setWinHighlightOff(winInfo) \
+ if ((winInfo) != (TuiWinInfoPtr)NULL) \
+ (winInfo)->isHighlighted = FALSE
+
+
+/* Global Data */
+extern TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS];
+extern int tui_version;
+
+/* Macros */
+#define srcWin winList[SRC_WIN]
+#define disassemWin winList[DISASSEM_WIN]
+#define dataWin winList[DATA_WIN]
+#define cmdWin winList[CMD_WIN]
+
+/* Data Manipulation Functions */
+extern void initializeStaticData PARAMS ((void));
+extern TuiGenWinInfoPtr allocGenericWinInfo PARAMS ((void));
+extern TuiWinInfoPtr allocWinInfo PARAMS ((TuiWinType));
+extern void initGenericPart PARAMS ((TuiGenWinInfoPtr));
+extern void initWinInfo PARAMS ((TuiWinInfoPtr));
+extern TuiWinContent allocContent PARAMS ((int, TuiWinType));
+extern int addContentElements
+ PARAMS ((TuiGenWinInfoPtr, int));
+extern void initContentElement
+ PARAMS ((TuiWinElementPtr, TuiWinType));
+extern void freeWindow PARAMS ((TuiWinInfoPtr));
+extern void freeAllWindows PARAMS ((void));
+extern void freeWinContent PARAMS ((TuiGenWinInfoPtr));
+extern void freeDataContent PARAMS ((TuiWinContent, int));
+extern void freeAllSourceWinsContent PARAMS ((void));
+extern void tuiDelWindow PARAMS ((TuiWinInfoPtr));
+extern void tuiDelDataWindows PARAMS ((TuiWinContent, int));
+extern TuiWinInfoPtr winByName PARAMS ((char *));
+extern TuiWinInfoPtr partialWinByName PARAMS ((char *));
+extern char *winName PARAMS ((TuiGenWinInfoPtr));
+extern char *displayableWinContentOf
+ PARAMS ((TuiGenWinInfoPtr, TuiWinElementPtr));
+extern char *displayableWinContentAt
+ PARAMS ((TuiGenWinInfoPtr, int));
+extern int winElementHeight
+ PARAMS ((TuiGenWinInfoPtr, TuiWinElementPtr));
+extern TuiLayoutType currentLayout PARAMS ((void));
+extern void setCurrentLayoutTo PARAMS ((TuiLayoutType));
+extern int termHeight PARAMS ((void));
+extern void setTermHeight PARAMS ((int));
+extern int termWidth PARAMS ((void));
+extern void setTermWidth PARAMS ((int));
+extern int historyLimit PARAMS ((void));
+extern void setHistoryLimit PARAMS ((int));
+extern void setGenWinOrigin PARAMS ((TuiGenWinInfoPtr, int, int));
+extern TuiGenWinInfoPtr locatorWinInfoPtr PARAMS ((void));
+extern TuiGenWinInfoPtr sourceExecInfoWinPtr PARAMS ((void));
+extern TuiGenWinInfoPtr disassemExecInfoWinPtr PARAMS ((void));
+extern char *nullStr PARAMS ((void));
+extern char *blankStr PARAMS ((void));
+extern char *locationStr PARAMS ((void));
+extern char *breakStr PARAMS ((void));
+extern char *breakLocationStr PARAMS ((void));
+extern TuiListPtr sourceWindows PARAMS ((void));
+extern void clearSourceWindows PARAMS ((void));
+extern void clearSourceWindowsDetail PARAMS ((void));
+extern void clearWinDetail PARAMS ((TuiWinInfoPtr winInfo));
+extern void tuiAddToSourceWindows PARAMS ((TuiWinInfoPtr));
+extern int tuiDefaultTabLen PARAMS ((void));
+extern void tuiSetDefaultTabLen PARAMS ((int));
+extern TuiWinInfoPtr tuiWinWithFocus PARAMS ((void));
+extern void tuiSetWinWithFocus PARAMS ((TuiWinInfoPtr));
+extern TuiLayoutDefPtr tuiLayoutDef PARAMS ((void));
+extern int tuiWinResized PARAMS ((void));
+extern void tuiSetWinResizedTo PARAMS ((int));
+
+extern TuiWinInfoPtr tuiNextWin PARAMS ((TuiWinInfoPtr));
+extern TuiWinInfoPtr tuiPrevWin PARAMS ((TuiWinInfoPtr));
+
+
+#endif /* TUI_DATA_H */
diff --git a/contrib/gdb/gdb/tui/tuiDataWin.c b/contrib/gdb/gdb/tui/tuiDataWin.c
new file mode 100644
index 0000000..522730a
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiDataWin.c
@@ -0,0 +1,400 @@
+/*
+** tuiDataWin.c
+** This module contains functions to support the data/register window display.
+*/
+
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiRegs.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+
+/*
+** tuiFirstDataItemDisplayed()
+** Answer the index first element displayed.
+** If none are displayed, then return (-1).
+*/
+int
+#ifdef __STDC__
+tuiFirstDataItemDisplayed (void)
+#else
+tuiFirstDataItemDisplayed ()
+#endif
+{
+ int elementNo = (-1);
+ int i;
+
+ for (i = 0; (i < dataWin->generic.contentSize && elementNo < 0); i++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+
+ dataItemWin = &((TuiWinContent)
+ dataWin->generic.content)[i]->whichElement.dataWindow;
+ if (dataItemWin->handle != (WINDOW *) NULL && dataItemWin->isVisible)
+ elementNo = i;
+ }
+
+ return elementNo;
+} /* tuiFirstDataItemDisplayed */
+
+
+/*
+** tuiFirstDataElementNoInLine()
+** Answer the index of the first element in lineNo. If lineNo is
+** past the data area (-1) is returned.
+*/
+int
+#ifdef __STDC__
+tuiFirstDataElementNoInLine (
+ int lineNo)
+#else
+tuiFirstDataElementNoInLine (lineNo)
+ int lineNo;
+#endif
+{
+ int firstElementNo = (-1);
+
+ /*
+ ** First see if there is a register on lineNo, and if so, set the
+ ** first element number
+ */
+ if ((firstElementNo = tuiFirstRegElementNoInLine (lineNo)) == -1)
+ { /*
+ ** Looking at the general data, the 1st element on lineNo
+ */
+ }
+
+ return firstElementNo;
+} /* tuiFirstDataElementNoInLine */
+
+
+/*
+** tuiDeleteDataContentWindows()
+** Function to delete all the item windows in the data window.
+** This is usually done when the data window is scrolled.
+*/
+void
+#ifdef __STDC__
+tuiDeleteDataContentWindows (void)
+#else
+tuiDeleteDataContentWindows ()
+#endif
+{
+ int i;
+ TuiGenWinInfoPtr dataItemWinPtr;
+
+ for (i = 0; (i < dataWin->generic.contentSize); i++)
+ {
+ dataItemWinPtr = &((TuiWinContent)
+ dataWin->generic.content)[i]->whichElement.dataWindow;
+ tuiDelwin (dataItemWinPtr->handle);
+ dataItemWinPtr->handle = (WINDOW *) NULL;
+ dataItemWinPtr->isVisible = FALSE;
+ }
+
+ return;
+} /* tuiDeleteDataContentWindows */
+
+
+void
+#ifdef __STDC__
+tuiEraseDataContent (
+ char *prompt)
+#else
+tuiEraseDataContent (prompt)
+ char *prompt;
+#endif
+{
+ werase (dataWin->generic.handle);
+ checkAndDisplayHighlightIfNeeded (dataWin);
+ if (prompt != (char *) NULL)
+ {
+ int halfWidth = (dataWin->generic.width - 2) / 2;
+ int xPos;
+
+ if (strlen (prompt) >= halfWidth)
+ xPos = 1;
+ else
+ xPos = halfWidth - strlen (prompt);
+ mvwaddstr (dataWin->generic.handle,
+ (dataWin->generic.height / 2),
+ xPos,
+ prompt);
+ }
+ wrefresh (dataWin->generic.handle);
+
+ return;
+} /* tuiEraseDataContent */
+
+
+/*
+** tuiDisplayAllData().
+** This function displays the data that is in the data window's
+** content. It does not set the content.
+*/
+void
+#ifdef __STDC__
+tuiDisplayAllData (void)
+#else
+tuiDisplayAllData ()
+#endif
+{
+ if (dataWin->generic.contentSize <= 0)
+ tuiEraseDataContent (NO_DATA_STRING);
+ else
+ {
+ tuiEraseDataContent ((char *) NULL);
+ tuiDeleteDataContentWindows ();
+ checkAndDisplayHighlightIfNeeded (dataWin);
+ tuiDisplayRegistersFrom (0);
+ /*
+ ** Then display the other data
+ */
+ if (dataWin->detail.dataDisplayInfo.dataContent !=
+ (TuiWinContent) NULL &&
+ dataWin->detail.dataDisplayInfo.dataContentCount > 0)
+ {
+ }
+ }
+ return;
+} /* tuiDisplayAllData */
+
+
+/*
+** tuiDisplayDataFromLine()
+** Function to display the data starting at line, lineNo, in the
+** data window.
+*/
+void
+#ifdef __STDC__
+tuiDisplayDataFromLine (
+ int lineNo)
+#else
+tuiDisplayDataFromLine (lineNo)
+ int lineNo;
+#endif
+{
+ int _lineNo = lineNo;
+
+ if (lineNo < 0)
+ _lineNo = 0;
+
+ checkAndDisplayHighlightIfNeeded (dataWin);
+
+ /* there is no general data, force regs to display (if there are any) */
+ if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0)
+ tuiDisplayRegistersFromLine (_lineNo, TRUE);
+ else
+ {
+ int elementNo, startLineNo;
+ int regsLastLine = tuiLastRegsLineNo ();
+
+
+ /* display regs if we can */
+ if (tuiDisplayRegistersFromLine (_lineNo, FALSE) < 0)
+ { /*
+ ** _lineNo is past the regs display, so calc where the
+ ** start data element is
+ */
+ if (regsLastLine < _lineNo)
+ { /* figure out how many lines each element is to obtain
+ the start elementNo */
+ }
+ }
+ else
+ { /*
+ ** calculate the starting element of the data display, given
+ ** regsLastLine and how many lines each element is, up to
+ ** _lineNo
+ */
+ }
+ /* Now display the data , starting at elementNo */
+ }
+
+ return;
+} /* tuiDisplayDataFromLine */
+
+
+/*
+** tuiDisplayDataFrom()
+** Display data starting at element elementNo
+*/
+void
+#ifdef __STDC__
+tuiDisplayDataFrom (
+ int elementNo,
+ int reuseWindows)
+#else
+tuiDisplayDataFrom (elementNo, reuseWindows)
+ int elementNo;
+ int reuseWindows;
+#endif
+{
+ int firstLine = (-1);
+
+ if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ firstLine = tuiLineFromRegElementNo (elementNo);
+ else
+ { /* calculate the firstLine from the element number */
+ }
+
+ if (firstLine >= 0)
+ {
+ tuiEraseDataContent ((char *) NULL);
+ if (!reuseWindows)
+ tuiDeleteDataContentWindows ();
+ tuiDisplayDataFromLine (firstLine);
+ }
+
+ return;
+} /* tuiDisplayDataFrom */
+
+
+/*
+** tuiRefreshDataWin()
+** Function to redisplay the contents of the data window.
+*/
+void
+#ifdef __STDC__
+tuiRefreshDataWin (void)
+#else
+tuiRefreshDataWin ()
+#endif
+{
+ tuiEraseDataContent ((char *) NULL);
+ if (dataWin->generic.contentSize > 0)
+ {
+ int firstElement = tuiFirstDataItemDisplayed ();
+
+ if (firstElement >= 0) /* re-use existing windows */
+ tuiDisplayDataFrom (firstElement, TRUE);
+ }
+
+ return;
+} /* tuiRefreshDataWin */
+
+
+/*
+** tuiCheckDataValues().
+** Function to check the data values and hilite any that have changed
+*/
+void
+#ifdef __STDC__
+tuiCheckDataValues (
+ struct frame_info *frame)
+#else
+tuiCheckDataValues (frame)
+ struct frame_info *frame;
+#endif
+{
+ tuiCheckRegisterValues (frame);
+
+ /* Now check any other data values that there are */
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ {
+ int i;
+
+ for (i = 0; dataWin->detail.dataDisplayInfo.dataContentCount; i++)
+ {
+#ifdef LATER
+ TuiDataElementPtr dataElementPtr;
+ TuiGenWinInfoPtr dataItemWinPtr;
+ Opaque newValue;
+
+ dataItemPtr = &dataWin->detail.dataDisplayInfo.
+ dataContent[i]->whichElement.dataWindow;
+ dataElementPtr = &((TuiWinContent)
+ dataItemWinPtr->content)[0]->whichElement.data;
+ if value
+ has changed (dataElementPtr, frame, &newValue)
+ {
+ dataElementPtr->value = newValue;
+ update the display with the new value, hiliting it.
+ }
+#endif
+ }
+ }
+} /* tuiCheckDataValues */
+
+
+/*
+** tui_vCheckDataValues().
+** Function to check the data values and hilite any that have
+** changed with args in a va_list
+*/
+void
+#ifdef __STDC__
+tui_vCheckDataValues (
+ va_list args)
+#else
+tui_vCheckDataValues (args)
+ va_list args;
+#endif
+{
+ struct frame_info *frame = va_arg (args, struct frame_info *);
+
+ tuiCheckDataValues (frame);
+
+ return;
+} /* tui_vCheckDataValues */
+
+
+/*
+** tuiVerticalDataScroll()
+** Scroll the data window vertically forward or backward.
+*/
+void
+#ifdef __STDC__
+tuiVerticalDataScroll (
+ TuiScrollDirection scrollDirection,
+ int numToScroll)
+#else
+tuiVerticalDataScroll (scrollDirection, numToScroll)
+ TuiScrollDirection scrollDirection;
+ int numToScroll;
+#endif
+{
+ int firstElementNo;
+ int firstLine = (-1);
+
+ firstElementNo = tuiFirstDataItemDisplayed ();
+ if (firstElementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ firstLine = tuiLineFromRegElementNo (firstElementNo);
+ else
+ { /* calculate the first line from the element number which is in
+ ** the general data content
+ */
+ }
+
+ if (firstLine >= 0)
+ {
+ int lastElementNo, lastLine;
+
+ if (scrollDirection == FORWARD_SCROLL)
+ firstLine += numToScroll;
+ else
+ firstLine -= numToScroll;
+ tuiEraseDataContent ((char *) NULL);
+ tuiDeleteDataContentWindows ();
+ tuiDisplayDataFromLine (firstLine);
+ }
+
+ return;
+} /* tuiVerticalDataScroll */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
diff --git a/contrib/gdb/gdb/tui/tuiDataWin.h b/contrib/gdb/gdb/tui/tuiDataWin.h
new file mode 100644
index 0000000..8f9e46d
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiDataWin.h
@@ -0,0 +1,29 @@
+#ifndef _TUI_DATAWIN_H
+#define _TUI_DATAWIN_H
+/*
+** This header file supports the display of registers/data in the data window.
+*/
+
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern void tuiEraseDataContent PARAMS ((char *));
+extern void tuiDisplayAllData PARAMS ((void));
+extern void tuiCheckDataValues PARAMS ((struct frame_info *));
+extern void tui_vCheckDataValues PARAMS ((va_list));
+extern void tuiDisplayDataFromLine PARAMS ((int));
+extern int tuiFirstDataItemDisplayed PARAMS ((void));
+extern int tuiFirstDataElementNoInLine PARAMS ((int));
+extern void tuiDeleteDataContentWindows PARAMS ((void));
+extern void tuiRefreshDataWin PARAMS ((void));
+extern void tuiDisplayDataFrom PARAMS ((int, int));
+extern void tuiVerticalDataScroll PARAMS ((TuiScrollDirection, int));
+
+#endif /*_TUI_DATAWIN_H*/
diff --git a/contrib/gdb/gdb/tui/tuiDisassem.c b/contrib/gdb/gdb/tui/tuiDisassem.c
new file mode 100644
index 0000000..ad0b70f
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiDisassem.c
@@ -0,0 +1,343 @@
+/*
+** tuiDisassem.c
+** This module contains functions for handling disassembly display.
+*/
+
+
+#include "defs.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "frame.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiLayout.h"
+#include "tuiSourceWin.h"
+#include "tuiStack.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+static struct breakpoint *_hasBreak PARAMS ((CORE_ADDR));
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*
+** tuiSetDisassemContent().
+** Function to set the disassembly window's content.
+*/
+TuiStatus
+#ifdef __STDC__
+tuiSetDisassemContent (
+ struct symtab *s,
+ Opaque startAddr)
+#else
+ tuiSetDisassemContent (s, startAddr)
+ struct symtab *s;
+ Opaque startAddr;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+ GDB_FILE *gdb_dis_out;
+
+ if (startAddr != (Opaque) NULL)
+ {
+ register int i, desc;
+
+ if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS)
+ {
+ register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
+ register int threshold, curLine = 0, lineWidth, maxLines;
+ CORE_ADDR newpc, pc;
+ disassemble_info asmInfo;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ extern void strcat_address PARAMS ((CORE_ADDR, char *, int));
+ extern void strcat_address_numeric PARAMS ((CORE_ADDR, int, char *, int));
+ int curLen = 0;
+ int tab_len = tuiDefaultTabLen ();
+
+ maxLines = disassemWin->generic.height - 2; /* account for hilite */
+ lineWidth = disassemWin->generic.width - 1;
+ threshold = (lineWidth - 1) + offset;
+
+ /* now init the gdb_file structure */
+ gdb_dis_out = gdb_file_init_astring (threshold);
+
+ INIT_DISASSEMBLE_INFO_NO_ARCH (asmInfo, gdb_dis_out, (fprintf_ftype) fprintf_filtered);
+ asmInfo.read_memory_func = dis_asm_read_memory;
+ asmInfo.memory_error_func = dis_asm_memory_error;
+
+ disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
+
+ /* Now construct each line */
+ for (curLine = 0, pc = (CORE_ADDR) startAddr; (curLine < maxLines);)
+ {
+ TuiWinElementPtr element = (TuiWinElementPtr)disassemWin->generic.content[curLine];
+ struct breakpoint *bp;
+
+ print_address (pc, gdb_dis_out);
+
+ curLen = strlen (gdb_file_get_strbuf (gdb_dis_out));
+ i = curLen - ((curLen / tab_len) * tab_len);
+
+ /* adjust buffer length if necessary */
+ gdb_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i ) : 0, gdb_dis_out);
+
+ /* Add spaces to make the instructions start onthe same column */
+ while (i < tab_len)
+ {
+ gdb_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
+ i++;
+ curLen++;
+ }
+ gdb_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
+
+ newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
+
+ /* Now copy the line taking the offset into account */
+ if (strlen (gdb_file_get_strbuf (gdb_dis_out)) > offset)
+ strcpy (element->whichElement.source.line,
+ &(gdb_file_get_strbuf (gdb_dis_out)[offset]));
+ else
+ element->whichElement.source.line[0] = '\0';
+ element->whichElement.source.lineOrAddr.addr = (Opaque) pc;
+ element->whichElement.source.isExecPoint =
+ (pc == (CORE_ADDR) ((TuiWinElementPtr)locator->content[0])->whichElement.locator.addr);
+ bp = _hasBreak (pc);
+ element->whichElement.source.hasBreak =
+ (bp != (struct breakpoint *) NULL &&
+ (!element->whichElement.source.isExecPoint ||
+ (bp->disposition != del || bp->hit_count <= 0)));
+ curLine++;
+ pc = newpc;
+ /* reset the buffer to empty */
+ gdb_file_get_strbuf (gdb_dis_out)[0] = '\0';
+ }
+ gdb_file_deallocate (&gdb_dis_out);
+ disassemWin->generic.contentSize = curLine;
+ ret = TUI_SUCCESS;
+ }
+ }
+
+ return ret;
+} /* tuiSetDisassemContent */
+
+
+/*
+** tuiShowDisassem().
+** Function to display the disassembly window with disassembled code.
+*/
+void
+#ifdef __STDC__
+tuiShowDisassem (
+ Opaque startAddr)
+#else
+tuiShowDisassem (startAddr)
+ Opaque startAddr;
+#endif
+{
+ struct symtab *s = find_pc_symtab ((CORE_ADDR) startAddr);
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+
+ tuiAddWinToLayout (DISASSEM_WIN);
+ tuiUpdateSourceWindow (disassemWin, s, startAddr, FALSE);
+ /*
+ ** if the focus was in the src win, put it in the asm win, if the
+ ** source view isn't split
+ */
+ if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
+ tuiSetWinFocusTo (disassemWin);
+
+ return;
+} /* tuiShowDisassem */
+
+
+/*
+** tuiShowDisassemAndUpdateSource().
+** Function to display the disassembly window.
+*/
+void
+#ifdef __STDC__
+tuiShowDisassemAndUpdateSource (
+ Opaque startAddr)
+#else
+tuiShowDisassemAndUpdateSource (startAddr)
+ Opaque startAddr;
+#endif
+{
+ struct symtab_and_line sal;
+
+ tuiShowDisassem (startAddr);
+ if (currentLayout () == SRC_DISASSEM_COMMAND)
+ {
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ /*
+ ** Update what is in the source window if it is displayed too,
+ ** note that it follows what is in the disassembly window and visa-versa
+ */
+ sal = find_pc_line ((CORE_ADDR) startAddr, 0);
+ current_source_symtab = sal.symtab;
+ tuiUpdateSourceWindow (srcWin, sal.symtab, (Opaque) sal.line, TRUE);
+ tuiUpdateLocatorFilename (sal.symtab->filename);
+ }
+
+ return;
+} /* tuiShowDisassemAndUpdateSource */
+
+
+/*
+** tuiShowDisassemAsIs().
+** Function to display the disassembly window. This function shows
+** the disassembly as specified by the horizontal offset.
+*/
+void
+#ifdef __STDC__
+tuiShowDisassemAsIs (
+ Opaque addr)
+#else
+tuiShowDisassemAsIs (addr)
+ Opaque addr;
+#endif
+{
+ tuiAddWinToLayout (DISASSEM_WIN);
+ tuiUpdateSourceWindowAsIs (disassemWin, (struct symtab *) NULL, addr, FALSE);
+ /*
+ ** Update what is in the source window if it is displayed too, not that it
+ ** follows what is in the disassembly window and visa-versa
+ */
+ if (currentLayout () == SRC_DISASSEM_COMMAND)
+ tuiShowSourceContent (srcWin); /*???? Need to do more? */
+
+ return;
+} /* tuiShowDisassem */
+
+
+/*
+** tuiGetBeginAsmAddress().
+*/
+Opaque
+#ifdef __STDC__
+tuiGetBeginAsmAddress (void)
+#else
+tuiGetBeginAsmAddress ()
+#endif
+{
+ TuiGenWinInfoPtr locator;
+ TuiLocatorElementPtr element;
+ Opaque addr;
+
+ locator = locatorWinInfoPtr ();
+ element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
+
+ if (element->addr == (Opaque) 0)
+ {
+ /*the target is not executing, because the pc is 0*/
+
+ addr = (Opaque) parse_and_eval_address ("main");
+
+ if (addr == (Opaque) 0)
+ addr = (Opaque) parse_and_eval_address ("MAIN");
+
+ }
+ else /* the target is executing */
+ addr = element->addr;
+
+ return addr;
+} /* tuiGetBeginAsmAddress */
+
+
+/*
+** tuiVerticalDisassemScroll().
+** Scroll the disassembly forward or backward vertically
+*/
+void
+#ifdef __STDC__
+tuiVerticalDisassemScroll (
+ TuiScrollDirection scrollDirection,
+ int numToScroll)
+#else
+tuiVerticalDisassemScroll (scrollDirection, numToScroll)
+ TuiScrollDirection scrollDirection;
+ int numToScroll;
+#endif
+{
+ if (disassemWin->generic.content != (OpaquePtr) NULL)
+ {
+ Opaque pc, lowAddr;
+ TuiWinContent content;
+ struct symtab *s;
+
+ content = (TuiWinContent) disassemWin->generic.content;
+ if (current_source_symtab == (struct symtab *) NULL)
+ s = find_pc_symtab (selected_frame->pc);
+ else
+ s = current_source_symtab;
+
+ pc = content[0]->whichElement.source.lineOrAddr.addr;
+ if (find_pc_partial_function ((CORE_ADDR) pc,
+ (char **) NULL,
+ (CORE_ADDR *) & lowAddr,
+ (CORE_ADDR) NULL) == 0)
+ error ("No function contains prgram counter for selected frame.\n");
+ else
+ {
+ register int line = 0;
+ register Opaque newLow;
+ bfd_byte buffer[4];
+
+ newLow = pc;
+ if (scrollDirection == FORWARD_SCROLL)
+ {
+ for (; line < numToScroll; line++)
+ newLow += sizeof (bfd_getb32 (buffer));
+ }
+ else
+ {
+ for (; newLow >= (Opaque) 0 && line < numToScroll; line++)
+ newLow -= sizeof (bfd_getb32 (buffer));
+ }
+ tuiUpdateSourceWindowAsIs (disassemWin, s, newLow, FALSE);
+ }
+ }
+
+ return;
+} /* tuiVerticalDisassemScroll */
+
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+/*
+** _hasBreak().
+** Answer whether there is a break point at the input line in the
+** source file indicated
+*/
+static struct breakpoint *
+#ifdef __STDC__
+_hasBreak (
+ CORE_ADDR addr)
+#else
+_hasBreak (addr)
+ CORE_ADDR addr;
+#endif
+{
+ struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
+ struct breakpoint *bp;
+ extern struct breakpoint *breakpoint_chain;
+
+
+ for (bp = breakpoint_chain;
+ (bp != (struct breakpoint *) NULL &&
+ bpWithBreak == (struct breakpoint *) NULL);
+ bp = bp->next)
+ if (addr == bp->address)
+ bpWithBreak = bp;
+
+ return bpWithBreak;
+} /* _hasBreak */
diff --git a/contrib/gdb/gdb/tui/tuiDisassem.h b/contrib/gdb/gdb/tui/tuiDisassem.h
new file mode 100644
index 0000000..711ac48
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiDisassem.h
@@ -0,0 +1,22 @@
+#ifndef _TUI_DISASSEM_H
+#define _TUI_DISASSEM_H
+/*
+** This header file supports
+*/
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern TuiStatus tuiSetDisassemContent PARAMS ((struct symtab *, Opaque));
+extern void tuiShowDisassem PARAMS ((Opaque));
+extern void tuiShowDisassemAndUpdateSource PARAMS ((Opaque));
+extern void tuiVerticalDisassemScroll PARAMS ((TuiScrollDirection, int));
+extern Opaque tuiGetBeginAsmAddress PARAMS ((void));
+
+#endif /*_TUI_DISASSEM_H*/
diff --git a/contrib/gdb/gdb/tui/tuiGeneralWin.c b/contrib/gdb/gdb/tui/tuiGeneralWin.c
new file mode 100644
index 0000000..5af0cd7
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiGeneralWin.c
@@ -0,0 +1,469 @@
+/*
+** TuiGeneralWin.c
+** This module supports general window behavior
+*/
+
+#include <curses.h>
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+
+
+/*
+** local support functions
+*/
+static void _winResize PARAMS ((void));
+
+
+/***********************
+** PUBLIC FUNCTIONS
+***********************/
+/*
+** tuiRefreshWin()
+** Refresh the window
+*/
+void
+#ifdef __STDC__
+tuiRefreshWin (
+ TuiGenWinInfoPtr winInfo)
+#else
+tuiRefreshWin (winInfo)
+ TuiGenWinInfoPtr winInfo;
+#endif
+{
+ if (winInfo->type == DATA_WIN && winInfo->contentSize > 0)
+ {
+ int i;
+
+ for (i = 0; (i < winInfo->contentSize); i++)
+ {
+ TuiGenWinInfoPtr dataItemWinPtr;
+
+ dataItemWinPtr = &((TuiWinContent)
+ winInfo->content)[i]->whichElement.dataWindow;
+ if (m_genWinPtrNotNull (dataItemWinPtr) &&
+ dataItemWinPtr->handle != (WINDOW *) NULL)
+ wrefresh (dataItemWinPtr->handle);
+ }
+ }
+ else if (winInfo->type == CMD_WIN)
+ {
+ /* Do nothing */
+ }
+ else
+ {
+ if (winInfo->handle != (WINDOW *) NULL)
+ wrefresh (winInfo->handle);
+ }
+
+ return;
+} /* tuiRefreshWin */
+
+
+/*
+** tuiDelwin()
+** Function to delete the curses window, checking for null
+*/
+void
+#ifdef __STDC__
+tuiDelwin (
+ WINDOW * window)
+#else
+tuiDelwin (window)
+ WINDOW *window;
+#endif
+{
+ if (window != (WINDOW *) NULL)
+ delwin (window);
+
+ return;
+} /* tuiDelwin */
+
+
+/*
+** boxWin().
+*/
+void
+#ifdef __STDC__
+boxWin (
+ TuiGenWinInfoPtr winInfo,
+ int highlightFlag)
+#else
+boxWin (winInfo, highlightFlag)
+ TuiGenWinInfoPtr winInfo;
+ int highlightFlag;
+#endif
+{
+ if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL)
+ {
+ if (highlightFlag == HILITE)
+ box (winInfo->handle, '|', '-');
+ else
+ {
+/* wattron(winInfo->handle, A_DIM);*/
+ box (winInfo->handle, ':', '.');
+/* wattroff(winInfo->handle, A_DIM);*/
+ }
+ }
+
+ return;
+} /* boxWin */
+
+
+/*
+** unhighlightWin().
+*/
+void
+#ifdef __STDC__
+unhighlightWin (
+ TuiWinInfoPtr winInfo)
+#else
+unhighlightWin (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (m_winPtrNotNull (winInfo) && winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ boxWin ((TuiGenWinInfoPtr) winInfo, NO_HILITE);
+ wrefresh (winInfo->generic.handle);
+ m_setWinHighlightOff (winInfo);
+ }
+} /* unhighlightWin */
+
+
+/*
+** highlightWin().
+*/
+void
+#ifdef __STDC__
+highlightWin (
+ TuiWinInfoPtr winInfo)
+#else
+highlightWin (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (m_winPtrNotNull (winInfo) &&
+ winInfo->canHighlight && winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ boxWin ((TuiGenWinInfoPtr) winInfo, HILITE);
+ wrefresh (winInfo->generic.handle);
+ m_setWinHighlightOn (winInfo);
+ }
+} /* highlightWin */
+
+
+/*
+** checkAndDisplayHighlightIfNecessay
+*/
+void
+#ifdef __STDC__
+checkAndDisplayHighlightIfNeeded (
+ TuiWinInfoPtr winInfo)
+#else
+checkAndDisplayHighlightIfNeeded (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (m_winPtrNotNull (winInfo) && winInfo->generic.type != CMD_WIN)
+ {
+ if (winInfo->isHighlighted)
+ highlightWin (winInfo);
+ else
+ unhighlightWin (winInfo);
+
+ }
+ return;
+} /* checkAndDisplayHighlightIfNeeded */
+
+
+/*
+** makeWindow().
+*/
+void
+#ifdef __STDC__
+makeWindow (
+ TuiGenWinInfoPtr winInfo,
+ int boxIt)
+#else
+makeWindow (winInfo, boxIt)
+ TuiGenWinInfoPtr winInfo;
+ int boxIt;
+#endif
+{
+ WINDOW *handle;
+
+ handle = newwin (winInfo->height,
+ winInfo->width,
+ winInfo->origin.y,
+ winInfo->origin.x);
+ winInfo->handle = handle;
+ if (handle != (WINDOW *) NULL)
+ {
+ if (boxIt == BOX_WINDOW)
+ boxWin (winInfo, NO_HILITE);
+ winInfo->isVisible = TRUE;
+ scrollok (handle, TRUE);
+ tuiRefreshWin (winInfo);
+
+#ifndef FOR_TEST
+ if ( /*!m_WinIsAuxillary(winInfo->type) && */
+ (winInfo->type != CMD_WIN) &&
+ (winInfo->content == (OpaquePtr) NULL))
+ {
+ mvwaddstr (handle, 1, 1, winName (winInfo));
+ tuiRefreshWin (winInfo);
+ }
+#endif /*FOR_TEST*/
+ }
+
+ return;
+} /* makeWindow */
+
+
+/*
+** tuiClearWin().
+** Clear the window of all contents without calling wclear.
+*/
+void
+#ifdef __STDC__
+tuiClearWin (
+ TuiGenWinInfoPtr winInfo)
+#else
+tuiClearWin (winInfo)
+ TuiGenWinInfoPtr winInfo;
+#endif
+{
+ if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL)
+ {
+ int curRow, curCol;
+
+ for (curRow = 0; (curRow < winInfo->height); curRow++)
+ for (curCol = 0; (curCol < winInfo->width); curCol++)
+ mvwaddch (winInfo->handle, curRow, curCol, ' ');
+
+ tuiRefreshWin (winInfo);
+ }
+
+ return;
+} /* tuiClearWin */
+
+
+/*
+** makeVisible().
+** We can't really make windows visible, or invisible. So we
+** have to delete the entire window when making it visible,
+** and create it again when making it visible.
+*/
+void
+#ifdef __STDC__
+makeVisible (
+ TuiGenWinInfoPtr winInfo,
+ int visible)
+#else
+makeVisible (winInfo, visible)
+ TuiGenWinInfoPtr winInfo;
+ int visible;
+#endif
+{
+ /* Don't tear down/recreate command window */
+ if (winInfo->type == CMD_WIN)
+ return;
+
+ if (visible)
+ {
+ if (!winInfo->isVisible)
+ {
+ makeWindow (
+ winInfo,
+ (winInfo->type != CMD_WIN && !m_winIsAuxillary (winInfo->type)));
+ winInfo->isVisible = TRUE;
+ }
+ tuiRefreshWin (winInfo);
+ }
+ else if (!visible &&
+ winInfo->isVisible && winInfo->handle != (WINDOW *) NULL)
+ {
+ winInfo->isVisible = FALSE;
+ tuiClearWin (winInfo);
+ tuiDelwin (winInfo->handle);
+ winInfo->handle = (WINDOW *) NULL;
+ }
+
+ return;
+} /* makeVisible */
+
+
+/*
+** makeAllVisible().
+** Makes all windows invisible (except the command and locator windows)
+*/
+void
+#ifdef __STDC__
+makeAllVisible (
+ int visible)
+#else
+makeAllVisible (visible)
+ int visible;
+#endif
+{
+ int i;
+
+ for (i = 0; i < MAX_MAJOR_WINDOWS; i++)
+ {
+ if (m_winPtrNotNull (winList[i]) &&
+ ((winList[i])->generic.type) != CMD_WIN)
+ {
+ if (m_winIsSourceType ((winList[i])->generic.type))
+ makeVisible ((winList[i])->detail.sourceInfo.executionInfo,
+ visible);
+ makeVisible ((TuiGenWinInfoPtr) winList[i], visible);
+ }
+ }
+
+ return;
+} /* makeAllVisible */
+
+
+/*
+** scrollWinForward
+*/
+void
+#ifdef __STDC__
+scrollWinForward (
+ TuiGenWinInfoPtr winInfo,
+ int numLines)
+#else
+scrollWinForward (winInfo, numLines)
+ TuiGenWinInfoPtr winInfo;
+ int numLines;
+#endif
+{
+ if (winInfo->content != (OpaquePtr) NULL &&
+ winInfo->lastVisibleLine < winInfo->contentSize - 1)
+ {
+ int i, firstLine, newLastLine;
+
+ firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1;
+ if (winInfo->lastVisibleLine + numLines > winInfo->contentSize)
+ newLastLine = winInfo->contentSize - 1;
+ else
+ newLastLine = winInfo->lastVisibleLine + numLines - 1;
+
+ for (i = (newLastLine - winInfo->viewportHeight);
+ (i <= newLastLine); i++)
+ {
+ TuiWinElementPtr line;
+ int lineHeight;
+
+ line = (TuiWinElementPtr) winInfo->content[i];
+ if (line->highlight)
+ wstandout (winInfo->handle);
+ mvwaddstr (winInfo->handle,
+ i - (newLastLine - winInfo->viewportHeight),
+ 1,
+ displayableWinContentOf (winInfo, line));
+ if (line->highlight)
+ wstandend (winInfo->handle);
+ lineHeight = winElementHeight (winInfo, line);
+ newLastLine += (lineHeight - 1);
+ }
+ winInfo->lastVisibleLine = newLastLine;
+ }
+
+ return;
+} /* scrollWinForward */
+
+
+/*
+** scrollWinBackward
+*/
+void
+#ifdef __STDC__
+scrollWinBackward (
+ TuiGenWinInfoPtr winInfo,
+ int numLines)
+#else
+scrollWinBackward (winInfo, numLines)
+ TuiGenWinInfoPtr winInfo;
+ int numLines;
+#endif
+{
+ if (winInfo->content != (OpaquePtr) NULL &&
+ (winInfo->lastVisibleLine - winInfo->viewportHeight) > 0)
+ {
+ int i, newLastLine, firstLine;
+
+ firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1;
+ if ((firstLine - numLines) < 0)
+ newLastLine = winInfo->viewportHeight - 1;
+ else
+ newLastLine = winInfo->lastVisibleLine - numLines + 1;
+
+ for (i = newLastLine - winInfo->viewportHeight; (i <= newLastLine); i++)
+ {
+ TuiWinElementPtr line;
+ int lineHeight;
+
+ line = (TuiWinElementPtr) winInfo->content[i];
+ if (line->highlight)
+ wstandout (winInfo->handle);
+ mvwaddstr (winInfo->handle,
+ i - (newLastLine - winInfo->viewportHeight),
+ 1,
+ displayableWinContentOf (winInfo, line));
+ if (line->highlight)
+ wstandend (winInfo->handle);
+ lineHeight = winElementHeight (winInfo, line);
+ newLastLine += (lineHeight - 1);
+ }
+ winInfo->lastVisibleLine = newLastLine;
+ }
+
+ return;
+} /* scrollWinBackward */
+
+
+/*
+** refreshAll().
+** Function to refresh all the windows currently displayed
+*/
+void
+#ifdef __STDC__
+refreshAll (
+ TuiWinInfoPtr * list)
+#else
+refreshAll (list)
+ TuiWinInfoPtr *list;
+#endif
+{
+ TuiWinType type;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
+ {
+ if (list[type]->generic.isVisible)
+ {
+ if (type == SRC_WIN || type == DISASSEM_WIN)
+ {
+ touchwin (list[type]->detail.sourceInfo.executionInfo->handle);
+ tuiRefreshWin (list[type]->detail.sourceInfo.executionInfo);
+ }
+ touchwin (list[type]->generic.handle);
+ tuiRefreshWin (&list[type]->generic);
+ }
+ }
+ if (locator->isVisible)
+ {
+ touchwin (locator->handle);
+ tuiRefreshWin (locator);
+ }
+
+ return;
+} /* refreshAll */
+
+
+/*********************************
+** Local Static Functions
+*********************************/
diff --git a/contrib/gdb/gdb/tui/tuiGeneralWin.h b/contrib/gdb/gdb/tui/tuiGeneralWin.h
new file mode 100644
index 0000000..559f8ab
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiGeneralWin.h
@@ -0,0 +1,31 @@
+#ifndef TUI_GENERAL_WIN_H
+#define TUI_GENERAL_WIN_H
+
+/*
+** Functions
+*/
+extern void tuiClearWin PARAMS ((TuiGenWinInfoPtr));
+extern void unhighlightWin PARAMS ((TuiWinInfoPtr));
+extern void makeVisible PARAMS ((TuiGenWinInfoPtr, int));
+extern void makeAllVisible PARAMS ((int));
+extern void scrollWinForward PARAMS ((TuiGenWinInfoPtr, int));
+extern void scrollWinBackward PARAMS ((TuiGenWinInfoPtr, int));
+extern void makeWindow PARAMS ((TuiGenWinInfoPtr, int));
+extern TuiWinInfoPtr copyWin PARAMS ((TuiWinInfoPtr));
+extern void boxWin PARAMS ((TuiGenWinInfoPtr, int));
+extern void highlightWin PARAMS ((TuiWinInfoPtr));
+extern void checkAndDisplayHighlightIfNeeded PARAMS ((TuiWinInfoPtr));
+extern void refreshAll PARAMS ((TuiWinInfoPtr *));
+extern void tuiDelwin PARAMS ((WINDOW *window));
+extern void tuiRefreshWin PARAMS ((TuiGenWinInfoPtr));
+
+/*
+** Macros
+*/
+#define m_beVisible(winInfo) makeVisible((TuiGenWinInfoPtr)(winInfo), TRUE)
+#define m_beInvisible(winInfo) \
+ makeVisible((TuiGenWinInfoPtr)(winInfo), FALSE)
+#define m_allBeVisible() makeAllVisible(TRUE)
+#define m_allBeInvisible() makeAllVisible(FALSE)
+
+#endif /*TUI_GENERAL_WIN_H*/
diff --git a/contrib/gdb/gdb/tui/tuiIO.c b/contrib/gdb/gdb/tui/tuiIO.c
new file mode 100644
index 0000000..29a3613
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiIO.c
@@ -0,0 +1,734 @@
+
+/*
+** This module contains functions to support i/o in the TUI
+*/
+
+
+#include <stdio.h>
+#include "defs.h"
+#include "terminal.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiIO.h"
+#include "tuiCommand.h"
+#include "tuiWin.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* The Solaris header files seem to provide no declaration for this at
+ all when __STDC__ is defined. This shouldn't conflict with
+ anything. */
+extern char *tgoto ();
+
+int insert_mode = 0;
+
+/********************************************
+** LOCAL STATIC FORWARD DECLS **
+********************************************/
+static void _updateCommandInfo PARAMS ((int));
+static unsigned int _tuiHandleResizeDuringIO PARAMS ((unsigned int));
+
+
+/*********************************************************************************
+** PUBLIC FUNCTIONS **
+*********************************************************************************/
+
+/*
+** tuiPuts_unfiltered().
+** Function to put a string to the command window
+** When running in TUI mode, this is the "hook"
+** for fputs_unfiltered(). That is, all debugger
+** output eventually makes it's way to the bottom-level
+** routine fputs_unfiltered (main.c), which (in TUI
+** mode), calls tuiPuts_unfiltered().
+*/
+void
+#ifdef __STDC__
+tuiPuts_unfiltered (
+ const char *string,
+ GDB_FILE * stream)
+#else
+tuiPuts_unfiltered (string, stream)
+ char *string;
+ GDB_FILE *stream;
+#endif
+{
+ int len = strlen (string);
+ int i, linech;
+
+ for (i = 0; i < len; i++)
+ {
+ if (string[i] == '\n' || string[i] == '\r')
+ m_tuiStartNewLine;
+ else
+ {
+ if ((cmdWin->detail.commandInfo.curch + 1) > cmdWin->generic.width)
+ m_tuiStartNewLine;
+
+ if (insert_mode)
+ {
+ mvwinsch (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch++,
+ string[i]);
+ wmove (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch);
+ }
+ else
+ mvwaddch (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch++,
+ string[i]);
+ }
+ }
+ tuiRefreshWin (&cmdWin->generic);
+
+ return;
+} /* tuiPuts_unfiltered */
+
+/* A cover routine for tputs().
+ * tputs() is called from the readline package to put
+ * out strings representing cursor positioning.
+ * In TUI mode (non-XDB-style), tui_tputs() is called instead.
+ *
+ * The reason we need to hook tputs() is:
+ * Since the output is going to curses and not to
+ * a raw terminal, we need to intercept these special
+ * sequences, and handle them them here.
+ *
+ * This function seems to be correctly handling all sequences
+ * aimed at hpterm's, but there is additional work to do
+ * for xterm's and dtterm's. I abandoned further work on this
+ * in favor of "XDB style". In "XDB style", the command region
+ * looks like terminal, not a curses window, and this routine
+ * is not called. - RT
+ */
+void
+tui_tputs (str, affcnt, putfunc)
+ char *str;
+ int affcnt;
+ int (*putfunc) PARAMS ((int));
+{
+ extern char *rl_prompt; /* the prompt string */
+
+ /* This set of globals are defined and initialized
+ * by the readline package.
+ *
+ * Note we're assuming tui_tputs() is being called
+ * by the readline package. That's because we're recognizing
+ * that a given string is being passed by
+ * matching the string address against readline's
+ * term_<whatever> global. To make this more general,
+ * we'd have to actually recognize the termcap sequence
+ * inside the string (more work than I want to do). - RT
+ *
+ * We don't see or need to handle every one of these here;
+ * this is just the full list defined in readline/readline.c
+ */
+ extern char *term_backspace;
+ extern char *term_clreol;
+ extern char *term_clrpag;
+ extern char *term_cr;
+ extern char *term_dc;
+ extern char *term_ei;
+ extern char *term_goto;
+ extern char *term_ic;
+ extern char *term_im;
+ extern char *term_mm;
+ extern char *term_mo;
+ extern char *term_up;
+ extern char *term_scroll_region;
+ extern char *term_memory_lock;
+ extern char *term_memory_unlock;
+ extern char *term_cursor_move;
+ extern char *visible_bell;
+
+ /* Sanity check - if not TUI, just call tputs() */
+ if (!tui_version)
+ tputs (str, affcnt, putfunc);
+
+ /* The strings we special-case are handled first */
+
+ if (str == term_backspace)
+ {
+ /* Backspace. */
+
+ /* We see this on an emacs control-B.
+ * I.e., it's like the left-arrow key (not like the backspace key).
+ * The effect that readline wants when it transmits this
+ * character to us is simply to back up one character
+ * (but not to write a space over the old character).
+ */
+
+ _updateCommandInfo (-1);
+ wmove (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch);
+ wrefresh (cmdWin->generic.handle);
+
+ }
+ else if (str == term_clreol)
+ {
+
+ /* Clear to end of line. */
+ wclrtoeol (cmdWin->generic.handle);
+ wrefresh (cmdWin->generic.handle);
+
+ }
+ else if (str == term_cr)
+ {
+
+ /* Carriage return */
+ _updateCommandInfo (-cmdWin->detail.commandInfo.curch);
+ wmove (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.curLine,
+ 0 /* readline will rewrite the prompt from 0 */ );
+ wrefresh (cmdWin->generic.handle);
+
+ }
+ else if (str == term_goto)
+ {
+
+ /* This is actually a tgoto() specifying a character position,
+ * followed by either a term_IC/term_DC which [I think] means
+ * insert/delete one character at that position.
+ * There are complications with this one - need to either
+ * extract the position from the string, or have a backdoor
+ * means of communicating it from ../readline/display.c.
+ * So this one is not yet implemented.
+ * Not doing it seems to have no ill effects on command-line-editing
+ * that I've noticed so far. - RT
+ */
+
+ }
+ else if (str == term_dc)
+ {
+
+ /* Delete character at current cursor position */
+ wdelch (cmdWin->generic.handle);
+ wrefresh (cmdWin->generic.handle);
+
+ }
+ else if (str == term_im)
+ {
+
+ /* Turn on insert mode. */
+ insert_mode = 1;
+
+ }
+ else if (str == term_ei)
+ {
+
+ /* Turn off insert mode. */
+ insert_mode = 0;
+
+ /* Strings we know about but don't handle
+ * specially here are just passed along to tputs().
+ *
+ * These are not handled because (as far as I can tell)
+ * they are not actually emitted by the readline package
+ * in the course of doing command-line editing. Some of them
+ * theoretically could be used in the future, in which case we'd
+ * need to handle them.
+ */
+ }
+ else if (str == term_ic || /* insert character */
+ str == term_cursor_move || /* cursor move */
+ str == term_clrpag ||/* clear page */
+ str == term_mm || /* turn on meta key */
+ str == term_mo || /* turn off meta key */
+ str == term_up || /* up one line (not expected) */
+ str == term_scroll_region || /* set scroll region */
+ str == term_memory_lock || /* lock screen above cursor */
+ str == term_memory_unlock || /* unlock screen above cursor */
+ str == visible_bell)
+ { /* flash screen */
+ tputs (str, affcnt, putfunc);
+ }
+ else
+ { /* something else */
+ tputs (str, affcnt, putfunc);
+ }
+} /* tui_tputs */
+
+
+/*
+** tui_vwgetch()
+** Wrapper around wgetch with the window in a va_list
+*/
+unsigned int
+#ifdef __STDC__
+tui_vwgetch (va_list args)
+#else
+tui_vwgetch (args)
+ va_list args;
+#endif
+{
+ unsigned int ch;
+ WINDOW *window;
+
+ window = va_arg (args, WINDOW *);
+
+ return ((unsigned int) wgetch (window));
+} /* tui_vwgetch */
+
+
+/*
+** tui_vread()
+** Wrapper around read() with paramets in a va_list
+*/
+unsigned int
+#ifdef __STDC__
+tui_vread (va_list args)
+#else
+tui_vread (args)
+ va_list args;
+#endif
+{
+ int result = 0;
+ int filedes = va_arg (args, int);
+ char *buf = va_arg (args, char *);
+ int nbytes = va_arg (args, int);
+
+ result = read (filedes, buf, nbytes);
+
+ return result;
+} /* tui_vread() */
+
+/*
+** tuiRead()
+** Function to perform a read() catching resize events
+*/
+int
+#ifdef __STDC__
+tuiRead (
+ int filedes,
+ char *buf,
+ int nbytes)
+#else
+tuiRead (filedes, buf, nbytes)
+ int filedes;
+ char *buf;
+ int nbytes;
+#endif
+{
+ int result = 0;
+
+ result = (int) vcatch_errors ((OpaqueFuncPtr) tui_vread, filedes, buf, nbytes);
+ *buf = _tuiHandleResizeDuringIO (*buf);
+
+ return result;
+} /* tuiRead */
+
+
+/*
+** tuiGetc().
+** Get a character from the command window.
+** This is called from the readline package,
+** that is, we have:
+** tuiGetc() [here], called from
+** readline code [in ../readline/], called from
+** command_line_input() in top.c
+*/
+unsigned int
+#ifdef __STDC__
+tuiGetc (void)
+#else
+tuiGetc ()
+#endif
+{
+ unsigned int ch;
+ extern char *rl_prompt;
+ extern char *rl_line_buffer;
+ extern int rl_point;
+
+ /* Call the curses routine that reads one character */
+#ifndef COMMENT
+ ch = (unsigned int) vcatch_errors ((OpaqueFuncPtr) tui_vwgetch,
+ cmdWin->generic.handle);
+#else
+ ch = wgetch (cmdWin->generic.handle);
+#endif
+ ch = _tuiHandleResizeDuringIO (ch);
+
+ if (m_isCommandChar (ch))
+ { /* Handle prev/next/up/down here */
+ tuiTermSetup (0);
+ ch = tuiDispatchCtrlChar (ch);
+ cmdWin->detail.commandInfo.curch = strlen (rl_prompt) + rl_point;
+ tuiTermUnsetup (0, cmdWin->detail.commandInfo.curch);
+ }
+ if (ch == '\n' || ch == '\r' || ch == '\f')
+ cmdWin->detail.commandInfo.curch = 0;
+ else
+ tuiIncrCommandCharCountBy (1);
+
+ return ch;
+} /* tuiGetc */
+
+
+/*
+** tuiBufferGetc().
+*/
+/*elz: this function reads a line of input from the user and
+puts it in a static buffer. Subsequent calls to this same function
+obtain one char at the time, providing the caller with a behavior
+similar to fgetc. When the input is buffered, the backspaces have
+the needed effect, i.e. ignore the last char active in the buffer*/
+/* so far this function is called only from the query function in
+utils.c*/
+
+unsigned int
+#ifdef __STDC__
+tuiBufferGetc (void)
+#else
+tuiBufferGetc ()
+#endif
+{
+ unsigned int ch;
+ static unsigned char _ibuffer[512];
+ static int index_read = -1;
+ static int length_of_answer = -1;
+ int pos = 0;
+
+ if (length_of_answer == -1)
+ {
+ /* this is the first time through, need to read the answer*/
+ do
+ {
+ /* Call the curses routine that reads one character */
+ ch = (unsigned int) wgetch (cmdWin->generic.handle);
+ if (ch != '\b')
+ {
+ _ibuffer[pos] = ch;
+ pos++;
+ }
+ else
+ pos--;
+ }
+ while (ch != '\r' && ch != '\n');
+
+ length_of_answer = pos;
+ index_read = 0;
+ }
+
+ ch = _ibuffer[index_read];
+ index_read++;
+
+ if (index_read == length_of_answer)
+ {
+ /*this is the last time through, reset for next query*/
+ index_read = -1;
+ length_of_answer = -1;
+ }
+
+ wrefresh (cmdWin->generic.handle);
+
+ return (ch);
+} /* tuiBufferGetc */
+
+
+/*
+** tuiStartNewLines().
+*/
+void
+#ifdef __STDC__
+tuiStartNewLines (
+ int numLines)
+#else
+tuiStartNewLines (numLines)
+ int numLines;
+#endif
+{
+ if (numLines > 0)
+ {
+ if (cmdWin->generic.viewportHeight > 1 &&
+ cmdWin->detail.commandInfo.curLine < cmdWin->generic.viewportHeight)
+ cmdWin->detail.commandInfo.curLine += numLines;
+ else
+ scroll (cmdWin->generic.handle);
+ cmdWin->detail.commandInfo.curch = 0;
+ wmove (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch);
+ tuiRefreshWin (&cmdWin->generic);
+ }
+
+ return;
+} /* tuiStartNewLines */
+
+
+/*
+** tui_vStartNewLines().
+** With numLines in a va_list
+*/
+void
+#ifdef __STDC__
+tui_vStartNewLines (
+ va_list args)
+#else
+tui_vStartNewLines (args)
+ va_list args;
+#endif
+{
+ int numLines = va_arg (args, int);
+
+ tuiStartNewLines (numLines);
+
+ return;
+} /* tui_vStartNewLines */
+
+
+/****************************************************************************
+** LOCAL STATIC FUNCTIONS **
+*****************************************************************************/
+
+
+/*
+** _tuiHandleResizeDuringIO
+** This function manages the cleanup when a resize has occured
+** From within a call to getch() or read. Returns the character
+** to return from getc or read.
+*/
+static unsigned int
+#ifdef __STDC__
+_tuiHandleResizeDuringIO (
+ unsigned int originalCh) /* the char just read */
+#else
+_tuiHandleResizeDuringIO (originalCh)
+ unsigned int originalCh;
+#endif
+{
+ if (tuiWinResized ())
+ {
+ tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll);
+ dont_repeat ();
+ tuiSetWinResizedTo (FALSE);
+ rl_reset ();
+ return '\n';
+ }
+ else
+ return originalCh;
+} /* _tuiHandleResizeDuringIO */
+
+
+/*
+** _updateCommandInfo().
+** Function to update the command window information.
+*/
+static void
+#ifdef __STDC__
+_updateCommandInfo (
+ int sizeOfString)
+#else
+_updateCommandInfo (sizeOfString)
+ int sizeOfString;
+#endif
+{
+
+ if ((sizeOfString +
+ cmdWin->detail.commandInfo.curch) > cmdWin->generic.width)
+ {
+ int newCurch = sizeOfString + cmdWin->detail.commandInfo.curch;
+
+ tuiStartNewLines (1);
+ cmdWin->detail.commandInfo.curch = newCurch - cmdWin->generic.width;
+ }
+ else
+ cmdWin->detail.commandInfo.curch += sizeOfString;
+
+ return;
+} /* _updateCommandInfo */
+
+
+/* Looked at in main.c, fputs_unfiltered(), to decide
+ * if it's safe to do standard output to the command window.
+ */
+int tui_owns_terminal = 0;
+
+/* Called to set up the terminal for TUI (curses) I/O.
+ * We do this either on our way "in" to GDB after target
+ * program execution, or else within tuiDo just before
+ * going off to TUI routines.
+ */
+
+void
+#ifdef __STDC__
+tuiTermSetup (
+ int turn_off_echo)
+#else
+tuiTermSetup (turn_off_echo)
+ int turn_off_echo;
+#endif
+{
+ char *buffer;
+ int start;
+ int end;
+ int endcol;
+ extern char *term_scroll_region;
+ extern char *term_cursor_move;
+ extern char *term_memory_lock;
+ extern char *term_memory_unlock;
+
+ /* Turn off echoing, since the TUI does not
+ * expect echoing. Below I only put in the TERMIOS
+ * case, since that is what applies on HP-UX. turn_off_echo
+ * is 1 except for the case where we're being called
+ * on a "quit", in which case we want to leave echo on.
+ */
+ if (turn_off_echo)
+ {
+#ifdef HAVE_TERMIOS
+ struct termios tio;
+ tcgetattr (0, &tio);
+ tio.c_lflag &= ~(ECHO);
+ tcsetattr (0, TCSANOW, &tio);
+#endif
+ }
+
+ /* Compute the start and end lines of the command
+ * region. (Actually we only use end here)
+ */
+ start = winList[CMD_WIN]->generic.origin.y;
+ end = start + winList[CMD_WIN]->generic.height - 1;
+ endcol = winList[CMD_WIN]->generic.width - 1;
+
+ if (term_memory_unlock)
+ {
+
+ /* Un-do the effect of the memory lock in terminal_inferior() */
+ tputs (term_memory_unlock, 1, (int (*)PARAMS ((int))) putchar);
+ fflush (stdout);
+
+ }
+ else if (term_scroll_region)
+ {
+
+ /* Un-do the effect of setting scroll region in terminal_inferior() */
+ /* I'm actually not sure how to do this (we don't know for
+ * sure what the scroll region was *before* we changed it),
+ * but I'll guess that setting it to the whole screen is
+ * the right thing. So, ...
+ */
+
+ /* Set scroll region to be 0..end */
+ buffer = (char *) tgoto (term_scroll_region, end, 0);
+ tputs (buffer, 1, (int (*)PARAMS ((int))) putchar);
+
+ } /* else we're out of luck */
+
+ /* This is an attempt to keep the logical & physical
+ * cursor in synch, going into curses. Without this,
+ * curses seems to be confused by the fact that
+ * GDB has physically moved the curser on it. One
+ * visible effect of removing this code is that the
+ * locator window fails to get updated and the line
+ * of text that *should* go into the locator window
+ * often goes to the wrong place.
+ */
+ /* What's done here is to tell curses to write a ' '
+ * at the bottom right corner of the screen.
+ * The idea is to wind up with the cursor in a known
+ * place.
+ * Note I'm relying on refresh()
+ * only writing what changed (the space),
+ * not the whole screen.
+ */
+ standend ();
+ move (end, endcol - 1);
+ addch (' ');
+ refresh ();
+
+ tui_owns_terminal = 1;
+} /* tuiTermSetup */
+
+
+/* Called to set up the terminal for target program I/O, meaning I/O
+ * is confined to the command-window area. We also call this on our
+ * way out of tuiDo, thus setting up the terminal this way for
+ * debugger command I/O. */
+void
+#ifdef __STDC__
+tuiTermUnsetup (
+ int turn_on_echo,
+ int to_column)
+#else
+tuiTermUnsetup (turn_on_echo, to_column)
+ int turn_on_echo;
+ int to_column;
+#endif
+{
+ int start;
+ int end;
+ int curline;
+ char *buffer;
+ /* The next bunch of things are from readline */
+ extern char *term_scroll_region;
+ extern char *term_cursor_move;
+ extern char *term_memory_lock;
+ extern char *term_memory_unlock;
+ extern char *term_se;
+
+ /* We need to turn on echoing, since the TUI turns it off */
+ /* Below I only put in the TERMIOS case, since that
+ * is what applies on HP-UX.
+ */
+ if (turn_on_echo)
+ {
+#ifdef HAVE_TERMIOS
+ struct termios tio;
+ tcgetattr (0, &tio);
+ tio.c_lflag |= (ECHO);
+ tcsetattr (0, TCSANOW, &tio);
+#endif
+ }
+
+ /* Compute the start and end lines of the command
+ * region, as well as the last "real" line of
+ * the region (normally same as end, except when
+ * we're first populating the region)
+ */
+ start = winList[CMD_WIN]->generic.origin.y;
+ end = start + winList[CMD_WIN]->generic.height - 1;
+ curline = start + winList[CMD_WIN]->detail.commandInfo.curLine;
+
+ /* We want to confine target I/O to the command region.
+ * In order to do so, we must either have "memory lock"
+ * (hpterm's) or "scroll regions" (xterm's).
+ */
+ if (term_cursor_move && term_memory_lock)
+ {
+
+ /* Memory lock means lock region above cursor.
+ * So first position the cursor, then call memory lock.
+ */
+ buffer = tgoto (term_cursor_move, 0, start);
+ tputs (buffer, 1, (int (*)PARAMS ((int))) putchar);
+ tputs (term_memory_lock, 1, (int (*)PARAMS ((int))) putchar);
+
+ }
+ else if (term_scroll_region)
+ {
+
+ /* Set the scroll region to the command window */
+ buffer = tgoto (term_scroll_region, end, start);
+ tputs (buffer, 1, (int (*)PARAMS ((int))) putchar);
+
+ } /* else we can't do anything about target I/O */
+
+ /* Also turn off standout mode, in case it is on */
+ if (term_se != NULL)
+ tputs (term_se, 1, (int (*)PARAMS ((int))) putchar);
+
+ /* Now go to the appropriate spot on the end line */
+ buffer = tgoto (term_cursor_move, to_column, end);
+ tputs (buffer, 1, (int (*)PARAMS ((int))) putchar);
+ fflush (stdout);
+
+ tui_owns_terminal = 0;
+} /* tuiTermUnsetup */
diff --git a/contrib/gdb/gdb/tui/tuiIO.h b/contrib/gdb/gdb/tui/tuiIO.h
new file mode 100644
index 0000000..bcbeffe
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiIO.h
@@ -0,0 +1,43 @@
+#ifndef _TUI_IO_H
+#define _TUI_IO_H
+/*
+** This header contains defitions to support tuiIO.c
+*/
+
+
+#include <stdio.h>
+
+extern void tuiPuts_unfiltered PARAMS ((const char *, GDB_FILE *));
+extern unsigned int tuiGetc PARAMS ((void));
+extern unsigned int tuiBufferGetc PARAMS ((void));
+extern int tuiRead PARAMS ((int, char *, int));
+extern void tuiStartNewLines PARAMS ((int));
+extern void tui_vStartNewLines PARAMS ((va_list));
+extern unsigned int tui_vwgetch PARAMS ((va_list));
+extern void tuiTermSetup PARAMS ((int));
+extern void tuiTermUnsetup PARAMS ((int, int));
+
+
+
+#define m_tuiStartNewLine tuiStartNewLines(1)
+#define m_isStartSequence(ch) (ch == 27)
+#define m_isEndSequence(ch) (ch == 126)
+#define m_isBackspace(ch) (ch == 8)
+#define m_isDeleteChar(ch) (ch == KEY_DC)
+#define m_isDeleteLine(ch) (ch == KEY_DL)
+#define m_isDeleteToEol(ch) (ch == KEY_EOL)
+#define m_isNextPage(ch) (ch == KEY_NPAGE)
+#define m_isPrevPage(ch) (ch == KEY_PPAGE)
+#define m_isLeftArrow(ch) (ch == KEY_LEFT)
+#define m_isRightArrow(ch) (ch == KEY_RIGHT)
+
+#define m_isCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch) || \
+ m_isLeftArrow(ch) || m_isRightArrow(ch) || \
+ (ch == KEY_UP) || (ch == KEY_DOWN) || \
+ (ch == KEY_SF) || (ch == KEY_SR) || \
+ (ch == (int)'\f') || m_isStartSequence(ch))
+
+#define m_isXdbStyleCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch))
+
+
+#endif /*_TUI_IO_H*/
diff --git a/contrib/gdb/gdb/tui/tuiLayout.c b/contrib/gdb/gdb/tui/tuiLayout.c
new file mode 100644
index 0000000..6aa380c
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiLayout.c
@@ -0,0 +1,1410 @@
+/*
+** tuiLayout.c
+** This module contains procedures for handling the layout of the windows.
+*/
+
+
+#include "defs.h"
+#include "command.h"
+#include "symtab.h"
+#include "frame.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+#include "tuiStack.h"
+#include "tuiRegs.h"
+#include "tuiDisassem.h"
+
+/*******************************
+** Static Local Decls
+********************************/
+
+static void _initGenWinInfo PARAMS
+ ((TuiGenWinInfoPtr, TuiWinType, int, int, int, int));
+static void _initAndMakeWin PARAMS
+ ((Opaque *, TuiWinType, int, int, int, int, int));
+static void _showSourceOrDisassemAndCommand PARAMS
+ ((TuiLayoutType));
+static void _makeSourceOrDisassemWindow PARAMS
+ ((TuiWinInfoPtr *, TuiWinType, int, int));
+static void _makeCommandWindow PARAMS ((TuiWinInfoPtr *, int, int));
+static void _makeSourceWindow PARAMS ((TuiWinInfoPtr *, int, int));
+static void _makeDisassemWindow PARAMS
+ ((TuiWinInfoPtr *, int, int));
+static void _makeDataWindow PARAMS ((TuiWinInfoPtr *, int, int));
+static void _showSourceCommand PARAMS ((void));
+static void _showDisassemCommand PARAMS ((void));
+static void _showSourceDisassemCommand PARAMS ((void));
+static void _showData PARAMS ((TuiLayoutType));
+static TuiLayoutType _nextLayout PARAMS ((void));
+static TuiLayoutType _prevLayout PARAMS ((void));
+static void _tuiLayout_command PARAMS ((char *, int));
+static void _tuiToggleLayout_command PARAMS ((char *, int));
+static void _tui_vToggleLayout_command PARAMS ((va_list));
+static void _tuiToggleSplitLayout_command PARAMS ((char *, int));
+static void _tui_vToggleSplitLayout_command PARAMS ((va_list));
+static Opaque _extractDisplayStartAddr PARAMS ((void));
+static void _tuiHandleXDBLayout PARAMS ((TuiLayoutDefPtr));
+static TuiStatus _tuiSetLayoutTo PARAMS ((char *));
+
+
+/***************************************
+** DEFINITIONS
+***************************************/
+
+#define LAYOUT_USAGE "Usage: layout prev | next | <layout_name> \n"
+
+/***************************************
+** Static Local Data
+***************************************/
+static TuiLayoutType lastLayout = UNDEFINED_LAYOUT;
+
+/***************************************
+** PUBLIC FUNCTIONS
+***************************************/
+
+/*
+** showLayout().
+** Show the screen layout defined
+*/
+void
+#ifdef __STDC__
+showLayout (
+ TuiLayoutType layout)
+#else
+showLayout (layout)
+ TuiLayoutType layout;
+#endif
+{
+ TuiLayoutType curLayout = currentLayout ();
+
+ if (layout != curLayout)
+ {
+ /*
+ ** Since the new layout may cause changes in window size, we
+ ** should free the content and reallocate on next display of
+ ** source/asm
+ */
+ tuiClearAllSourceWinsContent (NO_EMPTY_SOURCE_PROMPT);
+ freeAllSourceWinsContent ();
+ clearSourceWindows ();
+ if (layout == SRC_DATA_COMMAND || layout == DISASSEM_DATA_COMMAND)
+ {
+ _showData (layout);
+ refreshAll (winList);
+ }
+ else
+ {
+ /* First make the current layout be invisible */
+ m_allBeInvisible ();
+ m_beInvisible (locatorWinInfoPtr ());
+
+ switch (layout)
+ {
+ /* Now show the new layout */
+ case SRC_COMMAND:
+ _showSourceCommand ();
+ addToSourceWindows (srcWin);
+ break;
+ case DISASSEM_COMMAND:
+ _showDisassemCommand ();
+ addToSourceWindows (disassemWin);
+ break;
+ case SRC_DISASSEM_COMMAND:
+ _showSourceDisassemCommand ();
+ addToSourceWindows (srcWin);
+ addToSourceWindows (disassemWin);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return;
+} /* showLayout */
+
+
+/*
+** tuiSetLayout()
+** Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,
+** SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND.
+** If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or
+** UNDEFINED_LAYOUT, then the data window is populated according
+** to regsDisplayType.
+*/
+TuiStatus
+#ifdef __STDC__
+tuiSetLayout (
+ TuiLayoutType layoutType,
+ TuiRegisterDisplayType regsDisplayType)
+#else
+tuiSetLayout (layoutType, regsDisplayType)
+ TuiLayoutType layoutType;
+ TuiRegisterDisplayType regsDisplayType;
+#endif
+{
+ TuiStatus status = TUI_SUCCESS;
+
+ if (layoutType != UNDEFINED_LAYOUT || regsDisplayType != TUI_UNDEFINED_REGS)
+ {
+ TuiLayoutType curLayout = currentLayout (), newLayout = UNDEFINED_LAYOUT;
+ int regsPopulate = FALSE;
+ Opaque addr = _extractDisplayStartAddr ();
+ TuiWinInfoPtr newWinWithFocus = (TuiWinInfoPtr) NULL, winWithFocus = tuiWinWithFocus ();
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+
+ if (layoutType == UNDEFINED_LAYOUT &&
+ regsDisplayType != TUI_UNDEFINED_REGS)
+ {
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ newLayout = DISASSEM_DATA_COMMAND;
+ else if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND)
+ newLayout = SRC_DATA_COMMAND;
+ else if (curLayout == DISASSEM_COMMAND ||
+ curLayout == DISASSEM_DATA_COMMAND)
+ newLayout = DISASSEM_DATA_COMMAND;
+ }
+ else
+ newLayout = layoutType;
+
+ regsPopulate = (newLayout == SRC_DATA_COMMAND ||
+ newLayout == DISASSEM_DATA_COMMAND ||
+ regsDisplayType != TUI_UNDEFINED_REGS);
+ if (newLayout != curLayout || regsDisplayType != TUI_UNDEFINED_REGS)
+ {
+ if (newLayout != curLayout)
+ {
+ if (winWithFocus != cmdWin)
+ tuiClearWinFocus ();
+ showLayout (newLayout);
+ /*
+ ** Now determine where focus should be
+ */
+ if (winWithFocus != cmdWin)
+ {
+ switch (newLayout)
+ {
+ case SRC_COMMAND:
+ tuiSetWinFocusTo (srcWin);
+ layoutDef->displayMode = SRC_WIN;
+ layoutDef->split = FALSE;
+ break;
+ case DISASSEM_COMMAND:
+ /* the previous layout was not showing
+ ** code. this can happen if there is no
+ ** source available:
+ ** 1. if the source file is in another dir OR
+ ** 2. if target was compiled without -g
+ ** We still want to show the assembly though!
+ */
+ addr = vcatch_errors ((OpaqueFuncPtr)
+ tuiGetBeginAsmAddress);
+ tuiSetWinFocusTo (disassemWin);
+ layoutDef->displayMode = DISASSEM_WIN;
+ layoutDef->split = FALSE;
+ break;
+ case SRC_DISASSEM_COMMAND:
+ /* the previous layout was not showing
+ ** code. this can happen if there is no
+ ** source available:
+ ** 1. if the source file is in another dir OR
+ ** 2. if target was compiled without -g
+ ** We still want to show the assembly though!
+ */
+ addr = vcatch_errors ((OpaqueFuncPtr)
+ tuiGetBeginAsmAddress);
+ if (winWithFocus == srcWin)
+ tuiSetWinFocusTo (srcWin);
+ else
+ tuiSetWinFocusTo (disassemWin);
+ layoutDef->split = TRUE;
+ break;
+ case SRC_DATA_COMMAND:
+ if (winWithFocus != dataWin)
+ tuiSetWinFocusTo (srcWin);
+ else
+ tuiSetWinFocusTo (dataWin);
+ layoutDef->displayMode = SRC_WIN;
+ layoutDef->split = FALSE;
+ break;
+ case DISASSEM_DATA_COMMAND:
+ /* the previous layout was not showing
+ ** code. this can happen if there is no
+ ** source available:
+ ** 1. if the source file is in another dir OR
+ ** 2. if target was compiled without -g
+ ** We still want to show the assembly though!
+ */
+ addr = vcatch_errors ((OpaqueFuncPtr)
+ tuiGetBeginAsmAddress);
+ if (winWithFocus != dataWin)
+ tuiSetWinFocusTo (disassemWin);
+ else
+ tuiSetWinFocusTo (dataWin);
+ layoutDef->displayMode = DISASSEM_WIN;
+ layoutDef->split = FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+ if (newWinWithFocus != (TuiWinInfoPtr) NULL)
+ tuiSetWinFocusTo (newWinWithFocus);
+ /*
+ ** Now update the window content
+ */
+ if (!regsPopulate &&
+ (newLayout == SRC_DATA_COMMAND ||
+ newLayout == DISASSEM_DATA_COMMAND))
+ tuiDisplayAllData ();
+
+ tuiUpdateSourceWindowsWithAddr (addr);
+ }
+ if (regsPopulate)
+ {
+ layoutDef->regsDisplayType =
+ (regsDisplayType == TUI_UNDEFINED_REGS ?
+ TUI_GENERAL_REGS : regsDisplayType);
+ tuiShowRegisters (layoutDef->regsDisplayType);
+ }
+ }
+ }
+ else
+ status = TUI_FAILURE;
+
+ return status;
+} /* tuiSetLayout */
+
+
+/*
+** tui_vSetLayoutTo()
+** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA,
+** REGS, $REGS, $GREGS, $FREGS, $SREGS with arguments in a va_list
+*/
+TuiStatus
+#ifdef __STDC__
+tui_vSetLayoutTo (
+ va_list args)
+#else
+tui_vSetLayoutTo (args)
+ va_list args;
+#endif
+{
+ char *layoutName;
+
+ layoutName = va_arg (args, char *);
+
+ return (_tuiSetLayoutTo (layoutName));
+} /* tui_vSetLayoutTo */
+
+
+/*
+** tuiAddWinToLayout().
+** Add the specified window to the layout in a logical way.
+** This means setting up the most logical layout given the
+** window to be added.
+*/
+void
+#ifdef __STDC__
+tuiAddWinToLayout (
+ TuiWinType type)
+#else
+tuiAddWinToLayout (type)
+ TuiWinType type;
+#endif
+{
+ TuiLayoutType curLayout = currentLayout ();
+
+ switch (type)
+ {
+ case SRC_WIN:
+ if (curLayout != SRC_COMMAND &&
+ curLayout != SRC_DISASSEM_COMMAND &&
+ curLayout != SRC_DATA_COMMAND)
+ {
+ clearSourceWindowsDetail ();
+ if (curLayout == DISASSEM_DATA_COMMAND)
+ showLayout (SRC_DATA_COMMAND);
+ else
+ showLayout (SRC_COMMAND);
+ }
+ break;
+ case DISASSEM_WIN:
+ if (curLayout != DISASSEM_COMMAND &&
+ curLayout != SRC_DISASSEM_COMMAND &&
+ curLayout != DISASSEM_DATA_COMMAND)
+ {
+ clearSourceWindowsDetail ();
+ if (curLayout == SRC_DATA_COMMAND)
+ showLayout (DISASSEM_DATA_COMMAND);
+ else
+ showLayout (DISASSEM_COMMAND);
+ }
+ break;
+ case DATA_WIN:
+ if (curLayout != SRC_DATA_COMMAND &&
+ curLayout != DISASSEM_DATA_COMMAND)
+ {
+ if (curLayout == DISASSEM_COMMAND)
+ showLayout (DISASSEM_DATA_COMMAND);
+ else
+ showLayout (SRC_DATA_COMMAND);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* tuiAddWinToLayout */
+
+
+/*
+** tui_vAddWinToLayout().
+** Add the specified window to the layout in a logical way,
+** with arguments in a va_list.
+*/
+void
+#ifdef __STDC__
+tui_vAddWinToLayout (
+ va_list args)
+#else
+tui_vAddWinToLayout (args)
+ va_list args;
+#endif
+{
+ TuiWinType type = va_arg (args, TuiWinType);
+
+ tuiAddWinToLayout (type);
+
+ return;
+} /* tui_vAddWinToLayout */
+
+
+/*
+** tuiDefaultWinHeight().
+** Answer the height of a window. If it hasn't been created yet,
+** answer what the height of a window would be based upon its
+** type and the layout.
+*/
+int
+#ifdef __STDC__
+tuiDefaultWinHeight (
+ TuiWinType type,
+ TuiLayoutType layout)
+#else
+tuiDefaultWinHeight (type, layout)
+ TuiWinType type;
+ TuiLayoutType layout;
+#endif
+{
+ int h;
+
+ if (winList[type] != (TuiWinInfoPtr) NULL)
+ h = winList[type]->generic.height;
+ else
+ {
+ switch (layout)
+ {
+ case SRC_COMMAND:
+ case DISASSEM_COMMAND:
+ if (m_winPtrIsNull (cmdWin))
+ h = termHeight () / 2;
+ else
+ h = termHeight () - cmdWin->generic.height;
+ break;
+ case SRC_DISASSEM_COMMAND:
+ case SRC_DATA_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ if (m_winPtrIsNull (cmdWin))
+ h = termHeight () / 3;
+ else
+ h = (termHeight () - cmdWin->generic.height) / 2;
+ break;
+ default:
+ h = 0;
+ break;
+ }
+ }
+
+ return h;
+} /* tuiDefaultWinHeight */
+
+
+/*
+** tuiDefaultWinViewportHeight().
+** Answer the height of a window. If it hasn't been created yet,
+** answer what the height of a window would be based upon its
+** type and the layout.
+*/
+int
+#ifdef __STDC__
+tuiDefaultWinViewportHeight (
+ TuiWinType type,
+ TuiLayoutType layout)
+#else
+tuiDefaultWinViewportHeight (type, layout)
+ TuiWinType type;
+ TuiLayoutType layout;
+#endif
+{
+ int h;
+
+ h = tuiDefaultWinHeight (type, layout);
+
+ if (winList[type] == cmdWin)
+ h -= 1;
+ else
+ h -= 2;
+
+ return h;
+} /* tuiDefaultWinViewportHeight */
+
+
+/*
+** _initialize_tuiLayout().
+** Function to initialize gdb commands, for tui window layout
+** manipulation.
+*/
+void
+_initialize_tuiLayout ()
+{
+ if (tui_version)
+ {
+ add_com ("layout", class_tui, _tuiLayout_command,
+ "Change the layout of windows.\n\
+Usage: layout prev | next | <layout_name> \n\
+Layout names are:\n\
+ src : Displays source and command windows.\n\
+ asm : Displays disassembly and command windows.\n\
+ split : Displays source, disassembly and command windows.\n\
+ regs : Displays register window. If existing layout\n\
+ is source/command or assembly/command, the \n\
+ register window is displayed. If the\n\
+ source/assembly/command (split) is displayed, \n\
+ the register window is displayed with \n\
+ the window that has current logical focus.\n");
+ if (xdb_commands)
+ {
+ add_com ("td", class_tui, _tuiToggleLayout_command,
+ "Toggle between Source/Command and Disassembly/Command layouts.\n");
+ add_com ("ts", class_tui, _tuiToggleSplitLayout_command,
+ "Toggle between Source/Command or Disassembly/Command and \n\
+Source/Disassembly/Command layouts.\n");
+ }
+ }
+
+ return;
+} /* _intialize_tuiLayout */
+
+
+/*************************
+** STATIC LOCAL FUNCTIONS
+**************************/
+
+
+/*
+** _tuiSetLayoutTo()
+** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, REGS,
+** $REGS, $GREGS, $FREGS, $SREGS.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiSetLayoutTo (
+ char *layoutName)
+#else
+_tuiSetLayoutTo (layoutName)
+ char *layoutName;
+#endif
+{
+ TuiStatus status = TUI_SUCCESS;
+
+ if (layoutName != (char *) NULL)
+ {
+ register int i;
+ register char *bufPtr;
+ TuiLayoutType newLayout = UNDEFINED_LAYOUT;
+ TuiRegisterDisplayType dpyType = TUI_UNDEFINED_REGS;
+ TuiLayoutType curLayout = currentLayout ();
+
+ bufPtr = (char *) tuiStrDup (layoutName);
+ for (i = 0; (i < strlen (layoutName)); i++)
+ bufPtr[i] = toupper (bufPtr[i]);
+
+ /* First check for ambiguous input */
+ if (strlen (bufPtr) <= 1 && (*bufPtr == 'S' || *bufPtr == '$'))
+ {
+ warning ("Ambiguous command input.\n");
+ status = TUI_FAILURE;
+ }
+ else
+ {
+ if (subsetCompare (bufPtr, "SRC"))
+ newLayout = SRC_COMMAND;
+ else if (subsetCompare (bufPtr, "ASM"))
+ newLayout = DISASSEM_COMMAND;
+ else if (subsetCompare (bufPtr, "SPLIT"))
+ newLayout = SRC_DISASSEM_COMMAND;
+ else if (subsetCompare (bufPtr, "REGS") ||
+ subsetCompare (bufPtr, TUI_GENERAL_SPECIAL_REGS_NAME) ||
+ subsetCompare (bufPtr, TUI_GENERAL_REGS_NAME) ||
+ subsetCompare (bufPtr, TUI_FLOAT_REGS_NAME) ||
+ subsetCompare (bufPtr, TUI_SPECIAL_REGS_NAME))
+ {
+ if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND)
+ newLayout = SRC_DATA_COMMAND;
+ else
+ newLayout = DISASSEM_DATA_COMMAND;
+
+/* could ifdef out the following code. when compile with -z, there are null
+ pointer references that cause a core dump if 'layout regs' is the first
+ layout command issued by the user. HP has asked us to hook up this code
+ - edie epstein
+ */
+ if (subsetCompare (bufPtr, TUI_FLOAT_REGS_NAME))
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType !=
+ TUI_SFLOAT_REGS &&
+ dataWin->detail.dataDisplayInfo.regsDisplayType !=
+ TUI_DFLOAT_REGS)
+ dpyType = TUI_SFLOAT_REGS;
+ else
+ dpyType =
+ dataWin->detail.dataDisplayInfo.regsDisplayType;
+ }
+ else if (subsetCompare (bufPtr,
+ TUI_GENERAL_SPECIAL_REGS_NAME))
+ dpyType = TUI_GENERAL_AND_SPECIAL_REGS;
+ else if (subsetCompare (bufPtr, TUI_GENERAL_REGS_NAME))
+ dpyType = TUI_GENERAL_REGS;
+ else if (subsetCompare (bufPtr, TUI_SPECIAL_REGS_NAME))
+ dpyType = TUI_SPECIAL_REGS;
+ else
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType !=
+ TUI_UNDEFINED_REGS)
+ dpyType =
+ dataWin->detail.dataDisplayInfo.regsDisplayType;
+ else
+ dpyType = TUI_GENERAL_REGS;
+ }
+
+/* end of potential ifdef
+ */
+
+/* if ifdefed out code above, then assume that the user wishes to display the
+ general purpose registers
+ */
+
+/* dpyType = TUI_GENERAL_REGS;
+ */
+ }
+ else if (subsetCompare (bufPtr, "NEXT"))
+ newLayout = _nextLayout ();
+ else if (subsetCompare (bufPtr, "PREV"))
+ newLayout = _prevLayout ();
+ else
+ status = TUI_FAILURE;
+ free (bufPtr);
+
+ tuiSetLayout (newLayout, dpyType);
+ }
+ }
+ else
+ status = TUI_FAILURE;
+
+ return status;
+} /* _tuiSetLayoutTo */
+
+
+static Opaque
+#ifdef __STDC__
+_extractDisplayStartAddr (void)
+#else
+_extractDisplayStartAddr ()
+#endif
+{
+ TuiLayoutType curLayout = currentLayout ();
+ Opaque addr;
+
+ switch (curLayout)
+ {
+ case SRC_COMMAND:
+ case SRC_DATA_COMMAND:
+ addr = (Opaque) find_line_pc (
+ current_source_symtab,
+ srcWin->detail.sourceInfo.startLineOrAddr.lineNo);
+ break;
+ case DISASSEM_COMMAND:
+ case SRC_DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ addr = disassemWin->detail.sourceInfo.startLineOrAddr.addr;
+ break;
+ default:
+ addr = (Opaque) NULL;
+ break;
+ }
+
+ return addr;
+} /* _extractDisplayStartAddr */
+
+
+static void
+#ifdef __STDC__
+_tuiHandleXDBLayout (
+ TuiLayoutDefPtr layoutDef)
+#else
+_tuiHandleXDBLayout (layoutDef)
+ TuiLayoutDefPtr layoutDef;
+#endif
+{
+ if (layoutDef->split)
+ {
+ tuiSetLayout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS);
+ tuiSetWinFocusTo (winList[layoutDef->displayMode]);
+ }
+ else
+ {
+ if (layoutDef->displayMode == SRC_WIN)
+ tuiSetLayout (SRC_COMMAND, TUI_UNDEFINED_REGS);
+ else
+ tuiSetLayout (DISASSEM_DATA_COMMAND, layoutDef->regsDisplayType);
+ }
+
+
+ return;
+} /* _tuiHandleXDBLayout */
+
+
+static void
+#ifdef __STDC__
+_tuiToggleLayout_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiToggleLayout_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vToggleLayout_command, arg, fromTTY);
+}
+
+static void
+#ifdef __STDC__
+_tui_vToggleLayout_command (
+ va_list args)
+#else
+_tui_vToggleLayout_command (args)
+ va_list args;
+#endif
+{
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ if (layoutDef->displayMode == SRC_WIN)
+ layoutDef->displayMode = DISASSEM_WIN;
+ else
+ layoutDef->displayMode = SRC_WIN;
+
+ if (!layoutDef->split)
+ _tuiHandleXDBLayout (layoutDef);
+
+ return;
+} /* _tuiToggleLayout_command */
+
+
+static void
+#ifdef __STDC__
+_tuiToggleSplitLayout_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiToggleSplitLayout_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vToggleSplitLayout_command, arg, fromTTY);
+}
+
+static void
+#ifdef __STDC__
+_tui_vToggleSplitLayout_command (
+ va_list args)
+#else
+_tui_vToggleSplitLayout_command (args)
+ va_list args;
+#endif
+{
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ layoutDef->split = (!layoutDef->split);
+ _tuiHandleXDBLayout (layoutDef);
+
+ return;
+} /* _tui_vToggleSplitLayout_command */
+
+
+static void
+#ifdef __STDC__
+_tuiLayout_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiLayout_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if ((TuiStatus) tuiDo (
+ (TuiOpaqueFuncPtr) tui_vSetLayoutTo, arg) != TUI_SUCCESS)
+ warning ("Invalid layout specified.\n%s" LAYOUT_USAGE);
+
+ return;
+} /* _tuiLayout_command */
+
+/*
+** _nextLayout().
+** Answer the previous layout to cycle to.
+*/
+static TuiLayoutType
+#ifdef __STDC__
+_nextLayout (void)
+#else
+_nextLayout ()
+#endif
+{
+ TuiLayoutType newLayout;
+
+ newLayout = currentLayout ();
+ if (newLayout == UNDEFINED_LAYOUT)
+ newLayout = SRC_COMMAND;
+ else
+ {
+ newLayout++;
+ if (newLayout == UNDEFINED_LAYOUT)
+ newLayout = SRC_COMMAND;
+ }
+
+ return newLayout;
+} /* _nextLayout */
+
+
+/*
+** _prevLayout().
+** Answer the next layout to cycle to.
+*/
+static TuiLayoutType
+#ifdef __STDC__
+_prevLayout (void)
+#else
+_prevLayout ()
+#endif
+{
+ TuiLayoutType newLayout;
+
+ newLayout = currentLayout ();
+ if (newLayout == SRC_COMMAND)
+ newLayout = DISASSEM_DATA_COMMAND;
+ else
+ {
+ newLayout--;
+ if (newLayout == UNDEFINED_LAYOUT)
+ newLayout = DISASSEM_DATA_COMMAND;
+ }
+
+ return newLayout;
+} /* _prevLayout */
+
+
+
+/*
+** _makeCommandWindow().
+*/
+static void
+#ifdef __STDC__
+_makeCommandWindow (
+ TuiWinInfoPtr * winInfoPtr,
+ int height,
+ int originY)
+#else
+_makeCommandWindow (winInfoPtr, height, originY)
+ TuiWinInfoPtr *winInfoPtr;
+ int height;
+ int originY;
+#endif
+{
+ _initAndMakeWin ((Opaque *) winInfoPtr,
+ CMD_WIN,
+ height,
+ termWidth (),
+ 0,
+ originY,
+ DONT_BOX_WINDOW);
+
+ (*winInfoPtr)->canHighlight = FALSE;
+
+ return;
+} /* _makeCommandWindow */
+
+
+/*
+** _makeSourceWindow().
+*/
+static void
+#ifdef __STDC__
+_makeSourceWindow (
+ TuiWinInfoPtr * winInfoPtr,
+ int height,
+ int originY)
+#else
+_makeSourceWindow (winInfoPtr, height, originY)
+ TuiWinInfoPtr *winInfoPtr;
+ int height;
+ int originY;
+#endif
+{
+ _makeSourceOrDisassemWindow (winInfoPtr, SRC_WIN, height, originY);
+
+ return;
+} /* _makeSourceWindow */
+
+
+/*
+** _makeDisassemWindow().
+*/
+static void
+#ifdef __STDC__
+_makeDisassemWindow (
+ TuiWinInfoPtr * winInfoPtr,
+ int height,
+ int originY)
+#else
+_makeDisassemWindow (winInfoPtr, height, originY)
+ TuiWinInfoPtr *winInfoPtr;
+ int height;
+ int originY;
+#endif
+{
+ _makeSourceOrDisassemWindow (winInfoPtr, DISASSEM_WIN, height, originY);
+
+ return;
+} /* _makeDisassemWindow */
+
+
+/*
+** _makeDataWindow().
+*/
+static void
+#ifdef __STDC__
+_makeDataWindow (
+ TuiWinInfoPtr * winInfoPtr,
+ int height,
+ int originY)
+#else
+_makeDataWindow (winInfoPtr, height, originY)
+ TuiWinInfoPtr *winInfoPtr;
+ int height;
+ int originY;
+#endif
+{
+ _initAndMakeWin ((Opaque *) winInfoPtr,
+ DATA_WIN,
+ height,
+ termWidth (),
+ 0,
+ originY,
+ BOX_WINDOW);
+
+ return;
+} /* _makeDataWindow */
+
+
+
+/*
+** _showSourceCommand().
+** Show the Source/Command layout
+*/
+static void
+#ifdef __STDC__
+_showSourceCommand (void)
+#else
+_showSourceCommand ()
+#endif
+{
+ _showSourceOrDisassemAndCommand (SRC_COMMAND);
+
+ return;
+} /* _showSourceCommand */
+
+
+/*
+** _showDisassemCommand().
+** Show the Dissassem/Command layout
+*/
+static void
+#ifdef __STDC__
+_showDisassemCommand (void)
+#else
+_showDisassemCommand ()
+#endif
+{
+ _showSourceOrDisassemAndCommand (DISASSEM_COMMAND);
+
+ return;
+} /* _showDisassemCommand */
+
+
+/*
+** _showSourceDisassemCommand().
+** Show the Source/Disassem/Command layout
+*/
+static void
+#ifdef __STDC__
+_showSourceDisassemCommand (void)
+#else
+_showSourceDisassemCommand ()
+#endif
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (currentLayout () != SRC_DISASSEM_COMMAND)
+ {
+ int cmdHeight, srcHeight, asmHeight;
+
+ if (m_winPtrNotNull (cmdWin))
+ cmdHeight = cmdWin->generic.height;
+ else
+ cmdHeight = termHeight () / 3;
+
+ srcHeight = (termHeight () - cmdHeight) / 2;
+ asmHeight = termHeight () - (srcHeight + cmdHeight);
+
+ if (m_winPtrIsNull (srcWin))
+ _makeSourceWindow (&srcWin, srcHeight, 0);
+ else
+ {
+ _initGenWinInfo (&srcWin->generic,
+ srcWin->generic.type,
+ srcHeight,
+ srcWin->generic.width,
+ srcWin->detail.sourceInfo.executionInfo->width,
+ 0);
+ srcWin->canHighlight = TRUE;
+ _initGenWinInfo (srcWin->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ srcHeight,
+ 3,
+ 0,
+ 0);
+ m_beVisible (srcWin);
+ m_beVisible (srcWin->detail.sourceInfo.executionInfo);
+ srcWin->detail.sourceInfo.hasLocator = FALSE;;
+ }
+ if (m_winPtrNotNull (srcWin))
+ {
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ tuiShowSourceContent (srcWin);
+ if (m_winPtrIsNull (disassemWin))
+ {
+ _makeDisassemWindow (&disassemWin, asmHeight, srcHeight - 1);
+ _initAndMakeWin ((Opaque *) & locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ (srcHeight + asmHeight) - 1,
+ DONT_BOX_WINDOW);
+ }
+ else
+ {
+ _initGenWinInfo (locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ (srcHeight + asmHeight) - 1);
+ disassemWin->detail.sourceInfo.hasLocator = TRUE;
+ _initGenWinInfo (
+ &disassemWin->generic,
+ disassemWin->generic.type,
+ asmHeight,
+ disassemWin->generic.width,
+ disassemWin->detail.sourceInfo.executionInfo->width,
+ srcHeight - 1);
+ _initGenWinInfo (disassemWin->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ asmHeight,
+ 3,
+ 0,
+ srcHeight - 1);
+ disassemWin->canHighlight = TRUE;
+ m_beVisible (disassemWin);
+ m_beVisible (disassemWin->detail.sourceInfo.executionInfo);
+ }
+ if (m_winPtrNotNull (disassemWin))
+ {
+ srcWin->detail.sourceInfo.hasLocator = FALSE;
+ disassemWin->detail.sourceInfo.hasLocator = TRUE;
+ m_beVisible (locator);
+ tuiShowLocatorContent ();
+ tuiShowSourceContent (disassemWin);
+
+ if (m_winPtrIsNull (cmdWin))
+ _makeCommandWindow (&cmdWin,
+ cmdHeight,
+ termHeight () - cmdHeight);
+ else
+ {
+ _initGenWinInfo (&cmdWin->generic,
+ cmdWin->generic.type,
+ cmdWin->generic.height,
+ cmdWin->generic.width,
+ 0,
+ cmdWin->generic.origin.y);
+ cmdWin->canHighlight = FALSE;
+ m_beVisible (cmdWin);
+ }
+ if (m_winPtrNotNull (cmdWin))
+ tuiRefreshWin (&cmdWin->generic);
+ }
+ }
+ setCurrentLayoutTo (SRC_DISASSEM_COMMAND);
+ }
+
+ return;
+} /* _showSourceDisassemCommand */
+
+
+/*
+** _showData().
+** Show the Source/Data/Command or the Dissassembly/Data/Command layout
+*/
+static void
+#ifdef __STDC__
+_showData (
+ TuiLayoutType newLayout)
+#else
+_showData (newLayout)
+ TuiLayoutType newLayout;
+#endif
+{
+ int totalHeight = (termHeight () - cmdWin->generic.height);
+ int srcHeight, dataHeight;
+ TuiWinType winType;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+
+ dataHeight = totalHeight / 2;
+ srcHeight = totalHeight - dataHeight;
+ m_allBeInvisible ();
+ m_beInvisible (locator);
+ _makeDataWindow (&dataWin, dataHeight, 0);
+ dataWin->canHighlight = TRUE;
+ if (newLayout == SRC_DATA_COMMAND)
+ winType = SRC_WIN;
+ else
+ winType = DISASSEM_WIN;
+ if (m_winPtrIsNull (winList[winType]))
+ {
+ if (winType == SRC_WIN)
+ _makeSourceWindow (&winList[winType], srcHeight, dataHeight - 1);
+ else
+ _makeDisassemWindow (&winList[winType], srcHeight, dataHeight - 1);
+ _initAndMakeWin ((Opaque *) & locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ totalHeight - 1,
+ DONT_BOX_WINDOW);
+ }
+ else
+ {
+ _initGenWinInfo (&winList[winType]->generic,
+ winList[winType]->generic.type,
+ srcHeight,
+ winList[winType]->generic.width,
+ winList[winType]->detail.sourceInfo.executionInfo->width,
+ dataHeight - 1);
+ _initGenWinInfo (winList[winType]->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ srcHeight,
+ 3,
+ 0,
+ dataHeight - 1);
+ m_beVisible (winList[winType]);
+ m_beVisible (winList[winType]->detail.sourceInfo.executionInfo);
+ _initGenWinInfo (locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ totalHeight - 1);
+ }
+ winList[winType]->detail.sourceInfo.hasLocator = TRUE;
+ m_beVisible (locator);
+ tuiShowLocatorContent ();
+ addToSourceWindows (winList[winType]);
+ setCurrentLayoutTo (newLayout);
+
+ return;
+} /* _showData */
+
+/*
+** _initGenWinInfo().
+*/
+static void
+#ifdef __STDC__
+_initGenWinInfo (
+ TuiGenWinInfoPtr winInfo,
+ TuiWinType type,
+ int height,
+ int width,
+ int originX,
+ int originY)
+#else
+_initGenWinInfo (winInfo, type, height, width, originX, originY)
+ TuiGenWinInfoPtr winInfo;
+ TuiWinType type;
+ int height;
+ int width;
+ int originX;
+ int originY;
+#endif
+{
+ int h = height;
+
+ winInfo->type = type;
+ winInfo->width = width;
+ winInfo->height = h;
+ if (h > 1)
+ {
+ winInfo->viewportHeight = h - 1;
+ if (winInfo->type != CMD_WIN)
+ winInfo->viewportHeight--;
+ }
+ else
+ winInfo->viewportHeight = 1;
+ winInfo->origin.x = originX;
+ winInfo->origin.y = originY;
+
+ return;
+} /* _initGenWinInfo */
+
+/*
+** _initAndMakeWin().
+*/
+static void
+#ifdef __STDC__
+_initAndMakeWin (
+ Opaque * winInfoPtr,
+ TuiWinType winType,
+ int height,
+ int width,
+ int originX,
+ int originY,
+ int boxIt)
+#else
+_initAndMakeWin (winInfoPtr, winType, height, width, originX, originY, boxIt)
+ Opaque *winInfoPtr;
+ TuiWinType winType;
+ int height;
+ int width;
+ int originX;
+ int originY;
+ int boxIt;
+#endif
+{
+ Opaque opaqueWinInfo = *winInfoPtr;
+ TuiGenWinInfoPtr generic;
+
+ if (opaqueWinInfo == (Opaque) NULL)
+ {
+ if (m_winIsAuxillary (winType))
+ opaqueWinInfo = (Opaque) allocGenericWinInfo ();
+ else
+ opaqueWinInfo = (Opaque) allocWinInfo (winType);
+ }
+ if (m_winIsAuxillary (winType))
+ generic = (TuiGenWinInfoPtr) opaqueWinInfo;
+ else
+ generic = &((TuiWinInfoPtr) opaqueWinInfo)->generic;
+
+ if (opaqueWinInfo != (Opaque) NULL)
+ {
+ _initGenWinInfo (generic, winType, height, width, originX, originY);
+ if (!m_winIsAuxillary (winType))
+ {
+ if (generic->type == CMD_WIN)
+ ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = FALSE;
+ else
+ ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = TRUE;
+ }
+ makeWindow (generic, boxIt);
+ if (winType == LOCATOR_WIN)
+ tuiClearLocatorDisplay ();
+ echo ();
+ }
+ *winInfoPtr = opaqueWinInfo;
+
+ return;
+} /* _initAndMakeWin */
+
+
+/*
+** _makeSourceOrDisassemWindow().
+*/
+static void
+#ifdef __STDC__
+_makeSourceOrDisassemWindow (
+ TuiWinInfoPtr * winInfoPtr,
+ TuiWinType type,
+ int height,
+ int originY)
+#else
+_makeSourceOrDisassemWindow (winInfoPtr, type, height, originY)
+ TuiWinInfoPtr *winInfoPtr;
+ TuiWinType type;
+ int height;
+ int originY;
+#endif
+{
+ TuiGenWinInfoPtr executionInfo = (TuiGenWinInfoPtr) NULL;
+
+ /*
+ ** Create the exeuction info window.
+ */
+ if (type == SRC_WIN)
+ executionInfo = sourceExecInfoWinPtr ();
+ else
+ executionInfo = disassemExecInfoWinPtr ();
+ _initAndMakeWin ((Opaque *) & executionInfo,
+ EXEC_INFO_WIN,
+ height,
+ 3,
+ 0,
+ originY,
+ DONT_BOX_WINDOW);
+ /*
+ ** Now create the source window.
+ */
+ _initAndMakeWin ((Opaque *) winInfoPtr,
+ type,
+ height,
+ termWidth () - executionInfo->width,
+ executionInfo->width,
+ originY,
+ BOX_WINDOW);
+
+ (*winInfoPtr)->detail.sourceInfo.executionInfo = executionInfo;
+
+ return;
+} /* _makeSourceOrDisassemWindow */
+
+
+/*
+** _showSourceOrDisassemAndCommand().
+** Show the Source/Command or the Disassem layout
+*/
+static void
+#ifdef __STDC__
+_showSourceOrDisassemAndCommand (
+ TuiLayoutType layoutType)
+#else
+_showSourceOrDisassemAndCommand (layoutType)
+ TuiLayoutType layoutType;
+#endif
+{
+ if (currentLayout () != layoutType)
+ {
+ TuiWinInfoPtr *winInfoPtr;
+ int areaLeft;
+ int srcHeight, cmdHeight;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (m_winPtrNotNull (cmdWin))
+ cmdHeight = cmdWin->generic.height;
+ else
+ cmdHeight = termHeight () / 3;
+ srcHeight = termHeight () - cmdHeight;
+
+
+ if (layoutType == SRC_COMMAND)
+ winInfoPtr = &srcWin;
+ else
+ winInfoPtr = &disassemWin;
+
+ if (m_winPtrIsNull (*winInfoPtr))
+ {
+ if (layoutType == SRC_COMMAND)
+ _makeSourceWindow (winInfoPtr, srcHeight - 1, 0);
+ else
+ _makeDisassemWindow (winInfoPtr, srcHeight - 1, 0);
+ _initAndMakeWin ((Opaque *) & locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ srcHeight - 1,
+ DONT_BOX_WINDOW);
+ }
+ else
+ {
+ _initGenWinInfo (locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ srcHeight - 1);
+ (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE;
+ _initGenWinInfo (
+ &(*winInfoPtr)->generic,
+ (*winInfoPtr)->generic.type,
+ srcHeight - 1,
+ (*winInfoPtr)->generic.width,
+ (*winInfoPtr)->detail.sourceInfo.executionInfo->width,
+ 0);
+ _initGenWinInfo ((*winInfoPtr)->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ srcHeight - 1,
+ 3,
+ 0,
+ 0);
+ (*winInfoPtr)->canHighlight = TRUE;
+ m_beVisible (*winInfoPtr);
+ m_beVisible ((*winInfoPtr)->detail.sourceInfo.executionInfo);
+ }
+ if (m_winPtrNotNull (*winInfoPtr))
+ {
+ (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE;
+ m_beVisible (locator);
+ tuiShowLocatorContent ();
+ tuiShowSourceContent (*winInfoPtr);
+
+ if (m_winPtrIsNull (cmdWin))
+ {
+ _makeCommandWindow (&cmdWin, cmdHeight, srcHeight);
+ tuiRefreshWin (&cmdWin->generic);
+ }
+ else
+ {
+ _initGenWinInfo (&cmdWin->generic,
+ cmdWin->generic.type,
+ cmdWin->generic.height,
+ cmdWin->generic.width,
+ cmdWin->generic.origin.x,
+ cmdWin->generic.origin.y);
+ cmdWin->canHighlight = FALSE;
+ m_beVisible (cmdWin);
+ }
+ }
+ setCurrentLayoutTo (layoutType);
+ }
+
+ return;
+} /* _showSourceOrDisassemAndCommand */
diff --git a/contrib/gdb/gdb/tui/tuiLayout.h b/contrib/gdb/gdb/tui/tuiLayout.h
new file mode 100644
index 0000000..57d8bbc
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiLayout.h
@@ -0,0 +1,15 @@
+#ifndef TUI_LAYOUT_H
+#define TUI_LAYOUT_H
+
+extern void showLayout PARAMS ((TuiLayoutType));
+extern void tuiAddWinToLayout PARAMS ((TuiWinType));
+extern void tui_vAddWinToLayout PARAMS ((va_list));
+extern int tuiDefaultWinHeight
+ PARAMS ((TuiWinType, TuiLayoutType));
+extern int tuiDefaultWinViewportHeight
+ PARAMS ((TuiWinType, TuiLayoutType));
+extern TuiStatus tuiSetLayout
+ PARAMS ((TuiLayoutType, TuiRegisterDisplayType));
+extern TuiStatus tui_vSetLayoutTo PARAMS ((va_list));
+
+#endif /*TUI_LAYOUT_H*/
diff --git a/contrib/gdb/gdb/tui/tuiRegs.c b/contrib/gdb/gdb/tui/tuiRegs.c
new file mode 100644
index 0000000..b78b9bc
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiRegs.c
@@ -0,0 +1,1210 @@
+
+/*
+** tuiRegs.c
+** This module contains functions to support display of registers
+** in the data window.
+*/
+
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "tuiLayout.h"
+#include "tuiWin.h"
+
+
+/*****************************************
+** LOCAL DEFINITIONS **
+******************************************/
+#define DOUBLE_FLOAT_LABEL_WIDTH 6
+#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
+#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
+
+#define SINGLE_FLOAT_LABEL_WIDTH 6
+#define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
+#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
+
+#define SINGLE_LABEL_WIDTH 10
+#define SINGLE_LABEL_FMT "%10.10s: "
+#define SINGLE_VALUE_WIDTH 14/* minimum of 8 but may be in sci notation */
+
+/* In the code HP gave Cygnus, this was actually a function call to a
+ PA-specific function, which was supposed to determine whether the
+ target was a 64-bit or 32-bit processor. However, the 64-bit
+ support wasn't complete, so we didn't merge that in, so we leave
+ this here as a stub. */
+#define IS_64BIT 0
+
+/*****************************************
+** STATIC DATA **
+******************************************/
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+static TuiStatus _tuiSetRegsContent
+ PARAMS ((int, int, struct frame_info *,
+ TuiRegisterDisplayType, int));
+static char *_tuiRegisterName PARAMS ((int));
+static TuiStatus _tuiGetRegisterRawValue
+ PARAMS ((int, char *, struct frame_info *));
+static void _tuiSetRegisterElement
+ PARAMS ((int, struct frame_info *,
+ TuiDataElementPtr, int));
+static void _tuiDisplayRegister
+ PARAMS ((int, TuiGenWinInfoPtr, enum precision_type));
+static void _tuiRegisterFormat
+ PARAMS ((char *, int, int, TuiDataElementPtr,
+ enum precision_type));
+static TuiStatus _tuiSetGeneralRegsContent PARAMS ((int));
+static TuiStatus _tuiSetSpecialRegsContent PARAMS ((int));
+static TuiStatus _tuiSetGeneralAndSpecialRegsContent PARAMS ((int));
+static TuiStatus _tuiSetFloatRegsContent PARAMS ((TuiRegisterDisplayType, int));
+static int _tuiRegValueHasChanged
+ PARAMS ((TuiDataElementPtr, struct frame_info *,
+ char *));
+static void _tuiShowFloat_command PARAMS ((char *, int));
+static void _tuiShowGeneral_command PARAMS ((char *, int));
+static void _tuiShowSpecial_command PARAMS ((char *, int));
+static void _tui_vShowRegisters_commandSupport PARAMS ((va_list));
+static void _tuiToggleFloatRegs_command PARAMS ((char *, int));
+static void _tuiScrollRegsForward_command PARAMS ((char *, int));
+static void _tuiScrollRegsBackward_command PARAMS ((char *, int));
+static void _tui_vShowRegisters_commandSupport PARAMS ((va_list));
+
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*
+** tuiLastRegsLineNo()
+** Answer the number of the last line in the regs display.
+** If there are no registers (-1) is returned.
+*/
+int
+#ifdef __STDC__
+tuiLastRegsLineNo (void)
+#else
+tuiLastRegsLineNo ()
+#endif
+{
+ register int numLines = (-1);
+
+ if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
+ dataWin->detail.dataDisplayInfo.regsColumnCount);
+ if (dataWin->detail.dataDisplayInfo.regsContentCount %
+ dataWin->detail.dataDisplayInfo.regsColumnCount)
+ numLines++;
+ }
+ return numLines;
+} /* tuiLastRegsLineNo */
+
+
+/*
+** tuiLineFromRegElementNo()
+** Answer the line number that the register element at elementNo is
+** on. If elementNo is greater than the number of register elements
+** there are, -1 is returned.
+*/
+int
+#ifdef __STDC__
+tuiLineFromRegElementNo (
+ int elementNo)
+#else
+tuiLineFromRegElementNo (elementNo)
+ int elementNo;
+#endif
+{
+ if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ {
+ int i, line = (-1);
+
+ i = 1;
+ while (line == (-1))
+ {
+ if (elementNo <
+ (dataWin->detail.dataDisplayInfo.regsColumnCount * i))
+ line = i - 1;
+ else
+ i++;
+ }
+
+ return line;
+ }
+ else
+ return (-1);
+} /* tuiLineFromRegElementNo */
+
+
+/*
+** tuiFirstRegElementNoInLine()
+** Answer the index of the first element in lineNo. If lineNo is
+** past the register area (-1) is returned.
+*/
+int
+#ifdef __STDC__
+tuiFirstRegElementNoInLine (
+ int lineNo)
+#else
+tuiFirstRegElementNoInLine (lineNo)
+ int lineNo;
+#endif
+{
+ if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
+ <= dataWin->detail.dataDisplayInfo.regsContentCount)
+ return ((lineNo + 1) *
+ dataWin->detail.dataDisplayInfo.regsColumnCount) -
+ dataWin->detail.dataDisplayInfo.regsColumnCount;
+ else
+ return (-1);
+} /* tuiFirstRegElementNoInLine */
+
+
+/*
+** tuiLastRegElementNoInLine()
+** Answer the index of the last element in lineNo. If lineNo is past
+** the register area (-1) is returned.
+*/
+int
+#ifdef __STDC__
+tuiLastRegElementNoInLine (
+ int lineNo)
+#else
+tuiLastRegElementNoInLine (lineNo)
+ int lineNo;
+#endif
+{
+ if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
+ dataWin->detail.dataDisplayInfo.regsContentCount)
+ return ((lineNo + 1) *
+ dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
+ else
+ return (-1);
+} /* tuiLastRegElementNoInLine */
+
+
+/*
+** tuiCalculateRegsColumnCount
+** Calculate the number of columns that should be used to display
+** the registers.
+*/
+int
+#ifdef __STDC__
+tuiCalculateRegsColumnCount (
+ TuiRegisterDisplayType dpyType)
+#else
+tuiCalculateRegsColumnCount (dpyType)
+ TuiRegisterDisplayType dpyType;
+#endif
+{
+ int colCount, colWidth;
+
+ if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
+ colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
+ else
+ {
+ if (dpyType == TUI_SFLOAT_REGS)
+ colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
+ else
+ colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
+ }
+ colCount = (dataWin->generic.width - 2) / colWidth;
+
+ return colCount;
+} /* tuiCalulateRegsColumnCount */
+
+
+/*
+** tuiShowRegisters().
+** Show the registers int the data window as indicated by dpyType.
+** If there is any other registers being displayed, then they are
+** cleared. What registers are displayed is dependent upon dpyType.
+*/
+void
+#ifdef __STDC__
+tuiShowRegisters (
+ TuiRegisterDisplayType dpyType)
+#else
+tuiShowRegisters (dpyType)
+ TuiRegisterDisplayType dpyType;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+ int refreshValuesOnly = FALSE;
+
+ /* Say that registers should be displayed, even if there is a problem */
+ dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
+
+ if (target_has_registers)
+ {
+ refreshValuesOnly =
+ (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
+ switch (dpyType)
+ {
+ case TUI_GENERAL_REGS:
+ ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
+ break;
+ case TUI_SFLOAT_REGS:
+ case TUI_DFLOAT_REGS:
+ ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
+ break;
+
+/* could ifdef out */
+
+ case TUI_SPECIAL_REGS:
+ ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
+ break;
+ case TUI_GENERAL_AND_SPECIAL_REGS:
+ ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
+ break;
+
+/* end of potential if def */
+
+ default:
+ break;
+ }
+ }
+ if (ret == TUI_FAILURE)
+ {
+ dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
+ tuiEraseDataContent (NO_REGS_STRING);
+ }
+ else
+ {
+ int i;
+
+ /* Clear all notation of changed values */
+ for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+
+ dataItemWin = &dataWin->detail.dataDisplayInfo.
+ regsContent[i]->whichElement.dataWindow;
+ (&((TuiWinElementPtr)
+ dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
+ }
+ dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
+ tuiDisplayAllData ();
+ }
+ (tuiLayoutDef ())->regsDisplayType = dpyType;
+
+ return;
+} /* tuiShowRegisters */
+
+
+/*
+** tuiDisplayRegistersFrom().
+** Function to display the registers in the content from
+** 'startElementNo' until the end of the register content or the
+** end of the display height. No checking for displaying past
+** the end of the registers is done here.
+*/
+void
+#ifdef __STDC__
+tuiDisplayRegistersFrom (
+ int startElementNo)
+#else
+tuiDisplayRegistersFrom (startElementNo)
+ int startElementNo;
+#endif
+{
+ if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
+ dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ register int i = startElementNo;
+ int j, valueCharsWide, charsWide, itemWinWidth, curY, labelWidth;
+ enum precision_type precision;
+
+ precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
+ == TUI_DFLOAT_REGS) ?
+ double_precision : unspecified_precision;
+ if (IS_64BIT ||
+ dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
+ {
+ valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
+ labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_SFLOAT_REGS)
+ {
+ valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
+ labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ valueCharsWide = SINGLE_VALUE_WIDTH;
+ labelWidth = SINGLE_LABEL_WIDTH;
+ }
+ }
+ itemWinWidth = valueCharsWide + labelWidth;
+ /*
+ ** Now create each data "sub" window, and write the display into it.
+ */
+ curY = 1;
+ while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
+ curY <= dataWin->generic.viewportHeight)
+ {
+ for (j = 0;
+ (j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
+ i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+ TuiDataElementPtr dataElementPtr;
+
+ /* create the window if necessary*/
+ dataItemWin = &dataWin->detail.dataDisplayInfo.
+ regsContent[i]->whichElement.dataWindow;
+ dataElementPtr = &((TuiWinElementPtr)
+ dataItemWin->content[0])->whichElement.data;
+ if (dataItemWin->handle == (WINDOW *) NULL)
+ {
+ dataItemWin->height = 1;
+ dataItemWin->width = (precision == double_precision) ?
+ itemWinWidth + 2 : itemWinWidth + 1;
+ dataItemWin->origin.x = (itemWinWidth * j) + 1;
+ dataItemWin->origin.y = curY;
+ makeWindow (dataItemWin, DONT_BOX_WINDOW);
+ }
+ /*
+ ** Get the printable representation of the register
+ ** and display it
+ */
+ _tuiDisplayRegister (
+ dataElementPtr->itemNo, dataItemWin, precision);
+ i++; /* next register */
+ }
+ curY++; /* next row; */
+ }
+ }
+
+ return;
+} /* tuiDisplayRegistersFrom */
+
+
+/*
+** tuiDisplayRegElementAtLine().
+** Function to display the registers in the content from
+** 'startElementNo' on 'startLineNo' until the end of the
+** register content or the end of the display height.
+** This function checks that we won't display off the end
+** of the register display.
+*/
+void
+#ifdef __STDC__
+tuiDisplayRegElementAtLine (
+ int startElementNo,
+ int startLineNo)
+#else
+tuiDisplayRegElementAtLine (startElementNo, startLineNo)
+ int startElementNo;
+ int startLineNo;
+#endif
+{
+ if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
+ dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ register int elementNo = startElementNo;
+
+ if (startElementNo != 0 && startLineNo != 0)
+ {
+ register int lastLineNo, firstLineOnLastPage;
+
+ lastLineNo = tuiLastRegsLineNo ();
+ firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
+ if (firstLineOnLastPage < 0)
+ firstLineOnLastPage = 0;
+ /*
+ ** If there is no other data displayed except registers,
+ ** and the elementNo causes us to scroll past the end of the
+ ** registers, adjust what element to really start the display at.
+ */
+ if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
+ startLineNo > firstLineOnLastPage)
+ elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage);
+ }
+ tuiDisplayRegistersFrom (elementNo);
+ }
+
+ return;
+} /* tuiDisplayRegElementAtLine */
+
+
+
+/*
+** tuiDisplayRegistersFromLine().
+** Function to display the registers starting at line lineNo in
+** the data window. Answers the line number that the display
+** actually started from. If nothing is displayed (-1) is returned.
+*/
+int
+#ifdef __STDC__
+tuiDisplayRegistersFromLine (
+ int lineNo,
+ int forceDisplay)
+#else
+tuiDisplayRegistersFromLine (lineNo, forceDisplay)
+ int lineNo;
+ int forceDisplay;
+#endif
+{
+ int elementNo;
+
+ if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ int line, elementNo;
+
+ if (lineNo < 0)
+ line = 0;
+ else if (forceDisplay)
+ { /*
+ ** If we must display regs (forceDisplay is true), then make
+ ** sure that we don't display off the end of the registers.
+ */
+ if (lineNo >= tuiLastRegsLineNo ())
+ {
+ if ((line = tuiLineFromRegElementNo (
+ dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
+ line = 0;
+ }
+ else
+ line = lineNo;
+ }
+ else
+ line = lineNo;
+
+ elementNo = tuiFirstRegElementNoInLine (line);
+ if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ tuiDisplayRegElementAtLine (elementNo, line);
+ else
+ line = (-1);
+
+ return line;
+ }
+
+ return (-1); /* nothing was displayed */
+} /* tuiDisplayRegistersFromLine */
+
+
+/*
+** tuiCheckRegisterValues()
+** This function check all displayed registers for changes in
+** values, given a particular frame. If the values have changed,
+** they are updated with the new value and highlighted.
+*/
+void
+#ifdef __STDC__
+tuiCheckRegisterValues (
+ struct frame_info *frame)
+#else
+tuiCheckRegisterValues (frame)
+ struct frame_info *frame;
+#endif
+{
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ {
+ if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
+ dataWin->detail.dataDisplayInfo.displayRegs)
+ tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType);
+ else
+ {
+ int i, j;
+ char rawBuf[MAX_REGISTER_RAW_SIZE];
+
+ for (i = 0;
+ (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
+ {
+ TuiDataElementPtr dataElementPtr;
+ TuiGenWinInfoPtr dataItemWinPtr;
+ int wasHilighted;
+
+ dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
+ regsContent[i]->whichElement.dataWindow;
+ dataElementPtr = &((TuiWinElementPtr)
+ dataItemWinPtr->content[0])->whichElement.data;
+ wasHilighted = dataElementPtr->highlight;
+ dataElementPtr->highlight =
+ _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
+ if (dataElementPtr->highlight)
+ {
+ for (j = 0; j < MAX_REGISTER_RAW_SIZE; j++)
+ ((char *) dataElementPtr->value)[j] = rawBuf[j];
+ _tuiDisplayRegister (
+ dataElementPtr->itemNo,
+ dataItemWinPtr,
+ ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_DFLOAT_REGS) ?
+ double_precision : unspecified_precision));
+ }
+ else if (wasHilighted)
+ {
+ dataElementPtr->highlight = FALSE;
+ _tuiDisplayRegister (
+ dataElementPtr->itemNo,
+ dataItemWinPtr,
+ ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_DFLOAT_REGS) ?
+ double_precision : unspecified_precision));
+ }
+ }
+ }
+ }
+ return;
+} /* tuiCheckRegisterValues */
+
+
+/*
+** tuiToggleFloatRegs().
+*/
+void
+#ifdef __STDC__
+tuiToggleFloatRegs (void)
+#else
+tuiToggleFloatRegs ()
+#endif
+{
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
+ layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
+ else
+ layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
+
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
+ (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
+ dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
+ tuiShowRegisters (layoutDef->floatRegsDisplayType);
+
+ return;
+} /* tuiToggleFloatRegs */
+
+
+void
+_initialize_tuiRegs ()
+{
+ if (tui_version && xdb_commands)
+ {
+ add_com ("fr", class_tui, _tuiShowFloat_command,
+ "Display only floating point registers\n");
+ add_com ("gr", class_tui, _tuiShowGeneral_command,
+ "Display only general registers\n");
+ add_com ("sr", class_tui, _tuiShowSpecial_command,
+ "Display only special registers\n");
+ add_com ("+r", class_tui, _tuiScrollRegsForward_command,
+ "Scroll the registers window forward\n");
+ add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
+ "Scroll the register window backward\n");
+ add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
+ "Toggle between single and double precision floating point registers.\n");
+ add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
+ class_tui,
+ _tuiToggleFloatRegs_command,
+ "Toggle between single and double precision floating point \
+registers.\n",
+ &togglelist);
+ }
+
+ return;
+} /* _initialize_tuiRegs */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+
+
+/*
+** _tuiRegisterName().
+** Return the register name.
+*/
+static char *
+#ifdef __STDC__
+_tuiRegisterName (
+ int regNum)
+#else
+_tuiRegisterName (regNum)
+ int regNum;
+#endif
+{
+ if (reg_names[regNum] != (char *) NULL && *(reg_names[regNum]) != (char) 0)
+ return reg_names[regNum];
+ else
+ return ((char *) NULL);
+} /* tuiGetRegisterName */
+
+
+/*
+** _tuiRegisterFormat
+** Function to format the register name and value into a buffer,
+** suitable for printing or display
+*/
+static void
+#ifdef __STDC__
+_tuiRegisterFormat (
+ char *buf,
+ int bufLen,
+ int regNum,
+ TuiDataElementPtr dataElement,
+ enum precision_type precision)
+#else
+_tuiRegisterFormat (buf, bufLen, regNum, dataElement, precision)
+ char *buf;
+ int bufLen;
+ int regNum;
+ TuiDataElementPtr dataElement;
+ enum precision_type precision;
+#endif
+{
+ char tmpBuf[15];
+ char *fmt;
+ GDB_FILE *stream;
+
+ stream = gdb_file_init_astring(bufLen);
+ pa_do_strcat_registers_info (regNum, 0, stream, precision);
+ strcpy (buf, gdb_file_get_strbuf(stream));
+ gdb_file_deallocate(&stream);
+
+ return;
+} /* _tuiRegisterFormat */
+
+
+#define NUM_GENERAL_REGS 32
+/*
+** _tuiSetGeneralRegsContent().
+** Set the content of the data window to consist of the general registers.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiSetGeneralRegsContent (
+ int refreshValuesOnly)
+#else
+_tuiSetGeneralRegsContent (refreshValuesOnly)
+ int refreshValuesOnly;
+#endif
+{
+ return (_tuiSetRegsContent (0,
+ NUM_GENERAL_REGS - 1,
+ selected_frame,
+ TUI_GENERAL_REGS,
+ refreshValuesOnly));
+
+} /* _tuiSetGeneralRegsContent */
+
+
+#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
+/*
+** _tuiSetSpecialRegsContent().
+** Set the content of the data window to consist of the special registers.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiSetSpecialRegsContent (
+ int refreshValuesOnly)
+#else
+_tuiSetSpecialRegsContent (refreshValuesOnly)
+ int refreshValuesOnly;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+ int i, endRegNum;
+
+ endRegNum = FP0_REGNUM - 1;
+#if 0
+ endRegNum = (-1);
+ for (i = START_SPECIAL_REGS; (i < ARCH_NUM_REGS && endRegNum < 0); i++)
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ endRegNum = i - 1;
+#endif
+ ret = _tuiSetRegsContent (START_SPECIAL_REGS,
+ endRegNum,
+ selected_frame,
+ TUI_SPECIAL_REGS,
+ refreshValuesOnly);
+
+ return ret;
+} /* _tuiSetSpecialRegsContent */
+
+
+/*
+** _tuiSetGeneralAndSpecialRegsContent().
+** Set the content of the data window to consist of the special registers.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiSetGeneralAndSpecialRegsContent (
+ int refreshValuesOnly)
+#else
+_tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly)
+ int refreshValuesOnly;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+ int i, endRegNum = (-1);
+
+ endRegNum = FP0_REGNUM - 1;
+#if 0
+ endRegNum = (-1);
+ for (i = 0; (i < ARCH_NUM_REGS && endRegNum < 0); i++)
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ endRegNum = i - 1;
+#endif
+ ret = _tuiSetRegsContent (
+ 0, endRegNum, selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
+
+ return ret;
+} /* _tuiSetGeneralAndSpecialRegsContent */
+
+/*
+** _tuiSetFloatRegsContent().
+** Set the content of the data window to consist of the float registers.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiSetFloatRegsContent (
+ TuiRegisterDisplayType dpyType,
+ int refreshValuesOnly)
+#else
+_tuiSetFloatRegsContent (dpyType, refreshValuesOnly)
+ TuiRegisterDisplayType dpyType;
+ int refreshValuesOnly;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+ int i, startRegNum;
+
+ startRegNum = FP0_REGNUM;
+#if 0
+ startRegNum = (-1);
+ for (i = ARCH_NUM_REGS - 1; (i >= 0 && startRegNum < 0); i--)
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) != TYPE_CODE_FLT)
+ startRegNum = i + 1;
+#endif
+ ret = _tuiSetRegsContent (startRegNum,
+ ARCH_NUM_REGS - 1,
+ selected_frame,
+ dpyType,
+ refreshValuesOnly);
+
+ return ret;
+} /* _tuiSetFloatRegsContent */
+
+
+/*
+** _tuiRegValueHasChanged().
+** Answer TRUE if the register's value has changed, FALSE otherwise.
+** If TRUE, newValue is filled in with the new value.
+*/
+static int
+#ifdef __STDC__
+_tuiRegValueHasChanged (
+ TuiDataElementPtr dataElement,
+ struct frame_info *frame,
+ char *newValue)
+#else
+_tuiRegValueHasChanged (dataElement, frame, newValue)
+ TuiDataElementPtr dataElement;
+ struct frame_info *frame;
+ char *newValue;
+#endif
+{
+ int hasChanged = FALSE;
+
+ if (dataElement->itemNo != UNDEFINED_ITEM &&
+ _tuiRegisterName (dataElement->itemNo) != (char *) NULL)
+ {
+ char rawBuf[MAX_REGISTER_RAW_SIZE];
+ int i;
+
+ if (_tuiGetRegisterRawValue (
+ dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
+ {
+ for (i = 0; (i < MAX_REGISTER_RAW_SIZE && !hasChanged); i++)
+ hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
+ if (hasChanged && newValue != (char *) NULL)
+ {
+ for (i = 0; (i < MAX_REGISTER_RAW_SIZE); i++)
+ newValue[i] = rawBuf[i];
+ }
+ }
+ }
+ return hasChanged;
+} /* _tuiRegValueHasChanged */
+
+
+
+/*
+** _tuiGetRegisterRawValue().
+** Get the register raw value. The raw value is returned in regValue.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiGetRegisterRawValue (
+ int regNum,
+ char *regValue,
+ struct frame_info *frame)
+#else
+_tuiGetRegisterRawValue (regNum, regValue, frame)
+ int regNum;
+ char *regValue;
+ struct frame_info *frame;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+
+ if (target_has_registers)
+ {
+ read_relative_register_raw_bytes_for_frame (regNum, regValue, frame);
+ ret = TUI_SUCCESS;
+ }
+
+ return ret;
+} /* _tuiGetRegisterRawValue */
+
+
+
+/*
+** _tuiSetRegisterElement().
+** Function to initialize a data element with the input and
+** the register value.
+*/
+static void
+#ifdef __STDC__
+_tuiSetRegisterElement (
+ int regNum,
+ struct frame_info *frame,
+ TuiDataElementPtr dataElement,
+ int refreshValueOnly)
+#else
+_tuiSetRegisterElement (regNum, frame, dataElement, refreshValueOnly)
+ int regNum;
+ struct frame_info *frame;
+ TuiDataElementPtr dataElement;
+ int refreshValueOnly;
+#endif
+{
+ if (dataElement != (TuiDataElementPtr) NULL)
+ {
+ if (!refreshValueOnly)
+ {
+ dataElement->itemNo = regNum;
+ dataElement->name = _tuiRegisterName (regNum);
+ dataElement->highlight = FALSE;
+ }
+ if (dataElement->value == (Opaque) NULL)
+ dataElement->value = (Opaque) xmalloc (MAX_REGISTER_RAW_SIZE);
+ if (dataElement->value != (Opaque) NULL)
+ _tuiGetRegisterRawValue (regNum, dataElement->value, frame);
+ }
+
+ return;
+} /* _tuiSetRegisterElement */
+
+
+/*
+** _tuiSetRegsContent().
+** Set the content of the data window to consist of the registers
+** numbered from startRegNum to endRegNum. Note that if
+** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiSetRegsContent (
+ int startRegNum,
+ int endRegNum,
+ struct frame_info *frame,
+ TuiRegisterDisplayType dpyType,
+ int refreshValuesOnly)
+#else
+_tuiSetRegsContent (startRegNum, endRegNum, frame, dpyType, refreshValuesOnly)
+ int startRegNum;
+ int endRegNum;
+ struct frame_info *frame;
+ TuiRegisterDisplayType dpyType;
+ int refreshValuesOnly;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+ int numRegs = endRegNum - startRegNum + 1;
+ int allocatedHere = FALSE;
+
+ if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
+ !refreshValuesOnly)
+ {
+ freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
+ dataWin->detail.dataDisplayInfo.regsContentCount);
+ dataWin->detail.dataDisplayInfo.regsContentCount = 0;
+ }
+ if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
+ {
+ dataWin->detail.dataDisplayInfo.regsContent =
+ allocContent (numRegs, DATA_WIN);
+ allocatedHere = TRUE;
+ }
+
+ if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
+ {
+ int i;
+
+ if (!refreshValuesOnly || allocatedHere)
+ {
+ dataWin->generic.content = (OpaquePtr) NULL;
+ dataWin->generic.contentSize = 0;
+ addContentElements (&dataWin->generic, numRegs);
+ dataWin->detail.dataDisplayInfo.regsContent =
+ (TuiWinContent) dataWin->generic.content;
+ dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
+ }
+ /*
+ ** Now set the register names and values
+ */
+ for (i = startRegNum; (i <= endRegNum); i++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+
+ dataItemWin = &dataWin->detail.dataDisplayInfo.
+ regsContent[i - startRegNum]->whichElement.dataWindow;
+ _tuiSetRegisterElement (
+ i,
+ frame,
+ &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
+ !allocatedHere && refreshValuesOnly);
+ }
+ dataWin->detail.dataDisplayInfo.regsColumnCount =
+ tuiCalculateRegsColumnCount (dpyType);
+#ifdef LATER
+ if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
+ {
+ /* delete all the windows? */
+ /* realloc content equal to dataContentCount + regsContentCount */
+ /* append dataWin->detail.dataDisplayInfo.dataContent to content */
+ }
+#endif
+ dataWin->generic.contentSize =
+ dataWin->detail.dataDisplayInfo.regsContentCount +
+ dataWin->detail.dataDisplayInfo.dataContentCount;
+ ret = TUI_SUCCESS;
+ }
+
+ return ret;
+} /* _tuiSetRegsContent */
+
+
+/*
+** _tuiDisplayRegister().
+** Function to display a register in a window. If hilite is TRUE,
+** than the value will be displayed in reverse video
+*/
+static void
+#ifdef __STDC__
+_tuiDisplayRegister (
+ int regNum,
+ TuiGenWinInfoPtr winInfo, /* the data item window */
+ enum precision_type precision)
+#else
+_tuiDisplayRegister (regNum, winInfo, precision)
+ int regNum;
+ TuiGenWinInfoPtr winInfo; /* the data item window */
+ enum precision_type precision;
+#endif
+{
+ if (winInfo->handle != (WINDOW *) NULL)
+ {
+ char buf[100];
+ int valueCharsWide, labelWidth;
+ TuiDataElementPtr dataElementPtr = &((TuiWinContent)
+ winInfo->content)[0]->whichElement.data;
+
+ if (IS_64BIT ||
+ dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
+ {
+ valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
+ labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_SFLOAT_REGS)
+ {
+ valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
+ labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ valueCharsWide = SINGLE_VALUE_WIDTH;
+ labelWidth = SINGLE_LABEL_WIDTH;
+ }
+ }
+
+ buf[0] = (char) 0;
+ _tuiRegisterFormat (buf,
+ valueCharsWide + labelWidth,
+ regNum,
+ dataElementPtr,
+ precision);
+ if (dataElementPtr->highlight)
+ wstandout (winInfo->handle);
+
+ werase (winInfo->handle);
+ wmove (winInfo->handle, 0, 0);
+ waddstr (winInfo->handle, buf);
+
+ if (dataElementPtr->highlight)
+ wstandend (winInfo->handle);
+ tuiRefreshWin (winInfo);
+ }
+ return;
+} /* _tuiDisplayRegister */
+
+
+static void
+#ifdef __STDC__
+_tui_vShowRegisters_commandSupport (
+ va_list args)
+#else
+_tui_vShowRegisters_commandSupport (args)
+ va_list args;
+#endif
+{
+ TuiRegisterDisplayType dpyType = va_arg (args, TuiRegisterDisplayType);
+
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ { /* Data window already displayed, show the registers */
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
+ tuiShowRegisters (dpyType);
+ }
+ else
+ (tuiLayoutDef ())->regsDisplayType = dpyType;
+
+ return;
+} /* _tui_vShowRegisters_commandSupport */
+
+
+static void
+#ifdef __STDC__
+_tuiShowFloat_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiShowFloat_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
+ (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
+ dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport,
+ (tuiLayoutDef ())->floatRegsDisplayType);
+
+ return;
+} /* _tuiShowFloat_command */
+
+
+static void
+#ifdef __STDC__
+_tuiShowGeneral_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiShowGeneral_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport,
+ TUI_GENERAL_REGS);
+
+ return;
+} /* _tuiShowGeneral_command */
+
+
+static void
+#ifdef __STDC__
+_tuiShowSpecial_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiShowSpecial_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vShowRegisters_commandSupport,
+ TUI_SPECIAL_REGS);
+
+ return;
+} /* _tuiShowSpecial_command */
+
+
+static void
+#ifdef __STDC__
+_tuiToggleFloatRegs_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiToggleFloatRegs_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ tuiDo ((TuiOpaqueFuncPtr) tuiToggleFloatRegs);
+ else
+ {
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
+ layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
+ else
+ layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
+ }
+
+
+ return;
+} /* _tuiToggleFloatRegs_command */
+
+
+static void
+#ifdef __STDC__
+_tuiScrollRegsForward_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiScrollRegsForward_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, FORWARD_SCROLL, dataWin, 1);
+
+ return;
+} /* _tuiScrollRegsForward_command */
+
+
+static void
+#ifdef __STDC__
+_tuiScrollRegsBackward_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiScrollRegsBackward_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) tui_vScroll, BACKWARD_SCROLL, dataWin, 1);
+
+ return;
+} /* _tuiScrollRegsBackward_command */
diff --git a/contrib/gdb/gdb/tui/tuiRegs.h b/contrib/gdb/gdb/tui/tuiRegs.h
new file mode 100644
index 0000000..4a777ec
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiRegs.h
@@ -0,0 +1,28 @@
+#ifndef _TUI_REGS_H
+#define _TUI_REGS_H
+/*
+** This header file supports the display of registers in the data window.
+*/
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern void tuiCheckRegisterValues PARAMS ((struct frame_info *));
+extern void tuiShowRegisters PARAMS ((TuiRegisterDisplayType));
+extern void tuiDisplayRegistersFrom PARAMS ((int));
+extern int tuiDisplayRegistersFromLine PARAMS ((int, int));
+extern int tuiLastRegsLineNo PARAMS ((void));
+extern int tuiFirstRegElementInLine PARAMS ((int));
+extern int tuiLastRegElementInLine PARAMS ((int));
+extern int tuiLineFromRegElementNo PARAMS ((int));
+extern void tuiToggleFloatRegs PARAMS ((void));
+extern int tuiCalculateRegsColumnCount PARAMS ((TuiRegisterDisplayType));
+
+
+#endif /*_TUI_REGS_H*/
diff --git a/contrib/gdb/gdb/tui/tuiSource.c b/contrib/gdb/gdb/tui/tuiSource.c
new file mode 100644
index 0000000..e0259d0
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiSource.c
@@ -0,0 +1,465 @@
+/*
+** tuiSource.c
+** This module contains functions for displaying source in the source window
+*/
+
+#include "defs.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "breakpoint.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiStack.h"
+#include "tuiSourceWin.h"
+#include "tuiSource.h"
+
+
+/*****************************************
+** EXTERNAL FUNCTION DECLS **
+******************************************/
+
+extern int open_source_file PARAMS ((struct symtab *));
+extern void find_source_lines PARAMS ((struct symtab *, int));
+
+/*****************************************
+** EXTERNAL DATA DECLS **
+******************************************/
+extern int current_source_line;
+extern struct symtab *current_source_symtab;
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+static struct breakpoint *_hasBreak PARAMS ((char *, int));
+
+
+/*****************************************
+** STATIC LOCAL DATA **
+******************************************/
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*********************************
+** SOURCE/DISASSEM FUNCTIONS **
+*********************************/
+
+/*
+** tuiSetSourceContent().
+** Function to display source in the source window.
+*/
+TuiStatus
+#ifdef __STDC__
+tuiSetSourceContent (
+ struct symtab *s,
+ int lineNo,
+ int noerror)
+#else
+tuiSetSourceContent (s, lineNo, noerror)
+ struct symtab *s;
+ int lineNo;
+ int noerror;
+#endif
+{
+ TuiStatus ret = TUI_FAILURE;
+
+ if (s != (struct symtab *) NULL && s->filename != (char *) NULL)
+ {
+ register FILE *stream;
+ register int i, desc, c, lineWidth, nlines;
+ register char *srcLine;
+
+ if ((ret = tuiAllocSourceBuffer (srcWin)) == TUI_SUCCESS)
+ {
+ lineWidth = srcWin->generic.width - 1;
+ /*
+ ** Take hilite (window border) into account, when calculating
+ ** the number of lines
+ */
+ nlines = (lineNo + (srcWin->generic.height - 2)) - lineNo;
+ desc = open_source_file (s);
+ if (desc < 0)
+ {
+ if (!noerror)
+ {
+ char *name = alloca (strlen (s->filename) + 100);
+ sprintf (name, "%s:%d", s->filename, lineNo);
+ print_sys_errmsg (name, errno);
+ }
+ ret = TUI_FAILURE;
+ }
+ else
+ {
+ if (s->line_charpos == 0)
+ find_source_lines (s, desc);
+
+ if (lineNo < 1 || lineNo > s->nlines)
+ {
+ close (desc);
+ printf_unfiltered (
+ "Line number %d out of range; %s has %d lines.\n",
+ lineNo, s->filename, s->nlines);
+ }
+ else if (lseek (desc, s->line_charpos[lineNo - 1], 0) < 0)
+ {
+ close (desc);
+ perror_with_name (s->filename);
+ }
+ else
+ {
+ register int offset, curLineNo, curLine, curLen, threshold;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ /*
+ ** Determine the threshold for the length of the line
+ ** and the offset to start the display
+ */
+ offset = srcWin->detail.sourceInfo.horizontalOffset;
+ threshold = (lineWidth - 1) + offset;
+ stream = fdopen (desc, FOPEN_RT);
+ clearerr (stream);
+ curLine = 0;
+ curLineNo =
+ srcWin->detail.sourceInfo.startLineOrAddr.lineNo = lineNo;
+ if (offset > 0)
+ srcLine = (char *) xmalloc (
+ (threshold + 1) * sizeof (char));
+ while (curLine < nlines)
+ {
+ TuiWinElementPtr element = (TuiWinElementPtr)
+ srcWin->generic.content[curLine];
+ struct breakpoint *bp;
+
+ /* get the first character in the line */
+ c = fgetc (stream);
+
+ if (offset == 0)
+ srcLine = ((TuiWinElementPtr)
+ srcWin->generic.content[
+ curLine])->whichElement.source.line;
+ /* Init the line with the line number */
+ sprintf (srcLine, "%-6d", curLineNo);
+ curLen = strlen (srcLine);
+ i = curLen -
+ ((curLen / tuiDefaultTabLen ()) * tuiDefaultTabLen ());
+ while (i < tuiDefaultTabLen ())
+ {
+ srcLine[curLen] = ' ';
+ i++;
+ curLen++;
+ }
+ srcLine[curLen] = (char) 0;
+
+ /*
+ ** Set whether element is the execution point and
+ ** whether there is a break point on it.
+ */
+ element->whichElement.source.lineOrAddr.lineNo =
+ curLineNo;
+ element->whichElement.source.isExecPoint =
+ (strcmp (((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.fileName,
+ s->filename) == 0
+ && curLineNo == ((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.lineNo);
+ bp = _hasBreak (s->filename, curLineNo);
+ element->whichElement.source.hasBreak =
+ (bp != (struct breakpoint *) NULL &&
+ (!element->whichElement.source.isExecPoint ||
+ (bp->disposition != del || bp->hit_count <= 0)));
+ if (c != EOF)
+ {
+ i = strlen (srcLine) - 1;
+ do
+ {
+ if ((c != '\n') &&
+ (c != '\r') && (++i < threshold))
+ {
+ if (c < 040 && c != '\t')
+ {
+ srcLine[i++] = '^';
+ srcLine[i] = c + 0100;
+ }
+ else if (c == 0177)
+ {
+ srcLine[i++] = '^';
+ srcLine[i] = '?';
+ }
+ else
+ { /*
+ ** Store the charcter in the line
+ ** buffer. If it is a tab, then
+ ** translate to the correct number of
+ ** chars so we don't overwrite our
+ ** buffer.
+ */
+ if (c == '\t')
+ {
+ int j, maxTabLen = tuiDefaultTabLen ();
+
+ for (j = i - (
+ (i / maxTabLen) * maxTabLen);
+ ((j < maxTabLen) &&
+ i < threshold);
+ i++, j++)
+ srcLine[i] = ' ';
+ i--;
+ }
+ else
+ srcLine[i] = c;
+ }
+ srcLine[i + 1] = 0;
+ }
+ else
+ { /*
+ ** if we have not reached EOL, then eat
+ ** chars until we do
+ */
+ while (c != EOF && c != '\n' && c != '\r')
+ c = fgetc (stream);
+ }
+ }
+ while (c != EOF && c != '\n' && c != '\r' &&
+ i < threshold && (c = fgetc (stream)));
+ }
+ /* Now copy the line taking the offset into account */
+ if (strlen (srcLine) > offset)
+ strcpy (((TuiWinElementPtr) srcWin->generic.content[
+ curLine])->whichElement.source.line,
+ &srcLine[offset]);
+ else
+ ((TuiWinElementPtr)
+ srcWin->generic.content[
+ curLine])->whichElement.source.line[0] = (char) 0;
+ curLine++;
+ curLineNo++;
+ }
+ if (offset > 0)
+ tuiFree (srcLine);
+ fclose (stream);
+ srcWin->generic.contentSize = nlines;
+ ret = TUI_SUCCESS;
+ }
+ }
+ }
+ }
+ return ret;
+} /* tuiSetSourceContent */
+
+
+/* elz: this function sets the contents of the source window to empty
+ except for a line in the middle with a warning message about the
+ source not being available. This function is called by
+ tuiEraseSourceContents, which in turn is invoked when the source files
+ cannot be accessed*/
+
+void
+#ifdef __STDC__
+tuiSetSourceContentNil (
+ TuiWinInfoPtr winInfo,
+ char *warning_string)
+#else
+tuiSetSourceContentNil (winInfo, warning_string)
+ TuiWinInfoPtr winInfo;
+ char *warning_string;
+#endif
+{
+ int lineWidth;
+ int nLines;
+ int curr_line = 0;
+
+ lineWidth = winInfo->generic.width - 1;
+ nLines = winInfo->generic.height - 2;
+
+ /* set to empty each line in the window, except for the one
+ which contains the message*/
+ while (curr_line < winInfo->generic.contentSize)
+ {
+ /* set the information related to each displayed line
+ to null: i.e. the line number is 0, there is no bp,
+ it is not where the program is stopped */
+
+ TuiWinElementPtr element =
+ (TuiWinElementPtr) winInfo->generic.content[curr_line];
+ element->whichElement.source.lineOrAddr.lineNo = 0;
+ element->whichElement.source.isExecPoint = FALSE;
+ element->whichElement.source.hasBreak = FALSE;
+
+ /* set the contents of the line to blank*/
+ element->whichElement.source.line[0] = (char) 0;
+
+ /* if the current line is in the middle of the screen, then we want to
+ display the 'no source available' message in it.
+ Note: the 'weird' arithmetic with the line width and height comes from
+ the function tuiEraseSourceContent. We need to keep the screen and the
+ window's actual contents in synch */
+
+ if (curr_line == (nLines / 2 + 1))
+ {
+ int i;
+ int xpos;
+ int warning_length = strlen (warning_string);
+ char *srcLine;
+
+ srcLine = element->whichElement.source.line;
+
+ if (warning_length >= ((lineWidth - 1) / 2))
+ xpos = 1;
+ else
+ xpos = (lineWidth - 1) / 2 - warning_length;
+
+ for (i = 0; i < xpos; i++)
+ srcLine[i] = ' ';
+
+ sprintf (srcLine + i, "%s", warning_string);
+
+ for (i = xpos + warning_length; i < lineWidth; i++)
+ srcLine[i] = ' ';
+
+ srcLine[i] = '\n';
+
+ } /* end if */
+
+ curr_line++;
+
+ } /* end while*/
+
+} /*tuiSetSourceContentNil*/
+
+
+
+
+/*
+** tuiShowSource().
+** Function to display source in the source window. This function
+** initializes the horizontal scroll to 0.
+*/
+void
+#ifdef __STDC__
+tuiShowSource (
+ struct symtab *s,
+ Opaque line,
+ int noerror)
+#else
+tuiShowSource (s, line, noerror)
+ struct symtab *s;
+ Opaque line;
+ int noerror;
+#endif
+{
+ srcWin->detail.sourceInfo.horizontalOffset = 0;
+ m_tuiShowSourceAsIs (s, line, noerror);
+
+ return;
+} /* tuiShowSource */
+
+
+/*
+** tuiSourceIsDisplayed().
+** Answer whether the source is currently displayed in the source window.
+*/
+int
+#ifdef __STDC__
+tuiSourceIsDisplayed (
+ char *fname)
+#else
+tuiSourceIsDisplayed (fname)
+ char *fname;
+#endif
+{
+ return (srcWin->generic.contentInUse &&
+ (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())->
+ content[0])->whichElement.locator.fileName, fname) == 0));
+} /* tuiSourceIsDisplayed */
+
+
+/*
+** tuiVerticalSourceScroll().
+** Scroll the source forward or backward vertically
+*/
+void
+#ifdef __STDC__
+tuiVerticalSourceScroll (
+ TuiScrollDirection scrollDirection,
+ int numToScroll)
+#else
+tuiVerticalSourceScroll (scrollDirection, numToScroll)
+ TuiScrollDirection scrollDirection;
+ int numToScroll;
+#endif
+{
+ if (srcWin->generic.content != (OpaquePtr) NULL)
+ {
+ int line;
+ Opaque addr;
+ struct symtab *s;
+ TuiWinContent content = (TuiWinContent) srcWin->generic.content;
+
+ if (current_source_symtab == (struct symtab *) NULL)
+ s = find_pc_symtab (selected_frame->pc);
+ else
+ s = current_source_symtab;
+
+ if (scrollDirection == FORWARD_SCROLL)
+ {
+ line = content[0]->whichElement.source.lineOrAddr.lineNo +
+ numToScroll;
+ if (line > s->nlines)
+ /*line = s->nlines - winInfo->generic.contentSize + 1;*/
+ /*elz: fix for dts 23398*/
+ line = content[0]->whichElement.source.lineOrAddr.lineNo;
+ }
+ else
+ {
+ line = content[0]->whichElement.source.lineOrAddr.lineNo -
+ numToScroll;
+ if (line <= 0)
+ line = 1;
+ }
+ tuiUpdateSourceWindowAsIs (srcWin, s, (Opaque) line, FALSE);
+ }
+
+ return;
+} /* tuiVerticalSourceScroll */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+
+/*
+** _hasBreak().
+** Answer whether there is a break point at the input line in
+** the source file indicated
+*/
+static struct breakpoint *
+#ifdef __STDC__
+_hasBreak (
+ char *sourceFileName,
+ int lineNo)
+#else
+_hasBreak (sourceFileName, lineNo)
+ char *sourceFileName;
+ int lineNo;
+#endif
+{
+ struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
+ struct breakpoint *bp;
+ extern struct breakpoint *breakpoint_chain;
+
+
+ for (bp = breakpoint_chain;
+ (bp != (struct breakpoint *) NULL &&
+ bpWithBreak == (struct breakpoint *) NULL);
+ bp = bp->next)
+ if ((strcmp (sourceFileName, bp->source_file) == 0) &&
+ (lineNo == bp->line_number))
+ bpWithBreak = bp;
+
+ return bpWithBreak;
+} /* _hasBreak */
diff --git a/contrib/gdb/gdb/tui/tuiSource.h b/contrib/gdb/gdb/tui/tuiSource.h
new file mode 100644
index 0000000..f898c61
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiSource.h
@@ -0,0 +1,27 @@
+#ifndef _TUI_SOURCE_H
+#define _TUI_SOURCE_H
+/*
+** This header file supports
+*/
+
+
+#include "defs.h"
+#if 0
+#include "symtab.h"
+#include "breakpoint.h"
+#endif
+
+extern TuiStatus tuiSetSourceContent PARAMS ((struct symtab *, int, int));
+extern void tuiShowSource PARAMS ((struct symtab *, Opaque, int));
+extern void tuiShowSourceAsIs PARAMS ((struct symtab *, Opaque, int));
+extern int tuiSourceIsDisplayed PARAMS ((char *));
+extern void tuiVerticalSourceScroll PARAMS ((TuiScrollDirection, int));
+
+
+/*******************
+** MACROS **
+*******************/
+#define m_tuiShowSourceAsIs(s, line, noerror) tuiUpdateSourceWindowAsIs(srcWin, s, line, noerror)
+
+
+#endif /*_TUI_SOURCE_H*/
diff --git a/contrib/gdb/gdb/tui/tuiSourceWin.c b/contrib/gdb/gdb/tui/tuiSourceWin.c
new file mode 100644
index 0000000..e203925
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiSourceWin.c
@@ -0,0 +1,1098 @@
+/*
+** tuiSourceWin.c
+** This module contains functions for displaying source or assembly in the "source" window.
+* The "source" window may be the assembly or the source windows.
+*/
+
+#include "defs.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "breakpoint.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiStack.h"
+#include "tuiSourceWin.h"
+#include "tuiSource.h"
+#include "tuiDisassem.h"
+
+
+/*****************************************
+** EXTERNAL FUNCTION DECLS **
+******************************************/
+
+/*****************************************
+** EXTERNAL DATA DECLS **
+******************************************/
+extern int current_source_line;
+extern struct symtab *current_source_symtab;
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+/*****************************************
+** STATIC LOCAL DATA **
+******************************************/
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*********************************
+** SOURCE/DISASSEM FUNCTIONS **
+*********************************/
+
+/*
+** tuiSrcWinIsDisplayed().
+*/
+int
+#ifdef __STDC__
+tuiSrcWinIsDisplayed (void)
+#else
+tuiSrcWinIsDisplayed ()
+#endif
+{
+ return (m_winPtrNotNull (srcWin) && srcWin->generic.isVisible);
+} /* tuiSrcWinIsDisplayed */
+
+
+/*
+** tuiAsmWinIsDisplayed().
+*/
+int
+#ifdef __STDC__
+tuiAsmWinIsDisplayed (void)
+#else
+tuiAsmWinIsDisplayed ()
+#endif
+{
+ return (m_winPtrNotNull (disassemWin) && disassemWin->generic.isVisible);
+} /* tuiAsmWinIsDisplayed */
+
+
+/*
+** tuiDisplayMainFunction().
+** Function to display the "main" routine"
+*/
+void
+#ifdef __STDC__
+tuiDisplayMainFunction (void)
+#else
+tuiDisplayMainFunction ()
+#endif
+{
+ if ((sourceWindows ())->count > 0)
+ {
+ CORE_ADDR addr;
+
+ addr = parse_and_eval_address ("main");
+ if (addr <= (CORE_ADDR) 0)
+ addr = parse_and_eval_address ("MAIN");
+ if (addr > (CORE_ADDR) 0)
+ {
+ struct symtab_and_line sal;
+
+ tuiUpdateSourceWindowsWithAddr ((Opaque) addr);
+ sal = find_pc_line (addr, 0);
+ tuiSwitchFilename (sal.symtab->filename);
+ }
+ }
+
+ return;
+} /* tuiDisplayMainFunction */
+
+
+
+/*
+** tuiUpdateSourceWindow().
+** Function to display source in the source window. This function
+** initializes the horizontal scroll to 0.
+*/
+void
+#ifdef __STDC__
+tuiUpdateSourceWindow (
+ TuiWinInfoPtr winInfo,
+ struct symtab *s,
+ Opaque lineOrAddr,
+ int noerror)
+#else
+tuiUpdateSourceWindow (winInfo, s, lineOrAddr, noerror)
+ TuiWinInfoPtr winInfo;
+ struct symtab *s;
+ Opaque lineOrAddr;
+ int noerror;
+#endif
+{
+ winInfo->detail.sourceInfo.horizontalOffset = 0;
+ tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror);
+
+ return;
+} /* tuiUpdateSourceWindow */
+
+
+/*
+** tuiUpdateSourceWindowAsIs().
+** Function to display source in the source/asm window. This
+** function shows the source as specified by the horizontal offset.
+*/
+void
+#ifdef __STDC__
+tuiUpdateSourceWindowAsIs (
+ TuiWinInfoPtr winInfo,
+ struct symtab *s,
+ Opaque lineOrAddr,
+ int noerror)
+#else
+tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror)
+ TuiWinInfoPtr winInfo;
+ struct symtab *s;
+ Opaque lineOrAddr;
+ int noerror;
+#endif
+{
+ TuiStatus ret;
+
+ if (winInfo->generic.type == SRC_WIN)
+ ret = tuiSetSourceContent (s, (int) lineOrAddr, noerror);
+ else
+ ret = tuiSetDisassemContent (s, (Opaque) lineOrAddr);
+
+ if (ret == TUI_FAILURE)
+ {
+ tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
+ tuiClearExecInfoContent (winInfo);
+ }
+ else
+ {
+ tuiEraseSourceContent (winInfo, NO_EMPTY_SOURCE_PROMPT);
+ tuiShowSourceContent (winInfo);
+ tuiUpdateExecInfo (winInfo);
+ if (winInfo->generic.type == SRC_WIN)
+ {
+ current_source_line = (int) lineOrAddr +
+ (winInfo->generic.contentSize - 2);
+ current_source_symtab = s;
+ /*
+ ** If the focus was in the asm win, put it in the src
+ ** win if we don't have a split layout
+ */
+ if (tuiWinWithFocus () == disassemWin &&
+ currentLayout () != SRC_DISASSEM_COMMAND)
+ tuiSetWinFocusTo (srcWin);
+ }
+ }
+
+
+ return;
+} /* tuiUpdateSourceWindowAsIs */
+
+
+/*
+** tuiUpdateSourceWindowsWithAddr().
+** Function to ensure that the source and/or disassemly windows
+** reflect the input address.
+*/
+void
+#ifdef __STDC__
+tuiUpdateSourceWindowsWithAddr (
+ Opaque addr)
+#else
+tuiUpdateSourceWindowsWithAddr (addr)
+ Opaque addr;
+#endif
+{
+ if (addr > (Opaque) NULL)
+ {
+ struct symtab_and_line sal;
+
+ switch (currentLayout ())
+ {
+ case DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ tuiShowDisassem (addr);
+ break;
+ case SRC_DISASSEM_COMMAND:
+ tuiShowDisassemAndUpdateSource (addr);
+ break;
+ default:
+ sal = find_pc_line ((CORE_ADDR) addr, 0);
+ tuiShowSource (sal.symtab,
+ (Opaque) sal.line,
+ FALSE);
+ break;
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
+ tuiClearExecInfoContent (winInfo);
+ }
+ }
+
+ return;
+} /* tuiUpdateSourceWindowsWithAddr */
+
+
+/*
+** tui_vUpdateSourceWindowsWithAddr()
+** Update the source window with the address in a va_list
+*/
+void
+#ifdef __STDC__
+tui_vUpdateSourceWindowsWithAddr (
+ va_list args)
+#else
+tui_vUpdateSourceWindowsWithAddr (args)
+ va_list args;
+#endif
+{
+ Opaque addr = va_arg (args, Opaque);
+
+ tuiUpdateSourceWindowsWithAddr (addr);
+
+ return;
+} /* tui_vUpdateSourceWindowsWithAddr */
+
+
+/*
+** tuiUpdateSourceWindowsWithLine().
+** Function to ensure that the source and/or disassemly windows
+** reflect the input address.
+*/
+void
+#ifdef __STDC__
+tuiUpdateSourceWindowsWithLine (
+ struct symtab *s,
+ int line)
+#else
+tuiUpdateSourceWindowsWithLine (s, line)
+ struct symtab *s;
+ int line;
+#endif
+{
+ switch (currentLayout ())
+ {
+ case DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ tuiUpdateSourceWindowsWithAddr ((Opaque) find_line_pc (s, line));
+ break;
+ default:
+ tuiShowSource (s, (Opaque) line, FALSE);
+ if (currentLayout () == SRC_DISASSEM_COMMAND)
+ tuiShowDisassem ((Opaque) find_line_pc (s, line));
+ break;
+ }
+
+ return;
+} /* tuiUpdateSourceWindowsWithLine */
+
+
+/*
+** tui_vUpdateSourceWindowsWithLine()
+** Update the source window with the line number in a va_list
+*/
+void
+#ifdef __STDC__
+tui_vUpdateSourceWindowsWithLine (
+ va_list args)
+#else
+tui_vUpdateSourceWindowsWithLine (args)
+ va_list args;
+#endif
+{
+ struct symtab *s = va_arg (args, struct symtab *);
+ int line = va_arg (args, int);
+
+ tuiUpdateSourceWindowsWithLine (s, line);
+
+ return;
+} /* tui_vUpdateSourceWindowsWithLine */
+
+
+/*
+** tuiClearSourceContent().
+*/
+void
+#ifdef __STDC__
+tuiClearSourceContent (
+ TuiWinInfoPtr winInfo,
+ int displayPrompt)
+#else
+tuiClearSourceContent (winInfo, displayPrompt)
+ TuiWinInfoPtr winInfo;
+ int displayPrompt;
+#endif
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ register int i;
+
+ winInfo->generic.contentInUse = FALSE;
+ tuiEraseSourceContent (winInfo, displayPrompt);
+ for (i = 0; i < winInfo->generic.contentSize; i++)
+ {
+ TuiWinElementPtr element =
+ (TuiWinElementPtr) winInfo->generic.content[i];
+ element->whichElement.source.hasBreak = FALSE;
+ element->whichElement.source.isExecPoint = FALSE;
+ }
+ }
+
+ return;
+} /* tuiClearSourceContent */
+
+
+/*
+** tuiClearAllSourceWinsContent().
+*/
+void
+#ifdef __STDC__
+tuiClearAllSourceWinsContent (
+ int displayPrompt)
+#else
+tuiClearAllSourceWinsContent (displayPrompt)
+ int displayPrompt;
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiClearSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i],
+ displayPrompt);
+
+ return;
+} /* tuiClearAllSourceWinsContent */
+
+
+/*
+** tuiEraseSourceContent().
+*/
+void
+#ifdef __STDC__
+tuiEraseSourceContent (
+ TuiWinInfoPtr winInfo,
+ int displayPrompt)
+#else
+tuiEraseSourceContent (winInfo, displayPrompt)
+ TuiWinInfoPtr winInfo;
+ int displayPrompt;
+#endif
+{
+ int xPos;
+ int halfWidth = (winInfo->generic.width - 2) / 2;
+
+ if (winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ werase (winInfo->generic.handle);
+ checkAndDisplayHighlightIfNeeded (winInfo);
+ if (displayPrompt == EMPTY_SOURCE_PROMPT)
+ {
+ char *noSrcStr;
+
+ if (winInfo->generic.type == SRC_WIN)
+ noSrcStr = NO_SRC_STRING;
+ else
+ noSrcStr = NO_DISASSEM_STRING;
+ if (strlen (noSrcStr) >= halfWidth)
+ xPos = 1;
+ else
+ xPos = halfWidth - strlen (noSrcStr);
+ mvwaddstr (winInfo->generic.handle,
+ (winInfo->generic.height / 2),
+ xPos,
+ noSrcStr);
+
+ /* elz: added this function call to set the real contents of
+ the window to what is on the screen, so that later calls
+ to refresh, do display
+ the correct stuff, and not the old image */
+
+ tuiSetSourceContentNil (winInfo, noSrcStr);
+ }
+ tuiRefreshWin (&winInfo->generic);
+ }
+ return;
+} /* tuiEraseSourceContent */
+
+
+/*
+** tuiEraseAllSourceContent().
+*/
+void
+#ifdef __STDC__
+tuiEraseAllSourceWinsContent (
+ int displayPrompt)
+#else
+tuiEraseAllSourceWinsContent (displayPrompt)
+ int displayPrompt;
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiEraseSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i],
+ displayPrompt);
+
+ return;
+} /* tuiEraseAllSourceWinsContent */
+
+
+/*
+** tuiShowSourceContent().
+*/
+void
+#ifdef __STDC__
+tuiShowSourceContent (
+ TuiWinInfoPtr winInfo)
+#else
+tuiShowSourceContent (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ int curLine, i, curX;
+
+ tuiEraseSourceContent (winInfo, (winInfo->generic.contentSize <= 0));
+ if (winInfo->generic.contentSize > 0)
+ {
+ char *line;
+
+ for (curLine = 1; (curLine <= winInfo->generic.contentSize); curLine++)
+ mvwaddstr (
+ winInfo->generic.handle,
+ curLine,
+ 1,
+ ((TuiWinElementPtr)
+ winInfo->generic.content[curLine - 1])->whichElement.source.line);
+ }
+ checkAndDisplayHighlightIfNeeded (winInfo);
+ tuiRefreshWin (&winInfo->generic);
+ winInfo->generic.contentInUse = TRUE;
+
+ return;
+} /* tuiShowSourceContent */
+
+
+/*
+** tuiShowAllSourceWinsContent()
+*/
+void
+#ifdef __STDC__
+tuiShowAllSourceWinsContent (void)
+#else
+tuiShowAllSourceWinsContent ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiShowSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiShowAllSourceWinsContent */
+
+
+/*
+** tuiHorizontalSourceScroll().
+** Scroll the source forward or backward horizontally
+*/
+void
+#ifdef __STDC__
+tuiHorizontalSourceScroll (
+ TuiWinInfoPtr winInfo,
+ TuiScrollDirection direction,
+ int numToScroll)
+#else
+tuiHorizontalSourceScroll (winInfo, direction, numToScroll)
+ TuiWinInfoPtr winInfo;
+ TuiScrollDirection direction;
+ int numToScroll;
+#endif
+{
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ int offset;
+ struct symtab *s;
+
+ if (current_source_symtab == (struct symtab *) NULL)
+ s = find_pc_symtab (selected_frame->pc);
+ else
+ s = current_source_symtab;
+
+ if (direction == LEFT_SCROLL)
+ offset = winInfo->detail.sourceInfo.horizontalOffset + numToScroll;
+ else
+ {
+ if ((offset =
+ winInfo->detail.sourceInfo.horizontalOffset - numToScroll) < 0)
+ offset = 0;
+ }
+ winInfo->detail.sourceInfo.horizontalOffset = offset;
+ tuiUpdateSourceWindowAsIs (
+ winInfo,
+ s,
+ ((winInfo == srcWin) ?
+ (Opaque) ((TuiWinElementPtr)
+ winInfo->generic.content[0])->whichElement.source.lineOrAddr.lineNo :
+ (Opaque) ((TuiWinElementPtr)
+ winInfo->generic.content[0])->whichElement.source.lineOrAddr.addr),
+ (int) FALSE);
+ }
+
+ return;
+} /* tuiHorizontalSourceScroll */
+
+
+/*
+** tuiSetHasExecPointAt().
+** Set or clear the hasBreak flag in the line whose line is lineNo.
+*/
+void
+#ifdef __STDC__
+tuiSetIsExecPointAt (
+ Opaque lineOrAddr,
+ TuiWinInfoPtr winInfo)
+#else
+tuiSetIsExecPointAt (lineOrAddr, winInfo)
+ Opaque lineOrAddr;
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ int i;
+ TuiWinContent content = (TuiWinContent) winInfo->generic.content;
+
+ i = 0;
+ while (i < winInfo->generic.contentSize)
+ {
+ if (content[i]->whichElement.source.lineOrAddr.addr == lineOrAddr)
+ content[i]->whichElement.source.isExecPoint = TRUE;
+ else
+ content[i]->whichElement.source.isExecPoint = FALSE;
+ i++;
+ }
+
+ return;
+} /* tuiSetIsExecPointAt */
+
+
+/*
+** tuiSetHasBreakAt().
+** Set or clear the hasBreak flag in the line whose line is lineNo.
+*/
+void
+#ifdef __STDC__
+tuiSetHasBreakAt (
+ struct breakpoint *bp,
+ TuiWinInfoPtr winInfo,
+ int hasBreak)
+#else
+tuiSetHasBreakAt (bp, winInfo, hasBreak)
+ struct breakpoint *bp;
+ TuiWinInfoPtr winInfo;
+ int hasBreak;
+#endif
+{
+ int i;
+ TuiWinContent content = (TuiWinContent) winInfo->generic.content;
+
+ i = 0;
+ while (i < winInfo->generic.contentSize)
+ {
+ int gotIt;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (winInfo == srcWin)
+ {
+ char *fileNameDisplayed = (char *) NULL;
+
+ if (((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.fileName !=
+ (char *) NULL)
+ fileNameDisplayed = ((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.fileName;
+ else if (current_source_symtab != (struct symtab *) NULL)
+ fileNameDisplayed = current_source_symtab->filename;
+
+ gotIt = (fileNameDisplayed != (char *) NULL &&
+ (strcmp (bp->source_file, fileNameDisplayed) == 0) &&
+ content[i]->whichElement.source.lineOrAddr.lineNo ==
+ bp->line_number);
+ }
+ else
+ gotIt = (content[i]->whichElement.source.lineOrAddr.addr
+ == (Opaque) bp->address);
+ if (gotIt)
+ {
+ content[i]->whichElement.source.hasBreak = hasBreak;
+ break;
+ }
+ i++;
+ }
+
+ return;
+} /* tuiSetHasBreakAt */
+
+
+/*
+** tuiAllSetHasBreakAt().
+** Set or clear the hasBreak flag in all displayed source windows.
+*/
+void
+#ifdef __STDC__
+tuiAllSetHasBreakAt (
+ struct breakpoint *bp,
+ int hasBreak)
+#else
+tuiAllSetHasBreakAt (bp, hasBreak)
+ struct breakpoint *bp;
+ int hasBreak;
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiSetHasBreakAt (bp,
+ (TuiWinInfoPtr) (sourceWindows ())->list[i], hasBreak);
+
+ return;
+} /* tuiAllSetHasBreakAt */
+
+
+/*
+** tui_vAllSetHasBreakAt()
+** Set or clear the hasBreak flag in all displayed source windows,
+** with params in a va_list
+*/
+void
+#ifdef __STDC__
+tui_vAllSetHasBreakAt (
+ va_list args)
+#else
+tui_vAllSetHasBreakAt (args)
+ va_list args;
+#endif
+{
+ struct breakpoint *bp = va_arg (args, struct breakpoint *);
+ int hasBreak = va_arg (args, int);
+
+ tuiAllSetHasBreakAt (bp, hasBreak);
+
+ return;
+} /* tui_vAllSetHasBreakAt */
+
+
+
+/*********************************
+** EXECUTION INFO FUNCTIONS **
+*********************************/
+
+/*
+** tuiSetExecInfoContent().
+** Function to initialize the content of the execution info window,
+** based upon the input window which is either the source or
+** disassembly window.
+*/
+TuiStatus
+#ifdef __STDC__
+tuiSetExecInfoContent (
+ TuiWinInfoPtr winInfo)
+#else
+tuiSetExecInfoContent (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ TuiStatus ret = TUI_SUCCESS;
+
+ if (winInfo->detail.sourceInfo.executionInfo != (TuiGenWinInfoPtr) NULL)
+ {
+ TuiGenWinInfoPtr execInfoPtr = winInfo->detail.sourceInfo.executionInfo;
+
+ if (execInfoPtr->content == (OpaquePtr) NULL)
+ execInfoPtr->content =
+ (OpaquePtr) allocContent (winInfo->generic.height,
+ execInfoPtr->type);
+ if (execInfoPtr->content != (OpaquePtr) NULL)
+ {
+ int i;
+
+ for (i = 0; i < winInfo->generic.contentSize; i++)
+ {
+ TuiWinElementPtr element;
+ TuiWinElementPtr srcElement;
+
+ element = (TuiWinElementPtr) execInfoPtr->content[i];
+ srcElement = (TuiWinElementPtr) winInfo->generic.content[i];
+ /*
+ ** First check to see if we have a breakpoint that is
+ ** temporary. If so, and this is our current execution point,
+ ** then clear the break indicator.
+ */
+ if (srcElement->whichElement.source.hasBreak &&
+ srcElement->whichElement.source.isExecPoint)
+ {
+ struct breakpoint *bp;
+ int found = FALSE;
+ extern struct breakpoint *breakpoint_chain;
+
+ for (bp = breakpoint_chain;
+ (bp != (struct breakpoint *) NULL && !found);
+ bp = bp->next)
+ {
+ found =
+ (winInfo == srcWin &&
+ bp->line_number ==
+ srcElement->whichElement.source.lineOrAddr.lineNo) ||
+ (winInfo == disassemWin &&
+ bp->address == (CORE_ADDR)
+ srcElement->whichElement.source.lineOrAddr.addr);
+ if (found)
+ srcElement->whichElement.source.hasBreak =
+ (bp->disposition != del || bp->hit_count <= 0);
+ }
+ if (!found)
+ srcElement->whichElement.source.hasBreak = FALSE;
+ }
+ /*
+ ** Now update the exec info content based upon the state
+ ** of each line as indicated by the source content.
+ */
+ if (srcElement->whichElement.source.hasBreak &&
+ srcElement->whichElement.source.isExecPoint)
+ element->whichElement.simpleString = breakLocationStr ();
+ else if (srcElement->whichElement.source.hasBreak)
+ element->whichElement.simpleString = breakStr ();
+ else if (srcElement->whichElement.source.isExecPoint)
+ element->whichElement.simpleString = locationStr ();
+ else
+ element->whichElement.simpleString = blankStr ();
+ }
+ execInfoPtr->contentSize = winInfo->generic.contentSize;
+ }
+ else
+ ret = TUI_FAILURE;
+ }
+
+ return ret;
+} /* tuiSetExecInfoContent */
+
+
+/*
+** tuiShowExecInfoContent().
+*/
+void
+#ifdef __STDC__
+tuiShowExecInfoContent (
+ TuiWinInfoPtr winInfo)
+#else
+tuiShowExecInfoContent (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
+ int curLine;
+
+ werase (execInfo->handle);
+ tuiRefreshWin (execInfo);
+ for (curLine = 1; (curLine <= execInfo->contentSize); curLine++)
+ mvwaddstr (execInfo->handle,
+ curLine,
+ 0,
+ ((TuiWinElementPtr)
+ execInfo->content[curLine - 1])->whichElement.simpleString);
+ tuiRefreshWin (execInfo);
+ execInfo->contentInUse = TRUE;
+
+ return;
+} /* tuiShowExecInfoContent */
+
+
+/*
+** tuiShowAllExecInfosContent()
+*/
+void
+#ifdef __STDC__
+tuiShowAllExecInfosContent (void)
+#else
+tuiShowAllExecInfosContent ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiShowExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiShowAllExecInfosContent */
+
+
+/*
+** tuiEraseExecInfoContent().
+*/
+void
+#ifdef __STDC__
+tuiEraseExecInfoContent (
+ TuiWinInfoPtr winInfo)
+#else
+tuiEraseExecInfoContent (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
+
+ werase (execInfo->handle);
+ tuiRefreshWin (execInfo);
+
+ return;
+} /* tuiEraseExecInfoContent */
+
+
+/*
+** tuiEraseAllExecInfosContent()
+*/
+void
+#ifdef __STDC__
+tuiEraseAllExecInfosContent (void)
+#else
+tuiEraseAllExecInfosContent ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiEraseExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiEraseAllExecInfosContent */
+
+
+/*
+** tuiClearExecInfoContent().
+*/
+void
+#ifdef __STDC__
+tuiClearExecInfoContent (
+ TuiWinInfoPtr winInfo)
+#else
+tuiClearExecInfoContent (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE;
+ tuiEraseExecInfoContent (winInfo);
+
+ return;
+} /* tuiClearExecInfoContent */
+
+
+/*
+** tuiClearAllExecInfosContent()
+*/
+void
+#ifdef __STDC__
+tuiClearAllExecInfosContent (void)
+#else
+tuiClearAllExecInfosContent ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiClearExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiClearAllExecInfosContent */
+
+
+/*
+** tuiUpdateExecInfo().
+** Function to update the execution info window
+*/
+void
+#ifdef __STDC__
+tuiUpdateExecInfo (
+ TuiWinInfoPtr winInfo)
+#else
+tuiUpdateExecInfo (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ tuiSetExecInfoContent (winInfo);
+ tuiShowExecInfoContent (winInfo);
+} /* tuiUpdateExecInfo
+
+
+/*
+** tuiUpdateAllExecInfos()
+*/
+void
+#ifdef __STDC__
+tuiUpdateAllExecInfos (void)
+#else
+tuiUpdateAllExecInfos ()
+#endif
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiUpdateExecInfo ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiUpdateAllExecInfos*/
+
+
+
+/* tuiUpdateOnEnd()
+** elz: This function clears the execution info from the source windows
+** and resets the locator to display no line info, procedure info, pc
+** info. It is called by stack_publish_stopped_with_no_frame, which
+** is called then the target terminates execution
+*/
+void
+#ifdef __STDC__
+tuiUpdateOnEnd (void)
+#else
+tuiUpdateOnEnd ()
+#endif
+{
+ int i;
+ TuiGenWinInfoPtr locator;
+ char *filename;
+ TuiWinInfoPtr winInfo;
+
+ locator = locatorWinInfoPtr ();
+
+ /* for all the windows (src, asm) */
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ tuiSetIsExecPointAt ((Opaque) - 1, winInfo); /* the target is'n running */
+ /* -1 should not match any line number or pc */
+ tuiSetExecInfoContent (winInfo); /*set winInfo so that > is'n displayed*/
+ tuiShowExecInfoContent (winInfo); /* display the new contents */
+ }
+
+ /*now update the locator*/
+ tuiClearLocatorDisplay ();
+ tuiGetLocatorFilename (locator, &filename);
+ tuiSetLocatorInfo (
+ filename,
+ (char *) NULL,
+ 0,
+ (Opaque) NULL,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiUpdateOnEnd */
+
+
+
+TuiStatus
+#ifdef __STDC__
+tuiAllocSourceBuffer (
+ TuiWinInfoPtr winInfo)
+#else
+tuiAllocSourceBuffer (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ register char *srcLine, *srcLineBuf;
+ register int i, lineWidth, c, maxLines;
+ TuiStatus ret = TUI_FAILURE;
+
+ maxLines = winInfo->generic.height; /* less the highlight box */
+ lineWidth = winInfo->generic.width - 1;
+ /*
+ ** Allocate the buffer for the source lines. Do this only once since they
+ ** will be re-used for all source displays. The only other time this will
+ ** be done is when a window's size changes.
+ */
+ if (winInfo->generic.content == (OpaquePtr) NULL)
+ {
+ srcLineBuf = (char *) xmalloc ((maxLines * lineWidth) * sizeof (char));
+ if (srcLineBuf == (char *) NULL)
+ fputs_unfiltered (
+ "Unable to Allocate Memory for Source or Disassembly Display.\n",
+ gdb_stderr);
+ else
+ {
+ /* allocate the content list */
+ if ((winInfo->generic.content =
+ (OpaquePtr) allocContent (maxLines, SRC_WIN)) == (OpaquePtr) NULL)
+ {
+ tuiFree (srcLineBuf);
+ srcLineBuf = (char *) NULL;
+ fputs_unfiltered (
+ "Unable to Allocate Memory for Source or Disassembly Display.\n",
+ gdb_stderr);
+ }
+ }
+ for (i = 0; i < maxLines; i++)
+ ((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.source.line =
+ srcLineBuf + (lineWidth * i);
+ ret = TUI_SUCCESS;
+ }
+ else
+ ret = TUI_SUCCESS;
+
+ return ret;
+} /* tuiAllocSourceBuffer */
+
+
+/*
+** tuiLineIsDisplayed().
+** Answer whether the a particular line number or address is displayed
+** in the current source window.
+*/
+int
+#ifdef __STDC__
+tuiLineIsDisplayed (
+ Opaque lineNoOrAddr,
+ TuiWinInfoPtr winInfo,
+ int checkThreshold)
+#else
+tuiLineIsDisplayed (lineNoOrAddr, winInfo, checkThreshold)
+ Opaque lineNoOrAddr;
+ TuiWinInfoPtr winInfo;
+ int checkThreshold;
+#endif
+{
+ int isDisplayed = FALSE;
+ int i, threshold;
+
+ if (checkThreshold)
+ threshold = SCROLL_THRESHOLD;
+ else
+ threshold = 0;
+ i = 0;
+ while (i < winInfo->generic.contentSize - threshold && !isDisplayed)
+ {
+ if (winInfo == srcWin)
+ isDisplayed = (((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo
+ == (int) lineNoOrAddr);
+ else
+ isDisplayed = (((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr
+ == lineNoOrAddr);
+ i++;
+ }
+
+ return isDisplayed;
+} /* tuiLineIsDisplayed */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
diff --git a/contrib/gdb/gdb/tui/tuiSourceWin.h b/contrib/gdb/gdb/tui/tuiSourceWin.h
new file mode 100644
index 0000000..13f3a78
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiSourceWin.h
@@ -0,0 +1,74 @@
+#ifndef _TUI_SOURCEWIN_H
+#define _TUI_SOURCEWIN_H
+/*
+** This header file supports
+*/
+
+
+extern void tuiDisplayMainFunction PARAMS ((void));
+extern void tuiUpdateSourceWindow PARAMS
+ ((TuiWinInfoPtr, struct symtab *, Opaque, int));
+extern void tuiUpdateSourceWindowAsIs PARAMS
+ ((TuiWinInfoPtr, struct symtab *, Opaque, int));
+extern void tuiUpdateSourceWindowsWithAddr PARAMS ((Opaque));
+extern void tui_vUpdateSourceWindowsWithAddr PARAMS ((va_list));
+extern void tuiUpdateSourceWindowsWithLine PARAMS ((struct symtab *, int));
+extern void tui_vUpdateSourceWindowsWithLine PARAMS ((va_list));
+extern void tuiUpdateSourceWindowsFromLocator PARAMS ((void));
+extern void tuiClearSourceContent PARAMS ((TuiWinInfoPtr, int));
+extern void tuiClearAllSourceWinsContent PARAMS ((int));
+extern void tuiEraseSourceContent PARAMS ((TuiWinInfoPtr, int));
+extern void tuiEraseAllSourceWinsContent PARAMS ((int));
+extern void tuiSetSourceContentNil PARAMS ((TuiWinInfoPtr, char *));
+extern void tuiShowSourceContent PARAMS ((TuiWinInfoPtr));
+extern void tuiShowAllSourceWinsContent PARAMS ((void));
+extern void tuiHorizontalSourceScroll PARAMS ((TuiWinInfoPtr, TuiScrollDirection, int));
+extern void tuiUpdateOnEnd PARAMS ((void));
+
+extern TuiStatus tuiSetExecInfoContent PARAMS ((TuiWinInfoPtr));
+extern void tuiShowExecInfoContent PARAMS ((TuiWinInfoPtr));
+extern void tuiShowAllExecInfosContent PARAMS ((void));
+extern void tuiEraseExecInfoContent PARAMS ((TuiWinInfoPtr));
+extern void tuiEraseAllExecInfosContent PARAMS ((void));
+extern void tuiClearExecInfoContent PARAMS ((TuiWinInfoPtr));
+extern void tuiClearAllExecInfosContent PARAMS ((void));
+extern void tuiUpdateExecInfo PARAMS ((TuiWinInfoPtr));
+extern void tuiUpdateAllExecInfos PARAMS ((void));
+
+extern void tuiSetIsExecPointAt PARAMS ((Opaque, TuiWinInfoPtr));
+extern void tuiSetHasBreakAt PARAMS ((struct breakpoint *, TuiWinInfoPtr, int));
+extern void tuiAllSetHasBreakAt PARAMS ((struct breakpoint *, int));
+extern void tui_vAllSetHasBreakAt PARAMS ((va_list));
+extern TuiStatus tuiAllocSourceBuffer PARAMS ((TuiWinInfoPtr));
+extern int tuiLineIsDisplayed PARAMS ((Opaque, TuiWinInfoPtr, int));
+
+
+/*
+** Constant definitions
+*/
+#define SCROLL_THRESHOLD 2 /* threshold for lazy scroll */
+
+
+/*
+** Macros
+*/
+#define m_tuiSetBreakAt(bp, winInfo) tuiSetHasBreakAt((bp, winInfo, TRUE)
+#define m_tuiClearBreakAt(bp, winInfo) tuiSetHasBreakAt(bp, winInfo, FALSE)
+
+#define m_tuiAllSetBreakAt(bp) tuiAllSetHasBreakAt(bp, TRUE)
+#define m_tuiAllClearBreakAt(bp) tuiAllSetHasBreakAt(bp, FALSE)
+
+#define m_tuiSrcLineDisplayed(lineNo) tuiLineIsDisplayed((Opaque)(lineNo), srcWin, FALSE)
+#define m_tuiSrcAddrDisplayed(addr) tuiLineIsDisplayed((Opaque)(addr), disassemWin, FALSE)
+#define m_tuiSrcLineDisplayedWithinThreshold(lineNo) \
+ tuiLineIsDisplayed((Opaque)(lineNo), srcWin, TRUE)
+#define m_tuiSrcAddrDisplayedWithinThreshold(addr) \
+ tuiLineIsDisplayed((Opaque)(addr), disassemWin, TRUE)
+#define m_tuiLineDisplayedWithinThreshold(winInfo, lineOrAddr) \
+ ( (winInfo == srcWin) ? \
+ m_tuiSrcLineDisplayedWithinThreshold(lineOrAddr) : \
+ m_tuiSrcAddrDisplayedWithinThreshold(lineOrAddr) )
+
+
+
+#endif /*_TUI_SOURCEWIN_H */
diff --git a/contrib/gdb/gdb/tui/tuiStack.c b/contrib/gdb/gdb/tui/tuiStack.c
new file mode 100644
index 0000000..401dfe2
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiStack.c
@@ -0,0 +1,554 @@
+/*
+** This module contains functions for displaying the locator information in the locator window.
+*/
+
+#include "defs.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "frame.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiStack.h"
+#include "tuiSourceWin.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+static char *_getFuncNameFromFrame PARAMS ((struct frame_info *));
+static void _tuiUpdateLocation_command PARAMS ((char *, int));
+
+
+
+/*****************************************
+** PUBLIC FUNCTION **
+******************************************/
+
+/*
+** tuiClearLocatorDisplay()
+*/
+void
+#ifdef __STDC__
+tuiClearLocatorDisplay (void)
+#else
+tuiClearLocatorDisplay ()
+#endif
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ int i;
+
+ if (locator->handle != (WINDOW *) NULL)
+ {
+ /* No need to werase, since writing a line of
+ * blanks which we do below, is equivalent.
+ */
+ /* werase(locator->handle); */
+ wmove (locator->handle, 0, 0);
+ wstandout (locator->handle);
+ for (i = 0; i < locator->width; i++)
+ waddch (locator->handle, ' ');
+ wstandend (locator->handle);
+ tuiRefreshWin (locator);
+ wmove (locator->handle, 0, 0);
+ locator->contentInUse = FALSE;
+ }
+
+ return;
+} /* tuiClearLocatorDisplay */
+
+
+/*
+** tuiShowLocatorContent()
+*/
+void
+#ifdef __STDC__
+tuiShowLocatorContent (void)
+#else
+tuiShowLocatorContent ()
+#endif
+{
+ char *string;
+ TuiGenWinInfoPtr locator;
+
+ locator = locatorWinInfoPtr ();
+
+ if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL)
+ {
+ string = displayableWinContentAt (locator, 0);
+ if (string != (char *) NULL)
+ {
+ wmove (locator->handle, 0, 0);
+ wstandout (locator->handle);
+ waddstr (locator->handle, string);
+ wstandend (locator->handle);
+ tuiRefreshWin (locator);
+ wmove (locator->handle, 0, 0);
+ if (string != nullStr ())
+ tuiFree (string);
+ locator->contentInUse = TRUE;
+ }
+ }
+
+ return;
+} /* tuiShowLocatorContent */
+
+
+/*
+** tuiSetLocatorInfo().
+** Function to update the locator, with the provided arguments.
+*/
+void
+#ifdef __STDC__
+tuiSetLocatorInfo (
+ char *fname,
+ char *procname,
+ int lineNo,
+ Opaque addr,
+ TuiLocatorElementPtr element)
+#else
+tuiSetLocatorInfo (fname, procname, lineNo, addr, element)
+ char *fname;
+ char *procname;
+ int lineNo;
+ Opaque addr;
+ TuiLocatorElementPtr element;
+#endif
+{
+#ifdef COMMENT
+ /* first free the old info */
+ if (element->fileName)
+ tuiFree (element->fileName);
+ if (element->procName)
+ tuiFree (element->procName);
+
+ if (fname == (char *) NULL)
+ element->fileName = fname;
+ else
+ element->fileName = tuiStrDup (fname);
+ if (procname == (char *) NULL)
+ element->procName = procname;
+ else
+ element->procName = tuiStrDup (procname);
+#else
+ element->fileName[0] = (char) 0;
+ element->procName[0] = (char) 0;
+ strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, fname);
+ strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname);
+#endif
+ element->lineNo = lineNo;
+ element->addr = (Opaque) addr;
+
+ return;
+} /* tuiSetLocatorInfo */
+
+
+/*
+** tuiUpdateLocatorFilename().
+** Update only the filename portion of the locator.
+*/
+void
+#ifdef __STDC__
+tuiUpdateLocatorFilename (
+ char *fileName)
+#else
+tuiUpdateLocatorFilename (fileName)
+ char *fileName;
+#endif
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (locator->content[0] == (Opaque) NULL)
+ tuiSetLocatorContent ((struct frame_info *) NULL);
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0;
+ strcat_to_buf (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName,
+ MAX_LOCATOR_ELEMENT_LEN,
+ fileName);
+
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiUpdateLocatorFilename */
+
+
+/*
+** tui_vUpdateLocatorFilename().
+** Update only the filename portion of the locator with args in a va_list.
+*/
+void
+#ifdef __STDC__
+tui_vUpdateLocatorFilename (
+ va_list args)
+#else
+tui_vUpdateLocatorFilename (args)
+ va_list args;
+#endif
+{
+ char *fileName;
+
+ fileName = va_arg (args, char *);
+ tuiUpdateLocatorFilename (fileName);
+
+ return;
+} /* tui_vUpdateLocatorFilename */
+
+
+/*
+** tuiSwitchFilename().
+** Update the filename portion of the locator. Clear the other info in locator.
+** (elz)
+*/
+void
+#ifdef __STDC__
+tuiSwitchFilename (
+ char *fileName)
+#else
+tuiSwitchFilename (fileName)
+ char *fileName;
+#endif
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (locator->content[0] == (Opaque) NULL)
+ tuiSetLocatorContent ((struct frame_info *) NULL);
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0;
+
+ tuiSetLocatorInfo (fileName,
+ (char *) NULL,
+ 0,
+ (Opaque) NULL,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiSwitchFilename */
+
+
+/*
+** tuiGetLocatorFilename().
+** Get the filename portion of the locator.
+** (elz)
+*/
+void
+#ifdef __STDC__
+tuiGetLocatorFilename (
+ TuiGenWinInfoPtr locator,
+ char **filename)
+#else
+tuiGetLocatorFilename (locator, filename)
+ TuiGenWinInfoPtr locator;
+ char **filename;
+#endif
+{
+
+ /* the current filename could be non known, in which case the xmalloc would
+ allocate no memory, because the length would be 0 */
+ if (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName)
+ {
+ int name_length =
+ strlen (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName);
+
+ (*filename) = (char *) xmalloc (name_length + 1);
+ strcpy ((*filename),
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName);
+ }
+
+ return;
+} /* tuiGetLocatorFilename */
+
+
+/*
+** tuiUpdateLocatorInfoFromFrame().
+** Function to update the locator, with the information extracted from frameInfo
+*/
+void
+#ifdef __STDC__
+tuiUpdateLocatorInfoFromFrame (
+ struct frame_info *frameInfo,
+ TuiLocatorElementPtr element)
+#else
+tuiUpdateLocatorInfoFromFrame (frameInfo, element)
+ struct frame_info *frameInfo;
+ TuiLocatorElementPtr element;
+#endif
+{
+ struct symtab_and_line symtabAndLine;
+
+ /* now get the new info */
+ symtabAndLine = find_pc_line (frameInfo->pc,
+ (frameInfo->next != (struct frame_info *) NULL &&
+ !frameInfo->next->signal_handler_caller &&
+ !frame_in_dummy (frameInfo->next)));
+ if (symtabAndLine.symtab && symtabAndLine.symtab->filename)
+ tuiSetLocatorInfo (symtabAndLine.symtab->filename,
+ _getFuncNameFromFrame (frameInfo),
+ symtabAndLine.line,
+ (Opaque) frameInfo->pc,
+ element);
+ else
+ tuiSetLocatorInfo ((char *) NULL,
+ _getFuncNameFromFrame (frameInfo),
+ 0,
+ (Opaque) frameInfo->pc,
+ element);
+
+ return;
+} /* tuiUpdateLocatorInfoFromFrame */
+
+
+/*
+** tuiSetLocatorContent().
+** Function to set the content of the locator
+*/
+void
+#ifdef __STDC__
+tuiSetLocatorContent (
+ struct frame_info *frameInfo)
+#else
+tuiSetLocatorContent (frameInfo)
+ struct frame_info *frameInfo;
+#endif
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ TuiWinElementPtr element;
+ struct symtab_and_line symtabAndLine;
+
+ /* Allocate the element if necessary */
+ if (locator->contentSize <= 0)
+ {
+ TuiWinContent contentPtr;
+
+ if ((locator->content = (OpaquePtr) allocContent (1, locator->type)) == (OpaquePtr) NULL)
+ error ("Unable to Allocate Memory to Display Location.");
+ locator->contentSize = 1;
+ }
+
+ if (frameInfo != (struct frame_info *) NULL)
+ tuiUpdateLocatorInfoFromFrame (frameInfo,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+ else
+ tuiSetLocatorInfo ((char *) NULL,
+ (char *) NULL,
+ 0,
+ (Opaque) NULL,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+ return;
+} /* tuiSetLocatorContent */
+
+
+/*
+** tuiUpdateLocatorDisplay().
+** Function to update the locator display
+*/
+void
+#ifdef __STDC__
+tuiUpdateLocatorDisplay (
+ struct frame_info *frameInfo)
+#else
+tuiUpdateLocatorDisplay (frameInfo)
+ struct frame_info *frameInfo;
+#endif
+{
+ tuiClearLocatorDisplay ();
+ tuiSetLocatorContent (frameInfo);
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiUpdateLocatorDisplay */
+
+
+/*
+** tuiShowFrameInfo().
+** Function to print the frame inforrmation for the TUI.
+*/
+void
+#ifdef __STDC__
+tuiShowFrameInfo (
+ struct frame_info *fi)
+#else
+tuiShowFrameInfo (fi)
+ struct frame_info *fi;
+#endif
+{
+ TuiWinInfoPtr winInfo;
+ register int i;
+
+ if (fi)
+ {
+ register int startLine, i;
+ register struct symtab *s;
+ CORE_ADDR low;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ int sourceAlreadyDisplayed;
+
+
+ s = find_pc_symtab (fi->pc);
+ sourceAlreadyDisplayed = tuiSourceIsDisplayed (s->filename);
+ tuiUpdateLocatorDisplay (fi);
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+ if (winInfo == srcWin)
+ {
+ startLine =
+ (((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo -
+ (winInfo->generic.viewportHeight / 2)) + 1;
+ if (startLine <= 0)
+ startLine = 1;
+ }
+ else
+ {
+ if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0)
+ error ("No function contains program counter for selected frame.\n");
+ else
+ low = (CORE_ADDR) tuiGetLowDisassemblyAddress ((Opaque) low, (Opaque) fi->pc);
+ }
+
+ if (winInfo == srcWin)
+ {
+ if (!(sourceAlreadyDisplayed && m_tuiLineDisplayedWithinThreshold (
+ winInfo,
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo)))
+ tuiUpdateSourceWindow (winInfo, s, (Opaque) startLine, TRUE);
+ else
+ tuiSetIsExecPointAt ((Opaque)
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo,
+ winInfo);
+ }
+ else
+ {
+ if (winInfo == disassemWin)
+ {
+ if (!m_tuiLineDisplayedWithinThreshold (winInfo,
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr))
+ tuiUpdateSourceWindow (winInfo, s, (Opaque) low, TRUE);
+ else
+ tuiSetIsExecPointAt ((Opaque)
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr,
+ winInfo);
+ }
+ }
+ tuiUpdateExecInfo (winInfo);
+ }
+ }
+ else
+ {
+ tuiUpdateLocatorDisplay (fi);
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+ tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
+ tuiUpdateExecInfo (winInfo);
+ }
+ }
+
+ return;
+} /* tuiShowFrameInfo */
+
+
+/*
+** tui_vShowFrameInfo().
+** Function to print the frame inforrmation for the TUI with args in a va_list.
+*/
+void
+#ifdef __STDC__
+tui_vShowFrameInfo (
+ va_list args)
+#else
+tui_vShowFrameInfo (args)
+ va_list args;
+#endif
+{
+ struct frame_info *fi;
+
+ fi = va_arg (args, struct frame_info *);
+ tuiShowFrameInfo (fi);
+
+ return;
+} /* tui_vShowFrameInfo */
+
+
+/*
+** _initialize_tuiStack().
+** Function to initialize gdb commands, for tui window stack manipulation.
+*/
+void
+_initialize_tuiStack ()
+{
+ if (tui_version)
+ {
+ add_com ("update", class_tui, _tuiUpdateLocation_command,
+ "Update the source window and locator to display the current execution point.\n");
+ }
+
+ return;
+} /* _initialize_tuiStack */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+
+/*
+** _getFuncNameFromFrame().
+*/
+static char *
+#ifdef __STDC__
+_getFuncNameFromFrame (
+ struct frame_info *frameInfo)
+#else
+_getFuncNameFromFrame (frameInfo)
+ struct frame_info *frameInfo;
+#endif
+{
+ char *funcName = (char *) NULL;
+
+ find_pc_partial_function (frameInfo->pc,
+ &funcName,
+ (CORE_ADDR *) NULL,
+ (CORE_ADDR *) NULL);
+ return funcName;
+} /* _getFuncNameFromFrame */
+
+
+/*
+** _tuiUpdateLocation_command().
+** Command to update the display with the current execution point
+*/
+static void
+#ifdef __STDC__
+_tuiUpdateLocation_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiUpdateLocation_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+#ifndef TRY
+ extern void frame_command PARAMS ((char *, int));
+ frame_command ("0", FALSE);
+#else
+ struct frame_info *curFrame;
+
+ /* Obtain the current execution point */
+ if ((curFrame = get_current_frame ()) != (struct frame_info *) NULL)
+ {
+ struct frame_info *frame;
+ int curLevel = 0;
+
+ for (frame = get_prev_frame (curLevel);
+ (frame != (struct frame_info *) NULL && (frame != curFrame));
+ frame = get_prev_frame (frame))
+ curLevel++;
+
+ if (curFrame != (struct frame_info *) NULL)
+ print_frame_info (frame, curLevel, 0, 1);
+ }
+#endif
+
+ return;
+} /* _tuiUpdateLocation_command */
diff --git a/contrib/gdb/gdb/tui/tuiStack.h b/contrib/gdb/gdb/tui/tuiStack.h
new file mode 100644
index 0000000..20e9a92
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiStack.h
@@ -0,0 +1,22 @@
+#ifndef _TUI_STACK_H
+#define _TUI_STACK_H
+/*
+** This header file supports
+*/
+
+extern void tuiSetLocatorInfo PARAMS ((char *, char *, int, Opaque, TuiLocatorElementPtr));
+extern void tuiUpdateLocatorFilename PARAMS ((char *));
+extern void tui_vUpdateLocatorFilename PARAMS ((va_list));
+extern void tuiUpdateLocatorInfoFromFrame
+ PARAMS ((struct frame_info *, TuiLocatorElementPtr));
+extern void tuiUpdateLocatorDisplay PARAMS ((struct frame_info *));
+extern void tuiSetLocatorContent PARAMS ((struct frame_info *));
+extern void tuiShowLocatorContent PARAMS ((void));
+extern void tuiClearLocatorContent PARAMS ((void));
+extern void tuiSwitchFilename PARAMS ((char *));
+extern void tuiShowFrameInfo PARAMS ((struct frame_info *));
+extern void tui_vShowFrameInfo PARAMS ((va_list));
+extern void tuiGetLocatorFilename PARAMS ((TuiGenWinInfoPtr, char **));
+
+
+#endif /*_TUI_STACK_H*/
diff --git a/contrib/gdb/gdb/tui/tuiWin.c b/contrib/gdb/gdb/tui/tuiWin.c
new file mode 100644
index 0000000..45bb0f6
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiWin.c
@@ -0,0 +1,1650 @@
+/*
+** tuiWin.c
+** This module contains procedures for handling tui window functions
+** like resize, scrolling, scrolling, changing focus, etc.
+**
+** Author: Susan B. Macchia
+*/
+
+
+#include <string.h>
+#include "defs.h"
+#include "command.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "frame.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+#include "tuiStack.h"
+#include "tuiSourceWin.h"
+#include "tuiDataWin.h"
+
+/*******************************
+** External Declarations
+********************************/
+extern void init_page_info ();
+
+/*******************************
+** Static Local Decls
+********************************/
+static void _makeVisibleWithNewHeight PARAMS ((TuiWinInfoPtr));
+static void _makeInvisibleAndSetNewHeight PARAMS ((TuiWinInfoPtr, int));
+static TuiStatus _tuiAdjustWinHeights PARAMS ((TuiWinInfoPtr, int));
+static int _newHeightOk PARAMS ((TuiWinInfoPtr, int));
+static void _tuiSetTabWidth_command PARAMS ((char *, int));
+static void _tuiRefreshAll_command PARAMS ((char *, int));
+static void _tuiSetWinHeight_command PARAMS ((char *, int));
+static void _tuiXDBsetWinHeight_command PARAMS ((char *, int));
+static void _tuiAllWindowsInfo PARAMS ((char *, int));
+static void _tuiSetFocus_command PARAMS ((char *, int));
+static void _tuiScrollForward_command PARAMS ((char *, int));
+static void _tuiScrollBackward_command PARAMS ((char *, int));
+static void _tuiScrollLeft_command PARAMS ((char *, int));
+static void _tuiScrollRight_command PARAMS ((char *, int));
+static void _parseScrollingArgs PARAMS ((char *, TuiWinInfoPtr *, int *));
+
+
+/***************************************
+** DEFINITIONS
+***************************************/
+#define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
+#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
+#define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
+
+/***************************************
+** PUBLIC FUNCTIONS
+***************************************/
+
+/*
+** _initialize_tuiWin().
+** Function to initialize gdb commands, for tui window manipulation.
+*/
+void
+_initialize_tuiWin ()
+{
+ if (tui_version)
+ {
+ add_com ("refresh", class_tui, _tuiRefreshAll_command,
+ "Refresh the terminal display.\n");
+ if (xdb_commands)
+ add_com_alias ("U", "refresh", class_tui, 0);
+ add_com ("tabset", class_tui, _tuiSetTabWidth_command,
+ "Set the width (in characters) of tab stops.\n\
+Usage: tabset <n>\n");
+ add_com ("winheight", class_tui, _tuiSetWinHeight_command,
+ "Set the height of a specified window.\n\
+Usage: winheight <win_name> [+ | -] <#lines>\n\
+Window names are:\n\
+src : the source window\n\
+cmd : the command window\n\
+asm : the disassembly window\n\
+regs : the register display\n");
+ add_com_alias ("wh", "winheight", class_tui, 0);
+ add_info ("win", _tuiAllWindowsInfo,
+ "List of all displayed windows.\n");
+ add_com ("focus", class_tui, _tuiSetFocus_command,
+ "Set focus to named window or next/prev window.\n\
+Usage: focus {<win> | next | prev}\n\
+Valid Window names are:\n\
+src : the source window\n\
+asm : the disassembly window\n\
+regs : the register display\n\
+cmd : the command window\n");
+ add_com_alias ("fs", "focus", class_tui, 0);
+ add_com ("+", class_tui, _tuiScrollForward_command,
+ "Scroll window forward.\nUsage: + [win] [n]\n");
+ add_com ("-", class_tui, _tuiScrollBackward_command,
+ "Scroll window backward.\nUsage: - [win] [n]\n");
+ add_com ("<", class_tui, _tuiScrollLeft_command,
+ "Scroll window forward.\nUsage: < [win] [n]\n");
+ add_com (">", class_tui, _tuiScrollRight_command,
+ "Scroll window backward.\nUsage: > [win] [n]\n");
+ if (xdb_commands)
+ add_com ("w", class_xdb, _tuiXDBsetWinHeight_command,
+ "XDB compatibility command for setting the height of a command window.\n\
+Usage: w <#lines>\n");
+ }
+
+ return;
+} /* _intialize_tuiWin */
+
+
+/*
+** tuiClearWinFocusFrom
+** Clear the logical focus from winInfo
+*/
+void
+#ifdef __STDC__
+tuiClearWinFocusFrom (
+ TuiWinInfoPtr winInfo)
+#else
+tuiClearWinFocusFrom (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ if (winInfo->generic.type != CMD_WIN)
+ unhighlightWin (winInfo);
+ tuiSetWinWithFocus ((TuiWinInfoPtr) NULL);
+ }
+
+ return;
+} /* tuiClearWinFocusFrom */
+
+
+/*
+** tuiClearWinFocus().
+** Clear the window that has focus.
+*/
+void
+#ifdef __STDC__
+tuiClearWinFocus (void)
+#else
+tuiClearWinFocus ()
+#endif
+{
+ tuiClearWinFocusFrom (tuiWinWithFocus ());
+
+ return;
+} /* tuiClearWinFocus */
+
+
+/*
+** tuiSetWinFocusTo
+** Set the logical focus to winInfo
+*/
+void
+#ifdef __STDC__
+tuiSetWinFocusTo (
+ TuiWinInfoPtr winInfo)
+#else
+tuiSetWinFocusTo (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+
+ if (m_winPtrNotNull (winWithFocus) &&
+ winWithFocus->generic.type != CMD_WIN)
+ unhighlightWin (winWithFocus);
+ tuiSetWinWithFocus (winInfo);
+ if (winInfo->generic.type != CMD_WIN)
+ highlightWin (winInfo);
+ }
+
+ return;
+} /* tuiSetWinFocusTo */
+
+
+char *
+#ifdef __STDC__
+tuiStrDup (
+ char *str)
+#else
+tuiStrDup (str)
+ char *str;
+#endif
+{
+ char *newStr = (char *) NULL;
+
+ if (str != (char *) NULL)
+ {
+ newStr = (char *) xmalloc (strlen (str) + 1);
+ strcpy (newStr, str);
+ }
+
+ return newStr;
+} /* tuiStrDup */
+
+
+/*
+** tuiScrollForward().
+*/
+void
+#ifdef __STDC__
+tuiScrollForward (
+ TuiWinInfoPtr winToScroll,
+ int numToScroll)
+#else
+tuiScrollForward (winToScroll, numToScroll)
+ TuiWinInfoPtr winToScroll;
+ int numToScroll;
+#endif
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (numToScroll == 0)
+ _numToScroll = winToScroll->generic.height - 3;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin)
+ tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll);
+ else if (winToScroll == disassemWin)
+ tuiVerticalDisassemScroll (FORWARD_SCROLL, _numToScroll);
+ else if (winToScroll == dataWin)
+ tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll);
+ }
+
+ return;
+} /* tuiScrollForward */
+
+
+/*
+** tuiScrollBackward().
+*/
+void
+#ifdef __STDC__
+tuiScrollBackward (
+ TuiWinInfoPtr winToScroll,
+ int numToScroll)
+#else
+tuiScrollBackward (winToScroll, numToScroll)
+ TuiWinInfoPtr winToScroll;
+ int numToScroll;
+#endif
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (numToScroll == 0)
+ _numToScroll = winToScroll->generic.height - 3;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin)
+ tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll);
+ else if (winToScroll == disassemWin)
+ tuiVerticalDisassemScroll (BACKWARD_SCROLL, _numToScroll);
+ else if (winToScroll == dataWin)
+ tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll);
+ }
+ return;
+} /* tuiScrollBackward */
+
+
+/*
+** tuiScrollLeft().
+*/
+void
+#ifdef __STDC__
+tuiScrollLeft (
+ TuiWinInfoPtr winToScroll,
+ int numToScroll)
+#else
+tuiScrollLeft (winToScroll, numToScroll)
+ TuiWinInfoPtr winToScroll;
+ int numToScroll;
+#endif
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (_numToScroll == 0)
+ _numToScroll = 1;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin || winToScroll == disassemWin)
+ tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll);
+ }
+ return;
+} /* tuiScrollLeft */
+
+
+/*
+** tuiScrollRight().
+*/
+void
+#ifdef __STDC__
+tuiScrollRight (
+ TuiWinInfoPtr winToScroll,
+ int numToScroll)
+#else
+tuiScrollRight (winToScroll, numToScroll)
+ TuiWinInfoPtr winToScroll;
+ int numToScroll;
+#endif
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (_numToScroll == 0)
+ _numToScroll = 1;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin || winToScroll == disassemWin)
+ tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll);
+ }
+ return;
+} /* tuiScrollRight */
+
+
+/*
+** tui_vScroll().
+** Scroll a window. Arguments are passed through a va_list.
+*/
+void
+#ifdef __STDC__
+tui_vScroll (
+ va_list args)
+#else
+tui_vScroll (args)
+ va_list args;
+#endif
+{
+ TuiScrollDirection direction = va_arg (args, TuiScrollDirection);
+ TuiWinInfoPtr winToScroll = va_arg (args, TuiWinInfoPtr);
+ int numToScroll = va_arg (args, int);
+
+ switch (direction)
+ {
+ case FORWARD_SCROLL:
+ tuiScrollForward (winToScroll, numToScroll);
+ break;
+ case BACKWARD_SCROLL:
+ tuiScrollBackward (winToScroll, numToScroll);
+ break;
+ case LEFT_SCROLL:
+ tuiScrollLeft (winToScroll, numToScroll);
+ break;
+ case RIGHT_SCROLL:
+ tuiScrollRight (winToScroll, numToScroll);
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* tui_vScroll */
+
+
+/*
+** tuiRefreshAll().
+*/
+void
+#ifdef __STDC__
+tuiRefreshAll (void)
+#else
+tuiRefreshAll ()
+#endif
+{
+ TuiWinType type;
+
+ refreshAll (winList);
+ for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
+ {
+ if (winList[type]->generic.isVisible)
+ {
+ switch (type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ tuiClearWin (&winList[type]->generic);
+ if (winList[type]->detail.sourceInfo.hasLocator)
+ tuiClearLocatorDisplay ();
+ tuiShowSourceContent (winList[type]);
+ checkAndDisplayHighlightIfNeeded (winList[type]);
+ tuiEraseExecInfoContent (winList[type]);
+ tuiUpdateExecInfo (winList[type]);
+ break;
+ case DATA_WIN:
+ tuiRefreshDataWin ();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ tuiClearLocatorDisplay ();
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiRefreshAll */
+
+
+/*
+** tuiResizeAll().
+** Resize all the windows based on the the terminal size. This
+** function gets called from within the readline sinwinch handler.
+*/
+void
+#ifdef __STDC__
+tuiResizeAll (void)
+#else
+tuiResizeAll ()
+#endif
+{
+ int heightDiff, widthDiff;
+ extern int screenheight, screenwidth; /* in readline */
+
+ widthDiff = screenwidth - termWidth ();
+ heightDiff = screenheight - termHeight ();
+ if (heightDiff || widthDiff)
+ {
+ TuiLayoutType curLayout = currentLayout ();
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+ TuiWinInfoPtr firstWin, secondWin;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ TuiWinType winType;
+ int i, newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
+
+ /* turn keypad off while we resize */
+ if (winWithFocus != cmdWin)
+ keypad (cmdWin->generic.handle, FALSE);
+ init_page_info ();
+ setTermHeightTo (screenheight);
+ setTermWidthTo (screenwidth);
+ if (curLayout == SRC_DISASSEM_COMMAND ||
+ curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
+ numWinsDisplayed++;
+ splitDiff = heightDiff / numWinsDisplayed;
+ cmdSplitDiff = splitDiff;
+ if (heightDiff % numWinsDisplayed)
+ {
+ if (heightDiff < 0)
+ cmdSplitDiff--;
+ else
+ cmdSplitDiff++;
+ }
+ /* now adjust each window */
+ clear ();
+ refresh ();
+ switch (curLayout)
+ {
+ case SRC_COMMAND:
+ case DISASSEM_COMMAND:
+ firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ firstWin->generic.width += widthDiff;
+ locator->width += widthDiff;
+ /* check for invalid heights */
+ if (heightDiff == 0)
+ newHeight = firstWin->generic.height;
+ else if ((firstWin->generic.height + splitDiff) >=
+ (screenheight - MIN_CMD_WIN_HEIGHT - 1))
+ newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
+ else if ((firstWin->generic.height + splitDiff) <= 0)
+ newHeight = MIN_WIN_HEIGHT;
+ else
+ newHeight = firstWin->generic.height + splitDiff;
+
+ _makeInvisibleAndSetNewHeight (firstWin, newHeight);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ cmdWin->generic.width += widthDiff;
+ newHeight = screenheight - cmdWin->generic.origin.y;
+ _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
+ _makeVisibleWithNewHeight (firstWin);
+ _makeVisibleWithNewHeight (cmdWin);
+ if (firstWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
+ break;
+ default:
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ {
+ firstWin = srcWin;
+ firstWin->generic.width += widthDiff;
+ secondWin = disassemWin;
+ secondWin->generic.width += widthDiff;
+ }
+ else
+ {
+ firstWin = dataWin;
+ firstWin->generic.width += widthDiff;
+ secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ secondWin->generic.width += widthDiff;
+ }
+ /* Change the first window's height/width */
+ /* check for invalid heights */
+ if (heightDiff == 0)
+ newHeight = firstWin->generic.height;
+ else if ((firstWin->generic.height +
+ secondWin->generic.height + (splitDiff * 2)) >=
+ (screenheight - MIN_CMD_WIN_HEIGHT - 1))
+ newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
+ else if ((firstWin->generic.height + splitDiff) <= 0)
+ newHeight = MIN_WIN_HEIGHT;
+ else
+ newHeight = firstWin->generic.height + splitDiff;
+ _makeInvisibleAndSetNewHeight (firstWin, newHeight);
+
+ if (firstWin == dataWin && widthDiff != 0)
+ firstWin->detail.dataDisplayInfo.regsColumnCount =
+ tuiCalculateRegsColumnCount (
+ firstWin->detail.dataDisplayInfo.regsDisplayType);
+ locator->width += widthDiff;
+
+ /* Change the second window's height/width */
+ /* check for invalid heights */
+ if (heightDiff == 0)
+ newHeight = secondWin->generic.height;
+ else if ((firstWin->generic.height +
+ secondWin->generic.height + (splitDiff * 2)) >=
+ (screenheight - MIN_CMD_WIN_HEIGHT - 1))
+ {
+ newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
+ if (newHeight % 2)
+ newHeight = (newHeight / 2) + 1;
+ else
+ newHeight /= 2;
+ }
+ else if ((secondWin->generic.height + splitDiff) <= 0)
+ newHeight = MIN_WIN_HEIGHT;
+ else
+ newHeight = secondWin->generic.height + splitDiff;
+ secondWin->generic.origin.y = firstWin->generic.height - 1;
+ _makeInvisibleAndSetNewHeight (secondWin, newHeight);
+
+ /* Change the command window's height/width */
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ _makeInvisibleAndSetNewHeight (
+ cmdWin, cmdWin->generic.height + cmdSplitDiff);
+ _makeVisibleWithNewHeight (firstWin);
+ _makeVisibleWithNewHeight (secondWin);
+ _makeVisibleWithNewHeight (cmdWin);
+ if (firstWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
+ if (secondWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
+ break;
+ }
+ /*
+ ** Now remove all invisible windows, and their content so that they get
+ ** created again when called for with the new size
+ */
+ for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
+ {
+ if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) &&
+ !winList[winType]->generic.isVisible)
+ {
+ freeWindow (winList[winType]);
+ winList[winType] = (TuiWinInfoPtr) NULL;
+ }
+ }
+ tuiSetWinResizedTo (TRUE);
+ /* turn keypad back on, unless focus is in the command window */
+ if (winWithFocus != cmdWin)
+ keypad (cmdWin->generic.handle, TRUE);
+ }
+ return;
+} /* tuiResizeAll */
+
+
+/*
+** tuiSigwinchHandler()
+** SIGWINCH signal handler for the tui. This signal handler is
+** always called, even when the readline package clears signals
+** because it is set as the old_sigwinch() (TUI only)
+*/
+void
+#ifdef __STDC__
+tuiSigwinchHandler (
+ int signal)
+#else
+tuiSigwinchHandler (signal)
+ int signal;
+#endif
+{
+ /*
+ ** Say that a resize was done so that the readline can do it
+ ** later when appropriate.
+ */
+ tuiSetWinResizedTo (TRUE);
+
+ return;
+} /* tuiSigwinchHandler */
+
+
+
+/*************************
+** STATIC LOCAL FUNCTIONS
+**************************/
+
+
+/*
+** _tuiScrollForward_command().
+*/
+static void
+#ifdef __STDC__
+_tuiScrollForward_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiScrollForward_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ int numToScroll = 1;
+ TuiWinInfoPtr winToScroll;
+
+ if (arg == (char *) NULL)
+ _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
+ else
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
+ FORWARD_SCROLL,
+ winToScroll,
+ numToScroll);
+
+ return;
+} /* _tuiScrollForward_command */
+
+
+/*
+** _tuiScrollBackward_command().
+*/
+static void
+#ifdef __STDC__
+_tuiScrollBackward_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiScrollBackward_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ int numToScroll = 1;
+ TuiWinInfoPtr winToScroll;
+
+ if (arg == (char *) NULL)
+ _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
+ else
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
+ BACKWARD_SCROLL,
+ winToScroll,
+ numToScroll);
+
+ return;
+} /* _tuiScrollBackward_command */
+
+
+/*
+** _tuiScrollLeft_command().
+*/
+static void
+#ifdef __STDC__
+_tuiScrollLeft_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiScrollLeft_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ int numToScroll;
+ TuiWinInfoPtr winToScroll;
+
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
+ LEFT_SCROLL,
+ winToScroll,
+ numToScroll);
+
+ return;
+} /* _tuiScrollLeft_command */
+
+
+/*
+** _tuiScrollRight_command().
+*/
+static void
+#ifdef __STDC__
+_tuiScrollRight_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiScrollRight_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ int numToScroll;
+ TuiWinInfoPtr winToScroll;
+
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
+ RIGHT_SCROLL,
+ winToScroll,
+ numToScroll);
+
+ return;
+} /* _tuiScrollRight_command */
+
+
+/*
+** _tuiSetFocus().
+** Set focus to the window named by 'arg'
+*/
+static void
+#ifdef __STDC__
+_tuiSetFocus (
+ char *arg,
+ int fromTTY)
+#else
+_tuiSetFocus (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if (arg != (char *) NULL)
+ {
+ char *bufPtr = (char *) tuiStrDup (arg);
+ int i;
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+
+ for (i = 0; (i < strlen (bufPtr)); i++)
+ bufPtr[i] = toupper (arg[i]);
+
+ if (subsetCompare (bufPtr, "NEXT"))
+ winInfo = tuiNextWin (tuiWinWithFocus ());
+ else if (subsetCompare (bufPtr, "PREV"))
+ winInfo = tuiPrevWin (tuiWinWithFocus ());
+ else
+ winInfo = partialWinByName (bufPtr);
+
+ if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
+ warning ("Invalid window specified. \n\
+The window name specified must be valid and visible.\n");
+ else
+ {
+ tuiSetWinFocusTo (winInfo);
+ keypad (cmdWin->generic.handle, (winInfo != cmdWin));
+ }
+
+ if (dataWin->generic.isVisible)
+ tuiRefreshDataWin ();
+ tuiFree (bufPtr);
+ printf_filtered ("Focus set to %s window.\n",
+ winName ((TuiGenWinInfoPtr) tuiWinWithFocus ()));
+ }
+ else
+ warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
+
+ return;
+} /* _tuiSetFocus */
+
+
+/*
+** _tui_vSetFocus()
+*/
+static void
+#ifdef __STDC__
+_tui_vSetFocus (
+ va_list args)
+#else
+_tui_vSetFocus (args)
+ va_list args;
+#endif
+{
+ char *arg = va_arg (args, char *);
+ int fromTTY = va_arg (args, int);
+
+ _tuiSetFocus (arg, fromTTY);
+
+ return;
+} /* tui_vSetFocus */
+
+
+/*
+** _tuiSetFocus_command()
+*/
+static void
+#ifdef __STDC__
+_tuiSetFocus_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiSetFocus_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vSetFocus, arg, fromTTY);
+
+ return;
+} /* tui_SetFocus */
+
+
+/*
+** _tuiAllWindowsInfo().
+*/
+static void
+#ifdef __STDC__
+_tuiAllWindowsInfo (
+ char *arg,
+ int fromTTY)
+#else
+_tuiAllWindowsInfo (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ TuiWinType type;
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+
+ for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
+ if (winList[type]->generic.isVisible)
+ {
+ if (winWithFocus == winList[type])
+ printf_filtered (" %s\t(%d lines) <has focus>\n",
+ winName (&winList[type]->generic),
+ winList[type]->generic.height);
+ else
+ printf_filtered (" %s\t(%d lines)\n",
+ winName (&winList[type]->generic),
+ winList[type]->generic.height);
+ }
+
+ return;
+} /* _tuiAllWindowsInfo */
+
+
+/*
+** _tuiRefreshAll_command().
+*/
+static void
+#ifdef __STDC__
+_tuiRefreshAll_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiRefreshAll_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll);
+}
+
+
+/*
+** _tuiSetWinTabWidth_command().
+** Set the height of the specified window.
+*/
+static void
+#ifdef __STDC__
+_tuiSetTabWidth_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiSetTabWidth_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if (arg != (char *) NULL)
+ {
+ int ts;
+
+ ts = atoi (arg);
+ if (ts > 0)
+ tuiSetDefaultTabLen (ts);
+ else
+ warning ("Tab widths greater than 0 must be specified.\n");
+ }
+
+ return;
+} /* _tuiSetTabWidth_command */
+
+
+/*
+** _tuiSetWinHeight().
+** Set the height of the specified window.
+*/
+static void
+#ifdef __STDC__
+_tuiSetWinHeight (
+ char *arg,
+ int fromTTY)
+#else
+_tuiSetWinHeight (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if (arg != (char *) NULL)
+ {
+ char *buf = tuiStrDup (arg);
+ char *bufPtr = buf;
+ char *wname = (char *) NULL;
+ int newHeight, i;
+ TuiWinInfoPtr winInfo;
+
+ wname = bufPtr;
+ bufPtr = strchr (bufPtr, ' ');
+ if (bufPtr != (char *) NULL)
+ {
+ *bufPtr = (char) 0;
+
+ /*
+ ** Validate the window name
+ */
+ for (i = 0; i < strlen (wname); i++)
+ wname[i] = toupper (wname[i]);
+ winInfo = partialWinByName (wname);
+
+ if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
+ warning ("Invalid window specified. \n\
+The window name specified must be valid and visible.\n");
+ else
+ {
+ /* Process the size */
+ while (*(++bufPtr) == ' ')
+ ;
+
+ if (*bufPtr != (char) 0)
+ {
+ int negate = FALSE;
+ int fixedSize = TRUE;
+ int inputNo;;
+
+ if (*bufPtr == '+' || *bufPtr == '-')
+ {
+ if (*bufPtr == '-')
+ negate = TRUE;
+ fixedSize = FALSE;
+ bufPtr++;
+ }
+ inputNo = atoi (bufPtr);
+ if (inputNo > 0)
+ {
+ if (negate)
+ inputNo *= (-1);
+ if (fixedSize)
+ newHeight = inputNo;
+ else
+ newHeight = winInfo->generic.height + inputNo;
+ /*
+ ** Now change the window's height, and adjust all
+ ** other windows around it
+ */
+ if (_tuiAdjustWinHeights (winInfo,
+ newHeight) == TUI_FAILURE)
+ warning ("Invalid window height specified.\n%s",
+ WIN_HEIGHT_USAGE);
+ else
+ init_page_info ();
+ }
+ else
+ warning ("Invalid window height specified.\n%s",
+ WIN_HEIGHT_USAGE);
+ }
+ }
+ }
+ else
+ printf_filtered (WIN_HEIGHT_USAGE);
+
+ if (buf != (char *) NULL)
+ tuiFree (buf);
+ }
+ else
+ printf_filtered (WIN_HEIGHT_USAGE);
+
+ return;
+} /* _tuiSetWinHeight */
+
+
+/*
+** _tui_vSetWinHeight().
+** Set the height of the specified window, with va_list.
+*/
+static void
+#ifdef __STDC__
+_tui_vSetWinHeight (
+ va_list args)
+#else
+_tui_vSetWinHeight (args)
+ va_list args;
+#endif
+{
+ char *arg = va_arg (args, char *);
+ int fromTTY = va_arg (args, int);
+
+ _tuiSetWinHeight (arg, fromTTY);
+
+ return;
+} /* _tui_vSetWinHeight */
+
+
+/*
+** _tuiSetWinHeight_command().
+** Set the height of the specified window, with va_list.
+*/
+static void
+#ifdef __STDC__
+_tuiSetWinHeight_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiSetWinHeight_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vSetWinHeight, arg, fromTTY);
+
+ return;
+} /* _tuiSetWinHeight_command */
+
+
+/*
+** _tuiXDBsetWinHeight().
+** XDB Compatibility command for setting the window height. This will
+** increase or decrease the command window by the specified amount.
+*/
+static void
+#ifdef __STDC__
+_tuiXDBsetWinHeight (
+ char *arg,
+ int fromTTY)
+#else
+_tuiXDBsetWinHeight (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ if (arg != (char *) NULL)
+ {
+ int inputNo = atoi (arg);
+
+ if (inputNo > 0)
+ { /* Add 1 for the locator */
+ int newHeight = termHeight () - (inputNo + 1);
+
+ if (!_newHeightOk (winList[CMD_WIN], newHeight) ||
+ _tuiAdjustWinHeights (winList[CMD_WIN],
+ newHeight) == TUI_FAILURE)
+ warning ("Invalid window height specified.\n%s",
+ XDBWIN_HEIGHT_USAGE);
+ }
+ else
+ warning ("Invalid window height specified.\n%s",
+ XDBWIN_HEIGHT_USAGE);
+ }
+ else
+ warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
+
+ return;
+} /* _tuiXDBsetWinHeight */
+
+
+/*
+** _tui_vXDBsetWinHeight().
+** Set the height of the specified window, with va_list.
+*/
+static void
+#ifdef __STDC__
+_tui_vXDBsetWinHeight (
+ va_list args)
+#else
+_tui_vXDBsetWinHeight (args)
+ va_list args;
+#endif
+{
+ char *arg = va_arg (args, char *);
+ int fromTTY = va_arg (args, int);
+
+ _tuiXDBsetWinHeight (arg, fromTTY);
+
+ return;
+} /* _tui_vXDBsetWinHeight */
+
+
+/*
+** _tuiSetWinHeight_command().
+** Set the height of the specified window, with va_list.
+*/
+static void
+#ifdef __STDC__
+_tuiXDBsetWinHeight_command (
+ char *arg,
+ int fromTTY)
+#else
+_tuiXDBsetWinHeight_command (arg, fromTTY)
+ char *arg;
+ int fromTTY;
+#endif
+{
+ tuiDo ((TuiOpaqueFuncPtr) _tui_vXDBsetWinHeight, arg, fromTTY);
+
+ return;
+} /* _tuiXDBsetWinHeight_command */
+
+
+/*
+** _tuiAdjustWinHeights().
+** Function to adjust all window heights around the primary
+*/
+static TuiStatus
+#ifdef __STDC__
+_tuiAdjustWinHeights (
+ TuiWinInfoPtr primaryWinInfo,
+ int newHeight)
+#else
+_tuiAdjustWinHeights (primaryWinInfo, newHeight)
+ TuiWinInfoPtr primaryWinInfo;
+ int newHeight;
+#endif
+{
+ TuiStatus status = TUI_FAILURE;
+
+ if (_newHeightOk (primaryWinInfo, newHeight))
+ {
+ status = TUI_SUCCESS;
+ if (newHeight != primaryWinInfo->generic.height)
+ {
+ int i, diff;
+ TuiWinInfoPtr winInfo;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ TuiLayoutType curLayout = currentLayout ();
+
+ diff = (newHeight - primaryWinInfo->generic.height) * (-1);
+ if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
+ {
+ TuiWinInfoPtr srcWinInfo;
+
+ _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
+ if (primaryWinInfo->generic.type == CMD_WIN)
+ {
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ srcWinInfo = winInfo;
+ }
+ else
+ {
+ winInfo = winList[CMD_WIN];
+ srcWinInfo = primaryWinInfo;
+ }
+ _makeInvisibleAndSetNewHeight (winInfo,
+ winInfo->generic.height + diff);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ _makeVisibleWithNewHeight (winInfo);
+ _makeVisibleWithNewHeight (primaryWinInfo);
+ if (srcWinInfo->generic.contentSize <= 0)
+ tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT);
+ }
+ else
+ {
+ TuiWinInfoPtr firstWin, secondWin;
+
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ {
+ firstWin = srcWin;
+ secondWin = disassemWin;
+ }
+ else
+ {
+ firstWin = dataWin;
+ secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ }
+ if (primaryWinInfo == cmdWin)
+ { /*
+ ** Split the change in height accross the 1st & 2nd windows
+ ** adjusting them as well.
+ */
+ int firstSplitDiff = diff / 2; /* subtract the locator */
+ int secondSplitDiff = firstSplitDiff;
+
+ if (diff % 2)
+ {
+ if (firstWin->generic.height >
+ secondWin->generic.height)
+ if (diff < 0)
+ firstSplitDiff--;
+ else
+ firstSplitDiff++;
+ else
+ {
+ if (diff < 0)
+ secondSplitDiff--;
+ else
+ secondSplitDiff++;
+ }
+ }
+ /* make sure that the minimum hieghts are honored */
+ while ((firstWin->generic.height + firstSplitDiff) < 3)
+ {
+ firstSplitDiff++;
+ secondSplitDiff--;
+ }
+ while ((secondWin->generic.height + secondSplitDiff) < 3)
+ {
+ secondSplitDiff++;
+ firstSplitDiff--;
+ }
+ _makeInvisibleAndSetNewHeight (
+ firstWin,
+ firstWin->generic.height + firstSplitDiff);
+ secondWin->generic.origin.y = firstWin->generic.height - 1;
+ _makeInvisibleAndSetNewHeight (
+ secondWin, secondWin->generic.height + secondSplitDiff);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
+ }
+ else
+ {
+ if ((cmdWin->generic.height + diff) < 1)
+ { /*
+ ** If there is no way to increase the command window
+ ** take real estate from the 1st or 2nd window.
+ */
+ if ((cmdWin->generic.height + diff) < 1)
+ {
+ int i;
+ for (i = cmdWin->generic.height + diff;
+ (i < 1); i++)
+ if (primaryWinInfo == firstWin)
+ secondWin->generic.height--;
+ else
+ firstWin->generic.height--;
+ }
+ }
+ if (primaryWinInfo == firstWin)
+ _makeInvisibleAndSetNewHeight (firstWin, newHeight);
+ else
+ _makeInvisibleAndSetNewHeight (
+ firstWin,
+ firstWin->generic.height);
+ secondWin->generic.origin.y = firstWin->generic.height - 1;
+ if (primaryWinInfo == secondWin)
+ _makeInvisibleAndSetNewHeight (secondWin, newHeight);
+ else
+ _makeInvisibleAndSetNewHeight (
+ secondWin, secondWin->generic.height);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ if ((cmdWin->generic.height + diff) < 1)
+ _makeInvisibleAndSetNewHeight (cmdWin, 1);
+ else
+ _makeInvisibleAndSetNewHeight (
+ cmdWin, cmdWin->generic.height + diff);
+ }
+ _makeVisibleWithNewHeight (cmdWin);
+ _makeVisibleWithNewHeight (secondWin);
+ _makeVisibleWithNewHeight (firstWin);
+ if (firstWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
+ if (secondWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
+ }
+ }
+ }
+
+ return status;
+} /* _tuiAdjustWinHeights */
+
+
+/*
+** _makeInvisibleAndSetNewHeight().
+** Function make the target window (and auxillary windows associated
+** with the targer) invisible, and set the new height and location.
+*/
+static void
+#ifdef __STDC__
+_makeInvisibleAndSetNewHeight (
+ TuiWinInfoPtr winInfo,
+ int height)
+#else
+_makeInvisibleAndSetNewHeight (winInfo, height)
+ TuiWinInfoPtr winInfo;
+ int height;
+#endif
+{
+ int i;
+ struct symtab *s;
+ TuiGenWinInfoPtr genWinInfo;
+
+
+ m_beInvisible (&winInfo->generic);
+ winInfo->generic.height = height;
+ if (height > 1)
+ winInfo->generic.viewportHeight = height - 1;
+ else
+ winInfo->generic.viewportHeight = height;
+ if (winInfo != cmdWin)
+ winInfo->generic.viewportHeight--;
+
+ /* Now deal with the auxillary windows associated with winInfo */
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ genWinInfo = winInfo->detail.sourceInfo.executionInfo;
+ m_beInvisible (genWinInfo);
+ genWinInfo->height = height;
+ genWinInfo->origin.y = winInfo->generic.origin.y;
+ if (height > 1)
+ genWinInfo->viewportHeight = height - 1;
+ else
+ genWinInfo->viewportHeight = height;
+ if (winInfo != cmdWin)
+ genWinInfo->viewportHeight--;
+
+ if (m_hasLocator (winInfo))
+ {
+ genWinInfo = locatorWinInfoPtr ();
+ m_beInvisible (genWinInfo);
+ genWinInfo->origin.y = winInfo->generic.origin.y + height;
+ }
+ break;
+ case DATA_WIN:
+ /* delete all data item windows */
+ for (i = 0; i < winInfo->generic.contentSize; i++)
+ {
+ genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.dataWindow;
+ tuiDelwin (genWinInfo->handle);
+ genWinInfo->handle = (WINDOW *) NULL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* _makeInvisibleAndSetNewHeight */
+
+
+/*
+** _makeVisibleWithNewHeight().
+** Function to make the windows with new heights visible.
+** This means re-creating the windows' content since the window
+** had to be destroyed to be made invisible.
+*/
+static void
+#ifdef __STDC__
+_makeVisibleWithNewHeight (
+ TuiWinInfoPtr winInfo)
+#else
+_makeVisibleWithNewHeight (winInfo)
+ TuiWinInfoPtr winInfo;
+#endif
+{
+ int i;
+ struct symtab *s;
+
+ m_beVisible (&winInfo->generic);
+ checkAndDisplayHighlightIfNeeded (winInfo);
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ freeWinContent (winInfo->detail.sourceInfo.executionInfo);
+ m_beVisible (winInfo->detail.sourceInfo.executionInfo);
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ TuiLineOrAddress lineOrAddr;
+
+ if (winInfo->generic.type == SRC_WIN)
+ lineOrAddr.lineNo =
+ winInfo->detail.sourceInfo.startLineOrAddr.lineNo;
+ else
+ lineOrAddr.addr =
+ winInfo->detail.sourceInfo.startLineOrAddr.addr;
+ freeWinContent (&winInfo->generic);
+ tuiUpdateSourceWindow (winInfo,
+ current_source_symtab,
+ ((winInfo->generic.type == SRC_WIN) ?
+ (Opaque) lineOrAddr.lineNo :
+ lineOrAddr.addr),
+ TRUE);
+ }
+ else if (selected_frame != (struct frame_info *) NULL)
+ {
+ Opaque line = 0;
+ extern int current_source_line;
+
+ s = find_pc_symtab (selected_frame->pc);
+ if (winInfo->generic.type == SRC_WIN)
+ line = (Opaque) current_source_line;
+ else
+ line = (Opaque) find_line_pc (s, current_source_line);
+ tuiUpdateSourceWindow (winInfo, s, line, TRUE);
+ }
+ if (m_hasLocator (winInfo))
+ {
+ m_beVisible (locatorWinInfoPtr ());
+ tuiClearLocatorDisplay ();
+ tuiShowLocatorContent ();
+ }
+ break;
+ case DATA_WIN:
+ tuiDisplayAllData ();
+ break;
+ case CMD_WIN:
+ winInfo->detail.commandInfo.curLine = 0;
+ winInfo->detail.commandInfo.curch = 0;
+ wmove (winInfo->generic.handle,
+ winInfo->detail.commandInfo.curLine,
+ winInfo->detail.commandInfo.curch);
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* _makeVisibleWithNewHeight */
+
+
+static int
+#ifdef __STDC__
+_newHeightOk (
+ TuiWinInfoPtr primaryWinInfo,
+ int newHeight)
+#else
+_newHeightOk (primaryWinInfo, newHeight)
+ TuiWinInfoPtr primaryWinInfo;
+ int newHeight;
+#endif
+{
+ int ok = (newHeight < termHeight ());
+
+ if (ok)
+ {
+ int diff, curHeight;
+ TuiLayoutType curLayout = currentLayout ();
+
+ diff = (newHeight - primaryWinInfo->generic.height) * (-1);
+ if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
+ {
+ ok = ((primaryWinInfo->generic.type == CMD_WIN &&
+ newHeight <= (termHeight () - 4) &&
+ newHeight >= MIN_CMD_WIN_HEIGHT) ||
+ (primaryWinInfo->generic.type != CMD_WIN &&
+ newHeight <= (termHeight () - 2) &&
+ newHeight >= MIN_WIN_HEIGHT));
+ if (ok)
+ { /* check the total height */
+ TuiWinInfoPtr winInfo;
+
+ if (primaryWinInfo == cmdWin)
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ else
+ winInfo = cmdWin;
+ ok = ((newHeight +
+ (winInfo->generic.height + diff)) <= termHeight ());
+ }
+ }
+ else
+ {
+ int curTotalHeight, totalHeight, minHeight;
+ TuiWinInfoPtr firstWin, secondWin;
+
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ {
+ firstWin = srcWin;
+ secondWin = disassemWin;
+ }
+ else
+ {
+ firstWin = dataWin;
+ secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ }
+ /*
+ ** We could simply add all the heights to obtain the same result
+ ** but below is more explicit since we subtract 1 for the
+ ** line that the first and second windows share, and add one
+ ** for the locator.
+ */
+ curTotalHeight =
+ (firstWin->generic.height + secondWin->generic.height - 1)
+ + cmdWin->generic.height + 1 /*locator*/ ;
+ if (primaryWinInfo == cmdWin)
+ {
+ /* locator included since first & second win share a line */
+ ok = ((firstWin->generic.height +
+ secondWin->generic.height + diff) >=
+ (MIN_WIN_HEIGHT * 2) &&
+ newHeight >= MIN_CMD_WIN_HEIGHT);
+ if (ok)
+ {
+ totalHeight = newHeight + (firstWin->generic.height +
+ secondWin->generic.height + diff);
+ minHeight = MIN_CMD_WIN_HEIGHT;
+ }
+ }
+ else
+ {
+ minHeight = MIN_WIN_HEIGHT;
+ /*
+ ** First see if we can increase/decrease the command
+ ** window. And make sure that the command window is
+ ** at least 1 line
+ */
+ ok = ((cmdWin->generic.height + diff) > 0);
+ if (!ok)
+ { /*
+ ** Looks like we have to increase/decrease one of
+ ** the other windows
+ */
+ if (primaryWinInfo == firstWin)
+ ok = (secondWin->generic.height + diff) >= minHeight;
+ else
+ ok = (firstWin->generic.height + diff) >= minHeight;
+ }
+ if (ok)
+ {
+ if (primaryWinInfo == firstWin)
+ totalHeight = newHeight +
+ secondWin->generic.height +
+ cmdWin->generic.height + diff;
+ else
+ totalHeight = newHeight +
+ firstWin->generic.height +
+ cmdWin->generic.height + diff;
+ }
+ }
+ /*
+ ** Now make sure that the proposed total height doesn't exceed
+ ** the old total height.
+ */
+ if (ok)
+ ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
+ }
+ }
+
+ return ok;
+} /* _newHeightOk */
+
+
+/*
+** _parseScrollingArgs().
+*/
+static void
+#ifdef __STDC__
+_parseScrollingArgs (
+ char *arg,
+ TuiWinInfoPtr * winToScroll,
+ int *numToScroll)
+#else
+_parseScrollingArgs (arg, winToScroll, numToScroll)
+ char *arg;
+ TuiWinInfoPtr *winToScroll;
+ int *numToScroll;
+#endif
+{
+ if (numToScroll)
+ *numToScroll = 0;
+ *winToScroll = tuiWinWithFocus ();
+
+ /*
+ ** First set up the default window to scroll, in case there is no
+ ** window name arg
+ */
+ if (arg != (char *) NULL)
+ {
+ char *buf, *bufPtr;
+
+ /* process the number of lines to scroll */
+ buf = bufPtr = tuiStrDup (arg);
+ if (isdigit (*bufPtr))
+ {
+ char *numStr;
+
+ numStr = bufPtr;
+ bufPtr = strchr (bufPtr, ' ');
+ if (bufPtr != (char *) NULL)
+ {
+ *bufPtr = (char) 0;
+ if (numToScroll)
+ *numToScroll = atoi (numStr);
+ bufPtr++;
+ }
+ else if (numToScroll)
+ *numToScroll = atoi (numStr);
+ }
+
+ /* process the window name if one is specified */
+ if (bufPtr != (char *) NULL)
+ {
+ char *wname;
+ int i;
+
+ if (*bufPtr == ' ')
+ while (*(++bufPtr) == ' ')
+ ;
+
+ if (*bufPtr != (char) 0)
+ wname = bufPtr;
+
+ /* Validate the window name */
+ for (i = 0; i < strlen (wname); i++)
+ wname[i] = toupper (wname[i]);
+ *winToScroll = partialWinByName (wname);
+
+ if (*winToScroll == (TuiWinInfoPtr) NULL ||
+ !(*winToScroll)->generic.isVisible)
+ warning ("Invalid window specified. \n\
+The window name specified must be valid and visible.\n");
+ else if (*winToScroll == cmdWin)
+ *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ }
+ tuiFree (buf);
+ }
+
+ return;
+} /* _parseScrollingArgs */
diff --git a/contrib/gdb/gdb/tui/tuiWin.h b/contrib/gdb/gdb/tui/tuiWin.h
new file mode 100644
index 0000000..cb8455d
--- /dev/null
+++ b/contrib/gdb/gdb/tui/tuiWin.h
@@ -0,0 +1,28 @@
+#ifndef _TUI_WIN_H
+#define _TUI_WIN_H
+/*
+** This header file supports
+*/
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern void tuiScrollForward PARAMS ((TuiWinInfoPtr, int));
+extern void tuiScrollBackward PARAMS ((TuiWinInfoPtr, int));
+extern void tuiScrollLeft PARAMS ((TuiWinInfoPtr, int));
+extern void tuiScrollRight PARAMS ((TuiWinInfoPtr, int));
+extern void tui_vScroll PARAMS ((va_list));
+extern void tuiSetWinFocusTo PARAMS ((TuiWinInfoPtr));
+extern void tuiClearWinFocusFrom PARAMS ((TuiWinInfoPtr));
+extern void tuiClearWinFocus PARAMS ((void));
+extern void tuiResizeAll PARAMS ((void));
+extern void tuiRefreshAll PARAMS ((void));
+extern void tuiSigwinchHandler PARAMS ((int));
+
+#endif /*_TUI_WIN_H*/
diff --git a/contrib/gdb/gdb/typeprint.c b/contrib/gdb/gdb/typeprint.c
index 6b1c6de..1a4877b 100644
--- a/contrib/gdb/gdb/typeprint.c
+++ b/contrib/gdb/gdb/typeprint.c
@@ -1,5 +1,5 @@
/* Language independent support for printing types for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1986, 88, 89, 91, 92, 93, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -34,6 +34,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdb_string.h"
#include <errno.h>
+/* For real-type printing in whatis_exp() */
+extern int objectprint; /* Controls looking up an object's derived type
+ using what we find in its vtables. */
+
static void
ptype_command PARAMS ((char *, int));
@@ -74,17 +78,31 @@ whatis_exp (exp, show)
struct expression *expr;
register value_ptr val;
register struct cleanup *old_chain = NULL;
+ struct type * real_type = NULL;
+ int full = 0;
+ int top = -1;
+ int using_enc = 0;
if (exp)
{
expr = parse_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &expr);
val = evaluate_type (expr);
}
else
val = access_value_history (0);
+ real_type = value_rtti_type (val, &full, &top, &using_enc);
+
printf_filtered ("type = ");
+
+ if (real_type && objectprint)
+ printf_filtered ("/* real type = %s%s */\n",
+ TYPE_NAME (real_type),
+ full ? "" : " (incomplete object)");
+ /* FIXME: maybe better to use type_print (real_type, "", gdb_stdout, -1); */
+
type_print (VALUE_TYPE (val), "", gdb_stdout, show);
printf_filtered ("\n");
@@ -140,7 +158,8 @@ ptype_command (typename, from_tty)
else
{
expr = parse_expression (typename);
- old_chain = make_cleanup (free_current_contents, &expr);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &expr);
type = ptype_eval (expr);
if (type != NULL)
{
@@ -262,7 +281,7 @@ maintenance_print_type (typename, from_tty)
if (typename != NULL)
{
expr = parse_expression (typename);
- old_chain = make_cleanup (free_current_contents, &expr);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
if (expr -> elts[0].opcode == OP_TYPE)
{
/* The user expression names a type directly, just use that type. */
diff --git a/contrib/gdb/gdb/typeprint.h b/contrib/gdb/gdb/typeprint.h
index 0dc32cd..be4d81a 100644
--- a/contrib/gdb/gdb/typeprint.h
+++ b/contrib/gdb/gdb/typeprint.h
@@ -1,5 +1,6 @@
/* Language independent support for printing types for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1999
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -19,3 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
void
print_type_scalar PARAMS ((struct type *type, LONGEST, GDB_FILE *));
+
+void
+c_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *, int, int, int));
diff --git a/contrib/gdb/gdb/utils.c b/contrib/gdb/gdb/utils.c
index 5135514..08b801b 100644
--- a/contrib/gdb/gdb/utils.c
+++ b/contrib/gdb/gdb/utils.c
@@ -1,5 +1,5 @@
/* General utility routines for GDB, the GNU debugger.
- Copyright 1986, 1989, 1990, 1991, 1992, 1995 Free Software Foundation, Inc.
+ Copyright 1986, 89, 90, 91, 92, 95, 96, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,22 +18,24 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
-#if !defined(__GO32__) && !defined(__WIN32__) && !defined(MPW)
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <pwd.h>
-#endif
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include <ctype.h>
#include "gdb_string.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+
+/* SunOS's curses.h has a '#define reg register' in it. Thank you Sun. */
+#ifdef reg
+#undef reg
+#endif
+
#include "signals.h"
#include "gdbcmd.h"
#include "serial.h"
@@ -44,20 +46,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h"
#include "annotate.h"
-#include "readline.h"
+#include <readline/readline.h>
/* readline defines this. */
#undef savestring
+void (*error_begin_hook) PARAMS ((void));
+
/* Prototypes for local functions */
-#if defined (NO_MMALLOC) || defined (NO_MMALLOC_CHECK)
-#else
+static void vfprintf_maybe_filtered PARAMS ((GDB_FILE *, const char *,
+ va_list, int));
-static void
-malloc_botch PARAMS ((void));
+static void fputs_maybe_filtered PARAMS ((const char *, GDB_FILE *, int));
-#endif /* NO_MMALLOC, etc */
+#if defined (USE_MMALLOC) && !defined (NO_MMCHECK)
+static void malloc_botch PARAMS ((void));
+#endif
static void
fatal_dump_core PARAMS((char *, ...));
@@ -68,16 +73,25 @@ prompt_for_continue PARAMS ((void));
static void
set_width_command PARAMS ((char *, int, struct cmd_list_element *));
+static void
+set_width PARAMS ((void));
+
/* If this definition isn't overridden by the header files, assume
that isatty and fileno exist on this system. */
#ifndef ISATTY
#define ISATTY(FP) (isatty (fileno (FP)))
#endif
+#ifndef GDB_FILE_ISATTY
+#define GDB_FILE_ISATTY(GDB_FILE_PTR) (gdb_file_isatty(GDB_FILE_PTR))
+#endif
+
/* Chain of cleanup actions established with make_cleanup,
to be executed if an error happens. */
-static struct cleanup *cleanup_chain;
+static struct cleanup *cleanup_chain; /* cleaned up after a failed command */
+static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
+static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
/* Nonzero if we have job control. */
@@ -128,6 +142,9 @@ char *quit_pre_print;
/* String to be printed before warning messages, if any. */
char *warning_pre_print = "\nwarning: ";
+
+int pagination_enabled = 1;
+
/* Add a new cleanup to the cleanup_chain,
and return the previous chain pointer
@@ -139,14 +156,37 @@ make_cleanup (function, arg)
void (*function) PARAMS ((PTR));
PTR arg;
{
+ return make_my_cleanup (&cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_final_cleanup (function, arg)
+ void (*function) PARAMS ((PTR));
+ PTR arg;
+{
+ return make_my_cleanup (&final_cleanup_chain, function, arg);
+}
+struct cleanup *
+make_run_cleanup (function, arg)
+ void (*function) PARAMS ((PTR));
+ PTR arg;
+{
+ return make_my_cleanup (&run_cleanup_chain, function, arg);
+}
+struct cleanup *
+make_my_cleanup (pmy_chain, function, arg)
+ struct cleanup **pmy_chain;
+ void (*function) PARAMS ((PTR));
+ PTR arg;
+{
register struct cleanup *new
= (struct cleanup *) xmalloc (sizeof (struct cleanup));
- register struct cleanup *old_chain = cleanup_chain;
+ register struct cleanup *old_chain = *pmy_chain;
- new->next = cleanup_chain;
+ new->next = *pmy_chain;
new->function = function;
new->arg = arg;
- cleanup_chain = new;
+ *pmy_chain = new;
return old_chain;
}
@@ -158,10 +198,32 @@ void
do_cleanups (old_chain)
register struct cleanup *old_chain;
{
+ do_my_cleanups (&cleanup_chain, old_chain);
+}
+
+void
+do_final_cleanups (old_chain)
+ register struct cleanup *old_chain;
+{
+ do_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+void
+do_run_cleanups (old_chain)
+ register struct cleanup *old_chain;
+{
+ do_my_cleanups (&run_cleanup_chain, old_chain);
+}
+
+void
+do_my_cleanups (pmy_chain, old_chain)
+ register struct cleanup **pmy_chain;
+ register struct cleanup *old_chain;
+{
register struct cleanup *ptr;
- while ((ptr = cleanup_chain) != old_chain)
+ while ((ptr = *pmy_chain) != old_chain)
{
- cleanup_chain = ptr->next; /* Do this first incase recursion */
+ *pmy_chain = ptr->next; /* Do this first incase recursion */
(*ptr->function) (ptr->arg);
free (ptr);
}
@@ -174,10 +236,25 @@ void
discard_cleanups (old_chain)
register struct cleanup *old_chain;
{
+ discard_my_cleanups (&cleanup_chain, old_chain);
+}
+
+void
+discard_final_cleanups (old_chain)
+ register struct cleanup *old_chain;
+{
+ discard_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+void
+discard_my_cleanups (pmy_chain, old_chain)
+ register struct cleanup **pmy_chain;
+ register struct cleanup *old_chain;
+{
register struct cleanup *ptr;
- while ((ptr = cleanup_chain) != old_chain)
+ while ((ptr = *pmy_chain) != old_chain)
{
- cleanup_chain = ptr->next;
+ *pmy_chain = ptr->next;
free ((PTR)ptr);
}
}
@@ -186,9 +263,22 @@ discard_cleanups (old_chain)
struct cleanup *
save_cleanups ()
{
- struct cleanup *old_chain = cleanup_chain;
+ return save_my_cleanups (&cleanup_chain);
+}
+
+struct cleanup *
+save_final_cleanups ()
+{
+ return save_my_cleanups (&final_cleanup_chain);
+}
- cleanup_chain = 0;
+struct cleanup *
+save_my_cleanups (pmy_chain)
+ struct cleanup **pmy_chain;
+{
+ struct cleanup *old_chain = *pmy_chain;
+
+ *pmy_chain = 0;
return old_chain;
}
@@ -197,7 +287,22 @@ void
restore_cleanups (chain)
struct cleanup *chain;
{
- cleanup_chain = chain;
+ restore_my_cleanups (&cleanup_chain, chain);
+}
+
+void
+restore_final_cleanups (chain)
+ struct cleanup *chain;
+{
+ restore_my_cleanups (&final_cleanup_chain, chain);
+}
+
+void
+restore_my_cleanups (pmy_chain, chain)
+ struct cleanup **pmy_chain;
+ struct cleanup *chain;
+{
+ *pmy_chain = chain;
}
/* This function is useful for cleanups.
@@ -225,7 +330,7 @@ free_current_contents (location)
/* ARGSUSED */
void
null_cleanup (arg)
- char **arg;
+ PTR arg;
{
}
@@ -258,7 +363,7 @@ warning_begin ()
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-warning (char *string, ...)
+warning (const char *string, ...)
#else
warning (va_alist)
va_dcl
@@ -273,10 +378,15 @@ warning (va_alist)
va_start (args);
string = va_arg (args, char *);
#endif
- warning_begin ();
- vfprintf_unfiltered (gdb_stderr, string, args);
- fprintf_unfiltered (gdb_stderr, "\n");
- va_end (args);
+ if (warning_hook)
+ (*warning_hook) (string, args);
+ else
+ {
+ warning_begin ();
+ vfprintf_unfiltered (gdb_stderr, string, args);
+ fprintf_unfiltered (gdb_stderr, "\n");
+ va_end (args);
+ }
}
/* Start the printing of an error message. Way to use this is to call
@@ -289,6 +399,9 @@ warning (va_alist)
void
error_begin ()
{
+ if (error_begin_hook)
+ error_begin_hook ();
+
target_terminal_ours ();
wrap_here (""); /* Force out any buffered output */
gdb_flush (gdb_stdout);
@@ -303,11 +416,11 @@ error_begin ()
The first argument STRING is the error message, used as a fprintf string,
and the remaining args are passed as arguments to it. */
-#ifdef ANSI_PROTOTYPES
+/* VARARGS */
NORETURN void
-error (char *string, ...)
+#ifdef ANSI_PROTOTYPES
+error (const char *string, ...)
#else
-void
error (va_alist)
va_dcl
#endif
@@ -448,7 +561,7 @@ safe_strsignal (signo)
as the file name for which the error was encountered.
Then return to command level. */
-void
+NORETURN void
perror_with_name (string)
char *string;
{
@@ -467,7 +580,7 @@ perror_with_name (string)
bfd_set_error (bfd_error_no_error);
errno = 0;
- error ("%s.", combined);
+ error ("%s.", combined);
}
/* Print the system error message for ERRCODE, and also mention STRING
@@ -515,7 +628,7 @@ quit ()
gdb_flush (gdb_stderr);
/* 3. The system-level buffer. */
- SERIAL_FLUSH_OUTPUT (gdb_stdout_serial);
+ SERIAL_DRAIN_OUTPUT (gdb_stdout_serial);
SERIAL_UN_FDOPEN (gdb_stdout_serial);
annotate_error_begin ();
@@ -536,60 +649,65 @@ quit ()
}
-#if defined(__GO32__)||defined(WINGDB)
+#if defined(__GO32__)
/* In the absence of signals, poll keyboard for a quit.
Called from #define QUIT pollquit() in xm-go32.h. */
void
-pollquit()
+notice_quit()
{
if (kbhit ())
- {
- int k = getkey ();
- if (k == 1) {
+ switch (getkey ())
+ {
+ case 1:
quit_flag = 1;
- quit();
- }
- else if (k == 2) {
- immediate_quit = 1;
- quit ();
+ break;
+ case 2:
+ immediate_quit = 2;
+ break;
+ default:
+ /* We just ignore it */
+ /* FIXME!! Don't think this actually works! */
+ fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
+ break;
}
- else
- {
- /* We just ignore it */
- fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
- }
- }
}
+#elif defined(_MSC_VER) /* should test for wingdb instead? */
+
+/*
+ * Windows translates all keyboard and mouse events
+ * into a message which is appended to the message
+ * queue for the process.
+ */
-#endif
-#if defined(__GO32__)||defined(WINGDB)
void notice_quit()
{
- if (kbhit ())
- {
- int k = getkey ();
- if (k == 1) {
- quit_flag = 1;
- }
- else if (k == 2)
- {
- immediate_quit = 1;
- }
- else
- {
- fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
- }
- }
+ int k = win32pollquit();
+ if (k == 1)
+ quit_flag = 1;
+ else if (k == 2)
+ immediate_quit = 1;
}
-#else
+
+#else /* !defined(__GO32__) && !defined(_MSC_VER) */
+
void notice_quit()
{
/* Done by signals */
}
-#endif
+
+#endif /* !defined(__GO32__) && !defined(_MSC_VER) */
+
+void
+pollquit()
+{
+ notice_quit ();
+ if (quit_flag || immediate_quit)
+ quit ();
+}
+
/* Control C comes here */
void
@@ -602,7 +720,6 @@ request_quit (signo)
about USG defines and stuff like that. */
signal (signo, request_quit);
-
#ifdef REQUEST_QUIT
REQUEST_QUIT;
#else
@@ -614,19 +731,15 @@ request_quit (signo)
/* Memory management stuff (malloc friends). */
-#if defined (NO_MMALLOC)
-
/* Make a substitute size_t for non-ANSI compilers. */
-#ifdef _AIX
-#include <stddef.h>
-#else /* Not AIX */
-#ifndef __STDC__
+#ifndef HAVE_STDDEF_H
#ifndef size_t
#define size_t unsigned int
#endif
#endif
-#endif /* Not AIX */
+
+#if !defined (USE_MMALLOC)
PTR
mmalloc (md, size)
@@ -656,9 +769,9 @@ mfree (md, ptr)
free (ptr);
}
-#endif /* NO_MMALLOC */
+#endif /* USE_MMALLOC */
-#if defined (NO_MMALLOC) || defined (NO_MMALLOC_CHECK)
+#if !defined (USE_MMALLOC) || defined (NO_MMCHECK)
void
init_malloc (md)
@@ -666,7 +779,7 @@ init_malloc (md)
{
}
-#else /* have mmalloc and want corruption checking */
+#else /* Have mmalloc and want corruption checking */
static void
malloc_botch ()
@@ -678,7 +791,7 @@ malloc_botch ()
by MD, to detect memory corruption. Note that MD may be NULL to specify
the default heap that grows via sbrk.
- Note that for freshly created regions, we must call mmcheck prior to any
+ Note that for freshly created regions, we must call mmcheckf prior to any
mallocs in the region. Otherwise, any region which was allocated prior to
installing the checking hooks, which is later reallocated or freed, will
fail the checks! The mmcheck function only allows initial hooks to be
@@ -688,13 +801,24 @@ malloc_botch ()
Returns zero on failure, non-zero on success. */
+#ifndef MMCHECK_FORCE
+#define MMCHECK_FORCE 0
+#endif
+
void
init_malloc (md)
PTR md;
{
- if (!mmcheck (md, malloc_botch))
+ if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE))
{
- warning ("internal error: failed to install memory consistency checks");
+ /* Don't use warning(), which relies on current_target being set
+ to something other than dummy_target, until after
+ initialize_all_files(). */
+
+ fprintf_unfiltered
+ (gdb_stderr, "warning: failed to install memory consistency checks; ");
+ fprintf_unfiltered
+ (gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
}
mmtrace ();
@@ -772,7 +896,7 @@ xmrealloc (md, ptr, size)
PTR
xmalloc (size)
- long size;
+ size_t size;
{
return (xmmalloc ((PTR) NULL, size));
}
@@ -782,7 +906,7 @@ xmalloc (size)
PTR
xrealloc (ptr, size)
PTR ptr;
- long size;
+ size_t size;
{
return (xmrealloc ((PTR) NULL, ptr, size));
}
@@ -861,10 +985,23 @@ mstrsave (md, ptr)
void
print_spaces (n, file)
register int n;
- register FILE *file;
+ register GDB_FILE *file;
{
- while (n-- > 0)
- fputc (' ', file);
+ if (file->ts_streamtype == astring)
+ {
+ char *p;
+
+ gdb_file_adjust_strbuf (n, file);
+ p = file->ts_strbuf + strlen (file->ts_strbuf);
+
+ memset (p, ' ', n);
+ p[n] = '\000';
+ }
+ else
+ {
+ while (n-- > 0)
+ fputc (' ', file->ts_filestream);
+ }
}
/* Print a host address. */
@@ -944,21 +1081,43 @@ query (va_alist)
fputs_unfiltered ("\n", gdb_stdout);
#endif /* MPW */
+ wrap_here("");
gdb_flush (gdb_stdout);
- answer = fgetc (stdin);
+
+#if defined(TUI)
+ if (!tui_version || cmdWin == tuiWinWithFocus())
+#endif
+ answer = fgetc (stdin);
+#if defined(TUI)
+ else
+
+ answer = (unsigned char)tuiBufferGetc();
+
+#endif
clearerr (stdin); /* in case of C-d */
if (answer == EOF) /* C-d */
{
retval = 1;
break;
}
- if (answer != '\n') /* Eat rest of input line, to EOF or newline */
+ /* Eat rest of input line, to EOF or newline */
+ if ((answer != '\n') || (tui_version && answer != '\r'))
do
{
- ans2 = fgetc (stdin);
+#if defined(TUI)
+ if (!tui_version || cmdWin == tuiWinWithFocus())
+#endif
+ ans2 = fgetc (stdin);
+#if defined(TUI)
+ else
+
+ ans2 = (unsigned char)tuiBufferGetc();
+#endif
clearerr (stdin);
}
- while (ans2 != EOF && ans2 != '\n');
+ while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+ TUIDO(((TuiOpaqueFuncPtr)tui_vStartNewLines, 1));
+
if (answer >= 'a')
answer -= 040;
if (answer == 'Y')
@@ -1070,7 +1229,7 @@ parse_escape (string_ptr)
void
gdb_printchar (c, stream, quoter)
register int c;
- FILE *stream;
+ GDB_FILE *stream;
int quoter;
{
@@ -1112,6 +1271,37 @@ gdb_printchar (c, stream, quoter)
fprintf_filtered (stream, "%c", c);
}
}
+
+
+
+
+static char * hexlate = "0123456789abcdef" ;
+int fmthex(inbuf,outbuff,length,linelength)
+ unsigned char * inbuf ;
+ unsigned char * outbuff;
+ int length;
+ int linelength;
+{
+ unsigned char byte , nib ;
+ int outlength = 0 ;
+
+ while (length)
+ {
+ if (outlength >= linelength) break ;
+ byte = *inbuf ;
+ inbuf++ ;
+ nib = byte >> 4 ;
+ *outbuff++ = hexlate[nib] ;
+ nib = byte &0x0f ;
+ *outbuff++ = hexlate[nib] ;
+ *outbuff++ = ' ' ;
+ length-- ;
+ outlength += 3 ;
+ }
+ *outbuff = '\0' ; /* null terminate our output line */
+ return outlength ;
+}
+
/* Number of lines per page or UINT_MAX if paging is disabled. */
static unsigned int lines_per_page;
@@ -1144,13 +1334,88 @@ static char *wrap_indent;
is not in effect. */
static int wrap_column;
-/* ARGSUSED */
-static void
-set_width_command (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+
+/* Inialize the lines and chars per page */
+void
+init_page_info()
+{
+#if defined(TUI)
+ if (tui_version && m_winPtrNotNull(cmdWin))
+ {
+ lines_per_page = cmdWin->generic.height;
+ chars_per_line = cmdWin->generic.width;
+ }
+ else
+#endif
+ {
+ /* These defaults will be used if we are unable to get the correct
+ values from termcap. */
+#if defined(__GO32__)
+ lines_per_page = ScreenRows();
+ chars_per_line = ScreenCols();
+#else
+ lines_per_page = 24;
+ chars_per_line = 80;
+
+#if !defined (MPW) && !defined (_WIN32)
+ /* No termcap under MPW, although might be cool to do something
+ by looking at worksheet or console window sizes. */
+ /* Initialize the screen height and width from termcap. */
+ {
+ char *termtype = getenv ("TERM");
+
+ /* Positive means success, nonpositive means failure. */
+ int status;
+
+ /* 2048 is large enough for all known terminals, according to the
+ GNU termcap manual. */
+ char term_buffer[2048];
+
+ if (termtype)
+ {
+ status = tgetent (term_buffer, termtype);
+ if (status > 0)
+ {
+ int val;
+ int running_in_emacs = getenv ("EMACS") != NULL;
+
+ val = tgetnum ("li");
+ if (val >= 0 && !running_in_emacs)
+ lines_per_page = val;
+ else
+ /* The number of lines per page is not mentioned
+ in the terminal description. This probably means
+ that paging is not useful (e.g. emacs shell window),
+ so disable paging. */
+ lines_per_page = UINT_MAX;
+
+ val = tgetnum ("co");
+ if (val >= 0)
+ chars_per_line = val;
+ }
+ }
+ }
+#endif /* MPW */
+
+#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
+
+ /* If there is a better way to determine the window size, use it. */
+ SIGWINCH_HANDLER (SIGWINCH);
+#endif
+#endif
+ /* If the output is not a terminal, don't paginate it. */
+ if (!GDB_FILE_ISATTY (gdb_stdout))
+ lines_per_page = UINT_MAX;
+ } /* the command_line_version */
+ set_width();
+}
+
+static void
+set_width()
{
+ if (chars_per_line == 0)
+ init_page_info();
+
if (!wrap_buffer)
{
wrap_buffer = (char *) xmalloc (chars_per_line + 2);
@@ -1158,7 +1423,17 @@ set_width_command (args, from_tty, c)
}
else
wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
- wrap_pointer = wrap_buffer; /* Start it at the beginning */
+ wrap_pointer = wrap_buffer; /* Start it at the beginning */
+}
+
+/* ARGSUSED */
+static void
+set_width_command (args, from_tty, c)
+ char *args;
+ int from_tty;
+ struct cmd_list_element *c;
+{
+ set_width ();
}
/* Wait, so the user can read what's on the screen. Prompt the user
@@ -1297,26 +1572,121 @@ begin_line ()
}
}
+int
+gdb_file_isatty (stream)
+ GDB_FILE *stream;
+{
+
+ if (stream->ts_streamtype == afile)
+ return (isatty(fileno(stream->ts_filestream)));
+ else return 0;
+}
+
+GDB_FILE *
+gdb_file_init_astring (n)
+ int n;
+{
+ GDB_FILE *tmpstream;
+
+ tmpstream = xmalloc (sizeof(GDB_FILE));
+ tmpstream->ts_streamtype = astring;
+ tmpstream->ts_filestream = NULL;
+ if (n > 0)
+ {
+ tmpstream->ts_strbuf = xmalloc ((n + 1)*sizeof(char));
+ tmpstream->ts_strbuf[0] = '\0';
+ }
+ else
+ tmpstream->ts_strbuf = NULL;
+ tmpstream->ts_buflen = n;
+
+ return tmpstream;
+}
+
+void
+gdb_file_deallocate (streamptr)
+ GDB_FILE **streamptr;
+{
+ GDB_FILE *tmpstream;
+
+ tmpstream = *streamptr;
+ if ((tmpstream->ts_streamtype == astring) &&
+ (tmpstream->ts_strbuf != NULL))
+ {
+ free (tmpstream->ts_strbuf);
+ }
+
+ free (tmpstream);
+ *streamptr = NULL;
+}
+
+char *
+gdb_file_get_strbuf (stream)
+ GDB_FILE *stream;
+{
+ return (stream->ts_strbuf);
+}
+
+/* adjust the length of the buffer by the amount necessary
+ to accomodate appending a string of length N to the buffer contents */
+void
+gdb_file_adjust_strbuf (n, stream)
+ int n;
+ GDB_FILE *stream;
+{
+ int non_null_chars;
+
+ non_null_chars = strlen(stream->ts_strbuf);
+
+ if (n > (stream->ts_buflen - non_null_chars - 1))
+ {
+ stream->ts_buflen = n + non_null_chars + 1;
+ stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen);
+ }
+}
GDB_FILE *
gdb_fopen (name, mode)
char * name;
char * mode;
{
- return fopen (name, mode);
+ int gdb_file_size;
+ GDB_FILE *tmp;
+
+ gdb_file_size = sizeof(GDB_FILE);
+ tmp = (GDB_FILE *) xmalloc (gdb_file_size);
+ tmp->ts_streamtype = afile;
+ tmp->ts_filestream = fopen (name, mode);
+ tmp->ts_strbuf = NULL;
+ tmp->ts_buflen = 0;
+
+ return tmp;
}
void
gdb_flush (stream)
- FILE *stream;
+ GDB_FILE *stream;
{
- if (flush_hook)
+ if (flush_hook
+ && (stream == gdb_stdout
+ || stream == gdb_stderr))
{
flush_hook (stream);
return;
}
- fflush (stream);
+ fflush (stream->ts_filestream);
+}
+
+void
+gdb_fclose(streamptr)
+ GDB_FILE **streamptr;
+{
+ GDB_FILE *tmpstream;
+
+ tmpstream = *streamptr;
+ fclose (tmpstream->ts_filestream);
+ gdb_file_deallocate (streamptr);
}
/* Like fputs but if FILTER is true, pause after every screenful.
@@ -1335,7 +1705,7 @@ gdb_flush (stream)
static void
fputs_maybe_filtered (linebuffer, stream, filter)
const char *linebuffer;
- FILE *stream;
+ GDB_FILE *stream;
int filter;
{
const char *lineptr;
@@ -1439,7 +1809,7 @@ fputs_maybe_filtered (linebuffer, stream, filter)
void
fputs_filtered (linebuffer, stream)
const char *linebuffer;
- FILE *stream;
+ GDB_FILE *stream;
{
fputs_maybe_filtered (linebuffer, stream, 1);
}
@@ -1459,7 +1829,7 @@ putchar_unfiltered (c)
int
fputc_unfiltered (c, stream)
int c;
- FILE * stream;
+ GDB_FILE * stream;
{
char buf[2];
@@ -1469,6 +1839,92 @@ fputc_unfiltered (c, stream)
return c;
}
+int
+fputc_filtered (c, stream)
+ int c;
+ GDB_FILE * stream;
+{
+ char buf[2];
+
+ buf[0] = c;
+ buf[1] = 0;
+ fputs_filtered (buf, stream);
+ return c;
+}
+
+/* puts_debug is like fputs_unfiltered, except it prints special
+ characters in printable fashion. */
+
+void
+puts_debug (prefix, string, suffix)
+ char *prefix;
+ char *string;
+ char *suffix;
+{
+ int ch;
+
+ /* Print prefix and suffix after each line. */
+ static int new_line = 1;
+ static int return_p = 0;
+ static char *prev_prefix = "";
+ static char *prev_suffix = "";
+
+ if (*string == '\n')
+ return_p = 0;
+
+ /* If the prefix is changing, print the previous suffix, a new line,
+ and the new prefix. */
+ if ((return_p || (strcmp(prev_prefix, prefix) != 0)) && !new_line)
+ {
+ fputs_unfiltered (prev_suffix, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ fputs_unfiltered (prefix, gdb_stderr);
+ }
+
+ /* Print prefix if we printed a newline during the previous call. */
+ if (new_line)
+ {
+ new_line = 0;
+ fputs_unfiltered (prefix, gdb_stderr);
+ }
+
+ prev_prefix = prefix;
+ prev_suffix = suffix;
+
+ /* Output characters in a printable format. */
+ while ((ch = *string++) != '\0')
+ {
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ fputc_unfiltered (ch, gdb_stderr);
+
+ else
+ fprintf_unfiltered (gdb_stderr, "\\x%02x", ch & 0xff);
+ break;
+
+ case '\\': fputs_unfiltered ("\\\\", gdb_stderr); break;
+ case '\b': fputs_unfiltered ("\\b", gdb_stderr); break;
+ case '\f': fputs_unfiltered ("\\f", gdb_stderr); break;
+ case '\n': new_line = 1;
+ fputs_unfiltered ("\\n", gdb_stderr); break;
+ case '\r': fputs_unfiltered ("\\r", gdb_stderr); break;
+ case '\t': fputs_unfiltered ("\\t", gdb_stderr); break;
+ case '\v': fputs_unfiltered ("\\v", gdb_stderr); break;
+ }
+
+ return_p = ch == '\r';
+ }
+
+ /* Print suffix if we printed a newline. */
+ if (new_line)
+ {
+ fputs_unfiltered (suffix, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ }
+}
+
/* Print a variable number of ARGS using format FORMAT. If this
information is going to put the amount written (since the last call
@@ -1486,8 +1942,8 @@ fputc_unfiltered (c, stream)
static void
vfprintf_maybe_filtered (stream, format, args, filter)
- FILE *stream;
- char *format;
+ GDB_FILE *stream;
+ const char *format;
va_list args;
int filter;
{
@@ -1508,7 +1964,7 @@ vfprintf_maybe_filtered (stream, format, args, filter)
void
vfprintf_filtered (stream, format, args)
- FILE *stream;
+ GDB_FILE *stream;
const char *format;
va_list args;
{
@@ -1517,7 +1973,7 @@ vfprintf_filtered (stream, format, args)
void
vfprintf_unfiltered (stream, format, args)
- FILE *stream;
+ GDB_FILE *stream;
const char *format;
va_list args;
{
@@ -1554,7 +2010,7 @@ vprintf_unfiltered (format, args)
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-fprintf_filtered (FILE *stream, const char *format, ...)
+fprintf_filtered (GDB_FILE *stream, const char *format, ...)
#else
fprintf_filtered (va_alist)
va_dcl
@@ -1564,11 +2020,11 @@ fprintf_filtered (va_alist)
#ifdef ANSI_PROTOTYPES
va_start (args, format);
#else
- FILE *stream;
+ GDB_FILE *stream;
char *format;
va_start (args);
- stream = va_arg (args, FILE *);
+ stream = va_arg (args, GDB_FILE *);
format = va_arg (args, char *);
#endif
vfprintf_filtered (stream, format, args);
@@ -1578,7 +2034,7 @@ fprintf_filtered (va_alist)
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-fprintf_unfiltered (FILE *stream, const char *format, ...)
+fprintf_unfiltered (GDB_FILE *stream, const char *format, ...)
#else
fprintf_unfiltered (va_alist)
va_dcl
@@ -1588,11 +2044,11 @@ fprintf_unfiltered (va_alist)
#ifdef ANSI_PROTOTYPES
va_start (args, format);
#else
- FILE *stream;
+ GDB_FILE *stream;
char *format;
va_start (args);
- stream = va_arg (args, FILE *);
+ stream = va_arg (args, GDB_FILE *);
format = va_arg (args, char *);
#endif
vfprintf_unfiltered (stream, format, args);
@@ -1605,7 +2061,7 @@ fprintf_unfiltered (va_alist)
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-fprintfi_filtered (int spaces, FILE *stream, const char *format, ...)
+fprintfi_filtered (int spaces, GDB_FILE *stream, const char *format, ...)
#else
fprintfi_filtered (va_alist)
va_dcl
@@ -1616,12 +2072,12 @@ fprintfi_filtered (va_alist)
va_start (args, format);
#else
int spaces;
- FILE *stream;
+ GDB_FILE *stream;
char *format;
va_start (args);
spaces = va_arg (args, int);
- stream = va_arg (args, FILE *);
+ stream = va_arg (args, GDB_FILE *);
format = va_arg (args, char *);
#endif
print_spaces_filtered (spaces, stream);
@@ -1751,7 +2207,7 @@ n_spaces (n)
void
print_spaces_filtered (n, stream)
int n;
- FILE *stream;
+ GDB_FILE *stream;
{
fputs_filtered (n_spaces (n), stream);
}
@@ -1765,7 +2221,7 @@ print_spaces_filtered (n, stream)
void
fprintf_symbol_filtered (stream, name, lang, arg_mode)
- FILE *stream;
+ GDB_FILE *stream;
char *name;
enum language lang;
int arg_mode;
@@ -1786,6 +2242,9 @@ fprintf_symbol_filtered (stream, name, lang, arg_mode)
case language_cplus:
demangled = cplus_demangle (name, arg_mode);
break;
+ case language_java:
+ demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
+ break;
case language_chill:
demangled = chill_demangle (name);
break;
@@ -1840,6 +2299,50 @@ strcmp_iw (string1, string2)
}
+/*
+** subsetCompare()
+** Answer whether stringToCompare is a full or partial match to
+** templateString. The partial match must be in sequence starting
+** at index 0.
+*/
+int
+#ifdef _STDC__
+subsetCompare(
+ char *stringToCompare,
+ char *templateString)
+#else
+subsetCompare(stringToCompare, templateString)
+ char *stringToCompare;
+ char *templateString;
+#endif
+{
+ int match = 0;
+
+ if (templateString != (char *)NULL && stringToCompare != (char *)NULL &&
+ strlen(stringToCompare) <= strlen(templateString))
+ match = (strncmp(templateString,
+ stringToCompare,
+ strlen(stringToCompare)) == 0);
+
+ return match;
+} /* subsetCompare */
+
+
+void pagination_on_command(arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ pagination_enabled = 1;
+}
+
+void pagination_off_command(arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ pagination_enabled = 0;
+}
+
+
void
initialize_utils ()
{
@@ -1858,62 +2361,10 @@ initialize_utils ()
"Set number of lines gdb thinks are in a page.", &setlist),
&showlist);
- /* These defaults will be used if we are unable to get the correct
- values from termcap. */
-#if defined(__GO32__) || defined(__WIN32__)
- lines_per_page = ScreenRows();
- chars_per_line = ScreenCols();
-#else
- lines_per_page = 24;
- chars_per_line = 80;
-
-#ifndef MPW
- /* No termcap under MPW, although might be cool to do something
- by looking at worksheet or console window sizes. */
- /* Initialize the screen height and width from termcap. */
- {
- char *termtype = getenv ("TERM");
-
- /* Positive means success, nonpositive means failure. */
- int status;
+ init_page_info ();
- /* 2048 is large enough for all known terminals, according to the
- GNU termcap manual. */
- char term_buffer[2048];
-
- if (termtype)
- {
- status = tgetent (term_buffer, termtype);
- if (status > 0)
- {
- int val;
-
- val = tgetnum ("li");
- if (val >= 0)
- lines_per_page = val;
- else
- /* The number of lines per page is not mentioned
- in the terminal description. This probably means
- that paging is not useful (e.g. emacs shell window),
- so disable paging. */
- lines_per_page = UINT_MAX;
-
- val = tgetnum ("co");
- if (val >= 0)
- chars_per_line = val;
- }
- }
- }
-#endif /* MPW */
-
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-
- /* If there is a better way to determine the window size, use it. */
- SIGWINCH_HANDLER ();
-#endif
-#endif
/* If the output is not a terminal, don't paginate it. */
- if (!ISATTY (gdb_stdout))
+ if (!GDB_FILE_ISATTY (gdb_stdout))
lines_per_page = UINT_MAX;
set_width_command ((char *)NULL, 0, c);
@@ -1926,6 +2377,19 @@ initialize_utils ()
&showprintlist);
add_show_from_set
+ (add_set_cmd ("pagination", class_support,
+ var_boolean, (char *)&pagination_enabled,
+ "Set state of pagination.", &setlist),
+ &showlist);
+ if (xdb_commands)
+ {
+ add_com("am", class_support, pagination_on_command,
+ "Enable pagination");
+ add_com("sm", class_support, pagination_off_command,
+ "Disable pagination");
+ }
+
+ add_show_from_set
(add_set_cmd ("sevenbit-strings", class_support, var_boolean,
(char *)&sevenbit_strings,
"Set printing of 8-bit characters in strings as \\nnn.",
@@ -1945,4 +2409,524 @@ initialize_utils ()
#ifdef SIGWINCH_HANDLER_BODY
SIGWINCH_HANDLER_BODY
#endif
+
+/* Support for converting target fp numbers into host DOUBLEST format. */
+
+/* XXX - This code should really be in libiberty/floatformat.c, however
+ configuration issues with libiberty made this very difficult to do in the
+ available time. */
+
+#include "floatformat.h"
+#include <math.h> /* ldexp */
+
+/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
+ going to bother with trying to muck around with whether it is defined in
+ a system header, what we do if not, etc. */
+#define FLOATFORMAT_CHAR_BIT 8
+
+static unsigned long get_field PARAMS ((unsigned char *,
+ enum floatformat_byteorders,
+ unsigned int,
+ unsigned int,
+ unsigned int));
+
+/* Extract a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static unsigned long
+get_field (data, order, total_len, start, len)
+ unsigned char *data;
+ enum floatformat_byteorders order;
+ unsigned int total_len;
+ unsigned int start;
+ unsigned int len;
+{
+ unsigned long result;
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ result = *(data + cur_byte) >> (-cur_bitshift);
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ /* This is the last byte; zero out the bits which are not part of
+ this field. */
+ result |=
+ (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
+ << cur_bitshift;
+ else
+ result |= *(data + cur_byte) << cur_bitshift;
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+ return result;
+}
+
+/* Convert from FMT to a DOUBLEST.
+ FROM is the address of the extended float.
+ Store the DOUBLEST in *TO. */
+
+void
+floatformat_to_doublest (fmt, from, to)
+ const struct floatformat *fmt;
+ char *from;
+ DOUBLEST *to;
+{
+ unsigned char *ufrom = (unsigned char *)from;
+ DOUBLEST dto;
+ long exponent;
+ unsigned long mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ int special_exponent; /* It's a NaN, denorm or zero */
+
+ /* If the mantissa bits are not contiguous from one end of the
+ mantissa to the other, we need to make a private copy of the
+ source bytes that is in the right order since the unpacking
+ algorithm assumes that the bits are contiguous.
+
+ Swap the bytes individually rather than accessing them through
+ "long *" since we have no guarantee that they start on a long
+ alignment, and also sizeof(long) for the host could be different
+ than sizeof(long) for the target. FIXME: Assumes sizeof(long)
+ for the target is 4. */
+
+ if (fmt -> byteorder == floatformat_littlebyte_bigword)
+ {
+ static unsigned char *newfrom;
+ unsigned char *swapin, *swapout;
+ int longswaps;
+
+ longswaps = fmt -> totalsize / FLOATFORMAT_CHAR_BIT;
+ longswaps >>= 3;
+
+ if (newfrom == NULL)
+ {
+ newfrom = (unsigned char *) xmalloc (fmt -> totalsize);
+ }
+ swapout = newfrom;
+ swapin = ufrom;
+ ufrom = newfrom;
+ while (longswaps-- > 0)
+ {
+ /* This is ugly, but efficient */
+ *swapout++ = swapin[4];
+ *swapout++ = swapin[5];
+ *swapout++ = swapin[6];
+ *swapout++ = swapin[7];
+ *swapout++ = swapin[0];
+ *swapout++ = swapin[1];
+ *swapout++ = swapin[2];
+ *swapout++ = swapin[3];
+ swapin += 8;
+ }
+ }
+
+ exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ fmt->exp_start, fmt->exp_len);
+ /* Note that if exponent indicates a NaN, we can't really do anything useful
+ (not knowing if the host has NaN's, or how to build one). So it will
+ end up as an infinity or something close; that is OK. */
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ dto = 0.0;
+
+ special_exponent = exponent == 0 || exponent == fmt->exp_nan;
+
+/* Don't bias zero's, denorms or NaNs. */
+ if (!special_exponent)
+ exponent -= fmt->exp_bias;
+
+ /* Build the result algebraically. Might go infinite, underflow, etc;
+ who cares. */
+/* If this format uses a hidden bit, explicitly add it in now. Otherwise,
+ increment the exponent by one to account for the integer bit. */
+
+ if (!special_exponent)
+ if (fmt->intbit == floatformat_intbit_no)
+ dto = ldexp (1.0, exponent);
+ else
+ exponent++;
+
+ while (mant_bits_left > 0)
+ {
+ mant_bits = min (mant_bits_left, 32);
+
+ mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits);
+
+ dto += ldexp ((double)mant, exponent - mant_bits);
+ exponent -= mant_bits;
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+
+ /* Negate it if negative. */
+ if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
+ dto = -dto;
+ *to = dto;
+}
+
+static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders,
+ unsigned int,
+ unsigned int,
+ unsigned int,
+ unsigned long));
+
+/* Set a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static void
+put_field (data, order, total_len, start, len, stuff_to_put)
+ unsigned char *data;
+ enum floatformat_byteorders order;
+ unsigned int total_len;
+ unsigned int start;
+ unsigned int len;
+ unsigned long stuff_to_put;
+{
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ *(data + cur_byte) &=
+ ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
+ *(data + cur_byte) |=
+ (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ {
+ /* This is the last byte. */
+ *(data + cur_byte) &=
+ ~((1 << (len - cur_bitshift)) - 1);
+ *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
+ }
+ else
+ *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
+ & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+}
+
+#ifdef HAVE_LONG_DOUBLE
+/* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
+ The range of the returned value is >= 0.5 and < 1.0. This is equivalent to
+ frexp, but operates on the long double data type. */
+
+static long double ldfrexp PARAMS ((long double value, int *eptr));
+
+static long double
+ldfrexp (value, eptr)
+ long double value;
+ int *eptr;
+{
+ long double tmp;
+ int exp;
+
+ /* Unfortunately, there are no portable functions for extracting the exponent
+ of a long double, so we have to do it iteratively by multiplying or dividing
+ by two until the fraction is between 0.5 and 1.0. */
+
+ if (value < 0.0l)
+ value = -value;
+
+ tmp = 1.0l;
+ exp = 0;
+
+ if (value >= tmp) /* Value >= 1.0 */
+ while (value >= tmp)
+ {
+ tmp *= 2.0l;
+ exp++;
+ }
+ else if (value != 0.0l) /* Value < 1.0 and > 0.0 */
+ {
+ while (value < tmp)
+ {
+ tmp /= 2.0l;
+ exp--;
+ }
+ tmp *= 2.0l;
+ exp++;
+ }
+
+ *eptr = exp;
+ return value/tmp;
+}
+#endif /* HAVE_LONG_DOUBLE */
+
+
+/* The converse: convert the DOUBLEST *FROM to an extended float
+ and store where TO points. Neither FROM nor TO have any alignment
+ restrictions. */
+
+void
+floatformat_from_doublest (fmt, from, to)
+ CONST struct floatformat *fmt;
+ DOUBLEST *from;
+ char *to;
+{
+ DOUBLEST dfrom;
+ int exponent;
+ DOUBLEST mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ unsigned char *uto = (unsigned char *)to;
+
+ memcpy (&dfrom, from, sizeof (dfrom));
+ memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
+ if (dfrom == 0)
+ return; /* Result is zero */
+ if (dfrom != dfrom) /* Result is NaN */
+ {
+ /* From is NaN */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Be sure it's not infinity, but NaN value is irrel */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ 32, 1);
+ return;
+ }
+
+ /* If negative, set the sign bit. */
+ if (dfrom < 0)
+ {
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
+ dfrom = -dfrom;
+ }
+
+ if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity */
+ {
+ /* Infinity exponent is same as NaN's. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Infinity mantissa is all zeroes. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ fmt->man_len, 0);
+ return;
+ }
+
+#ifdef HAVE_LONG_DOUBLE
+ mant = ldfrexp (dfrom, &exponent);
+#else
+ mant = frexp (dfrom, &exponent);
+#endif
+
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
+ exponent + fmt->exp_bias - 1);
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ while (mant_bits_left > 0)
+ {
+ unsigned long mant_long;
+ mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
+
+ mant *= 4294967296.0;
+ mant_long = (unsigned long)mant;
+ mant -= mant_long;
+
+ /* If the integer bit is implicit, then we need to discard it.
+ If we are discarding a zero, we should be (but are not) creating
+ a denormalized number which means adjusting the exponent
+ (I think). */
+ if (mant_bits_left == fmt->man_len
+ && fmt->intbit == floatformat_intbit_no)
+ {
+ mant_long <<= 1;
+ mant_bits -= 1;
+ }
+
+ if (mant_bits < 32)
+ {
+ /* The bits we want are in the most significant MANT_BITS bits of
+ mant_long. Move them to the least significant. */
+ mant_long >>= 32 - mant_bits;
+ }
+
+ put_field (uto, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits, mant_long);
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+ if (fmt -> byteorder == floatformat_littlebyte_bigword)
+ {
+ int count;
+ unsigned char *swaplow = uto;
+ unsigned char *swaphigh = uto + 4;
+ unsigned char tmp;
+
+ for (count = 0; count < 4; count++)
+ {
+ tmp = *swaplow;
+ *swaplow++ = *swaphigh;
+ *swaphigh++ = tmp;
+ }
+ }
+}
+
+/* temporary storage using circular buffer */
+#define NUMCELLS 16
+#define CELLSIZE 32
+static char*
+get_cell()
+{
+ static char buf[NUMCELLS][CELLSIZE];
+ static int cell=0;
+ if (++cell>=NUMCELLS) cell=0;
+ return buf[cell];
+}
+
+/* print routines to handle variable size regs, etc.
+
+ FIXME: Note that t_addr is a bfd_vma, which is currently either an
+ unsigned long or unsigned long long, determined at configure time.
+ If t_addr is an unsigned long long and sizeof (unsigned long long)
+ is greater than sizeof (unsigned long), then I believe this code will
+ probably lose, at least for little endian machines. I believe that
+ it would also be better to eliminate the switch on the absolute size
+ of t_addr and replace it with a sequence of if statements that compare
+ sizeof t_addr with sizeof the various types and do the right thing,
+ which includes knowing whether or not the host supports long long.
+ -fnf
+
+ */
+
+static int thirty_two = 32; /* eliminate warning from compiler on 32-bit systems */
+
+char*
+paddr(addr)
+ t_addr addr;
+{
+ char *paddr_str=get_cell();
+ switch (sizeof(t_addr))
+ {
+ case 8:
+ sprintf (paddr_str, "%08lx%08lx",
+ (unsigned long) (addr >> thirty_two), (unsigned long) (addr & 0xffffffff));
+ break;
+ case 4:
+ sprintf (paddr_str, "%08lx", (unsigned long) addr);
+ break;
+ case 2:
+ sprintf (paddr_str, "%04x", (unsigned short) (addr & 0xffff));
+ break;
+ default:
+ sprintf (paddr_str, "%lx", (unsigned long) addr);
+ }
+ return paddr_str;
+}
+
+char*
+preg(reg)
+ t_reg reg;
+{
+ char *preg_str=get_cell();
+ switch (sizeof(t_reg))
+ {
+ case 8:
+ sprintf (preg_str, "%08lx%08lx",
+ (unsigned long) (reg >> thirty_two), (unsigned long) (reg & 0xffffffff));
+ break;
+ case 4:
+ sprintf (preg_str, "%08lx", (unsigned long) reg);
+ break;
+ case 2:
+ sprintf (preg_str, "%04x", (unsigned short) (reg & 0xffff));
+ break;
+ default:
+ sprintf (preg_str, "%lx", (unsigned long) reg);
+ }
+ return preg_str;
+}
+
+char*
+paddr_nz(addr)
+ t_addr addr;
+{
+ char *paddr_str=get_cell();
+ switch (sizeof(t_addr))
+ {
+ case 8:
+ {
+ unsigned long high = (unsigned long) (addr >> thirty_two);
+ if (high == 0)
+ sprintf (paddr_str, "%lx", (unsigned long) (addr & 0xffffffff));
+ else
+ sprintf (paddr_str, "%lx%08lx",
+ high, (unsigned long) (addr & 0xffffffff));
+ break;
+ }
+ case 4:
+ sprintf (paddr_str, "%lx", (unsigned long) addr);
+ break;
+ case 2:
+ sprintf (paddr_str, "%x", (unsigned short) (addr & 0xffff));
+ break;
+ default:
+ sprintf (paddr_str,"%lx", (unsigned long) addr);
+ }
+ return paddr_str;
+}
+
+char*
+preg_nz(reg)
+ t_reg reg;
+{
+ char *preg_str=get_cell();
+ switch (sizeof(t_reg))
+ {
+ case 8:
+ {
+ unsigned long high = (unsigned long) (reg >> thirty_two);
+ if (high == 0)
+ sprintf (preg_str, "%lx", (unsigned long) (reg & 0xffffffff));
+ else
+ sprintf (preg_str, "%lx%08lx",
+ high, (unsigned long) (reg & 0xffffffff));
+ break;
+ }
+ case 4:
+ sprintf (preg_str, "%lx", (unsigned long) reg);
+ break;
+ case 2:
+ sprintf (preg_str, "%x", (unsigned short) (reg & 0xffff));
+ break;
+ default:
+ sprintf (preg_str, "%lx", (unsigned long) reg);
+ }
+ return preg_str;
+}
diff --git a/contrib/gdb/gdb/v850-tdep.c b/contrib/gdb/gdb/v850-tdep.c
new file mode 100644
index 0000000..b98a4bd
--- /dev/null
+++ b/contrib/gdb/gdb/v850-tdep.c
@@ -0,0 +1,884 @@
+/* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
+ Copyright 1996, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+
+
+static char *v850_generic_reg_names[] = REGISTER_NAMES;
+
+static char *v850e_reg_names[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+ "pc", "fp"
+};
+
+char **v850_register_names = v850_generic_reg_names;
+
+struct
+{
+ char **regnames;
+ int mach;
+} v850_processor_type_table[] =
+{
+ { v850_generic_reg_names, bfd_mach_v850 },
+ { v850e_reg_names, bfd_mach_v850e },
+ { v850e_reg_names, bfd_mach_v850ea },
+ { NULL, 0 }
+};
+
+/* Info gleaned from scanning a function's prologue. */
+
+struct pifsr /* Info about one saved reg */
+{
+ int framereg; /* Frame reg (SP or FP) */
+ int offset; /* Offset from framereg */
+ int cur_frameoffset; /* Current frameoffset */
+ int reg; /* Saved register number */
+};
+
+struct prologue_info
+{
+ int framereg;
+ int frameoffset;
+ int start_function;
+ struct pifsr *pifsrs;
+};
+
+static CORE_ADDR v850_scan_prologue PARAMS ((CORE_ADDR pc,
+ struct prologue_info *fs));
+
+
+/* Should call_function allocate stack space for a struct return? */
+int
+v850_use_struct_convention (gcc_p, type)
+ int gcc_p;
+ struct type *type;
+{
+ return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 4);
+}
+
+
+
+/* Structure for mapping bits in register lists to register numbers. */
+struct reg_list
+{
+ long mask;
+ int regno;
+};
+
+/* Helper function for v850_scan_prologue to handle prepare instruction. */
+
+static void
+handle_prepare (int insn, int insn2, CORE_ADDR *current_pc_ptr,
+ struct prologue_info *pi, struct pifsr **pifsr_ptr)
+
+{
+ CORE_ADDR current_pc = *current_pc_ptr;
+ struct pifsr *pifsr = *pifsr_ptr;
+ long next = insn2 & 0xffff;
+ long list12 = ((insn & 1) << 16) + (next & 0xffe0);
+ long offset = (insn & 0x3e) << 1;
+ static struct reg_list reg_table [] =
+ {
+ { 0x00800, 20 }, /* r20 */
+ { 0x00400, 21 }, /* r21 */
+ { 0x00200, 22 }, /* r22 */
+ { 0x00100, 23 }, /* r23 */
+ { 0x08000, 24 }, /* r24 */
+ { 0x04000, 25 }, /* r25 */
+ { 0x02000, 26 }, /* r26 */
+ { 0x01000, 27 }, /* r27 */
+ { 0x00080, 28 }, /* r28 */
+ { 0x00040, 29 }, /* r29 */
+ { 0x10000, 30 }, /* ep */
+ { 0x00020, 31 }, /* lp */
+ { 0, 0 } /* end of table */
+ };
+ int i;
+
+ if ((next & 0x1f) == 0x0b) /* skip imm16 argument */
+ current_pc += 2;
+ else if ((next & 0x1f) == 0x13) /* skip imm16 argument */
+ current_pc += 2;
+ else if ((next & 0x1f) == 0x1b) /* skip imm32 argument */
+ current_pc += 4;
+
+ /* Calculate the total size of the saved registers, and add it
+ it to the immediate value used to adjust SP. */
+ for (i = 0; reg_table[i].mask != 0; i++)
+ if (list12 & reg_table[i].mask)
+ offset += REGISTER_RAW_SIZE (regtable[i].regno);
+ pi->frameoffset -= offset;
+
+ /* Calculate the offsets of the registers relative to the value
+ the SP will have after the registers have been pushed and the
+ imm5 value has been subtracted from it. */
+ if (pifsr)
+ {
+ for (i = 0; reg_table[i].mask != 0; i++)
+ {
+ if (list12 & reg_table[i].mask)
+ {
+ int reg = reg_table[i].regno;
+ offset -= REGISTER_RAW_SIZE (reg);
+ pifsr->reg = reg;
+ pifsr->offset = offset;
+ pifsr->cur_frameoffset = pi->frameoffset;
+ #ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+ #endif
+ pifsr++;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+
+ /* Set result parameters. */
+ *current_pc_ptr = current_pc;
+ *pifsr_ptr = pifsr;
+}
+
+
+/* Helper function for v850_scan_prologue to handle pushm/pushl instructions.
+ FIXME: the SR bit of the register list is not supported; must check
+ that the compiler does not ever generate this bit. */
+
+static void
+handle_pushm (int insn, int insn2, struct prologue_info *pi,
+ struct pifsr **pifsr_ptr)
+
+{
+ struct pifsr *pifsr = *pifsr_ptr;
+ long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0);
+ long offset = 0;
+ static struct reg_list pushml_reg_table [] =
+ {
+ { 0x80000, PS_REGNUM }, /* PSW */
+ { 0x40000, 1 }, /* r1 */
+ { 0x20000, 2 }, /* r2 */
+ { 0x10000, 3 }, /* r3 */
+ { 0x00800, 4 }, /* r4 */
+ { 0x00400, 5 }, /* r5 */
+ { 0x00200, 6 }, /* r6 */
+ { 0x00100, 7 }, /* r7 */
+ { 0x08000, 8 }, /* r8 */
+ { 0x04000, 9 }, /* r9 */
+ { 0x02000, 10 }, /* r10 */
+ { 0x01000, 11 }, /* r11 */
+ { 0x00080, 12 }, /* r12 */
+ { 0x00040, 13 }, /* r13 */
+ { 0x00020, 14 }, /* r14 */
+ { 0x00010, 15 }, /* r15 */
+ { 0, 0 } /* end of table */
+ };
+ static struct reg_list pushmh_reg_table [] =
+ {
+ { 0x80000, 16 }, /* r16 */
+ { 0x40000, 17 }, /* r17 */
+ { 0x20000, 18 }, /* r18 */
+ { 0x10000, 19 }, /* r19 */
+ { 0x00800, 20 }, /* r20 */
+ { 0x00400, 21 }, /* r21 */
+ { 0x00200, 22 }, /* r22 */
+ { 0x00100, 23 }, /* r23 */
+ { 0x08000, 24 }, /* r24 */
+ { 0x04000, 25 }, /* r25 */
+ { 0x02000, 26 }, /* r26 */
+ { 0x01000, 27 }, /* r27 */
+ { 0x00080, 28 }, /* r28 */
+ { 0x00040, 29 }, /* r29 */
+ { 0x00010, 30 }, /* r30 */
+ { 0x00020, 31 }, /* r31 */
+ { 0, 0 } /* end of table */
+ };
+ struct reg_list *reg_table;
+ int i;
+
+ /* Is this a pushml or a pushmh? */
+ if ((insn2 & 7) == 1)
+ reg_table = pushml_reg_table;
+ else
+ reg_table = pushmh_reg_table;
+
+ /* Calculate the total size of the saved registers, and add it
+ it to the immediate value used to adjust SP. */
+ for (i = 0; reg_table[i].mask != 0; i++)
+ if (list12 & reg_table[i].mask)
+ offset += REGISTER_RAW_SIZE (regtable[i].regno);
+ pi->frameoffset -= offset;
+
+ /* Calculate the offsets of the registers relative to the value
+ the SP will have after the registers have been pushed and the
+ imm5 value is subtracted from it. */
+ if (pifsr)
+ {
+ for (i = 0; reg_table[i].mask != 0; i++)
+ {
+ if (list12 & reg_table[i].mask)
+ {
+ int reg = reg_table[i].regno;
+ offset -= REGISTER_RAW_SIZE (reg);
+ pifsr->reg = reg;
+ pifsr->offset = offset;
+ pifsr->cur_frameoffset = pi->frameoffset;
+ #ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+ #endif
+ pifsr++;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+
+ /* Set result parameters. */
+ *pifsr_ptr = pifsr;
+}
+
+
+
+
+/* Function: scan_prologue
+ Scan the prologue of the function that contains PC, and record what
+ we find in PI. PI->fsr must be zeroed by the called. Returns the
+ pc after the prologue. Note that the addresses saved in pi->fsr
+ are actually just frame relative (negative offsets from the frame
+ pointer). This is because we don't know the actual value of the
+ frame pointer yet. In some circumstances, the frame pointer can't
+ be determined till after we have scanned the prologue. */
+
+static CORE_ADDR
+v850_scan_prologue (pc, pi)
+ CORE_ADDR pc;
+ struct prologue_info *pi;
+{
+ CORE_ADDR func_addr, prologue_end, current_pc;
+ struct pifsr *pifsr, *pifsr_tmp;
+ int fp_used;
+ int ep_used;
+ int reg;
+ CORE_ADDR save_pc, save_end;
+ int regsave_func_p;
+ int r12_tmp;
+
+ /* First, figure out the bounds of the prologue so that we can limit the
+ search to something reasonable. */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (func_addr == entry_point_address ())
+ pi->start_function = 1;
+ else
+ pi->start_function = 0;
+
+#if 0
+ if (sal.line == 0)
+ prologue_end = pc;
+ else
+ prologue_end = sal.end;
+#else
+ prologue_end = pc;
+#endif
+ }
+ else
+ { /* We're in the boondocks */
+ func_addr = pc - 100;
+ prologue_end = pc;
+ }
+
+ prologue_end = min (prologue_end, pc);
+
+ /* Now, search the prologue looking for instructions that setup fp, save
+ rp, adjust sp and such. We also record the frame offset of any saved
+ registers. */
+
+ pi->frameoffset = 0;
+ pi->framereg = SP_REGNUM;
+ fp_used = 0;
+ ep_used = 0;
+ pifsr = pi->pifsrs;
+ regsave_func_p = 0;
+ save_pc = 0;
+ save_end = 0;
+ r12_tmp = 0;
+
+#ifdef DEBUG
+ printf_filtered ("Current_pc = 0x%.8lx, prologue_end = 0x%.8lx\n",
+ (long)func_addr, (long)prologue_end);
+#endif
+
+ for (current_pc = func_addr; current_pc < prologue_end; )
+ {
+ int insn, insn2;
+
+#ifdef DEBUG
+ printf_filtered ("0x%.8lx ", (long)current_pc);
+ (*tm_print_insn) (current_pc, &tm_print_insn_info);
+#endif
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+ current_pc += 2;
+ if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */
+ {
+ insn2 = read_memory_unsigned_integer (current_pc, 2);
+ current_pc += 2;
+ }
+
+ if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p)
+ { /* jarl <func>,10 */
+ long low_disp = insn2 & ~ (long) 1;
+ long disp = (((((insn & 0x3f) << 16) + low_disp)
+ & ~ (long) 1) ^ 0x00200000) - 0x00200000;
+
+ save_pc = current_pc;
+ save_end = prologue_end;
+ regsave_func_p = 1;
+ current_pc += disp - 4;
+ prologue_end = (current_pc
+ + (2 * 3) /* moves to/from ep */
+ + 4 /* addi <const>,sp,sp */
+ + 2 /* jmp [r10] */
+ + (2 * 12) /* sst.w to save r2, r20-r29, r31 */
+ + 20); /* slop area */
+
+#ifdef DEBUG
+ printf_filtered ("\tfound jarl <func>,r10, disp = %ld, low_disp = %ld, new pc = 0x%.8lx\n",
+ disp, low_disp, (long)current_pc + 2);
+#endif
+ continue;
+ }
+ else if ((insn & 0xffc0) == 0x0200 && !regsave_func_p)
+ { /* callt <imm6> */
+ long ctbp = read_register (CTBP_REGNUM);
+ long adr = ctbp + ((insn & 0x3f) << 1);
+
+ save_pc = current_pc;
+ save_end = prologue_end;
+ regsave_func_p = 1;
+ current_pc = ctbp + (read_memory_unsigned_integer (adr, 2) & 0xffff);
+ prologue_end = (current_pc
+ + (2 * 3) /* prepare list2,imm5,sp/imm */
+ + 4 /* ctret */
+ + 20); /* slop area */
+
+#ifdef DEBUG
+ printf_filtered ("\tfound callt, ctbp = 0x%.8lx, adr = %.8lx, new pc = 0x%.8lx\n",
+ ctbp, adr, (long)current_pc);
+#endif
+ continue;
+ }
+ else if ((insn & 0xffc0) == 0x0780) /* prepare list2,imm5 */
+ {
+ handle_prepare (insn, insn2, &current_pc, pi, &pifsr);
+ continue;
+ }
+ else if (insn == 0x07e0 && regsave_func_p && insn2 == 0x0144)
+ { /* ctret after processing register save function */
+ current_pc = save_pc;
+ prologue_end = save_end;
+ regsave_func_p = 0;
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+ continue;
+ }
+ else if ((insn & 0xfff0) == 0x07e0 && (insn2 & 5) == 1)
+ { /* pushml, pushmh */
+ handle_pushm (insn, insn2, pi, &pifsr);
+ continue;
+ }
+ else if ((insn & 0xffe0) == 0x0060 && regsave_func_p)
+ { /* jmp after processing register save function */
+ current_pc = save_pc;
+ prologue_end = save_end;
+ regsave_func_p = 0;
+#ifdef DEBUG
+ printf_filtered ("\tfound jmp after regsave func");
+#endif
+ continue;
+ }
+ else if ((insn & 0x07c0) == 0x0780 /* jarl or jr */
+ || (insn & 0xffe0) == 0x0060 /* jmp */
+ || (insn & 0x0780) == 0x0580) /* branch */
+ {
+#ifdef DEBUG
+ printf_filtered ("\n");
+#endif
+ break; /* Ran into end of prologue */
+ }
+
+ else if ((insn & 0xffe0) == ((SP_REGNUM << 11) | 0x0240)) /* add <imm>,sp */
+ pi->frameoffset += ((insn & 0x1f) ^ 0x10) - 0x10;
+ else if (insn == ((SP_REGNUM << 11) | 0x0600 | SP_REGNUM)) /* addi <imm>,sp,sp */
+ pi->frameoffset += insn2;
+ else if (insn == ((FP_RAW_REGNUM << 11) | 0x0000 | SP_REGNUM)) /* mov sp,fp */
+ {
+ fp_used = 1;
+ pi->framereg = FP_RAW_REGNUM;
+ }
+
+ else if (insn == ((R12_REGNUM << 11) | 0x0640 | R0_REGNUM)) /* movhi hi(const),r0,r12 */
+ r12_tmp = insn2 << 16;
+ else if (insn == ((R12_REGNUM << 11) | 0x0620 | R12_REGNUM)) /* movea lo(const),r12,r12 */
+ r12_tmp += insn2;
+ else if (insn == ((SP_REGNUM << 11) | 0x01c0 | R12_REGNUM) && r12_tmp) /* add r12,sp */
+ pi->frameoffset = r12_tmp;
+ else if (insn == ((EP_REGNUM << 11) | 0x0000 | SP_REGNUM)) /* mov sp,ep */
+ ep_used = 1;
+ else if (insn == ((EP_REGNUM << 11) | 0x0000 | R1_REGNUM)) /* mov r1,ep */
+ ep_used = 0;
+ else if (((insn & 0x07ff) == (0x0760 | SP_REGNUM) /* st.w <reg>,<offset>[sp] */
+ || (fp_used
+ && (insn & 0x07ff) == (0x0760 | FP_RAW_REGNUM))) /* st.w <reg>,<offset>[fp] */
+ && pifsr
+ && (((reg = (insn >> 11) & 0x1f) >= SAVE1_START_REGNUM && reg <= SAVE1_END_REGNUM)
+ || (reg >= SAVE2_START_REGNUM && reg <= SAVE2_END_REGNUM)
+ || (reg >= SAVE3_START_REGNUM && reg <= SAVE3_END_REGNUM)))
+ {
+ pifsr->reg = reg;
+ pifsr->offset = insn2 & ~1;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+
+ else if (ep_used /* sst.w <reg>,<offset>[ep] */
+ && ((insn & 0x0781) == 0x0501)
+ && pifsr
+ && (((reg = (insn >> 11) & 0x1f) >= SAVE1_START_REGNUM && reg <= SAVE1_END_REGNUM)
+ || (reg >= SAVE2_START_REGNUM && reg <= SAVE2_END_REGNUM)
+ || (reg >= SAVE3_START_REGNUM && reg <= SAVE3_END_REGNUM)))
+ {
+ pifsr->reg = reg;
+ pifsr->offset = (insn & 0x007e) << 1;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+
+#ifdef DEBUG
+ printf_filtered ("\n");
+#endif
+ }
+
+ if (pifsr)
+ pifsr->framereg = 0; /* Tie off last entry */
+
+ /* Fix up any offsets to the final offset. If a frame pointer was created, use it
+ instead of the stack pointer. */
+ for (pifsr_tmp = pi->pifsrs; pifsr_tmp && pifsr_tmp != pifsr; pifsr_tmp++)
+ {
+ pifsr_tmp->offset -= pi->frameoffset - pifsr_tmp->cur_frameoffset;
+ pifsr_tmp->framereg = pi->framereg;
+
+#ifdef DEBUG
+ printf_filtered ("Saved register r%d, offset = %d, framereg = r%d\n",
+ pifsr_tmp->reg, pifsr_tmp->offset, pifsr_tmp->framereg);
+#endif
+ }
+
+#ifdef DEBUG
+ printf_filtered ("Framereg = r%d, frameoffset = %d\n", pi->framereg, pi->frameoffset);
+#endif
+
+ return current_pc;
+}
+
+/* Function: init_extra_frame_info
+ Setup the frame's frame pointer, pc, and frame addresses for saved
+ registers. Most of the work is done in scan_prologue().
+
+ Note that when we are called for the last frame (currently active frame),
+ that fi->pc and fi->frame will already be setup. However, fi->frame will
+ be valid only if this routine uses FP. For previous frames, fi-frame will
+ always be correct (since that is derived from v850_frame_chain ()).
+
+ We can be called with the PC in the call dummy under two circumstances.
+ First, during normal backtracing, second, while figuring out the frame
+ pointer just prior to calling the target function (see run_stack_dummy). */
+
+void
+v850_init_extra_frame_info (fi)
+ struct frame_info *fi;
+{
+ struct prologue_info pi;
+ struct pifsr pifsrs[NUM_REGS + 1], *pifsr;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+
+ /* The call dummy doesn't save any registers on the stack, so we can return
+ now. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return;
+
+ pi.pifsrs = pifsrs;
+
+ v850_scan_prologue (fi->pc, &pi);
+
+ if (!fi->next && pi.framereg == SP_REGNUM)
+ fi->frame = read_register (pi.framereg) - pi.frameoffset;
+
+ for (pifsr = pifsrs; pifsr->framereg; pifsr++)
+ {
+ fi->fsr.regs[pifsr->reg] = pifsr->offset + fi->frame;
+
+ if (pifsr->framereg == SP_REGNUM)
+ fi->fsr.regs[pifsr->reg] += pi.frameoffset;
+ }
+}
+
+/* Function: frame_chain
+ Figure out the frame prior to FI. Unfortunately, this involves
+ scanning the prologue of the caller, which will also be done
+ shortly by v850_init_extra_frame_info. For the dummy frame, we
+ just return the stack pointer that was in use at the time the
+ function call was made. */
+
+CORE_ADDR
+v850_frame_chain (fi)
+ struct frame_info *fi;
+{
+ struct prologue_info pi;
+ CORE_ADDR callers_pc, fp;
+
+ /* First, find out who called us */
+ callers_pc = FRAME_SAVED_PC (fi);
+ /* If caller is a call-dummy, then our FP bears no relation to his FP! */
+ fp = v850_find_callers_reg (fi, FP_RAW_REGNUM);
+ if (PC_IN_CALL_DUMMY(callers_pc, fp, fp))
+ return fp; /* caller is call-dummy: return oldest value of FP */
+
+ /* Caller is NOT a call-dummy, so everything else should just work.
+ Even if THIS frame is a call-dummy! */
+ pi.pifsrs = NULL;
+
+ v850_scan_prologue (callers_pc, &pi);
+
+ if (pi.start_function)
+ return 0; /* Don't chain beyond the start function */
+
+ if (pi.framereg == FP_RAW_REGNUM)
+ return v850_find_callers_reg (fi, pi.framereg);
+
+ return fi->frame - pi.frameoffset;
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register.
+ One thing we might want to do here is to check REGNUM against the
+ clobber mask, and somehow flag it as invalid if it isn't saved on
+ the stack somewhere. This would provide a graceful failure mode
+ when trying to get the value of caller-saves registers for an inner
+ frame. */
+
+CORE_ADDR
+v850_find_callers_reg (fi, regnum)
+ struct frame_info *fi;
+ int regnum;
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->fsr.regs[regnum] != 0)
+ return read_memory_unsigned_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum));
+
+ return read_register (regnum);
+}
+
+/* Function: skip_prologue
+ Return the address of the first code past the prologue of the function. */
+
+CORE_ADDR
+v850_skip_prologue (pc)
+ CORE_ADDR pc;
+{
+ CORE_ADDR func_addr, func_end;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end < func_end)
+ return sal.end;
+ else
+ /* Either there's no line info, or the line after the prologue is after
+ the end of the function. In this case, there probably isn't a
+ prologue. */
+ return pc;
+ }
+
+/* We can't find the start of this function, so there's nothing we can do. */
+ return pc;
+}
+
+/* Function: pop_frame
+ This routine gets called when either the user uses the `return'
+ command, or the call dummy breakpoint gets hit. */
+
+void
+v850_pop_frame (frame)
+ struct frame_info *frame;
+{
+ int regnum;
+
+ if (PC_IN_CALL_DUMMY(frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_unsigned_integer (frame->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum)));
+
+ write_register (SP_REGNUM, FRAME_FP (frame));
+ }
+
+ flush_cached_frames ();
+}
+
+/* Function: push_arguments
+ Setup arguments and RP for a call to the target. First four args
+ go in R6->R9, subsequent args go into sp + 16 -> sp + ... Structs
+ are passed by reference. 64 bit quantities (doubles and long
+ longs) may be split between the regs and the stack. When calling a
+ function that returns a struct, a pointer to the struct is passed
+ in as a secret first argument (always in R6).
+
+ Stack space for the args has NOT been allocated: that job is up to us.
+ */
+
+CORE_ADDR
+v850_push_arguments (nargs, args, sp, struct_return, struct_addr)
+ int nargs;
+ value_ptr *args;
+ CORE_ADDR sp;
+ unsigned char struct_return;
+ CORE_ADDR struct_addr;
+{
+ int argreg;
+ int argnum;
+ int len = 0;
+ int stack_offset;
+
+ /* First, just for safety, make sure stack is aligned */
+ sp &= ~3;
+
+ /* Now make space on the stack for the args. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ len += ((TYPE_LENGTH(VALUE_TYPE(args[argnum])) + 3) & ~3);
+ sp -= len; /* possibly over-allocating, but it works... */
+ /* (you might think we could allocate 16 bytes */
+ /* less, but the ABI seems to use it all! ) */
+ argreg = ARG0_REGNUM;
+
+ /* the struct_return pointer occupies the first parameter-passing reg */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ stack_offset = 16;
+ /* The offset onto the stack at which we will start copying parameters
+ (after the registers are used up) begins at 16 rather than at zero.
+ I don't really know why, that's just the way it seems to work. */
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 16 bytes
+ in four registers available. Loop thru args from first to last. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+ char valbuf[REGISTER_RAW_SIZE(ARG0_REGNUM)];
+
+ if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
+ && TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
+ {
+ store_address (valbuf, 4, VALUE_ADDRESS (*args));
+ len = 4;
+ val = valbuf;
+ }
+ else
+ {
+ len = TYPE_LENGTH (VALUE_TYPE (*args));
+ val = (char *)VALUE_CONTENTS (*args);
+ }
+
+ while (len > 0)
+ if (argreg <= ARGLAST_REGNUM)
+ {
+ CORE_ADDR regval;
+
+ regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
+ write_register (argreg, regval);
+
+ len -= REGISTER_RAW_SIZE (argreg);
+ val += REGISTER_RAW_SIZE (argreg);
+ argreg++;
+ }
+ else
+ {
+ write_memory (sp + stack_offset, val, 4);
+
+ len -= 4;
+ val += 4;
+ stack_offset += 4;
+ }
+ args++;
+ }
+ return sp;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+CORE_ADDR
+v850_push_return_address (pc, sp)
+ CORE_ADDR pc;
+ CORE_ADDR sp;
+{
+ write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers. If the inner frame is a dummy frame, return its PC
+ instead of RP, because that's where "caller" of the dummy-frame
+ will be found. */
+
+CORE_ADDR
+v850_frame_saved_pc (fi)
+ struct frame_info *fi;
+{
+ if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM);
+ else
+ return v850_find_callers_reg (fi, RP_REGNUM);
+}
+
+void
+get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+ char *raw_buffer;
+ int *optimized;
+ CORE_ADDR *addrp;
+ struct frame_info *frame;
+ int regnum;
+ enum lval_type *lval;
+{
+ generic_get_saved_register (raw_buffer, optimized, addrp,
+ frame, regnum, lval);
+}
+
+
+/* Function: fix_call_dummy
+ Pokes the callee function's address into the CALL_DUMMY assembly stub.
+ Assumes that the CALL_DUMMY looks like this:
+ jarl <offset24>, r31
+ trap
+ */
+
+int
+v850_fix_call_dummy (dummy, sp, fun, nargs, args, type, gcc_p)
+ char *dummy;
+ CORE_ADDR sp;
+ CORE_ADDR fun;
+ int nargs;
+ value_ptr *args;
+ struct type *type;
+ int gcc_p;
+{
+ long offset24;
+
+ offset24 = (long) fun - (long) entry_point_address ();
+ offset24 &= 0x3fffff;
+ offset24 |= 0xff800000; /* jarl <offset24>, r31 */
+
+ store_unsigned_integer ((unsigned int *)&dummy[2], 2, offset24 & 0xffff);
+ store_unsigned_integer ((unsigned int *)&dummy[0], 2, offset24 >> 16);
+ return 0;
+}
+
+/* Change the register names based on the current machine type. */
+
+static int
+v850_target_architecture_hook (ap)
+ const bfd_arch_info_type *ap;
+{
+ int i, j;
+
+ if (ap->arch != bfd_arch_v850)
+ return 0;
+
+ for (i = 0; v850_processor_type_table[i].regnames != NULL; i++)
+ {
+ if (v850_processor_type_table[i].mach == ap->mach)
+ {
+ v850_register_names = v850_processor_type_table[i].regnames;
+ return 1;
+ }
+ }
+
+ fatal ("Architecture `%s' unreconized", ap->printable_name);
+}
+
+void
+_initialize_v850_tdep ()
+{
+ tm_print_insn = print_insn_v850;
+ target_architecture_hook = v850_target_architecture_hook;
+}
diff --git a/contrib/gdb/gdb/valarith.c b/contrib/gdb/gdb/valarith.c
index c03d0a4..0a3aa4d 100644
--- a/contrib/gdb/gdb/valarith.c
+++ b/contrib/gdb/gdb/valarith.c
@@ -1,5 +1,5 @@
/* Perform arithmetic and other operations on values, for GDB.
- Copyright 1986, 1989, 1991, 1992, 1993, 1994
+ Copyright 1986, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -37,6 +37,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static value_ptr value_subscripted_rvalue PARAMS ((value_ptr, value_ptr, int));
+void _initialize_valarith PARAMS ((void));
+
value_ptr
value_add (arg1, arg2)
@@ -58,6 +60,8 @@ value_add (arg1, arg2)
|| TYPE_CODE (type2) == TYPE_CODE_INT))
/* Exactly one argument is a pointer, and one is an integer. */
{
+ value_ptr retval;
+
if (TYPE_CODE (type1) == TYPE_CODE_PTR)
{
valptr = arg1;
@@ -71,10 +75,13 @@ value_add (arg1, arg2)
valptrtype = type2;
}
len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype)));
- if (len == 0) len = 1; /* For (void *) */
- return value_from_longest (valptrtype,
- value_as_long (valptr)
- + (len * value_as_long (valint)));
+ if (len == 0)
+ len = 1; /* For (void *) */
+ retval = value_from_longest (valptrtype,
+ value_as_long (valptr)
+ + (len * value_as_long (valint)));
+ VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
+ return retval;
}
return value_binop (arg1, arg2, BINOP_ADD);
@@ -293,9 +300,10 @@ int unop_user_defined_p (op, arg1)
unused. */
value_ptr
-value_x_binop (arg1, arg2, op, otherop)
+value_x_binop (arg1, arg2, op, otherop, noside)
value_ptr arg1, arg2;
enum exp_opcode op, otherop;
+ enum noside noside;
{
value_ptr * argvec;
char *ptr;
@@ -375,6 +383,13 @@ value_x_binop (arg1, arg2, op, otherop)
argvec[1] = argvec[0];
argvec++;
}
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *return_type;
+ return_type
+ = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
+ return value_zero (return_type, VALUE_LVAL (arg1));
+ }
return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
}
error ("member function %s not found", tstr);
@@ -390,9 +405,10 @@ value_x_binop (arg1, arg2, op, otherop)
is legal for GNU C++). */
value_ptr
-value_x_unop (arg1, op)
+value_x_unop (arg1, op, noside)
value_ptr arg1;
enum exp_opcode op;
+ enum noside noside;
{
value_ptr * argvec;
char *ptr, *mangle_ptr;
@@ -426,8 +442,9 @@ value_x_unop (arg1, op)
case UNOP_LOGICAL_NOT: strcpy(ptr,"!"); break;
case UNOP_COMPLEMENT: strcpy(ptr,"~"); break;
case UNOP_NEG: strcpy(ptr,"-"); break;
+ case UNOP_IND: strcpy(ptr,"*"); break;
default:
- error ("Invalid binary operation specified.");
+ error ("Invalid unary operation specified.");
}
argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure");
@@ -439,6 +456,13 @@ value_x_unop (arg1, op)
argvec[1] = argvec[0];
argvec++;
}
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *return_type;
+ return_type
+ = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
+ return value_zero (return_type, VALUE_LVAL (arg1));
+ }
return call_function_by_hand (argvec[0], 1 - static_memfuncp, argvec + 1);
}
error ("member function %s not found", tstr);
@@ -753,12 +777,12 @@ value_binop (arg1, arg2, op)
if (unsigned_operation)
{
- unsigned LONGEST v1, v2, v;
- v1 = (unsigned LONGEST) value_as_long (arg1);
- v2 = (unsigned LONGEST) value_as_long (arg2);
+ ULONGEST v1, v2, v;
+ v1 = (ULONGEST) value_as_long (arg1);
+ v2 = (ULONGEST) value_as_long (arg2);
/* Truncate values to the type length of the result. */
- if (result_len < sizeof (unsigned LONGEST))
+ if (result_len < sizeof (ULONGEST))
{
v1 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
v2 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
@@ -1045,18 +1069,19 @@ value_equal (arg1, arg2)
code1 = TYPE_CODE (type1);
code2 = TYPE_CODE (type2);
- if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
+ if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
+ (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return longest_to_int (value_as_long (value_binop (arg1, arg2,
BINOP_EQUAL)));
- else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
- && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
+ else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
+ && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_double (arg1) == value_as_double (arg2);
/* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
is bigger. */
- else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_pointer (arg1) == (CORE_ADDR) value_as_long (arg2);
- else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT)
+ else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
return (CORE_ADDR) value_as_long (arg1) == value_as_pointer (arg2);
else if (code1 == code2
@@ -1098,20 +1123,21 @@ value_less (arg1, arg2)
code1 = TYPE_CODE (type1);
code2 = TYPE_CODE (type2);
- if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
+ if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
+ (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return longest_to_int (value_as_long (value_binop (arg1, arg2,
BINOP_LESS)));
- else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
- && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
+ else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
+ && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_double (arg1) < value_as_double (arg2);
else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
return value_as_pointer (arg1) < value_as_pointer (arg2);
/* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
is bigger. */
- else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2);
- else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT)
+ else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2);
else
@@ -1128,6 +1154,7 @@ value_neg (arg1)
register value_ptr arg1;
{
register struct type *type;
+ register struct type *result_type = VALUE_TYPE (arg1);
COERCE_REF (arg1);
COERCE_ENUM (arg1);
@@ -1135,9 +1162,16 @@ value_neg (arg1)
type = check_typedef (VALUE_TYPE (arg1));
if (TYPE_CODE (type) == TYPE_CODE_FLT)
- return value_from_double (type, - value_as_double (arg1));
- else if (TYPE_CODE (type) == TYPE_CODE_INT)
- return value_from_longest (type, - value_as_long (arg1));
+ return value_from_double (result_type, - value_as_double (arg1));
+ else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_BOOL)
+ {
+ /* Perform integral promotion for ANSI C/C++.
+ FIXME: What about FORTRAN and chill ? */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ result_type = builtin_type_int;
+
+ return value_from_longest (result_type, - value_as_long (arg1));
+ }
else {
error ("Argument to negate operation not a number.");
return 0; /* For lint -- never reached */
@@ -1148,13 +1182,25 @@ value_ptr
value_complement (arg1)
register value_ptr arg1;
{
+ register struct type *type;
+ register struct type *result_type = VALUE_TYPE (arg1);
+ int typecode;
+
COERCE_REF (arg1);
COERCE_ENUM (arg1);
- if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_INT)
- error ("Argument to complement operation not an integer.");
+ type = check_typedef (VALUE_TYPE (arg1));
+
+ typecode = TYPE_CODE (type);
+ if ((typecode != TYPE_CODE_INT) && (typecode != TYPE_CODE_BOOL))
+ error ("Argument to complement operation not an integer or boolean.");
+
+ /* Perform integral promotion for ANSI C/C++.
+ FIXME: What about FORTRAN ? */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ result_type = builtin_type_int;
- return value_from_longest (VALUE_TYPE (arg1), ~ value_as_long (arg1));
+ return value_from_longest (result_type, ~ value_as_long (arg1));
}
/* The INDEX'th bit of SET value whose VALUE_TYPE is TYPE,
diff --git a/contrib/gdb/gdb/valops.c b/contrib/gdb/gdb/valops.c
index 684b224..77d2396 100644
--- a/contrib/gdb/gdb/valops.c
+++ b/contrib/gdb/gdb/valops.c
@@ -1,5 +1,5 @@
/* Perform non-arithmetic operations on values, for GDB.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "target.h"
#include "demangle.h"
#include "language.h"
+#include "gdbcmd.h"
#include <errno.h>
#include "gdb_string.h"
@@ -41,17 +42,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define COERCE_FLOAT_TO_DOUBLE (param_type == NULL)
#endif
+/* Flag indicating HP compilers were used; needed to correctly handle some
+ value operations with HP aCC code/runtime. */
+extern int hp_som_som_object_present;
+
+
/* Local functions. */
static int typecmp PARAMS ((int staticp, struct type *t1[], value_ptr t2[]));
+#ifdef CALL_DUMMY
static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **));
+static value_ptr value_arg_coerce PARAMS ((value_ptr, struct type *, int));
+#endif
+
+#ifndef PUSH_ARGUMENTS
static CORE_ADDR value_push PARAMS ((CORE_ADDR, value_ptr));
+#endif
static value_ptr search_struct_field PARAMS ((char *, value_ptr, int,
struct type *, int));
+static value_ptr search_struct_field_aux PARAMS ((char *, value_ptr, int,
+ struct type *, int, int *, char *,
+ struct type **));
+
static value_ptr search_struct_method PARAMS ((char *, value_ptr *,
value_ptr *,
int, int *, struct type *));
@@ -62,6 +78,8 @@ static CORE_ADDR allocate_space_in_inferior PARAMS ((int));
static value_ptr cast_into_complex PARAMS ((struct type *, value_ptr));
+void _initialize_valops PARAMS ((void));
+
#define VALUE_SUBSTRING_START(VAL) VALUE_FRAME(VAL)
/* Flag for whether we want to abandon failed expression evals by default. */
@@ -70,6 +88,9 @@ static value_ptr cast_into_complex PARAMS ((struct type *, value_ptr));
static int auto_abandon = 0;
#endif
+int overload_resolution = 0;
+
+
/* Find the address of function name NAME in the inferior. */
@@ -103,7 +124,10 @@ find_function_in_inferior (name)
}
else
{
- error ("evaluation of this expression requires the program to have a function \"%s\".", name);
+ if (!target_has_execution)
+ error ("evaluation of this expression requires the target program to be active");
+ else
+ error ("evaluation of this expression requires the program to have a function \"%s\".", name);
}
}
}
@@ -122,7 +146,10 @@ value_allocate_space_in_inferior (len)
val = call_function_by_hand (val, 1, &blocklen);
if (value_logical_not (val))
{
- error ("No memory available to program.");
+ if (!target_has_execution)
+ error ("No memory available to program now: you need to start the target first");
+ else
+ error ("No memory available to program: call to malloc failed");
}
return val;
}
@@ -149,6 +176,8 @@ value_cast (type, arg2)
register int scalar;
struct type *type2;
+ int convert_to_boolean = 0;
+
if (VALUE_TYPE (arg2) == type)
return arg2;
@@ -174,7 +203,7 @@ value_cast (type, arg2)
low_bound = 0, high_bound = 0;
new_length = val_length / element_length;
if (val_length % element_length != 0)
- warning("array element type size does not divide object size in cast");
+ warning("array element type size does not divide object size in cast");
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
range_type = create_range_type ((struct type *) NULL,
@@ -200,8 +229,13 @@ value_cast (type, arg2)
if (code1 == TYPE_CODE_COMPLEX)
return cast_into_complex (type, arg2);
- if (code1 == TYPE_CODE_BOOL || code1 == TYPE_CODE_CHAR)
- code1 = TYPE_CODE_INT;
+ if (code1 == TYPE_CODE_BOOL)
+ {
+ code1 = TYPE_CODE_INT;
+ convert_to_boolean = 1;
+ }
+ if (code1 == TYPE_CODE_CHAR)
+ code1 = TYPE_CODE_INT;
if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR)
code2 = TYPE_CODE_INT;
@@ -228,32 +262,86 @@ value_cast (type, arg2)
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
|| code1 == TYPE_CODE_RANGE)
&& (scalar || code2 == TYPE_CODE_PTR))
- return value_from_longest (type, value_as_long (arg2));
+ {
+ LONGEST longest;
+
+ if (hp_som_som_object_present && /* if target compiled by HP aCC */
+ (code2 == TYPE_CODE_PTR))
+ {
+ unsigned int * ptr;
+ value_ptr retvalp;
+
+ switch (TYPE_CODE (TYPE_TARGET_TYPE (type2)))
+ {
+ /* With HP aCC, pointers to data members have a bias */
+ case TYPE_CODE_MEMBER:
+ retvalp = value_from_longest (type, value_as_long (arg2));
+ ptr = (unsigned int *) VALUE_CONTENTS (retvalp); /* force evaluation */
+ *ptr &= ~0x20000000; /* zap 29th bit to remove bias */
+ return retvalp;
+
+ /* While pointers to methods don't really point to a function */
+ case TYPE_CODE_METHOD:
+ error ("Pointers to methods not supported with HP aCC");
+
+ default:
+ break; /* fall out and go to normal handling */
+ }
+ }
+ longest = value_as_long (arg2);
+ return value_from_longest (type, convert_to_boolean ? (LONGEST) (longest ? 1 : 0) : longest);
+ }
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
{
- /* Look in the type of the source to see if it contains the
- type of the target as a superclass. If so, we'll need to
- offset the pointer rather than just change its type. */
struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
if ( TYPE_CODE (t1) == TYPE_CODE_STRUCT
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
- && TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */
+ && !value_logical_not (arg2))
{
- value_ptr v = search_struct_field (type_name_no_tag (t1),
- value_ind (arg2), 0, t2, 1);
- if (v)
+ value_ptr v;
+
+ /* Look in the type of the source to see if it contains the
+ type of the target as a superclass. If so, we'll need to
+ offset the pointer rather than just change its type. */
+ if (TYPE_NAME (t1) != NULL)
{
- v = value_addr (v);
- VALUE_TYPE (v) = type;
- return v;
+ v = search_struct_field (type_name_no_tag (t1),
+ value_ind (arg2), 0, t2, 1);
+ if (v)
+ {
+ v = value_addr (v);
+ VALUE_TYPE (v) = type;
+ return v;
+ }
+ }
+
+ /* Look in the type of the target to see if it contains the
+ type of the source as a superclass. If so, we'll need to
+ offset the pointer rather than just change its type.
+ FIXME: This fails silently with virtual inheritance. */
+ if (TYPE_NAME (t2) != NULL)
+ {
+ v = search_struct_field (type_name_no_tag (t2),
+ value_zero (t1, not_lval), 0, t1, 1);
+ if (v)
+ {
+ value_ptr v2 = value_ind (arg2);
+ VALUE_ADDRESS (v2) -= VALUE_ADDRESS (v)
+ + VALUE_OFFSET (v);
+ v2 = value_addr (v2);
+ VALUE_TYPE (v2) = type;
+ return v2;
+ }
}
}
/* No superclass found, just fall through to change ptr type. */
}
VALUE_TYPE (arg2) = type;
+ VALUE_ENCLOSING_TYPE (arg2) = type; /* pai: chk_val */
+ VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */
return arg2;
}
else if (chill_varying_type (type))
@@ -263,6 +351,8 @@ value_cast (type, arg2)
int count1, count2;
LONGEST low_bound, high_bound;
char *valaddr, *valaddr_data;
+ /* For lint warning about eltype2 possibly uninitialized: */
+ eltype2 = NULL;
if (code2 == TYPE_CODE_BITSTRING)
error ("not implemented: converting bitstring to varying type");
if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING)
@@ -299,7 +389,8 @@ value_cast (type, arg2)
}
else if (VALUE_LVAL (arg2) == lval_memory)
{
- return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
+ return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2),
+ VALUE_BFD_SECTION (arg2));
}
else if (code1 == TYPE_CODE_VOID)
{
@@ -334,12 +425,16 @@ value_zero (type, lv)
value_at_lazy instead. value_at_lazy simply records the address of
the data and sets the lazy-evaluation-required flag. The lazy flag
is tested in the VALUE_CONTENTS macro, which is used if and when
- the contents are actually required. */
+ the contents are actually required.
+
+ Note: value_at does *NOT* handle embedded offsets; perform such
+ adjustments before or after calling it. */
value_ptr
-value_at (type, addr)
+value_at (type, addr, sect)
struct type *type;
CORE_ADDR addr;
+ asection *sect;
{
register value_ptr val;
@@ -348,10 +443,34 @@ value_at (type, addr)
val = allocate_value (type);
- read_memory (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (type));
+#ifdef GDB_TARGET_IS_D10V
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ && TYPE_TARGET_TYPE (type)
+ && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
+ {
+ /* pointer to function */
+ unsigned long num;
+ unsigned short snum;
+ snum = read_memory_unsigned_integer (addr, 2);
+ num = D10V_MAKE_IADDR(snum);
+ store_address ( VALUE_CONTENTS_RAW (val), 4, num);
+ }
+ else if (TYPE_CODE(type) == TYPE_CODE_PTR)
+ {
+ /* pointer to data */
+ unsigned long num;
+ unsigned short snum;
+ snum = read_memory_unsigned_integer (addr, 2);
+ num = D10V_MAKE_DADDR(snum);
+ store_address ( VALUE_CONTENTS_RAW (val), 4, num);
+ }
+ else
+#endif
+ read_memory_section (addr, VALUE_CONTENTS_ALL_RAW (val), TYPE_LENGTH (type), sect);
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
+ VALUE_BFD_SECTION (val) = sect;
return val;
}
@@ -359,9 +478,10 @@ value_at (type, addr)
/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */
value_ptr
-value_at_lazy (type, addr)
+value_at_lazy (type, addr, sect)
struct type *type;
CORE_ADDR addr;
+ asection *sect;
{
register value_ptr val;
@@ -373,14 +493,15 @@ value_at_lazy (type, addr)
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
VALUE_LAZY (val) = 1;
+ VALUE_BFD_SECTION (val) = sect;
return val;
}
-/* Called only from the VALUE_CONTENTS macro, if the current data for
- a variable needs to be loaded into VALUE_CONTENTS(VAL). Fetches the
- data from the user's process, and clears the lazy flag to indicate
- that the data in the buffer is valid.
+/* Called only from the VALUE_CONTENTS and VALUE_CONTENTS_ALL macros,
+ if the current data for a variable needs to be loaded into
+ VALUE_CONTENTS(VAL). Fetches the data from the user's process, and
+ clears the lazy flag to indicate that the data in the buffer is valid.
If the value is zero-length, we avoid calling read_memory, which would
abort. We mark the value as fetched anyway -- all 0 bytes of it.
@@ -394,10 +515,36 @@ value_fetch_lazy (val)
register value_ptr val;
{
CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
- int length = TYPE_LENGTH (VALUE_TYPE (val));
+ int length = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val));
+
+#ifdef GDB_TARGET_IS_D10V
+ struct type *type = VALUE_TYPE(val);
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ && TYPE_TARGET_TYPE (type)
+ && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
+ {
+ /* pointer to function */
+ unsigned long num;
+ unsigned short snum;
+ snum = read_memory_unsigned_integer (addr, 2);
+ num = D10V_MAKE_IADDR(snum);
+ store_address ( VALUE_CONTENTS_RAW (val), 4, num);
+ }
+ else if (TYPE_CODE(type) == TYPE_CODE_PTR)
+ {
+ /* pointer to data */
+ unsigned long num;
+ unsigned short snum;
+ snum = read_memory_unsigned_integer (addr, 2);
+ num = D10V_MAKE_DADDR(snum);
+ store_address ( VALUE_CONTENTS_RAW (val), 4, num);
+ }
+ else
+#endif
if (length)
- read_memory (addr, VALUE_CONTENTS_RAW (val), length);
+ read_memory_section (addr, VALUE_CONTENTS_ALL_RAW (val), length,
+ VALUE_BFD_SECTION (val));
VALUE_LAZY (val) = 0;
return 0;
}
@@ -451,7 +598,11 @@ value_assign (toval, fromval)
{
case lval_internalvar:
set_internalvar (VALUE_INTERNALVAR (toval), fromval);
- return value_copy (VALUE_INTERNALVAR (toval)->value);
+ val = value_copy (VALUE_INTERNALVAR (toval)->value);
+ VALUE_ENCLOSING_TYPE (val) = VALUE_ENCLOSING_TYPE (fromval);
+ VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);
+ VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);
+ return val;
case lval_internalvar_component:
set_internalvar_component (VALUE_INTERNALVAR (toval),
@@ -462,33 +613,49 @@ value_assign (toval, fromval)
break;
case lval_memory:
- if (VALUE_BITSIZE (toval))
- {
- char buffer[sizeof (LONGEST)];
- /* We assume that the argument to read_memory is in units of
- host chars. FIXME: Is that correct? */
- int len = (VALUE_BITPOS (toval)
+ {
+ char *dest_buffer;
+ CORE_ADDR changed_addr;
+ int changed_len;
+
+ if (VALUE_BITSIZE (toval))
+ {
+ char buffer[sizeof (LONGEST)];
+ /* We assume that the argument to read_memory is in units of
+ host chars. FIXME: Is that correct? */
+ changed_len = (VALUE_BITPOS (toval)
+ VALUE_BITSIZE (toval)
+ HOST_CHAR_BIT - 1)
/ HOST_CHAR_BIT;
- if (len > (int) sizeof (LONGEST))
- error ("Can't handle bitfields which don't fit in a %d bit word.",
- sizeof (LONGEST) * HOST_CHAR_BIT);
+ if (changed_len > (int) sizeof (LONGEST))
+ error ("Can't handle bitfields which don't fit in a %d bit word.",
+ sizeof (LONGEST) * HOST_CHAR_BIT);
- read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- buffer, len);
- modify_field (buffer, value_as_long (fromval),
- VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
- write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- buffer, len);
- }
- else if (use_buffer)
- write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- raw_buffer, use_buffer);
- else
- write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
+ read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ buffer, changed_len);
+ modify_field (buffer, value_as_long (fromval),
+ VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+ changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
+ dest_buffer = buffer;
+ }
+ else if (use_buffer)
+ {
+ changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
+ changed_len = use_buffer;
+ dest_buffer = raw_buffer;
+ }
+ else
+ {
+ changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
+ changed_len = TYPE_LENGTH (type);
+ dest_buffer = VALUE_CONTENTS (fromval);
+ }
+
+ write_memory (changed_addr, dest_buffer, changed_len);
+ if (memory_changed_hook)
+ memory_changed_hook (changed_addr, changed_len);
+ }
break;
case lval_register:
@@ -615,6 +782,9 @@ Can't handle bitfield which doesn't fit in a single register.");
else
error ("Attempt to assign to an unmodifiable value.");
}
+
+ if (register_changed_hook)
+ register_changed_hook (-1);
}
break;
@@ -629,7 +799,7 @@ Can't handle bitfield which doesn't fit in a single register.");
&& (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST)))
{
LONGEST fieldval = value_as_long (fromval);
- LONGEST valmask = (((unsigned LONGEST) 1) << VALUE_BITSIZE (toval)) - 1;
+ LONGEST valmask = (((ULONGEST) 1) << VALUE_BITSIZE (toval)) - 1;
fieldval &= valmask;
if (!TYPE_UNSIGNED (type) && (fieldval & (valmask ^ (valmask >> 1))))
@@ -642,6 +812,9 @@ Can't handle bitfield which doesn't fit in a single register.");
memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
TYPE_LENGTH (type));
VALUE_TYPE (val) = type;
+ VALUE_ENCLOSING_TYPE (val) = VALUE_ENCLOSING_TYPE (fromval);
+ VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);
+ VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);
return val;
}
@@ -660,11 +833,11 @@ value_repeat (arg1, count)
if (count < 1)
error ("Invalid number %d of repetitions.", count);
- val = allocate_repeat_value (VALUE_TYPE (arg1), count);
+ val = allocate_repeat_value (VALUE_ENCLOSING_TYPE (arg1), count);
read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1),
- VALUE_CONTENTS_RAW (val),
- TYPE_LENGTH (VALUE_TYPE (val)));
+ VALUE_CONTENTS_ALL_RAW (val),
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val)));
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1);
@@ -677,27 +850,28 @@ value_of_variable (var, b)
struct block *b;
{
value_ptr val;
- struct frame_info *frame;
+ struct frame_info *frame = NULL;
- if (b == NULL)
- /* Use selected frame. */
- frame = NULL;
- else
+ if (!b)
+ frame = NULL; /* Use selected frame. */
+ else if (symbol_read_needs_frame (var))
{
frame = block_innermost_frame (b);
- if (frame == NULL && symbol_read_needs_frame (var))
- {
- if (BLOCK_FUNCTION (b) != NULL
- && SYMBOL_NAME (BLOCK_FUNCTION (b)) != NULL)
+ if (!frame)
+ {
+ if (BLOCK_FUNCTION (b)
+ && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)))
error ("No frame is currently executing in block %s.",
- SYMBOL_NAME (BLOCK_FUNCTION (b)));
+ SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)));
else
error ("No frame is currently executing in specified block");
- }
+ }
}
+
val = read_var_value (var, frame);
- if (val == 0)
+ if (!val)
error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
+
return val;
}
@@ -744,12 +918,15 @@ value_ptr
value_coerce_function (arg1)
value_ptr arg1;
{
+ value_ptr retval;
if (VALUE_LVAL (arg1) != lval_memory)
error ("Attempt to take address of value not located in memory.");
- return value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
- (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
+ retval = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
+ (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
+ VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1);
+ return retval;
}
/* Return a pointer value for the object for which ARG1 is the contents. */
@@ -758,13 +935,15 @@ value_ptr
value_addr (arg1)
value_ptr arg1;
{
+ value_ptr arg2;
+
struct type *type = check_typedef (VALUE_TYPE (arg1));
if (TYPE_CODE (type) == TYPE_CODE_REF)
{
/* Copy the value, but change the type from (T&) to (T*).
We keep the same location information, which is efficient,
and allows &(&X) to get the location containing the reference. */
- value_ptr arg2 = value_copy (arg1);
+ arg2 = value_copy (arg1);
VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type));
return arg2;
}
@@ -774,8 +953,19 @@ value_addr (arg1)
if (VALUE_LVAL (arg1) != lval_memory)
error ("Attempt to take address of value not located in memory.");
- return value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
- (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
+ /* Get target memory address */
+ arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
+ (LONGEST) (VALUE_ADDRESS (arg1)
+ + VALUE_OFFSET (arg1)
+ + VALUE_EMBEDDED_OFFSET (arg1)));
+
+ /* This may be a pointer to a base subobject; so remember the
+ full derived object's type ... */
+ VALUE_ENCLOSING_TYPE (arg2) = lookup_pointer_type (VALUE_ENCLOSING_TYPE (arg1));
+ /* ... and also the relative position of the subobject in the full object */
+ VALUE_POINTED_TO_OFFSET (arg2) = VALUE_EMBEDDED_OFFSET (arg1);
+ VALUE_BFD_SECTION (arg2) = VALUE_BFD_SECTION (arg1);
+ return arg2;
}
/* Given a value of a pointer type, apply the C unary * operator to it. */
@@ -784,22 +974,47 @@ value_ptr
value_ind (arg1)
value_ptr arg1;
{
- struct type *type1;
+ struct type *base_type;
+ value_ptr arg2;
+ value_ptr real_val;
+
COERCE_ARRAY (arg1);
- type1 = check_typedef (VALUE_TYPE (arg1));
- if (TYPE_CODE (type1) == TYPE_CODE_MEMBER)
+ base_type = check_typedef (VALUE_TYPE (arg1));
+
+ if (TYPE_CODE (base_type) == TYPE_CODE_MEMBER)
error ("not implemented: member types in value_ind");
/* Allow * on an integer so we can cast it to whatever we want.
This returns an int, which seems like the most C-like thing
to do. "long long" variables are rare enough that
BUILTIN_TYPE_LONGEST would seem to be a mistake. */
- if (TYPE_CODE (type1) == TYPE_CODE_INT)
+ if (TYPE_CODE (base_type) == TYPE_CODE_INT)
return value_at (builtin_type_int,
- (CORE_ADDR) value_as_long (arg1));
- else if (TYPE_CODE (type1) == TYPE_CODE_PTR)
- return value_at_lazy (TYPE_TARGET_TYPE (type1), value_as_pointer (arg1));
+ (CORE_ADDR) value_as_long (arg1),
+ VALUE_BFD_SECTION (arg1));
+ else if (TYPE_CODE (base_type) == TYPE_CODE_PTR)
+ {
+ struct type *enc_type;
+ /* We may be pointing to something embedded in a larger object */
+ /* Get the real type of the enclosing object */
+ enc_type = check_typedef (VALUE_ENCLOSING_TYPE (arg1));
+ enc_type = TYPE_TARGET_TYPE (enc_type);
+ /* Retrieve the enclosing object pointed to */
+ arg2 = value_at_lazy (enc_type,
+ value_as_pointer (arg1) - VALUE_POINTED_TO_OFFSET (arg1),
+ VALUE_BFD_SECTION (arg1));
+ /* Re-adjust type */
+ VALUE_TYPE (arg2) = TYPE_TARGET_TYPE (base_type);
+ /* Add embedding info */
+ VALUE_ENCLOSING_TYPE (arg2) = enc_type;
+ VALUE_EMBEDDED_OFFSET (arg2) = VALUE_POINTED_TO_OFFSET (arg1);
+
+ /* We may be pointing to an object of some derived type */
+ arg2 = value_full_object (arg2, NULL, 0, 0, 0);
+ return arg2;
+ }
+
error ("Attempt to take contents of a non-pointer value.");
return 0; /* For lint -- never reached */
}
@@ -811,19 +1026,24 @@ value_ind (arg1)
CORE_ADDR
push_word (sp, word)
CORE_ADDR sp;
- unsigned LONGEST word;
+ ULONGEST word;
{
register int len = REGISTER_SIZE;
char buffer[MAX_REGISTER_RAW_SIZE];
store_unsigned_integer (buffer, len, word);
-#if 1 INNER_THAN 2
- sp -= len;
- write_memory (sp, buffer, len);
-#else /* stack grows upward */
- write_memory (sp, buffer, len);
- sp += len;
-#endif /* stack grows upward */
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ write_memory (sp, buffer, len);
+ }
+ else
+ {
+ /* stack grows upward */
+ write_memory (sp, buffer, len);
+ sp += len;
+ }
return sp;
}
@@ -836,46 +1056,63 @@ push_bytes (sp, buffer, len)
char *buffer;
int len;
{
-#if 1 INNER_THAN 2
- sp -= len;
- write_memory (sp, buffer, len);
-#else /* stack grows upward */
- write_memory (sp, buffer, len);
- sp += len;
-#endif /* stack grows upward */
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ write_memory (sp, buffer, len);
+ }
+ else
+ {
+ /* stack grows upward */
+ write_memory (sp, buffer, len);
+ sp += len;
+ }
return sp;
}
/* Push onto the stack the specified value VALUE. */
+#ifndef PUSH_ARGUMENTS
+
static CORE_ADDR
value_push (sp, arg)
register CORE_ADDR sp;
value_ptr arg;
{
- register int len = TYPE_LENGTH (VALUE_TYPE (arg));
+ register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
-#if 1 INNER_THAN 2
- sp -= len;
- write_memory (sp, VALUE_CONTENTS (arg), len);
-#else /* stack grows upward */
- write_memory (sp, VALUE_CONTENTS (arg), len);
- sp += len;
-#endif /* stack grows upward */
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
+ }
+ else
+ {
+ /* stack grows upward */
+ write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
+ sp += len;
+ }
return sp;
}
+#endif /* !PUSH_ARGUMENTS */
+
+#ifdef CALL_DUMMY
/* Perform the standard coercions that are specified
for arguments to be passed to C functions.
- If PARAM_TYPE is non-NULL, it is the expected parameter type. */
+ If PARAM_TYPE is non-NULL, it is the expected parameter type.
+ IS_PROTOTYPED is non-zero if the function declaration is prototyped. */
static value_ptr
-value_arg_coerce (arg, param_type)
+value_arg_coerce (arg, param_type, is_prototyped)
value_ptr arg;
struct type *param_type;
+ int is_prototyped;
{
register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
register struct type *type
@@ -895,19 +1132,31 @@ value_arg_coerce (arg, param_type)
case TYPE_CODE_CHAR:
case TYPE_CODE_BOOL:
case TYPE_CODE_ENUM:
+ /* If we don't have a prototype, coerce to integer type if necessary. */
+ if (!is_prototyped)
+ {
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ type = builtin_type_int;
+ }
+ /* Currently all target ABIs require at least the width of an integer
+ type for an argument. We may have to conditionalize the following
+ type coercion for future targets. */
if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
type = builtin_type_int;
break;
- case TYPE_CODE_FLT:
- /* coerce float to double, unless the function prototype specifies float */
- if (COERCE_FLOAT_TO_DOUBLE)
- {
- if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
- type = builtin_type_double;
- else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
- type = builtin_type_long_double;
- }
- break;
+ case TYPE_CODE_FLT:
+ /* FIXME: We should always convert floats to doubles in the
+ non-prototyped case. As many debugging formats include
+ no information about prototyping, we have to live with
+ COERCE_FLOAT_TO_DOUBLE for now. */
+ if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE)
+ {
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
+ type = builtin_type_double;
+ else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
+ type = builtin_type_long_double;
+ }
+ break;
case TYPE_CODE_FUNC:
type = lookup_pointer_type (type);
break;
@@ -994,7 +1243,6 @@ find_function_addr (function, retval_type)
return funaddr;
}
-#if defined (CALL_DUMMY)
/* All this stuff with a dummy frame may seem unnecessarily complicated
(why not just save registers in GDB?). The purpose of pushing a dummy
frame which looks just like a real frame is so that if you call a
@@ -1024,26 +1272,35 @@ call_function_by_hand (function, nargs, args)
CORE_ADDR start_sp;
/* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word
is in host byte order. Before calling FIX_CALL_DUMMY, we byteswap it
- and remove any extra bytes which might exist because unsigned LONGEST is
- bigger than REGISTER_SIZE. */
- static unsigned LONGEST dummy[] = CALL_DUMMY;
- char dummy1[REGISTER_SIZE * sizeof dummy / sizeof (unsigned LONGEST)];
+ and remove any extra bytes which might exist because ULONGEST is
+ bigger than REGISTER_SIZE.
+
+ NOTE: This is pretty wierd, as the call dummy is actually a
+ sequence of instructions. But CISC machines will have
+ to pack the instructions into REGISTER_SIZE units (and
+ so will RISC machines for which INSTRUCTION_SIZE is not
+ REGISTER_SIZE). */
+
+ static ULONGEST dummy[] = CALL_DUMMY;
+ char dummy1[REGISTER_SIZE * sizeof dummy / sizeof (ULONGEST)];
CORE_ADDR old_sp;
struct type *value_type;
unsigned char struct_return;
- CORE_ADDR struct_addr;
+ CORE_ADDR struct_addr = 0;
struct inferior_status inf_status;
struct cleanup *old_chain;
CORE_ADDR funaddr;
- int using_gcc;
+ int using_gcc; /* Set to version of gcc in use, or zero if not gcc */
CORE_ADDR real_pc;
+ struct type *param_type = NULL;
struct type *ftype = check_typedef (SYMBOL_TYPE (function));
if (!target_has_execution)
noprocess();
save_inferior_status (&inf_status, 1);
- old_chain = make_cleanup (restore_inferior_status, &inf_status);
+ old_chain = make_cleanup ((make_cleanup_func) restore_inferior_status,
+ &inf_status);
/* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
(and POP_FRAME for restoring them). (At least on most machines)
@@ -1052,21 +1309,26 @@ call_function_by_hand (function, nargs, args)
old_sp = sp = read_sp ();
-#if 1 INNER_THAN 2 /* Stack grows down */
- sp -= sizeof dummy1;
- start_sp = sp;
-#else /* Stack grows up */
- start_sp = sp;
- sp += sizeof dummy1;
-#endif
+ if (INNER_THAN (1, 2))
+ {
+ /* Stack grows down */
+ sp -= sizeof dummy1;
+ start_sp = sp;
+ }
+ else
+ {
+ /* Stack grows up */
+ start_sp = sp;
+ sp += sizeof dummy1;
+ }
funaddr = find_function_addr (function, &value_type);
CHECK_TYPEDEF (value_type);
{
struct block *b = block_for_pc (funaddr);
- /* If compiled without -g, assume GCC. */
- using_gcc = b == NULL ? 0 : BLOCK_GCC_COMPILED (b);
+ /* If compiled without -g, assume GCC 2. */
+ using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
}
/* Are we returning a value using a structure return or a normal
@@ -1080,7 +1342,7 @@ call_function_by_hand (function, nargs, args)
for (i = 0; i < (int) (sizeof (dummy) / sizeof (dummy[0])); i++)
store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
REGISTER_SIZE,
- (unsigned LONGEST)dummy[i]);
+ (ULONGEST)dummy[i]);
#ifdef GDB_TARGET_IS_HPPA
real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
@@ -1137,12 +1399,50 @@ call_function_by_hand (function, nargs, args)
for (i = nargs - 1; i >= 0; i--)
{
- struct type *param_type;
- if (TYPE_NFIELDS (ftype) > i)
- param_type = TYPE_FIELD_TYPE (ftype, i);
- else
- param_type = 0;
- args[i] = value_arg_coerce (args[i], param_type);
+ /* If we're off the end of the known arguments, do the standard
+ promotions. FIXME: if we had a prototype, this should only
+ be allowed if ... were present. */
+ if (i >= TYPE_NFIELDS (ftype))
+ args[i] = value_arg_coerce (args[i], NULL, 0);
+
+ else
+ {
+ int is_prototyped = TYPE_FLAGS (ftype) & TYPE_FLAG_PROTOTYPED;
+ param_type = TYPE_FIELD_TYPE (ftype, i);
+
+ args[i] = value_arg_coerce (args[i], param_type, is_prototyped);
+ }
+
+ /*elz: this code is to handle the case in which the function to be called
+ has a pointer to function as parameter and the corresponding actual argument
+ is the address of a function and not a pointer to function variable.
+ In aCC compiled code, the calls through pointers to functions (in the body
+ of the function called by hand) are made via $$dyncall_external which
+ requires some registers setting, this is taken care of if we call
+ via a function pointer variable, but not via a function address.
+ In cc this is not a problem. */
+
+ if (using_gcc == 0)
+ if (param_type)
+ /* if this parameter is a pointer to function*/
+ if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
+ if (TYPE_CODE (param_type->target_type) == TYPE_CODE_FUNC)
+ /* elz: FIXME here should go the test about the compiler used
+ to compile the target. We want to issue the error
+ message only if the compiler used was HP's aCC.
+ If we used HP's cc, then there is no problem and no need
+ to return at this point */
+ if (using_gcc == 0) /* && compiler == aCC*/
+ /* go see if the actual parameter is a variable of type
+ pointer to function or just a function */
+ if (args[i]->lval == not_lval)
+ {
+ char *arg_name;
+ if (find_pc_partial_function((CORE_ADDR)args[i]->aligner.contents[0], &arg_name, NULL, NULL))
+ error("\
+You cannot use function <%s> as argument. \n\
+You must use a pointer to function type variable. Command ignored.", arg_name);
+ }
}
#if defined (REG_STRUCT_HAS_ADDR)
@@ -1164,31 +1464,48 @@ call_function_by_hand (function, nargs, args)
&& REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
{
CORE_ADDR addr;
- int len = TYPE_LENGTH (arg_type);
+ int len; /* = TYPE_LENGTH (arg_type); */
+ int aligned_len;
+ arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
+ len = TYPE_LENGTH (arg_type);
+
#ifdef STACK_ALIGN
- int aligned_len = STACK_ALIGN (len);
+ /* MVS 11/22/96: I think at least some of this stack_align code is
+ really broken. Better to let PUSH_ARGUMENTS adjust the stack in
+ a target-defined manner. */
+ aligned_len = STACK_ALIGN (len);
#else
- int aligned_len = len;
-#endif
-#if !(1 INNER_THAN 2)
- /* The stack grows up, so the address of the thing we push
- is the stack pointer before we push it. */
- addr = sp;
-#else
- sp -= aligned_len;
+ aligned_len = len;
#endif
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= aligned_len;
+ }
+ else
+ {
+ /* The stack grows up, so the address of the thing we push
+ is the stack pointer before we push it. */
+ addr = sp;
+ }
/* Push the structure. */
- write_memory (sp, VALUE_CONTENTS (args[i]), len);
-#if 1 INNER_THAN 2
- /* The stack grows down, so the address of the thing we push
- is the stack pointer after we push it. */
- addr = sp;
-#else
- sp += aligned_len;
-#endif
+ write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len);
+ if (INNER_THAN (1, 2))
+ {
+ /* The stack grows down, so the address of the thing we push
+ is the stack pointer after we push it. */
+ addr = sp;
+ }
+ else
+ {
+ /* stack grows upward */
+ sp += aligned_len;
+ }
/* The value we're going to pass is the address of the thing
we just pushed. */
- args[i] = value_from_longest (lookup_pointer_type (value_type),
+ /*args[i] = value_from_longest (lookup_pointer_type (value_type),
+ (LONGEST) addr);*/
+ args[i] = value_from_longest (lookup_pointer_type (arg_type),
(LONGEST) addr);
}
}
@@ -1202,34 +1519,49 @@ call_function_by_hand (function, nargs, args)
{
int len = TYPE_LENGTH (value_type);
#ifdef STACK_ALIGN
+ /* MVS 11/22/96: I think at least some of this stack_align code is
+ really broken. Better to let PUSH_ARGUMENTS adjust the stack in
+ a target-defined manner. */
len = STACK_ALIGN (len);
#endif
-#if 1 INNER_THAN 2
- sp -= len;
- struct_addr = sp;
-#else
- struct_addr = sp;
- sp += len;
-#endif
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ struct_addr = sp;
+ }
+ else
+ {
+ /* stack grows upward */
+ struct_addr = sp;
+ sp += len;
+ }
}
-#ifdef STACK_ALIGN
- /* If stack grows down, we must leave a hole at the top. */
- {
- int len = 0;
+/* elz: on HPPA no need for this extra alignment, maybe it is needed
+ on other architectures. This is because all the alignment is taken care
+ of in the above code (ifdef REG_STRUCT_HAS_ADDR) and in
+ hppa_push_arguments*/
+#ifndef NO_EXTRA_ALIGNMENT_NEEDED
+
+#if defined(STACK_ALIGN)
+ /* MVS 11/22/96: I think at least some of this stack_align code is
+ really broken. Better to let PUSH_ARGUMENTS adjust the stack in
+ a target-defined manner. */
+ if (INNER_THAN (1, 2))
+ {
+ /* If stack grows down, we must leave a hole at the top. */
+ int len = 0;
- for (i = nargs - 1; i >= 0; i--)
- len += TYPE_LENGTH (VALUE_TYPE (args[i]));
+ for (i = nargs - 1; i >= 0; i--)
+ len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
#ifdef CALL_DUMMY_STACK_ADJUST
- len += CALL_DUMMY_STACK_ADJUST;
-#endif
-#if 1 INNER_THAN 2
- sp -= STACK_ALIGN (len) - len;
-#else
- sp += STACK_ALIGN (len) - len;
+ len += CALL_DUMMY_STACK_ADJUST;
#endif
- }
+ sp -= STACK_ALIGN (len) - len;
+ }
#endif /* STACK_ALIGN */
+#endif /* NO_EXTRA_ALIGNMENT_NEEDED */
#ifdef PUSH_ARGUMENTS
PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr);
@@ -1238,12 +1570,42 @@ call_function_by_hand (function, nargs, args)
sp = value_push (sp, args[i]);
#endif /* !PUSH_ARGUMENTS */
+#ifdef PUSH_RETURN_ADDRESS /* for targets that use no CALL_DUMMY */
+ /* There are a number of targets now which actually don't write any
+ CALL_DUMMY instructions into the target, but instead just save the
+ machine state, push the arguments, and jump directly to the callee
+ function. Since this doesn't actually involve executing a JSR/BSR
+ instruction, the return address must be set up by hand, either by
+ pushing onto the stack or copying into a return-address register
+ as appropriate. Formerly this has been done in PUSH_ARGUMENTS,
+ but that's overloading its functionality a bit, so I'm making it
+ explicit to do it here. */
+ sp = PUSH_RETURN_ADDRESS(real_pc, sp);
+#endif /* PUSH_RETURN_ADDRESS */
+
+#if defined(STACK_ALIGN)
+ if (! INNER_THAN (1, 2))
+ {
+ /* If stack grows up, we must leave a hole at the bottom, note
+ that sp already has been advanced for the arguments! */
#ifdef CALL_DUMMY_STACK_ADJUST
-#if 1 INNER_THAN 2
- sp -= CALL_DUMMY_STACK_ADJUST;
-#else
- sp += CALL_DUMMY_STACK_ADJUST;
+ sp += CALL_DUMMY_STACK_ADJUST;
#endif
+ sp = STACK_ALIGN (sp);
+ }
+#endif /* STACK_ALIGN */
+
+/* XXX This seems wrong. For stacks that grow down we shouldn't do
+ anything here! */
+ /* MVS 11/22/96: I think at least some of this stack_align code is
+ really broken. Better to let PUSH_ARGUMENTS adjust the stack in
+ a target-defined manner. */
+#ifdef CALL_DUMMY_STACK_ADJUST
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= CALL_DUMMY_STACK_ADJUST;
+ }
#endif /* CALL_DUMMY_STACK_ADJUST */
/* Store the address at which the structure is supposed to be
@@ -1328,6 +1690,19 @@ the function call).", name);
do_cleanups (old_chain);
/* Figure out the value returned by the function. */
+/* elz: I defined this new macro for the hppa architecture only.
+ this gives us a way to get the value returned by the function from the stack,
+ at the same address we told the function to put it.
+ We cannot assume on the pa that r28 still contains the address of the returned
+ structure. Usually this will be overwritten by the callee.
+ I don't know about other architectures, so I defined this macro
+*/
+
+#ifdef VALUE_RETURNED_FROM_STACK
+ if (struct_return)
+ return (value_ptr) VALUE_RETURNED_FROM_STACK (value_type, struct_addr);
+#endif
+
return value_being_returned (value_type, retbuf, struct_return);
}
}
@@ -1375,10 +1750,10 @@ value_array (lowbound, highbound, elemvec)
{
error ("bad array bounds (%d, %d)", lowbound, highbound);
}
- typelength = TYPE_LENGTH (VALUE_TYPE (elemvec[0]));
+ typelength = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[0]));
for (idx = 1; idx < nelem; idx++)
{
- if (TYPE_LENGTH (VALUE_TYPE (elemvec[idx])) != typelength)
+ if (TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[idx])) != typelength)
{
error ("array elements must all be the same size");
}
@@ -1387,17 +1762,18 @@ value_array (lowbound, highbound, elemvec)
rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
lowbound, highbound);
arraytype = create_array_type ((struct type *) NULL,
- VALUE_TYPE (elemvec[0]), rangetype);
+ VALUE_ENCLOSING_TYPE (elemvec[0]), rangetype);
if (!current_language->c_style_arrays)
{
val = allocate_value (arraytype);
for (idx = 0; idx < nelem; idx++)
{
- memcpy (VALUE_CONTENTS_RAW (val) + (idx * typelength),
- VALUE_CONTENTS (elemvec[idx]),
+ memcpy (VALUE_CONTENTS_ALL_RAW (val) + (idx * typelength),
+ VALUE_CONTENTS_ALL (elemvec[idx]),
typelength);
}
+ VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (elemvec[0]);
return val;
}
@@ -1409,13 +1785,13 @@ value_array (lowbound, highbound, elemvec)
addr = allocate_space_in_inferior (nelem * typelength);
for (idx = 0; idx < nelem; idx++)
{
- write_memory (addr + (idx * typelength), VALUE_CONTENTS (elemvec[idx]),
+ write_memory (addr + (idx * typelength), VALUE_CONTENTS_ALL (elemvec[idx]),
typelength);
}
/* Create the array type and set up an array value to be evaluated lazily. */
- val = value_at_lazy (arraytype, addr);
+ val = value_at_lazy (arraytype, addr, VALUE_BFD_SECTION (elemvec[0]));
return (val);
}
@@ -1455,7 +1831,7 @@ value_string (ptr, len)
addr = allocate_space_in_inferior (len);
write_memory (addr, ptr, len);
- val = value_at_lazy (stringtype, addr);
+ val = value_at_lazy (stringtype, addr, NULL);
return (val);
}
@@ -1560,11 +1936,12 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
int looking_for_baseclass;
{
int i;
+ int nbases = TYPE_N_BASECLASSES (type);
CHECK_TYPEDEF (type);
if (! looking_for_baseclass)
- for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+ for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
@@ -1572,16 +1949,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
{
value_ptr v;
if (TYPE_FIELD_STATIC (type, i))
- {
- char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, i);
- struct symbol *sym =
- lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
- if (sym == NULL)
- error ("Internal error: could not find physical static variable named %s",
- phys_name);
- v = value_at (TYPE_FIELD_TYPE (type, i),
- (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
- }
+ v = value_static_field (type, i);
else
v = value_primitive_field (arg1, offset, i, type);
if (v == 0)
@@ -1628,7 +1996,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
}
}
- for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ for (i = 0; i < nbases; i++)
{
value_ptr v;
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
@@ -1641,28 +2009,48 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- int boffset = VALUE_OFFSET (arg1) + offset;
+ int boffset;
+ value_ptr v2 = allocate_value (basetype);
+
boffset = baseclass_offset (type, i,
- VALUE_CONTENTS (arg1) + boffset,
- VALUE_ADDRESS (arg1) + boffset);
+ VALUE_CONTENTS (arg1) + offset,
+ VALUE_ADDRESS (arg1)
+ + VALUE_OFFSET (arg1) + offset);
if (boffset == -1)
error ("virtual baseclass botch");
- if (found_baseclass)
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ boffset += offset;
+ if (boffset < 0 || boffset >= TYPE_LENGTH (type))
+ {
+ CORE_ADDR base_addr;
+
+ base_addr = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1) + boffset;
+ if (target_read_memory (base_addr, VALUE_CONTENTS_RAW (v2),
+ TYPE_LENGTH (basetype)) != 0)
+ error ("virtual baseclass botch");
+ VALUE_LVAL (v2) = lval_memory;
+ VALUE_ADDRESS (v2) = base_addr;
+ }
+ else
{
- value_ptr v2 = allocate_value (basetype);
VALUE_LVAL (v2) = VALUE_LVAL (arg1);
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
- VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + offset + boffset;
+ VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + boffset;
if (VALUE_LAZY (arg1))
VALUE_LAZY (v2) = 1;
else
memcpy (VALUE_CONTENTS_RAW (v2),
- VALUE_CONTENTS_RAW (arg1) + offset + boffset,
+ VALUE_CONTENTS_RAW (arg1) + boffset,
TYPE_LENGTH (basetype));
- return v2;
}
- v = search_struct_field (name, arg1, offset + boffset,
- TYPE_BASECLASS (type, i),
+
+ if (found_baseclass)
+ return v2;
+ v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
looking_for_baseclass);
}
else if (found_baseclass)
@@ -1676,6 +2064,99 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
return NULL;
}
+
+/* Return the offset (in bytes) of the virtual base of type BASETYPE
+ * in an object pointed to by VALADDR (on the host), assumed to be of
+ * type TYPE. OFFSET is number of bytes beyond start of ARG to start
+ * looking (in case VALADDR is the contents of an enclosing object).
+ *
+ * This routine recurses on the primary base of the derived class because
+ * the virtual base entries of the primary base appear before the other
+ * virtual base entries.
+ *
+ * If the virtual base is not found, a negative integer is returned.
+ * The magnitude of the negative integer is the number of entries in
+ * the virtual table to skip over (entries corresponding to various
+ * ancestral classes in the chain of primary bases).
+ *
+ * Important: This assumes the HP / Taligent C++ runtime
+ * conventions. Use baseclass_offset() instead to deal with g++
+ * conventions. */
+
+void
+find_rt_vbase_offset(type, basetype, valaddr, offset, boffset_p, skip_p)
+ struct type * type;
+ struct type * basetype;
+ char * valaddr;
+ int offset;
+ int * boffset_p;
+ int * skip_p;
+{
+ int boffset; /* offset of virtual base */
+ int index; /* displacement to use in virtual table */
+ int skip;
+
+ value_ptr vp;
+ CORE_ADDR vtbl; /* the virtual table pointer */
+ struct type * pbc; /* the primary base class */
+
+ /* Look for the virtual base recursively in the primary base, first.
+ * This is because the derived class object and its primary base
+ * subobject share the primary virtual table. */
+
+ boffset = 0;
+ pbc = TYPE_PRIMARY_BASE(type);
+ if (pbc)
+ {
+ find_rt_vbase_offset (pbc, basetype, valaddr, offset, &boffset, &skip);
+ if (skip < 0)
+ {
+ *boffset_p = boffset;
+ *skip_p = -1;
+ return;
+ }
+ }
+ else
+ skip = 0;
+
+
+ /* Find the index of the virtual base according to HP/Taligent
+ runtime spec. (Depth-first, left-to-right.) */
+ index = virtual_base_index_skip_primaries (basetype, type);
+
+ if (index < 0) {
+ *skip_p = skip + virtual_base_list_length_skip_primaries (type);
+ *boffset_p = 0;
+ return;
+ }
+
+ /* pai: FIXME -- 32x64 possible problem */
+ /* First word (4 bytes) in object layout is the vtable pointer */
+ vtbl = * (CORE_ADDR *) (valaddr + offset);
+
+ /* Before the constructor is invoked, things are usually zero'd out. */
+ if (vtbl == 0)
+ error ("Couldn't find virtual table -- object may not be constructed yet.");
+
+
+ /* Find virtual base's offset -- jump over entries for primary base
+ * ancestors, then use the index computed above. But also adjust by
+ * HP_ACC_VBASE_START for the vtable slots before the start of the
+ * virtual base entries. Offset is negative -- virtual base entries
+ * appear _before_ the address point of the virtual table. */
+
+ /* pai: FIXME -- 32x64 problem, if word = 8 bytes, change multiplier
+ & use long type */
+
+ /* epstein : FIXME -- added param for overlay section. May not be correct */
+ vp = value_at (builtin_type_int, vtbl + 4 * (- skip - index - HP_ACC_VBASE_START), NULL);
+ boffset = value_as_long (vp);
+ *skip_p = -1;
+ *boffset_p = boffset;
+ return;
+}
+
+
/* Helper function used by value_struct_elt to recurse through baseclasses.
Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
and search in it assuming it has (class) type TYPE.
@@ -1698,6 +2179,7 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
{
char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ /* FIXME! May need to check for ARM demangling here */
if (strncmp(t_field_name, "__", 2)==0 ||
strncmp(t_field_name, "op", 2)==0 ||
strncmp(t_field_name, "type", 4)==0 )
@@ -1714,7 +2196,7 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
name_matched = 1;
if (j > 0 && args == 0)
- error ("cannot resolve overloaded method `%s'", name);
+ error ("cannot resolve overloaded method `%s': no arguments supplied", name);
while (j >= 0)
{
if (TYPE_FN_FIELD_STUB (f, j))
@@ -1740,14 +2222,47 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- base_offset = VALUE_OFFSET (*arg1p) + offset;
- base_offset =
- baseclass_offset (type, i,
- VALUE_CONTENTS (*arg1p) + base_offset,
- VALUE_ADDRESS (*arg1p) + base_offset);
- if (base_offset == -1)
- error ("virtual baseclass botch");
- }
+ if (TYPE_HAS_VTABLE (type))
+ {
+ /* HP aCC compiled type, search for virtual base offset
+ according to HP/Taligent runtime spec. */
+ int skip;
+ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
+ VALUE_CONTENTS_ALL (*arg1p),
+ offset + VALUE_EMBEDDED_OFFSET (*arg1p),
+ &base_offset, &skip);
+ if (skip >= 0)
+ error ("Virtual base class offset not found in vtable");
+ }
+ else
+ {
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *base_valaddr;
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ if (offset < 0 || offset >= TYPE_LENGTH (type))
+ {
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (VALUE_ADDRESS (*arg1p)
+ + VALUE_OFFSET (*arg1p) + offset,
+ base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
+ error ("virtual baseclass botch");
+ }
+ else
+ base_valaddr = VALUE_CONTENTS (*arg1p) + offset;
+
+ base_offset =
+ baseclass_offset (type, i, base_valaddr,
+ VALUE_ADDRESS (*arg1p)
+ + VALUE_OFFSET (*arg1p) + offset);
+ if (base_offset == -1)
+ error ("virtual baseclass botch");
+ }
+ }
else
{
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
@@ -1853,11 +2368,19 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
{
if (!args[1])
{
- /* destructors are a special case. */
- v = value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
- TYPE_FN_FIELDLIST_LENGTH (t, 0), 0, 0);
- if (!v) error("could not find destructor function named %s.", name);
- else return v;
+ /* Destructors are a special case. */
+ int m_index, f_index;
+
+ v = NULL;
+ if (get_destructor_fn_field (t, &m_index, &f_index))
+ {
+ v = value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, m_index),
+ f_index, NULL, 0);
+ }
+ if (v == NULL)
+ error ("could not find destructor function named %s.", name);
+ else
+ return v;
}
else
{
@@ -1884,6 +2407,365 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
return v;
}
+/* Search through the methods of an object (and its bases)
+ * to find a specified method. Return the pointer to the
+ * fn_field list of overloaded instances.
+ * Helper function for value_find_oload_list.
+ * ARGP is a pointer to a pointer to a value (the object)
+ * METHOD is a string containing the method name
+ * OFFSET is the offset within the value
+ * STATIC_MEMFUNCP is set if the method is static
+ * TYPE is the assumed type of the object
+ * NUM_FNS is the number of overloaded instances
+ * BASETYPE is set to the actual type of the subobject where the method is found
+ * BOFFSET is the offset of the base subobject where the method is found */
+
+struct fn_field *
+find_method_list (argp, method, offset, static_memfuncp, type, num_fns, basetype, boffset)
+ value_ptr *argp;
+ char * method;
+ int offset;
+ int * static_memfuncp;
+ struct type * type;
+ int * num_fns;
+ struct type ** basetype;
+ int * boffset;
+{
+ int i;
+ struct fn_field * f;
+ CHECK_TYPEDEF (type);
+
+ *num_fns = 0;
+
+ /* First check in object itself */
+ for (i = TYPE_NFN_FIELDS (type) -1; i >= 0; i--)
+ {
+ /* pai: FIXME What about operators and type conversions? */
+ char * fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ if (fn_field_name && STREQ (fn_field_name, method))
+ {
+ *num_fns = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ *basetype = type;
+ *boffset = offset;
+ return TYPE_FN_FIELDLIST1 (type, i);
+ }
+ }
+
+ /* Not found in object, check in base subobjects */
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ {
+ int base_offset;
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ if (TYPE_HAS_VTABLE (type))
+ {
+ /* HP aCC compiled type, search for virtual base offset
+ * according to HP/Taligent runtime spec. */
+ int skip;
+ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
+ VALUE_CONTENTS_ALL (*argp),
+ offset + VALUE_EMBEDDED_OFFSET (*argp),
+ &base_offset, &skip);
+ if (skip >= 0)
+ error ("Virtual base class offset not found in vtable");
+ }
+ else
+ {
+ /* probably g++ runtime model */
+ base_offset = VALUE_OFFSET (*argp) + offset;
+ base_offset =
+ baseclass_offset (type, i,
+ VALUE_CONTENTS (*argp) + base_offset,
+ VALUE_ADDRESS (*argp) + base_offset);
+ if (base_offset == -1)
+ error ("virtual baseclass botch");
+ }
+ }
+ else /* non-virtual base, simply use bit position from debug info */
+ {
+ base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
+ }
+ f = find_method_list (argp, method, base_offset + offset,
+ static_memfuncp, TYPE_BASECLASS (type, i), num_fns, basetype, boffset);
+ if (f)
+ return f;
+ }
+ return NULL;
+}
+
+/* Return the list of overloaded methods of a specified name.
+ * ARGP is a pointer to a pointer to a value (the object)
+ * METHOD is the method name
+ * OFFSET is the offset within the value contents
+ * STATIC_MEMFUNCP is set if the method is static
+ * NUM_FNS is the number of overloaded instances
+ * BASETYPE is set to the type of the base subobject that defines the method
+ * BOFFSET is the offset of the base subobject which defines the method */
+
+struct fn_field *
+value_find_oload_method_list (argp, method, offset, static_memfuncp, num_fns, basetype, boffset)
+ value_ptr *argp;
+ char * method;
+ int offset;
+ int * static_memfuncp;
+ int * num_fns;
+ struct type ** basetype;
+ int * boffset;
+{
+ struct type * t;
+ value_ptr v;
+
+ t = check_typedef (VALUE_TYPE (*argp));
+
+ /* code snarfed from value_struct_elt */
+ while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+ {
+ *argp = value_ind (*argp);
+ /* Don't coerce fn pointer to fn and then back again! */
+ if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
+ COERCE_ARRAY (*argp);
+ t = check_typedef (VALUE_TYPE (*argp));
+ }
+
+ if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
+ error ("Not implemented: member type in value_find_oload_lis");
+
+ if ( TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error ("Attempt to extract a component of a value that is not a struct or union");
+
+ /* Assume it's not static, unless we see that it is. */
+ if (static_memfuncp)
+ *static_memfuncp =0;
+
+ return find_method_list (argp, method, 0, static_memfuncp, t, num_fns, basetype, boffset);
+
+}
+
+/* Given an array of argument types (ARGTYPES) (which includes an
+ entry for "this" in the case of C++ methods), the number of
+ arguments NARGS, the NAME of a function whether it's a method or
+ not (METHOD), and the degree of laxness (LAX) in conforming to
+ overload resolution rules in ANSI C++, find the best function that
+ matches on the argument types according to the overload resolution
+ rules.
+
+ In the case of class methods, the parameter OBJ is an object value
+ in which to search for overloaded methods.
+
+ In the case of non-method functions, the parameter FSYM is a symbol
+ corresponding to one of the overloaded functions.
+
+ Return value is an integer: 0 -> good match, 10 -> debugger applied
+ non-standard coercions, 100 -> incompatible.
+
+ If a method is being searched for, VALP will hold the value.
+ If a non-method is being searched for, SYMP will hold the symbol for it.
+
+ If a method is being searched for, and it is a static method,
+ then STATICP will point to a non-zero value.
+
+ Note: This function does *not* check the value of
+ overload_resolution. Caller must check it to see whether overload
+ resolution is permitted.
+ */
+
+int
+find_overload_match (arg_types, nargs, name, method, lax, obj, fsym, valp, symp, staticp)
+ struct type ** arg_types;
+ int nargs;
+ char * name;
+ int method;
+ int lax;
+ value_ptr obj;
+ struct symbol * fsym;
+ value_ptr * valp;
+ struct symbol ** symp;
+ int * staticp;
+{
+ int nparms;
+ struct type ** parm_types;
+ int champ_nparms = 0;
+
+ short oload_champ = -1; /* Index of best overloaded function */
+ short oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
+ /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
+ short oload_ambig_champ = -1; /* 2nd contender for best match */
+ short oload_non_standard = 0; /* did we have to use non-standard conversions? */
+ short oload_incompatible = 0; /* are args supplied incompatible with any function? */
+
+ struct badness_vector * bv; /* A measure of how good an overloaded instance is */
+ struct badness_vector * oload_champ_bv = NULL; /* The measure for the current best match */
+
+ value_ptr temp = obj;
+ struct fn_field * fns_ptr = NULL; /* For methods, the list of overloaded methods */
+ struct symbol ** oload_syms = NULL; /* For non-methods, the list of overloaded function symbols */
+ int num_fns = 0; /* Number of overloaded instances being considered */
+ struct type * basetype = NULL;
+ int boffset;
+ register int jj;
+ register int ix;
+
+ char * obj_type_name = NULL;
+ char * func_name = NULL;
+
+ /* Get the list of overloaded methods or functions */
+ if (method)
+ {
+ obj_type_name = TYPE_NAME (VALUE_TYPE (obj));
+ /* Hack: evaluate_subexp_standard often passes in a pointer
+ value rather than the object itself, so try again */
+ if ((!obj_type_name || !*obj_type_name) &&
+ (TYPE_CODE (VALUE_TYPE (obj)) == TYPE_CODE_PTR))
+ obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (VALUE_TYPE (obj)));
+
+ fns_ptr = value_find_oload_method_list (&temp, name, 0,
+ staticp,
+ &num_fns,
+ &basetype, &boffset);
+ if (!fns_ptr || !num_fns)
+ error ("Couldn't find method %s%s%s",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ }
+ else
+ {
+ int i = -1;
+ func_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_NO_OPTS);
+
+ oload_syms = make_symbol_overload_list (fsym);
+ while (oload_syms[++i])
+ num_fns++;
+ if (!num_fns)
+ error ("Couldn't find function %s", func_name);
+ }
+
+ oload_champ_bv = NULL;
+
+ /* Consider each candidate in turn */
+ for (ix = 0; ix < num_fns; ix++)
+ {
+ int jj;
+
+ /* Number of parameters for current candidate */
+ nparms = method ? TYPE_NFIELDS (fns_ptr[ix].type)
+ : TYPE_NFIELDS (SYMBOL_TYPE (oload_syms[ix]));
+
+ /* Prepare array of parameter types */
+ parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *)));
+ for (jj = 0; jj < nparms; jj++)
+ parm_types[jj] = method ? TYPE_FIELD_TYPE (fns_ptr[ix].type, jj)
+ : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj);
+
+ /* Compare parameter types to supplied argument types */
+ bv = rank_function (parm_types, nparms, arg_types, nargs);
+
+ if (!oload_champ_bv)
+ {
+ oload_champ_bv = bv;
+ oload_champ = 0;
+ champ_nparms = nparms;
+ }
+ else
+ /* See whether current candidate is better or worse than previous best */
+ switch (compare_badness (bv, oload_champ_bv))
+ {
+ case 0:
+ oload_ambiguous = 1; /* top two contenders are equally good */
+ oload_ambig_champ = ix;
+ break;
+ case 1:
+ oload_ambiguous = 2; /* incomparable top contenders */
+ oload_ambig_champ = ix;
+ break;
+ case 2:
+ oload_champ_bv = bv; /* new champion, record details */
+ oload_ambiguous = 0;
+ oload_champ = ix;
+ oload_ambig_champ = -1;
+ champ_nparms = nparms;
+ break;
+ case 3:
+ default:
+ break;
+ }
+ free (parm_types);
+#ifdef DEBUG_OLOAD
+ if (method)
+ printf("Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
+ else
+ printf("Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME(oload_syms[ix]),nparms);
+ for (jj = 0; jj <= nargs; jj++)
+ printf("...Badness @ %d : %d\n", jj, bv->rank[jj]);
+ printf("Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
+#endif
+ } /* end loop over all candidates */
+
+ if (oload_ambiguous)
+ {
+ if (method)
+ error ("Cannot resolve overloaded method %s%s%s to unique instance; disambiguate by specifying function signature",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ else
+ error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature",
+ func_name);
+ }
+
+ /* Check how bad the best match is */
+ for (ix = 1; ix <= nargs; ix++)
+ {
+ switch (oload_champ_bv->rank[ix])
+ {
+ case 10:
+ oload_non_standard = 1; /* non-standard type conversions needed */
+ break;
+ case 100:
+ oload_incompatible = 1; /* truly mismatched types */
+ break;
+ }
+ }
+ if (oload_incompatible)
+ {
+ if (method)
+ error ("Cannot resolve method %s%s%s to any overloaded instance",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ else
+ error ("Cannot resolve function %s to any overloaded instance",
+ func_name);
+ }
+ else if (oload_non_standard)
+ {
+ if (method)
+ warning ("Using non-standard conversion to match method %s%s%s to supplied arguments",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ else
+ warning ("Using non-standard conversion to match function %s to supplied arguments",
+ func_name);
+ }
+
+ if (method)
+ {
+ if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
+ *valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
+ else
+ *valp = value_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
+ }
+ else
+ {
+ *symp = oload_syms[oload_champ];
+ free (func_name);
+ }
+
+ return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
+}
+
/* C++: return 1 is NAME is a legitimate name for the destructor
of type TYPE. If TYPE does not have a destructor, or
if NAME is inappropriate for TYPE, an error is signaled. */
@@ -1936,7 +2818,11 @@ check_field_in (type, name)
/* Destructors are a special case. */
if (destructor_name_p (name, type))
- return 1;
+ {
+ int m_index, f_index;
+
+ return get_destructor_fn_field (type, &m_index, &f_index);
+ }
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
{
@@ -2016,14 +2902,11 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
{
if (TYPE_FIELD_STATIC (t, i))
{
- char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
- struct symbol *sym =
- lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
- if (sym == NULL)
- error ("Internal error: could not find physical static variable named %s",
- phys_name);
- return value_at (SYMBOL_TYPE (sym),
- (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
+ v = value_static_field (t, i);
+ if (v == NULL)
+ error ("Internal error: could not find static variable %s",
+ name);
+ return v;
}
if (TYPE_FIELD_PACKED (t, i))
error ("pointers to bitfield members not allowed");
@@ -2131,6 +3014,226 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
return 0;
}
+
+/* Find the real run-time type of a value using RTTI.
+ * V is a pointer to the value.
+ * A pointer to the struct type entry of the run-time type
+ * is returneed.
+ * FULL is a flag that is set only if the value V includes
+ * the entire contents of an object of the RTTI type.
+ * TOP is the offset to the top of the enclosing object of
+ * the real run-time type. This offset may be for the embedded
+ * object, or for the enclosing object of V.
+ * USING_ENC is the flag that distinguishes the two cases.
+ * If it is 1, then the offset is for the enclosing object,
+ * otherwise for the embedded object.
+ *
+ * This currently works only for RTTI information generated
+ * by the HP ANSI C++ compiler (aCC). g++ today (1997-06-10)
+ * does not appear to support RTTI. This function returns a
+ * NULL value for objects in the g++ runtime model. */
+
+struct type *
+value_rtti_type (v, full, top, using_enc)
+ value_ptr v;
+ int * full;
+ int * top;
+ int * using_enc;
+{
+ struct type * known_type;
+ struct type * rtti_type;
+ CORE_ADDR coreptr;
+ value_ptr vp;
+ int using_enclosing = 0;
+ long top_offset = 0;
+ char rtti_type_name[256];
+
+ if (full)
+ *full = 0;
+ if (top)
+ *top = -1;
+ if (using_enc)
+ *using_enc = 0;
+
+ /* Get declared type */
+ known_type = VALUE_TYPE (v);
+ CHECK_TYPEDEF (known_type);
+ /* RTTI works only or class objects */
+ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+ return NULL;
+
+ /* If neither the declared type nor the enclosing type of the
+ * value structure has a HP ANSI C++ style virtual table,
+ * we can't do anything. */
+ if (!TYPE_HAS_VTABLE (known_type))
+ {
+ known_type = VALUE_ENCLOSING_TYPE (v);
+ CHECK_TYPEDEF (known_type);
+ if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) ||
+ !TYPE_HAS_VTABLE (known_type))
+ return NULL; /* No RTTI, or not HP-compiled types */
+ CHECK_TYPEDEF (known_type);
+ using_enclosing = 1;
+ }
+
+ if (using_enclosing && using_enc)
+ *using_enc = 1;
+
+ /* First get the virtual table address */
+ coreptr = * (CORE_ADDR *) ((VALUE_CONTENTS_ALL (v))
+ + VALUE_OFFSET (v)
+ + (using_enclosing ? 0 : VALUE_EMBEDDED_OFFSET (v)));
+ if (coreptr == 0)
+ return NULL; /* return silently -- maybe called on gdb-generated value */
+
+ /* Fetch the top offset of the object */
+ /* FIXME possible 32x64 problem with pointer size & arithmetic */
+ vp = value_at (builtin_type_int,
+ coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET,
+ VALUE_BFD_SECTION (v));
+ top_offset = value_as_long (vp);
+ if (top)
+ *top = top_offset;
+
+ /* Fetch the typeinfo pointer */
+ /* FIXME possible 32x64 problem with pointer size & arithmetic */
+ vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET, VALUE_BFD_SECTION (v));
+ /* Indirect through the typeinfo pointer and retrieve the pointer
+ * to the string name */
+ coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (vp));
+ if (!coreptr)
+ error ("Retrieved null typeinfo pointer in trying to determine run-time type");
+ vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v)); /* 4 -> offset of name field */
+ /* FIXME possible 32x64 problem */
+
+ coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (vp));
+
+ read_memory_string (coreptr, rtti_type_name, 256);
+
+ if (strlen (rtti_type_name) == 0)
+ error ("Retrieved null type name from typeinfo");
+
+ /* search for type */
+ rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1);
+
+ if (!rtti_type)
+ error ("Could not find run-time type: invalid type name %s in typeinfo??", rtti_type_name);
+ CHECK_TYPEDEF (rtti_type);
+
+#if 0 /* debugging*/
+ printf("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), TYPE_TAG_NAME (rtti_type), full ? *full : -1);
+#endif
+
+ /* Check whether we have the entire object */
+ if (full /* Non-null pointer passed */
+
+ &&
+ /* Either we checked on the whole object in hand and found the
+ top offset to be zero */
+ (((top_offset == 0) &&
+ using_enclosing &&
+ TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type))
+ ||
+ /* Or we checked on the embedded object and top offset was the
+ same as the embedded offset */
+ ((top_offset == VALUE_EMBEDDED_OFFSET (v)) &&
+ !using_enclosing &&
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
+
+ *full = 1;
+
+ return rtti_type;
+}
+
+/* Given a pointer value V, find the real (RTTI) type
+ of the object it points to.
+ Other parameters FULL, TOP, USING_ENC as with value_rtti_type()
+ and refer to the values computed for the object pointed to. */
+
+struct type *
+value_rtti_target_type (v, full, top, using_enc)
+ value_ptr v;
+ int * full;
+ int * top;
+ int * using_enc;
+{
+ value_ptr target;
+
+ target = value_ind (v);
+
+ return value_rtti_type (target, full, top, using_enc);
+}
+
+/* Given a value pointed to by ARGP, check its real run-time type, and
+ if that is different from the enclosing type, create a new value
+ using the real run-time type as the enclosing type (and of the same
+ type as ARGP) and return it, with the embedded offset adjusted to
+ be the correct offset to the enclosed object
+ RTYPE is the type, and XFULL, XTOP, and XUSING_ENC are the other
+ parameters, computed by value_rtti_type(). If these are available,
+ they can be supplied and a second call to value_rtti_type() is avoided.
+ (Pass RTYPE == NULL if they're not available */
+
+value_ptr
+value_full_object (argp, rtype, xfull, xtop, xusing_enc)
+ value_ptr argp;
+ struct type * rtype;
+ int xfull;
+ int xtop;
+ int xusing_enc;
+
+{
+ struct type * real_type;
+ int full = 0;
+ int top = -1;
+ int using_enc = 0;
+ value_ptr new_val;
+
+ if (rtype)
+ {
+ real_type = rtype;
+ full = xfull;
+ top = xtop;
+ using_enc = xusing_enc;
+ }
+ else
+ real_type = value_rtti_type (argp, &full, &top, &using_enc);
+
+ /* If no RTTI data, or if object is already complete, do nothing */
+ if (!real_type || real_type == VALUE_ENCLOSING_TYPE (argp))
+ return argp;
+
+ /* If we have the full object, but for some reason the enclosing
+ type is wrong, set it */ /* pai: FIXME -- sounds iffy */
+ if (full)
+ {
+ VALUE_ENCLOSING_TYPE (argp) = real_type;
+ return argp;
+ }
+
+ /* Check if object is in memory */
+ if (VALUE_LVAL (argp) != lval_memory)
+ {
+ warning ("Couldn't retrieve complete object of RTTI type %s; object may be in register(s).", TYPE_NAME (real_type));
+
+ return argp;
+ }
+
+ /* All other cases -- retrieve the complete object */
+ /* Go back by the computed top_offset from the beginning of the object,
+ adjusting for the embedded offset of argp if that's what value_rtti_type
+ used for its computation. */
+ new_val = value_at_lazy (real_type, VALUE_ADDRESS (argp) - top +
+ (using_enc ? 0 : VALUE_EMBEDDED_OFFSET (argp)),
+ VALUE_BFD_SECTION (argp));
+ VALUE_TYPE (new_val) = VALUE_TYPE (argp);
+ VALUE_EMBEDDED_OFFSET (new_val) = using_enc ? top + VALUE_EMBEDDED_OFFSET (argp) : top;
+ return new_val;
+}
+
+
+
+
/* C++: return the value of the class instance variable, if one exists.
Flag COMPLAIN signals an error if the request is made in an
inappropriate context. */
@@ -2146,9 +3249,11 @@ value_of_this (complain)
value_ptr this;
if (selected_frame == 0)
- if (complain)
- error ("no frame selected");
- else return 0;
+ {
+ if (complain)
+ error ("no frame selected");
+ else return 0;
+ }
func = get_frame_function (selected_frame);
if (!func)
@@ -2161,9 +3266,11 @@ value_of_this (complain)
b = SYMBOL_BLOCK_VALUE (func);
i = BLOCK_NSYMS (b);
if (i <= 0)
- if (complain)
- error ("no args, no `this'");
- else return 0;
+ {
+ if (complain)
+ error ("no args, no `this'");
+ else return 0;
+ }
/* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
symbol instead of the LOC_ARG one (if both exist). */
@@ -2214,7 +3321,7 @@ value_slice (array, lowbound, length)
done with it. */
slice_range_type = create_range_type ((struct type*) NULL,
TYPE_TARGET_TYPE (range_type),
- lowerbound, lowerbound + length - 1);
+ lowbound, lowbound + length - 1);
if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
{
int i;
@@ -2343,4 +3450,12 @@ _initialize_valops ()
&setlist),
&showlist);
#endif
+
+ add_show_from_set
+ (add_set_cmd ("overload-resolution", class_support, var_boolean, (char *)&overload_resolution,
+ "Set overload resolution in evaluating C++ functions.",
+ &setlist),
+ &showlist);
+ overload_resolution = 1;
+
}
diff --git a/contrib/gdb/gdb/valprint.c b/contrib/gdb/gdb/valprint.c
index ce113ce..b09da9b 100644
--- a/contrib/gdb/gdb/valprint.c
+++ b/contrib/gdb/gdb/valprint.c
@@ -1,5 +1,5 @@
/* Print values for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,37 +30,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "language.h"
#include "demangle.h"
#include "annotate.h"
+#include "valprint.h"
#include <errno.h>
/* Prototypes for local functions */
-static void
-print_hex_chars PARAMS ((GDB_FILE *, unsigned char *, unsigned int));
+static void print_hex_chars PARAMS ((GDB_FILE *, unsigned char *,
+ unsigned int));
-static void
-show_print PARAMS ((char *, int));
+static void show_print PARAMS ((char *, int));
-static void
-set_print PARAMS ((char *, int));
+static void set_print PARAMS ((char *, int));
-static void
-set_radix PARAMS ((char *, int));
+static void set_radix PARAMS ((char *, int));
-static void
-show_radix PARAMS ((char *, int));
+static void show_radix PARAMS ((char *, int));
-static void
-set_input_radix PARAMS ((char *, int, struct cmd_list_element *));
+static void set_input_radix PARAMS ((char *, int, struct cmd_list_element *));
-static void
-set_input_radix_1 PARAMS ((int, unsigned));
+static void set_input_radix_1 PARAMS ((int, unsigned));
-static void
-set_output_radix PARAMS ((char *, int, struct cmd_list_element *));
+static void set_output_radix PARAMS ((char *, int, struct cmd_list_element *));
-static void
-set_output_radix_1 PARAMS ((int, unsigned));
+static void set_output_radix_1 PARAMS ((int, unsigned));
+
+void _initialize_valprint PARAMS ((void));
/* Maximum number of chars to print for a string pointer value or vector
contents, or UINT_MAX for no limit. Note that "set print elements 0"
@@ -125,9 +120,11 @@ int addressprint; /* Controls printing of machine addresses */
int
-val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
+val_print (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, pretty)
struct type *type;
char *valaddr;
+ int embedded_offset;
CORE_ADDR address;
GDB_FILE *stream;
int format;
@@ -154,8 +151,8 @@ val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
return (0);
}
- return (LA_VAL_PRINT (type, valaddr, address, stream, format, deref_ref,
- recurse, pretty));
+ return (LA_VAL_PRINT (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, pretty));
}
/* Print the value VAL in C-ish syntax on stream STREAM.
@@ -225,15 +222,56 @@ val_print_type_code_int (type, valaddr, stream)
}
/* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
- The raison d'etre of this function is to consolidate printing of LONG_LONG's
- into this one function. Some platforms have long longs but don't have a
- printf() that supports "ll" in the format string. We handle these by seeing
- if the number is actually a long, and if not we just bail out and print the
- number in hex. The format chars b,h,w,g are from
- print_scalar_formatted(). If USE_LOCAL, format it according to the current
- language (this should be used for most integers which GDB prints, the
- exception is things like protocols where the format of the integer is
- a protocol thing, not a user-visible thing). */
+ The raison d'etre of this function is to consolidate printing of
+ LONG_LONG's into this one function. Some platforms have long longs but
+ don't have a printf() that supports "ll" in the format string. We handle
+ these by seeing if the number is representable as either a signed or
+ unsigned long, depending upon what format is desired, and if not we just
+ bail out and print the number in hex.
+
+ The format chars b,h,w,g are from print_scalar_formatted(). If USE_LOCAL,
+ format it according to the current language (this should be used for most
+ integers which GDB prints, the exception is things like protocols where
+ the format of the integer is a protocol thing, not a user-visible thing).
+ */
+
+#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
+static void
+print_decimal (stream, sign, use_local, val_ulong)
+ GDB_FILE *stream;
+ char *sign;
+ int use_local;
+ ULONGEST val_ulong;
+{
+ unsigned long temp[3];
+ int i = 0;
+ do
+ {
+ temp[i] = val_ulong % (1000 * 1000 * 1000);
+ val_ulong /= (1000 * 1000 * 1000);
+ i++;
+ }
+ while (val_ulong != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+ switch (i)
+ {
+ case 1:
+ fprintf_filtered (stream, "%s%lu",
+ sign, temp[0]);
+ break;
+ case 2:
+ fprintf_filtered (stream, "%s%lu%09lu",
+ sign, temp[1], temp[0]);
+ break;
+ case 3:
+ fprintf_filtered (stream, "%s%lu%09lu%09lu",
+ sign, temp[2], temp[1], temp[0]);
+ break;
+ default:
+ abort ();
+ }
+ return;
+}
+#endif
void
print_longest (stream, format, use_local, val_long)
@@ -243,20 +281,62 @@ print_longest (stream, format, use_local, val_long)
LONGEST val_long;
{
#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
- long vtop, vbot;
-
- vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT);
- vbot = (long) val_long;
-
- if ((format == 'd' && (val_long < INT_MIN || val_long > INT_MAX))
- || ((format == 'u' || format == 'x') && (unsigned long long)val_long > UINT_MAX))
+ if (sizeof (long) < sizeof (LONGEST))
{
- fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
- return;
+ switch (format)
+ {
+ case 'd':
+ {
+ /* Print a signed value, that doesn't fit in a long */
+ if ((long) val_long != val_long)
+ {
+ if (val_long < 0)
+ print_decimal (stream, "-", use_local, -val_long);
+ else
+ print_decimal (stream, "", use_local, val_long);
+ return;
+ }
+ break;
+ }
+ case 'u':
+ {
+ /* Print an unsigned value, that doesn't fit in a long */
+ if ((unsigned long) val_long != (ULONGEST) val_long)
+ {
+ print_decimal (stream, "", use_local, val_long);
+ return;
+ }
+ break;
+ }
+ case 'x':
+ case 'o':
+ case 'b':
+ case 'h':
+ case 'w':
+ case 'g':
+ /* Print as unsigned value, must fit completely in unsigned long */
+ {
+ unsigned long temp = val_long;
+ if (temp != val_long)
+ {
+ /* Urk, can't represent value in long so print in hex.
+ Do shift in two operations so that if sizeof (long)
+ == sizeof (LONGEST) we can avoid warnings from
+ picky compilers about shifts >= the size of the
+ shiftee in bits */
+ unsigned long vbot = (unsigned long) val_long;
+ LONGEST temp = (val_long >> (sizeof (long) * HOST_CHAR_BIT - 1));
+ unsigned long vtop = temp >> 1;
+ fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
+ return;
+ }
+ break;
+ }
+ }
}
#endif
-#ifdef PRINTF_HAS_LONG_LONG
+#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
switch (format)
{
case 'd':
@@ -295,7 +375,7 @@ print_longest (stream, format, use_local, val_long)
default:
abort ();
}
-#else /* !PRINTF_HAS_LONG_LONG */
+#else /* !CC_HAS_LONG_LONG || !PRINTF_HAS_LONG_LONG*/
/* In the following it is important to coerce (val_long) to a long. It does
nothing if !LONG_LONG, but it will chop off the top half (which we know
we can ignore) if the host supports long longs. */
@@ -315,33 +395,137 @@ print_longest (stream, format, use_local, val_long)
fprintf_filtered (stream,
use_local ? local_hex_format_custom ("l")
: "%lx",
- (long) val_long);
+ (unsigned long) val_long);
break;
case 'o':
fprintf_filtered (stream,
use_local ? local_octal_format_custom ("l")
: "%lo",
- (long) val_long);
+ (unsigned long) val_long);
break;
case 'b':
fprintf_filtered (stream, local_hex_format_custom ("02l"),
- (long) val_long);
+ (unsigned long) val_long);
break;
case 'h':
fprintf_filtered (stream, local_hex_format_custom ("04l"),
- (long) val_long);
+ (unsigned long) val_long);
break;
case 'w':
fprintf_filtered (stream, local_hex_format_custom ("08l"),
- (long) val_long);
+ (unsigned long) val_long);
break;
case 'g':
fprintf_filtered (stream, local_hex_format_custom ("016l"),
- (long) val_long);
+ (unsigned long) val_long);
+ break;
+ default:
+ abort ();
+ }
+#endif /* CC_HAS_LONG_LONG || PRINTF_HAS_LONG_LONG */
+}
+
+void
+strcat_longest (format, use_local, val_long, buf, buflen)
+ int format;
+ int use_local;
+ LONGEST val_long;
+ char *buf;
+ int buflen; /* ignored, for now */
+{
+#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
+ long vtop, vbot;
+
+ vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT);
+ vbot = (long) val_long;
+
+ if ((format == 'd' && (val_long < INT_MIN || val_long > INT_MAX))
+ || ((format == 'u' || format == 'x') && (unsigned long long)val_long > UINT_MAX))
+ {
+ sprintf (buf, "0x%lx%08lx", vtop, vbot);
+ return;
+ }
+#endif
+
+#ifdef PRINTF_HAS_LONG_LONG
+ switch (format)
+ {
+ case 'd':
+ sprintf (buf,
+ (use_local ? local_decimal_format_custom ("ll") : "%lld"),
+ val_long);
+ break;
+ case 'u':
+ sprintf (buf, "%llu", val_long);
+ break;
+ case 'x':
+ sprintf (buf,
+ (use_local ? local_hex_format_custom ("ll") : "%llx"),
+
+ val_long);
+ break;
+ case 'o':
+ sprintf (buf,
+ (use_local ? local_octal_format_custom ("ll") : "%llo"),
+ val_long);
+ break;
+ case 'b':
+ sprintf (buf, local_hex_format_custom ("02ll"), val_long);
+ break;
+ case 'h':
+ sprintf (buf, local_hex_format_custom ("04ll"), val_long);
+ break;
+ case 'w':
+ sprintf (buf, local_hex_format_custom ("08ll"), val_long);
+ break;
+ case 'g':
+ sprintf (buf, local_hex_format_custom ("016ll"), val_long);
+ break;
+ default:
+ abort ();
+ }
+#else /* !PRINTF_HAS_LONG_LONG */
+ /* In the following it is important to coerce (val_long) to a long. It does
+ nothing if !LONG_LONG, but it will chop off the top half (which we know
+ we can ignore) if the host supports long longs. */
+
+ switch (format)
+ {
+ case 'd':
+ sprintf (buf, (use_local ? local_decimal_format_custom ("l") : "%ld"),
+ ((long) val_long));
+ break;
+ case 'u':
+ sprintf (buf, "%lu", ((unsigned long) val_long));
+ break;
+ case 'x':
+ sprintf (buf, (use_local ? local_hex_format_custom ("l") : "%lx"),
+ ((long) val_long));
+ break;
+ case 'o':
+ sprintf (buf, (use_local ? local_octal_format_custom ("l") : "%lo"),
+ ((long) val_long));
+ break;
+ case 'b':
+ sprintf (buf, local_hex_format_custom ("02l"),
+ ((long) val_long));
+ break;
+ case 'h':
+ sprintf (buf, local_hex_format_custom ("04l"),
+ ((long) val_long));
+ break;
+ case 'w':
+ sprintf (buf, local_hex_format_custom ("08l"),
+ ((long) val_long));
+ break;
+ case 'g':
+ sprintf (buf, local_hex_format_custom ("016l"),
+ ((long) val_long));
break;
default:
abort ();
}
+
#endif /* !PRINTF_HAS_LONG_LONG */
}
@@ -355,16 +539,18 @@ int
longest_to_int (arg)
LONGEST arg;
{
+ /* Let the compiler do the work */
+ int rtnval = (int) arg;
- /* This check is in case a system header has botched the
- definition of INT_MIN, like on BSDI. */
- if (sizeof (LONGEST) <= sizeof (int))
- return arg;
-
- if (arg > INT_MAX || arg < INT_MIN)
- error ("Value out of range.");
-
- return arg;
+ /* Check for overflows or underflows */
+ if (sizeof (LONGEST) > sizeof (int))
+ {
+ if (rtnval != arg)
+ {
+ error ("Value out of range.");
+ }
+ }
+ return (rtnval);
}
/* Print a floating point value of type TYPE, pointed to in GDB by VALADDR,
@@ -397,6 +583,8 @@ print_floating (valaddr, type, stream)
the fraction is nonzero)? */
int is_nan;
+ /* For lint, initialize these two variables to suppress warning: */
+ low = high = nonnegative = 0;
if (len == 4)
{
/* It's single precision. */
@@ -472,6 +660,350 @@ print_floating (valaddr, type, stream)
#endif
}
+void
+print_binary_chars (stream, valaddr, len)
+ GDB_FILE *stream;
+ unsigned char *valaddr;
+ unsigned len;
+{
+
+#define BITS_IN_BYTES 8
+
+ unsigned char *p;
+ int i;
+ int b;
+
+ /* Declared "int" so it will be signed.
+ * This ensures that right shift will shift in zeros.
+ */
+ const int mask = 0x080;
+
+ /* FIXME: We should be not printing leading zeroes in most cases. */
+
+ fprintf_filtered (stream, local_binary_format_prefix ());
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ {
+ for (p = valaddr;
+ p < valaddr + len;
+ p++)
+ {
+ /* Every byte has 8 binary characters; peel off
+ * and print from the MSB end.
+ */
+ for( i = 0; i < (BITS_IN_BYTES * sizeof( *p )); i++ ) {
+ if( *p & ( mask >> i ))
+ b = 1;
+ else
+ b = 0;
+
+ fprintf_filtered (stream, "%1d", b);
+ }
+ }
+ }
+ else
+ {
+ for (p = valaddr + len - 1;
+ p >= valaddr;
+ p--)
+ {
+ for( i = 0; i < (BITS_IN_BYTES * sizeof( *p )); i++ ) {
+ if( *p & ( mask >> i ))
+ b = 1;
+ else
+ b = 0;
+
+ fprintf_filtered (stream, "%1d", b);
+ }
+ }
+ }
+ fprintf_filtered (stream, local_binary_format_suffix ());
+}
+
+/* VALADDR points to an integer of LEN bytes.
+ * Print it in octal on stream or format it in buf.
+ */
+void
+print_octal_chars (stream, valaddr, len)
+ GDB_FILE *stream;
+ unsigned char *valaddr;
+ unsigned len;
+{
+ unsigned char *p;
+ unsigned char octa1, octa2, octa3, carry;
+ int cycle;
+
+ /* FIXME: We should be not printing leading zeroes in most cases. */
+
+
+ /* Octal is 3 bits, which doesn't fit. Yuk. So we have to track
+ * the extra bits, which cycle every three bytes:
+ *
+ * Byte side: 0 1 2 3
+ * | | | |
+ * bit number 123 456 78 | 9 012 345 6 | 78 901 234 | 567 890 12 |
+ *
+ * Octal side: 0 1 carry 3 4 carry ...
+ *
+ * Cycle number: 0 1 2
+ *
+ * But of course we are printing from the high side, so we have to
+ * figure out where in the cycle we are so that we end up with no
+ * left over bits at the end.
+ */
+#define BITS_IN_OCTAL 3
+#define HIGH_ZERO 0340
+#define LOW_ZERO 0016
+#define CARRY_ZERO 0003
+#define HIGH_ONE 0200
+#define MID_ONE 0160
+#define LOW_ONE 0016
+#define CARRY_ONE 0001
+#define HIGH_TWO 0300
+#define MID_TWO 0070
+#define LOW_TWO 0007
+
+ /* For 32 we start in cycle 2, with two bits and one bit carry;
+ * for 64 in cycle in cycle 1, with one bit and a two bit carry.
+ */
+ cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL;
+ carry = 0;
+
+ fprintf_filtered (stream, local_octal_format_prefix ());
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ {
+ for (p = valaddr;
+ p < valaddr + len;
+ p++)
+ {
+ switch (cycle) {
+ case 0:
+ /* No carry in, carry out two bits.
+ */
+ octa1 = (HIGH_ZERO & *p) >> 5;
+ octa2 = (LOW_ZERO & *p) >> 2;
+ carry = (CARRY_ZERO & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ break;
+
+ case 1:
+ /* Carry in two bits, carry out one bit.
+ */
+ octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
+ octa2 = (MID_ONE & *p) >> 4;
+ octa3 = (LOW_ONE & *p) >> 1;
+ carry = (CARRY_ONE & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ case 2:
+ /* Carry in one bit, no carry out.
+ */
+ octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
+ octa2 = (MID_TWO & *p) >> 3;
+ octa3 = (LOW_TWO & *p);
+ carry = 0;
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ default:
+ error( "Internal error in octal conversion;" );
+ }
+
+ cycle++;
+ cycle = cycle % BITS_IN_OCTAL;
+ }
+ }
+ else
+ {
+ for (p = valaddr + len - 1;
+ p >= valaddr;
+ p--)
+ {
+ switch (cycle) {
+ case 0:
+ /* Carry out, no carry in */
+ octa1 = (HIGH_ZERO & *p) >> 5;
+ octa2 = (LOW_ZERO & *p) >> 2;
+ carry = (CARRY_ZERO & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ break;
+
+ case 1:
+ /* Carry in, carry out */
+ octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
+ octa2 = (MID_ONE & *p) >> 4;
+ octa3 = (LOW_ONE & *p) >> 1;
+ carry = (CARRY_ONE & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ case 2:
+ /* Carry in, no carry out */
+ octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
+ octa2 = (MID_TWO & *p) >> 3;
+ octa3 = (LOW_TWO & *p);
+ carry = 0;
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ default:
+ error( "Internal error in octal conversion;" );
+ }
+
+ cycle++;
+ cycle = cycle % BITS_IN_OCTAL;
+ }
+ }
+
+ fprintf_filtered (stream, local_octal_format_suffix ());
+}
+
+/* VALADDR points to an integer of LEN bytes.
+ * Print it in decimal on stream or format it in buf.
+ */
+void
+print_decimal_chars (stream, valaddr, len)
+ GDB_FILE *stream;
+ unsigned char *valaddr;
+ unsigned len;
+{
+#define TEN 10
+#define TWO_TO_FOURTH 16
+#define CARRY_OUT( x ) ((x) / TEN) /* extend char to int */
+#define CARRY_LEFT( x ) ((x) % TEN)
+#define SHIFT( x ) ((x) << 4)
+#define START_P \
+ ((TARGET_BYTE_ORDER == BIG_ENDIAN) ? valaddr : valaddr + len - 1)
+#define NOT_END_P \
+ ((TARGET_BYTE_ORDER == BIG_ENDIAN) ? (p < valaddr + len) : (p >= valaddr))
+#define NEXT_P \
+ ((TARGET_BYTE_ORDER == BIG_ENDIAN) ? p++ : p-- )
+#define LOW_NIBBLE( x ) ( (x) & 0x00F)
+#define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4)
+
+ unsigned char *p;
+ unsigned char *digits;
+ int carry;
+ int decimal_len;
+ int i, j, decimal_digits;
+ int dummy;
+ int flip;
+
+ /* Base-ten number is less than twice as many digits
+ * as the base 16 number, which is 2 digits per byte.
+ */
+ decimal_len = len * 2 * 2;
+ digits = (unsigned char *) malloc( decimal_len );
+ if( digits == NULL )
+ error( "Can't allocate memory for conversion to decimal." );
+
+ for( i = 0; i < decimal_len; i++ ) {
+ digits[i] = 0;
+ }
+
+ fprintf_filtered (stream, local_decimal_format_prefix ());
+
+ /* Ok, we have an unknown number of bytes of data to be printed in
+ * decimal.
+ *
+ * Given a hex number (in nibbles) as XYZ, we start by taking X and
+ * decemalizing it as "x1 x2" in two decimal nibbles. Then we multiply
+ * the nibbles by 16, add Y and re-decimalize. Repeat with Z.
+ *
+ * The trick is that "digits" holds a base-10 number, but sometimes
+ * the individual digits are > 10.
+ *
+ * Outer loop is per nibble (hex digit) of input, from MSD end to
+ * LSD end.
+ */
+ decimal_digits = 0; /* Number of decimal digits so far */
+ p = START_P;
+ flip = 0;
+ while( NOT_END_P ) {
+ /*
+ * Multiply current base-ten number by 16 in place.
+ * Each digit was between 0 and 9, now is between
+ * 0 and 144.
+ */
+ for( j = 0; j < decimal_digits; j++ ) {
+ digits[j] = SHIFT( digits[j] );
+ }
+
+ /* Take the next nibble off the input and add it to what
+ * we've got in the LSB position. Bottom 'digit' is now
+ * between 0 and 159.
+ *
+ * "flip" is used to run this loop twice for each byte.
+ */
+ if( flip == 0 ) {
+ /* Take top nibble.
+ */
+ digits[0] += HIGH_NIBBLE( *p );
+ flip = 1;
+ }
+ else {
+ /* Take low nibble and bump our pointer "p".
+ */
+ digits[0] += LOW_NIBBLE( *p );
+ NEXT_P;
+ flip = 0;
+ }
+
+ /* Re-decimalize. We have to do this often enough
+ * that we don't overflow, but once per nibble is
+ * overkill. Easier this way, though. Note that the
+ * carry is often larger than 10 (e.g. max initial
+ * carry out of lowest nibble is 15, could bubble all
+ * the way up greater than 10). So we have to do
+ * the carrying beyond the last current digit.
+ */
+ carry = 0;
+ for( j = 0; j < decimal_len - 1; j++ ) {
+ digits[j] += carry;
+
+ /* "/" won't handle an unsigned char with
+ * a value that if signed would be negative.
+ * So extend to longword int via "dummy".
+ */
+ dummy = digits[j];
+ carry = CARRY_OUT( dummy );
+ digits[j] = CARRY_LEFT( dummy );
+
+ if( j >= decimal_digits && carry == 0 ) {
+ /*
+ * All higher digits are 0 and we
+ * no longer have a carry.
+ *
+ * Note: "j" is 0-based, "decimal_digits" is
+ * 1-based.
+ */
+ decimal_digits = j + 1;
+ break;
+ }
+ }
+ }
+
+ /* Ok, now "digits" is the decimal representation, with
+ * the "decimal_digits" actual digits. Print!
+ */
+ for( i = decimal_digits - 1; i >= 0; i-- ) {
+ fprintf_filtered( stream, "%1d", digits[i] );
+ }
+ free( digits );
+
+ fprintf_filtered (stream, local_decimal_format_suffix ());
+}
+
/* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */
static void
@@ -571,7 +1103,7 @@ val_print_array_elements (type, valaddr, address, stream, format, deref_ref,
if (reps > repeat_count_threshold)
{
- val_print (elttype, valaddr + i * eltlen, 0, stream, format,
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
deref_ref, recurse + 1, pretty);
annotate_elt_rep (reps);
fprintf_filtered (stream, " <repeats %u times>", reps);
@@ -582,7 +1114,7 @@ val_print_array_elements (type, valaddr, address, stream, format, deref_ref,
}
else
{
- val_print (elttype, valaddr + i * eltlen, 0, stream, format,
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
deref_ref, recurse + 1, pretty);
annotate_elt ();
things_printed++;
@@ -596,128 +1128,148 @@ val_print_array_elements (type, valaddr, address, stream, format, deref_ref,
}
/* Print a string from the inferior, starting at ADDR and printing up to LEN
- characters, to STREAM. If LEN is zero, printing stops at the first null
- byte, otherwise printing proceeds (including null bytes) until either
- print_max or LEN characters have been printed, whichever is smaller. */
+ characters, of WIDTH bytes a piece, to STREAM. If LEN is -1, printing
+ stops at the first null byte, otherwise printing proceeds (including null
+ bytes) until either print_max or LEN characters have been printed,
+ whichever is smaller. */
-/* FIXME: All callers supply LEN of zero. Supplying a non-zero LEN is
- pointless, this routine just then becomes a convoluted version of
- target_read_memory_partial. Removing all the LEN stuff would simplify
- this routine enormously.
-
- FIXME: Use target_read_string. */
+/* FIXME: Use target_read_string. */
int
-val_print_string (addr, len, stream)
+val_print_string (addr, len, width, stream)
CORE_ADDR addr;
- unsigned int len;
+ int len;
+ int width;
GDB_FILE *stream;
{
int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero. */
int errcode; /* Errno returned from bad reads. */
- unsigned int fetchlimit; /* Maximum number of bytes to fetch. */
- unsigned int nfetch; /* Bytes to fetch / bytes fetched. */
- unsigned int chunksize; /* Size of each fetch, in bytes. */
- unsigned int bufsize; /* Size of current fetch buffer. */
+ unsigned int fetchlimit; /* Maximum number of chars to print. */
+ unsigned int nfetch; /* Chars to fetch / chars fetched. */
+ unsigned int chunksize; /* Size of each fetch, in chars. */
char *buffer = NULL; /* Dynamically growable fetch buffer. */
char *bufptr; /* Pointer to next available byte in buffer. */
char *limit; /* First location past end of fetch buffer. */
struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
- char peekchar; /* Place into which we can read one char. */
+ int found_nul; /* Non-zero if we found the nul char */
/* First we need to figure out the limit on the number of characters we are
going to attempt to fetch and print. This is actually pretty simple. If
- LEN is nonzero, then the limit is the minimum of LEN and print_max. If
- LEN is zero, then the limit is print_max. This is true regardless of
+ LEN >= zero, then the limit is the minimum of LEN and print_max. If
+ LEN is -1, then the limit is print_max. This is true regardless of
whether print_max is zero, UINT_MAX (unlimited), or something in between,
because finding the null byte (or available memory) is what actually
limits the fetch. */
- fetchlimit = (len == 0 ? print_max : min (len, print_max));
+ fetchlimit = (len == -1 ? print_max : min (len, print_max));
/* Now decide how large of chunks to try to read in one operation. This
- is also pretty simple. If LEN is nonzero, then we want fetchlimit bytes,
- so we might as well read them all in one operation. If LEN is zero, we
+ is also pretty simple. If LEN >= zero, then we want fetchlimit chars,
+ so we might as well read them all in one operation. If LEN is -1, we
are looking for a null terminator to end the fetching, so we might as
well read in blocks that are large enough to be efficient, but not so
large as to be slow if fetchlimit happens to be large. So we choose the
minimum of 8 and fetchlimit. We used to use 200 instead of 8 but
200 is way too big for remote debugging over a serial line. */
- chunksize = (len == 0 ? min (8, fetchlimit) : fetchlimit);
+ chunksize = (len == -1 ? min (8, fetchlimit) : fetchlimit);
/* Loop until we either have all the characters to print, or we encounter
some error, such as bumping into the end of the address space. */
- bufsize = 0;
- do {
- QUIT;
- /* Figure out how much to fetch this time, and grow the buffer to fit. */
- nfetch = min (chunksize, fetchlimit - bufsize);
- bufsize += nfetch;
- if (buffer == NULL)
- {
- buffer = (char *) xmalloc (bufsize);
- bufptr = buffer;
- }
- else
- {
- discard_cleanups (old_chain);
- buffer = (char *) xrealloc (buffer, bufsize);
- bufptr = buffer + bufsize - nfetch;
- }
- old_chain = make_cleanup (free, buffer);
+ found_nul = 0;
+ old_chain = make_cleanup (null_cleanup, 0);
- /* Read as much as we can. */
- nfetch = target_read_memory_partial (addr, bufptr, nfetch, &errcode);
- if (len != 0)
- {
- addr += nfetch;
- bufptr += nfetch;
- }
- else
- {
- /* Scan this chunk for the null byte that terminates the string
- to print. If found, we don't need to fetch any more. Note
- that bufptr is explicitly left pointing at the next character
- after the null byte, or at the next character after the end of
- the buffer. */
- limit = bufptr + nfetch;
- while (bufptr < limit)
- {
- ++addr;
- ++bufptr;
- if (bufptr[-1] == '\0')
- {
- /* We don't care about any error which happened after
- the NULL terminator. */
- errcode = 0;
- break;
- }
- }
- }
- } while (errcode == 0 /* no error */
- && bufsize < fetchlimit /* no overrun */
- && !(len == 0 && *(bufptr - 1) == '\0')); /* no null term */
+ if (len > 0)
+ {
+ buffer = (char *) xmalloc (len * width);
+ bufptr = buffer;
+ old_chain = make_cleanup (free, buffer);
+
+ nfetch = target_read_memory_partial (addr, bufptr, len * width, &errcode)
+ / width;
+ addr += nfetch * width;
+ bufptr += nfetch * width;
+ }
+ else if (len == -1)
+ {
+ unsigned long bufsize = 0;
+ do
+ {
+ QUIT;
+ nfetch = min (chunksize, fetchlimit - bufsize);
+
+ if (buffer == NULL)
+ buffer = (char *) xmalloc (nfetch * width);
+ else
+ {
+ discard_cleanups (old_chain);
+ buffer = (char *) xrealloc (buffer, (nfetch + bufsize) * width);
+ }
+
+ old_chain = make_cleanup (free, buffer);
+ bufptr = buffer + bufsize * width;
+ bufsize += nfetch;
+
+ /* Read as much as we can. */
+ nfetch = target_read_memory_partial (addr, bufptr, nfetch * width, &errcode)
+ / width;
+
+ /* Scan this chunk for the null byte that terminates the string
+ to print. If found, we don't need to fetch any more. Note
+ that bufptr is explicitly left pointing at the next character
+ after the null byte, or at the next character after the end of
+ the buffer. */
+
+ limit = bufptr + nfetch * width;
+ while (bufptr < limit)
+ {
+ unsigned long c;
+
+ c = extract_unsigned_integer (bufptr, width);
+ addr += width;
+ bufptr += width;
+ if (c == 0)
+ {
+ /* We don't care about any error which happened after
+ the NULL terminator. */
+ errcode = 0;
+ found_nul = 1;
+ break;
+ }
+ }
+ }
+ while (errcode == 0 /* no error */
+ && bufptr - buffer < fetchlimit * width /* no overrun */
+ && !found_nul); /* haven't found nul yet */
+ }
+ else
+ { /* length of string is really 0! */
+ buffer = bufptr = NULL;
+ errcode = 0;
+ }
/* bufptr and addr now point immediately beyond the last byte which we
consider part of the string (including a '\0' which ends the string). */
/* We now have either successfully filled the buffer to fetchlimit, or
- terminated early due to an error or finding a null byte when LEN is
- zero. */
+ terminated early due to an error or finding a null char when LEN is -1. */
- if (len == 0 && bufptr > buffer && *(bufptr - 1) != '\0')
+ if (len == -1 && !found_nul)
{
+ char *peekbuf;
+
/* We didn't find a null terminator we were looking for. Attempt
to peek at the next character. If not successful, or it is not
a null byte, then force ellipsis to be printed. */
- if (target_read_memory (addr, &peekchar, 1) != 0 || peekchar != '\0')
- {
- force_ellipsis = 1;
- }
+
+ peekbuf = (char *) alloca (width);
+
+ if (target_read_memory (addr, peekbuf, width) == 0
+ && extract_unsigned_integer (peekbuf, width) != 0)
+ force_ellipsis = 1;
}
- else if ((len != 0 && errcode != 0) || (len > bufptr - buffer))
+ else if ((len >= 0 && errcode != 0) || (len > (bufptr - buffer)/width))
{
/* Getting an error when we have a requested length, or fetching less
than the number of characters actually requested, always make us
@@ -736,7 +1288,7 @@ val_print_string (addr, len, stream)
{
fputs_filtered (" ", stream);
}
- LA_PRINT_STRING (stream, buffer, bufptr - buffer, force_ellipsis);
+ LA_PRINT_STRING (stream, buffer, (bufptr - buffer)/width, width, force_ellipsis);
}
if (errcode != 0)
@@ -756,7 +1308,7 @@ val_print_string (addr, len, stream)
}
gdb_flush (stream);
do_cleanups (old_chain);
- return (bufptr - buffer);
+ return ((bufptr - buffer)/width);
}
diff --git a/contrib/gdb/gdb/valprint.h b/contrib/gdb/gdb/valprint.h
index c486dee..e6edb15 100644
--- a/contrib/gdb/gdb/valprint.h
+++ b/contrib/gdb/gdb/valprint.h
@@ -37,8 +37,18 @@ extern int stop_print_at_null; /* Stop printing at null char? */
extern void
val_print_array_elements PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *,
- int, int, int, enum val_prettyprint, int));
+ int, int, int, enum val_prettyprint,
+ unsigned int));
extern void
val_print_type_code_int PARAMS ((struct type *, char *, GDB_FILE *));
+extern void
+print_binary_chars PARAMS ((GDB_FILE *, unsigned char *, unsigned int));
+
+extern void
+print_octal_chars PARAMS ((GDB_FILE *, unsigned char *, unsigned int));
+
+extern void
+print_decimal_chars PARAMS ((GDB_FILE *, unsigned char *, unsigned int));
+
diff --git a/contrib/gdb/gdb/value.h b/contrib/gdb/gdb/value.h
index 2363695..44c70de 100644
--- a/contrib/gdb/gdb/value.h
+++ b/contrib/gdb/gdb/value.h
@@ -1,5 +1,6 @@
/* Definitions for values of C expressions, for GDB.
- Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -60,7 +61,9 @@ struct value
lval_reg_frame_relative. */
int regnum;
} location;
- /* Describes offset of a value within lval a structure in bytes. */
+ /* Describes offset of a value within lval of a structure in bytes.
+ This is used in retrieving contents from target memory. [Note also
+ the member embedded_offset below.] */
int offset;
/* Only used for bitfields; number of bits contained in them. */
int bitsize;
@@ -76,6 +79,14 @@ struct value
CORE_ADDR frame_addr;
/* Type of the value. */
struct type *type;
+ /* Type of the enclosing object if this is an embedded subobject.
+ The member embedded_offset gives the real position of the subobject
+ if type is not the same as enclosing_type.
+
+ If the type field is a pointer type, then enclosing_type is
+ a pointer type pointing to the real (enclosing) type of the target
+ object. */
+ struct type *enclosing_type;
/* Values are stored in a chain, so that they can be deleted
easily over calls to the inferior. Values assigned to internal
variables or put into the value history are taken off this
@@ -100,22 +111,41 @@ struct value
/* If nonzero, this is the value of a variable which does not
actually exist in the program. */
char optimized_out;
+ /* If this value represents an object that is embedded inside a
+ larger object (e.g., a base subobject in C++), this gives the
+ offset (in bytes) from the start of the contents buffer where
+ the embedded object begins. This is required because some C++
+ runtime implementations lay out objects (especially virtual bases
+ with possibly negative offsets to ancestors).
+ Note: This may be positive or negative! Also note that this offset
+ is not used when retrieving contents from target memory; the entire
+ enclosing object has to be retrieved always, and the offset for
+ that is given by the member offset above. */
+ int embedded_offset;
+ /* If this value represents a pointer to an object that is embedded
+ in another object, this gives the embedded_offset of the object
+ that is pointed to. */
+ int pointed_to_offset;
+ /* The BFD section associated with this value. */
+ asection *bfd_section;
/* Actual contents of the value. For use of this value; setting
it uses the stuff above. Not valid if lazy is nonzero.
Target byte-order. We force it to be aligned properly for any
- possible value. */
+ possible value. Note that a value therefore extends beyond
+ what is declared here. */
union {
long contents[1];
double force_double_align;
LONGEST force_longlong_align;
char *literal_data;
} aligner;
-
+ /* Do not add any new members here -- contents above will trash them */
};
typedef struct value *value_ptr;
#define VALUE_TYPE(val) (val)->type
+#define VALUE_ENCLOSING_TYPE(val) (val)->enclosing_type
#define VALUE_LAZY(val) (val)->lazy
/* VALUE_CONTENTS and VALUE_CONTENTS_RAW both return the address of
the gdb buffer used to hold a copy of the contents of the lval.
@@ -123,10 +153,23 @@ typedef struct value *value_ptr;
it uses value_fetch_lazy() to load the buffer from the process being
debugged if it hasn't already been loaded. VALUE_CONTENTS_RAW is
used when data is being stored into the buffer, or when it is
- certain that the contents of the buffer are valid. */
-#define VALUE_CONTENTS_RAW(val) ((char *) (val)->aligner.contents)
+ certain that the contents of the buffer are valid.
+ Note: The contents pointer is adjusted by the offset required to
+ get to the real subobject, if the value happens to represent
+ something embedded in a larger run-time object. */
+
+#define VALUE_CONTENTS_RAW(val) ((char *) (val)->aligner.contents + (val)->embedded_offset)
#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\
VALUE_CONTENTS_RAW(val))
+
+/* The ALL variants of the above two macros do not adjust the returned
+ pointer by the embedded_offset value. */
+
+#define VALUE_CONTENTS_ALL_RAW(val) ((char *) (val)->aligner.contents)
+#define VALUE_CONTENTS_ALL(val) ((void) (VALUE_LAZY(val) && value_fetch_lazy(val)),\
+ VALUE_CONTENTS_ALL_RAW(val))
+
+
extern int value_fetch_lazy PARAMS ((value_ptr val));
#define VALUE_LVAL(val) (val)->lval
@@ -140,14 +183,20 @@ extern int value_fetch_lazy PARAMS ((value_ptr val));
#define VALUE_NEXT(val) (val)->next
#define VALUE_REGNO(val) (val)->regno
#define VALUE_OPTIMIZED_OUT(val) ((val)->optimized_out)
+#define VALUE_EMBEDDED_OFFSET(val) ((val)->embedded_offset)
+#define VALUE_POINTED_TO_OFFSET(val) ((val)->pointed_to_offset)
+#define VALUE_BFD_SECTION(val) ((val)->bfd_section)
/* Convert a REF to the object referenced. */
#define COERCE_REF(arg) \
-{ if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_REF) \
- arg = value_at_lazy (TYPE_TARGET_TYPE (VALUE_TYPE (arg)), \
- unpack_long (VALUE_TYPE (arg), \
- VALUE_CONTENTS (arg)));}
+do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\
+ if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF) \
+ arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), \
+ unpack_long (VALUE_TYPE (arg), \
+ VALUE_CONTENTS (arg)), \
+ VALUE_BFD_SECTION (arg)); \
+ } while (0)
/* If ARG is an array, convert it to a pointer.
If ARG is an enum, convert it to an integer.
@@ -174,7 +223,7 @@ do { COERCE_REF(arg); \
/* If ARG is an enum, convert it to an integer. */
#define COERCE_ENUM(arg) { \
- if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) \
+ if (TYPE_CODE (check_typedef (VALUE_TYPE (arg))) == TYPE_CODE_ENUM) \
arg = value_cast (builtin_type_unsigned_int, arg); \
}
@@ -227,9 +276,9 @@ extern value_ptr value_from_longest PARAMS ((struct type *type, LONGEST num));
extern value_ptr value_from_double PARAMS ((struct type *type, DOUBLEST num));
-extern value_ptr value_at PARAMS ((struct type *type, CORE_ADDR addr));
+extern value_ptr value_at PARAMS ((struct type *type, CORE_ADDR addr, asection *sect));
-extern value_ptr value_at_lazy PARAMS ((struct type *type, CORE_ADDR addr));
+extern value_ptr value_at_lazy PARAMS ((struct type *type, CORE_ADDR addr, asection *sect));
extern value_ptr value_from_register PARAMS ((struct type *type, int regnum,
struct frame_info * frame));
@@ -294,12 +343,26 @@ extern value_ptr value_struct_elt_for_reference PARAMS ((struct type *domain,
char *name,
struct type *intype));
+extern value_ptr value_static_field PARAMS ((struct type *type, int fieldno));
+
+extern struct fn_field *
+value_find_oload_method_list PARAMS ((value_ptr *, char *, int, int *, int *, struct type **, int *));
+
extern value_ptr value_field PARAMS ((value_ptr arg1, int fieldno));
extern value_ptr value_primitive_field PARAMS ((value_ptr arg1, int offset,
int fieldno,
struct type *arg_type));
+extern struct type *
+value_rtti_type PARAMS ((value_ptr, int *, int *, int *));
+
+extern struct type *
+value_rtti_target_type PARAMS ((value_ptr, int *, int *, int *));
+
+extern value_ptr
+value_full_object PARAMS ((value_ptr, struct type *, int, int, int));
+
extern value_ptr value_cast PARAMS ((struct type *type, value_ptr arg2));
extern value_ptr value_zero PARAMS ((struct type *type, enum lval_type lv));
@@ -366,9 +429,11 @@ extern value_ptr value_of_this PARAMS ((int complain));
extern value_ptr value_x_binop PARAMS ((value_ptr arg1, value_ptr arg2,
enum exp_opcode op,
- enum exp_opcode otherop));
+ enum exp_opcode otherop,
+ enum noside noside));
-extern value_ptr value_x_unop PARAMS ((value_ptr arg1, enum exp_opcode op));
+extern value_ptr value_x_unop PARAMS ((value_ptr arg1, enum exp_opcode op,
+ enum noside noside));
extern value_ptr value_fn_field PARAMS ((value_ptr *arg1p, struct fn_field *f,
int j,
@@ -407,10 +472,16 @@ read_register_gen PARAMS ((int regno, char *myaddr));
extern CORE_ADDR
read_register PARAMS ((int regno));
+extern CORE_ADDR
+read_register_pid PARAMS ((int regno, int pid));
+
extern void
write_register PARAMS ((int regno, LONGEST val));
extern void
+write_register_pid PARAMS ((int regno, CORE_ADDR val, int pid));
+
+extern void
supply_register PARAMS ((int regno, char *val));
extern void
@@ -447,12 +518,12 @@ extern value_ptr
value_release_to_mark PARAMS ((value_ptr mark));
extern int
-val_print PARAMS ((struct type *type, char *valaddr, CORE_ADDR address,
+val_print PARAMS ((struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address,
GDB_FILE *stream, int format, int deref_ref,
int recurse, enum val_prettyprint pretty));
extern int
-val_print_string PARAMS ((CORE_ADDR addr, unsigned int len, GDB_FILE *stream));
+val_print_string PARAMS ((CORE_ADDR addr, int len, int width, GDB_FILE *stream));
extern void
print_variable_value PARAMS ((struct symbol *var, struct frame_info *frame,
@@ -488,4 +559,10 @@ extern value_ptr call_function_by_hand PARAMS ((value_ptr, int, value_ptr *));
extern value_ptr value_literal_complex PARAMS ((value_ptr, value_ptr, struct type*));
+extern void find_rt_vbase_offset PARAMS ((struct type *, struct type *, char *, int, int *, int *));
+
+extern value_ptr find_function_in_inferior PARAMS ((char *));
+
+extern value_ptr value_allocate_space_in_inferior PARAMS ((int));
+
#endif /* !defined (VALUE_H) */
diff --git a/contrib/gdb/gdb/values.c b/contrib/gdb/gdb/values.c
index a3b6abd..c7053b8 100644
--- a/contrib/gdb/gdb/values.c
+++ b/contrib/gdb/gdb/values.c
@@ -1,5 +1,5 @@
/* Low level packing and unpacking of values for GDB, the GNU Debugger.
- Copyright 1986, 1987, 1989, 1991, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 91, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -32,7 +32,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "scm-lang.h"
#include "demangle.h"
-/* Local function prototypes. */
+/* Prototypes for exported functions. */
+
+void _initialize_values PARAMS ((void));
+
+/* Prototypes for local functions. */
static value_ptr value_headof PARAMS ((value_ptr, struct type *,
struct type *));
@@ -41,6 +45,8 @@ static void show_values PARAMS ((char *, int));
static void show_convenience PARAMS ((char *, int));
+static int vb_match PARAMS ((struct type *, int, struct type *));
+
/* The value-history records all the values printed
by print commands during this session. Each chunk
records 60 consecutive values. The first chunk on
@@ -80,6 +86,7 @@ allocate_value (type)
VALUE_NEXT (val) = all_values;
all_values = val;
VALUE_TYPE (val) = type;
+ VALUE_ENCLOSING_TYPE (val) = type;
VALUE_LVAL (val) = not_lval;
VALUE_ADDRESS (val) = 0;
VALUE_FRAME (val) = 0;
@@ -89,6 +96,9 @@ allocate_value (type)
VALUE_REGNO (val) = -1;
VALUE_LAZY (val) = 0;
VALUE_OPTIMIZED_OUT (val) = 0;
+ VALUE_BFD_SECTION (val) = NULL;
+ VALUE_EMBEDDED_OFFSET (val) = 0;
+ VALUE_POINTED_TO_OFFSET (val) = 0;
val->modifiable = 1;
return val;
}
@@ -206,8 +216,9 @@ value_ptr
value_copy (arg)
value_ptr arg;
{
- register struct type *type = VALUE_TYPE (arg);
- register value_ptr val = allocate_value (type);
+ register struct type *encl_type = VALUE_ENCLOSING_TYPE (arg);
+ register value_ptr val = allocate_value (encl_type);
+ VALUE_TYPE (val) = VALUE_TYPE (arg);
VALUE_LVAL (val) = VALUE_LVAL (arg);
VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
VALUE_OFFSET (val) = VALUE_OFFSET (arg);
@@ -217,11 +228,15 @@ value_copy (arg)
VALUE_REGNO (val) = VALUE_REGNO (arg);
VALUE_LAZY (val) = VALUE_LAZY (arg);
VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg);
+ VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (arg);
+ VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (arg);
+ VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (arg);
val->modifiable = arg->modifiable;
if (!VALUE_LAZY (val))
{
- memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS_RAW (arg),
- TYPE_LENGTH (VALUE_TYPE (arg)));
+ memcpy (VALUE_CONTENTS_ALL_RAW (val), VALUE_CONTENTS_ALL_RAW (arg),
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg)));
+
}
return val;
}
@@ -630,6 +645,10 @@ unpack_long (type, valaddr)
case TYPE_CODE_REF:
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
+#ifdef GDB_TARGET_IS_D10V
+ if (len == 2)
+ return D10V_MAKE_DADDR(extract_address (valaddr, len));
+#endif
return extract_address (valaddr, len);
case TYPE_CODE_MEMBER:
@@ -653,12 +672,15 @@ unpack_double (type, valaddr, invp)
char *valaddr;
int *invp;
{
- register enum type_code code = TYPE_CODE (type);
- register int len = TYPE_LENGTH (type);
- register int nosign = TYPE_UNSIGNED (type);
+ enum type_code code;
+ int len;
+ int nosign;
*invp = 0; /* Assume valid. */
CHECK_TYPEDEF (type);
+ code = TYPE_CODE (type);
+ len = TYPE_LENGTH (type);
+ nosign = TYPE_UNSIGNED (type);
if (code == TYPE_CODE_FLT)
{
#ifdef INVALID_FLOAT
@@ -673,7 +695,12 @@ unpack_double (type, valaddr, invp)
else if (nosign)
{
/* Unsigned -- be sure we compensate for signed LONGEST. */
- return (unsigned LONGEST) unpack_long (type, valaddr);
+#if !defined (_MSC_VER) || (_MSC_VER > 900)
+ return (ULONGEST) unpack_long (type, valaddr);
+#else
+ /* FIXME!!! msvc22 doesn't support unsigned __int64 -> double */
+ return (LONGEST) unpack_long (type, valaddr);
+#endif /* _MSC_VER */
}
else
{
@@ -705,12 +732,51 @@ unpack_pointer (type, valaddr)
return unpack_long (type, valaddr);
}
+/* Get the value of the FIELDN'th field (which must be static) of TYPE. */
+
+value_ptr
+value_static_field (type, fieldno)
+ struct type *type;
+ int fieldno;
+{
+ CORE_ADDR addr;
+ asection *sect;
+ if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno))
+ {
+ addr = TYPE_FIELD_STATIC_PHYSADDR (type, fieldno);
+ sect = NULL;
+ }
+ else
+ {
+ char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+ struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
+ if (sym == NULL)
+ {
+ /* With some compilers, e.g. HP aCC, static data members are reported
+ as non-debuggable symbols */
+ struct minimal_symbol * msym = lookup_minimal_symbol (phys_name, NULL, NULL);
+ if (!msym)
+ return NULL;
+ else
+ {
+ addr = SYMBOL_VALUE_ADDRESS (msym);
+ sect = SYMBOL_BFD_SECTION (msym);
+ }
+ }
+ else
+ {
+ addr = SYMBOL_VALUE_ADDRESS (sym);
+ sect = SYMBOL_BFD_SECTION (sym);
+ }
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), addr);
+ }
+ return value_at (TYPE_FIELD_TYPE (type, fieldno), addr, sect);
+}
+
/* Given a value ARG1 (offset by OFFSET bytes)
of a struct or union type ARG_TYPE,
- extract and return the value of one of its fields.
- FIELDNO says which field.
-
- For C++, must also be able to return values from static fields */
+ extract and return the value of one of its (non-static) fields.
+ FIELDNO says which field. */
value_ptr
value_primitive_field (arg1, offset, fieldno, arg_type)
@@ -727,38 +793,59 @@ value_primitive_field (arg1, offset, fieldno, arg_type)
/* Handle packed fields */
- offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
{
v = value_from_longest (type,
- unpack_field_as_long (arg_type,
- VALUE_CONTENTS (arg1),
- fieldno));
+ unpack_field_as_long (arg_type,
+ VALUE_CONTENTS (arg1)
+ + offset,
+ fieldno));
VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
}
+ else if (fieldno < TYPE_N_BASECLASSES (arg_type))
+ {
+ /* This field is actually a base subobject, so preserve the
+ entire object's contents for later references to virtual
+ bases, etc. */
+ v = allocate_value (VALUE_ENCLOSING_TYPE (arg1));
+ VALUE_TYPE (v) = arg_type;
+ if (VALUE_LAZY (arg1))
+ VALUE_LAZY (v) = 1;
+ else
+ memcpy (VALUE_CONTENTS_ALL_RAW (v), VALUE_CONTENTS_ALL_RAW (arg1),
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg1)));
+ VALUE_OFFSET (v) = VALUE_OFFSET (arg1);
+ VALUE_EMBEDDED_OFFSET (v)
+ = offset +
+ VALUE_EMBEDDED_OFFSET (arg1) +
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+ }
else
{
+ /* Plain old data member */
+ offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
v = allocate_value (type);
if (VALUE_LAZY (arg1))
VALUE_LAZY (v) = 1;
else
- memcpy (VALUE_CONTENTS_RAW (v), VALUE_CONTENTS_RAW (arg1) + offset,
+ memcpy (VALUE_CONTENTS_RAW (v),
+ VALUE_CONTENTS_RAW (arg1) + offset,
TYPE_LENGTH (type));
+ VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset;
}
VALUE_LVAL (v) = VALUE_LVAL (arg1);
if (VALUE_LVAL (arg1) == lval_internalvar)
VALUE_LVAL (v) = lval_internalvar_component;
VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
- VALUE_OFFSET (v) = offset + VALUE_OFFSET (arg1);
+/* VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */
return v;
}
/* Given a value ARG1 of a struct or union type,
- extract and return the value of one of its fields.
- FIELDNO says which field.
-
- For C++, must also be able to return values from static fields */
+ extract and return the value of one of its (non-static) fields.
+ FIELDNO says which field. */
value_ptr
value_field (arg1, fieldno)
@@ -829,74 +916,182 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
{
value_ptr arg1 = *arg1p;
struct type *type1 = check_typedef (VALUE_TYPE (arg1));
- struct type *entry_type;
- /* First, get the virtual function table pointer. That comes
- with a strange type, so cast it to type `pointer to long' (which
- should serve just fine as a function type). Then, index into
- the table, and convert final value to appropriate function type. */
- value_ptr entry, vfn, vtbl;
- value_ptr vi = value_from_longest (builtin_type_int,
- (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
- struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
- struct type *context;
- if (fcontext == NULL)
- /* We don't have an fcontext (e.g. the program was compiled with
- g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE.
- This won't work right for multiple inheritance, but at least we
- should do as well as GDB 3.x did. */
- fcontext = TYPE_VPTR_BASETYPE (type);
- context = lookup_pointer_type (fcontext);
- /* Now context is a pointer to the basetype containing the vtbl. */
- if (TYPE_TARGET_TYPE (context) != type1)
- {
- arg1 = value_ind (value_cast (context, value_addr (arg1)));
- type1 = check_typedef (VALUE_TYPE (arg1));
- }
- context = type1;
- /* Now context is the basetype containing the vtbl. */
-
- /* This type may have been defined before its virtual function table
- was. If so, fill in the virtual function table entry for the
- type now. */
- if (TYPE_VPTR_FIELDNO (context) < 0)
- fill_in_vptr_fieldno (context);
-
- /* The virtual function table is now an array of structures
- which have the form { int16 offset, delta; void *pfn; }. */
- vtbl = value_ind (value_primitive_field (arg1, 0,
- TYPE_VPTR_FIELDNO (context),
- TYPE_VPTR_BASETYPE (context)));
-
- /* Index into the virtual function table. This is hard-coded because
- looking up a field is not cheap, and it may be important to save
- time, e.g. if the user has set a conditional breakpoint calling
- a virtual function. */
- entry = value_subscript (vtbl, vi);
- entry_type = check_typedef (VALUE_TYPE (entry));
-
- if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
+ if (TYPE_HAS_VTABLE (type))
{
- /* Move the `this' pointer according to the virtual function table. */
- VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
+ /* Deal with HP/Taligent runtime model for virtual functions */
+ value_ptr vp;
+ value_ptr argp; /* arg1 cast to base */
+ CORE_ADDR vfunc_addr; /* address of virtual method */
+ CORE_ADDR coreptr; /* pointer to target address */
+ int class_index; /* which class segment pointer to use */
+ struct type * ftype = TYPE_FN_FIELD_TYPE (f, j); /* method type */
+
+ argp = value_cast (type, *arg1p);
+
+ if (VALUE_ADDRESS (argp) == 0)
+ error ("Address of object is null; object may not have been created.");
+
+ /* pai: FIXME -- 32x64 possible problem? */
+ /* First word (4 bytes) in object layout is the vtable pointer */
+ coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (argp)); /* pai: (temp) */
+ /* + offset + VALUE_EMBEDDED_OFFSET (argp)); */
+
+ if (!coreptr)
+ error ("Virtual table pointer is null for object; object may not have been created.");
- if (! VALUE_LAZY (arg1))
+ /* pai/1997-05-09
+ * FIXME: The code here currently handles only
+ * the non-RRBC case of the Taligent/HP runtime spec; when RRBC
+ * is introduced, the condition for the "if" below will have to
+ * be changed to be a test for the RRBC case. */
+
+ if (1)
+ {
+ /* Non-RRBC case; the virtual function pointers are stored at fixed
+ * offsets in the virtual table. */
+
+ /* Retrieve the offset in the virtual table from the debug
+ * info. The offset of the vfunc's entry is in words from
+ * the beginning of the vtable; but first we have to adjust
+ * by HP_ACC_VFUNC_START to account for other entries */
+
+ /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in
+ * which case the multiplier should be 8 and values should be long */
+ vp = value_at (builtin_type_int,
+ coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) + HP_ACC_VFUNC_START), NULL);
+
+ coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (vp));
+ /* coreptr now contains the address of the virtual function */
+ /* (Actually, it contains the pointer to the plabel for the function. */
+ }
+ else
+ {
+ /* RRBC case; the virtual function pointers are found by double
+ * indirection through the class segment tables. */
+
+ /* Choose class segment depending on type we were passed */
+ class_index = class_index_in_primary_list (type);
+
+ /* Find class segment pointer. These are in the vtable slots after
+ * some other entries, so adjust by HP_ACC_VFUNC_START for that. */
+ /* pai: FIXME 32x64 problem here, if words are 8 bytes long
+ * the multiplier below has to be 8 and value should be long. */
+ vp = value_at (builtin_type_int,
+ coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL);
+ /* Indirect once more, offset by function index */
+ /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */
+ coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (vp) + 4 * TYPE_FN_FIELD_VOFFSET (f, j));
+ vp = value_at (builtin_type_int, coreptr, NULL);
+ coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (vp));
+
+ /* coreptr now contains the address of the virtual function */
+ /* (Actually, it contains the pointer to the plabel for the function.) */
+
+ }
+
+ if (!coreptr)
+ error ("Address of virtual function is null; error in virtual table?");
+
+ /* Wrap this addr in a value and return pointer */
+ vp = allocate_value (ftype);
+ VALUE_TYPE (vp) = ftype;
+ VALUE_ADDRESS (vp) = coreptr;
+
+ /* pai: (temp) do we need the value_ind stuff in value_fn_field? */
+ return vp;
+ }
+ else
+ { /* Not using HP/Taligent runtime conventions; so try to
+ * use g++ conventions for virtual table */
+
+ struct type *entry_type;
+ /* First, get the virtual function table pointer. That comes
+ with a strange type, so cast it to type `pointer to long' (which
+ should serve just fine as a function type). Then, index into
+ the table, and convert final value to appropriate function type. */
+ value_ptr entry, vfn, vtbl;
+ value_ptr vi = value_from_longest (builtin_type_int,
+ (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+ struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
+ struct type *context;
+ if (fcontext == NULL)
+ /* We don't have an fcontext (e.g. the program was compiled with
+ g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE.
+ This won't work right for multiple inheritance, but at least we
+ should do as well as GDB 3.x did. */
+ fcontext = TYPE_VPTR_BASETYPE (type);
+ context = lookup_pointer_type (fcontext);
+ /* Now context is a pointer to the basetype containing the vtbl. */
+ if (TYPE_TARGET_TYPE (context) != type1)
+ {
+ value_ptr tmp = value_cast (context, value_addr (arg1));
+ VALUE_POINTED_TO_OFFSET (tmp) = 0;
+ arg1 = value_ind (tmp);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ }
+
+ context = type1;
+ /* Now context is the basetype containing the vtbl. */
+
+ /* This type may have been defined before its virtual function table
+ was. If so, fill in the virtual function table entry for the
+ type now. */
+ if (TYPE_VPTR_FIELDNO (context) < 0)
+ fill_in_vptr_fieldno (context);
+
+ /* The virtual function table is now an array of structures
+ which have the form { int16 offset, delta; void *pfn; }. */
+ vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
+ TYPE_VPTR_BASETYPE (context));
+
+ /* With older versions of g++, the vtbl field pointed to an array
+ of structures. Nowadays it points directly to the structure. */
+ if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY)
{
- VALUE_LAZY (arg1) = 1;
- value_fetch_lazy (arg1);
+ /* Handle the case where the vtbl field points to an
+ array of structures. */
+ vtbl = value_ind (vtbl);
+
+ /* Index into the virtual function table. This is hard-coded because
+ looking up a field is not cheap, and it may be important to save
+ time, e.g. if the user has set a conditional breakpoint calling
+ a virtual function. */
+ entry = value_subscript (vtbl, vi);
+ }
+ else
+ {
+ /* Handle the case where the vtbl field points directly to a structure. */
+ vtbl = value_add (vtbl, vi);
+ entry = value_ind (vtbl);
}
- vfn = value_field (entry, 2);
- }
- else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
- vfn = entry;
- else
- error ("I'm confused: virtual function table has bad type");
- /* Reinstantiate the function pointer with the correct type. */
- VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
+ entry_type = check_typedef (VALUE_TYPE (entry));
+
+ if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
+ {
+ /* Move the `this' pointer according to the virtual function table. */
+ VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
- *arg1p = arg1;
- return vfn;
+ if (! VALUE_LAZY (arg1))
+ {
+ VALUE_LAZY (arg1) = 1;
+ value_fetch_lazy (arg1);
+ }
+
+ vfn = value_field (entry, 2);
+ }
+ else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
+ vfn = entry;
+ else
+ error ("I'm confused: virtual function table has bad type");
+ /* Reinstantiate the function pointer with the correct type. */
+ VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
+
+ *arg1p = arg1;
+ return vfn;
+ }
}
/* ARG is a pointer to an object we know to be at least
@@ -1136,13 +1331,16 @@ unpack_field_as_long (type, valaddr, fieldno)
char *valaddr;
int fieldno;
{
- unsigned LONGEST val;
- unsigned LONGEST valmask;
+ ULONGEST val;
+ ULONGEST valmask;
int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
int lsbcount;
+ struct type *field_type;
val = extract_unsigned_integer (valaddr + bitpos / 8, sizeof (val));
+ field_type = TYPE_FIELD_TYPE (type, fieldno);
+ CHECK_TYPEDEF (field_type);
/* Extract bits. See comment above. */
@@ -1157,9 +1355,9 @@ unpack_field_as_long (type, valaddr, fieldno)
if ((bitsize > 0) && (bitsize < 8 * (int) sizeof (val)))
{
- valmask = (((unsigned LONGEST) 1) << bitsize) - 1;
+ valmask = (((ULONGEST) 1) << bitsize) - 1;
val &= valmask;
- if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno)))
+ if (!TYPE_UNSIGNED (field_type))
{
if (val & (valmask ^ (valmask >> 1)))
{
@@ -1209,9 +1407,9 @@ modify_field (addr, fieldval, bitpos, bitsize)
/* Mask out old value, while avoiding shifts >= size of oword */
if (bitsize < 8 * (int) sizeof (oword))
- oword &= ~(((((unsigned LONGEST)1) << bitsize) - 1) << bitpos);
+ oword &= ~(((((ULONGEST)1) << bitsize) - 1) << bitpos);
else
- oword &= ~((~(unsigned LONGEST)0) << bitpos);
+ oword &= ~((~(ULONGEST)0) << bitpos);
oword |= fieldval << bitpos;
store_signed_integer (addr, sizeof oword, oword);
@@ -1250,9 +1448,9 @@ value_from_longest (type, num)
have the same form. */
store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num);
break;
-
+
default:
- error ("Unexpected type encountered for integer constant.");
+ error ("Unexpected type (%d) encountered for integer constant.", code);
}
return val;
}
@@ -1307,7 +1505,7 @@ value_being_returned (valtype, retbuf, struct_return)
addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf);
if (!addr)
error ("Function return value unknown");
- return value_at (valtype, addr);
+ return value_at (valtype, addr, NULL);
}
#endif
@@ -1332,14 +1530,21 @@ value_being_returned (valtype, retbuf, struct_return)
2.0-2.3.3. This is somewhat unfortunate, but changing gcc2_compiled
would cause more chaos than dealing with some struct returns being
handled wrong. */
-#if !defined (USE_STRUCT_CONVENTION)
-#define USE_STRUCT_CONVENTION(gcc_p, type)\
- (!((gcc_p == 1) && (TYPE_LENGTH (value_type) == 1 \
- || TYPE_LENGTH (value_type) == 2 \
- || TYPE_LENGTH (value_type) == 4 \
- || TYPE_LENGTH (value_type) == 8 \
- ) \
- ))
+
+int
+generic_use_struct_convention (gcc_p, value_type)
+ int gcc_p;
+ struct type *value_type;
+{
+ return !((gcc_p == 1)
+ && (TYPE_LENGTH (value_type) == 1
+ || TYPE_LENGTH (value_type) == 2
+ || TYPE_LENGTH (value_type) == 4
+ || TYPE_LENGTH (value_type) == 8));
+}
+
+#ifndef USE_STRUCT_CONVENTION
+#define USE_STRUCT_CONVENTION(gcc_p,type) generic_use_struct_convention (gcc_p, type)
#endif
/* Some fundamental types (such as long double) are returned on the stack for
diff --git a/contrib/gdb/gdb/xcoffread.c b/contrib/gdb/gdb/xcoffread.c
index 7704a5f..0cf9371 100644
--- a/contrib/gdb/gdb/xcoffread.c
+++ b/contrib/gdb/gdb/xcoffread.c
@@ -1,5 +1,5 @@
/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
@@ -20,12 +20,6 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* RS/6000 and PowerPC only:
- Needs xcoff_add_toc_to_loadinfo and xcoff_init_loadinfo in
- rs6000-tdep.c from target.
- However, if you define FAKING_RS6000, then this code will link with
- any target. */
-
#include "defs.h"
#include "bfd.h"
@@ -180,6 +174,9 @@ struct coff_symfile_info {
/* Number of symbols in symtbl. */
int symtbl_num_syms;
+
+ /* Offset in data section to TOC anchor. */
+ CORE_ADDR toc_offset;
};
static struct complaint storclass_complaint =
@@ -195,6 +192,18 @@ static struct complaint eb_complaint =
{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
static void
+xcoff_initial_scan PARAMS ((struct objfile *, struct section_offsets *, int));
+
+static void
+scan_xcoff_symtab PARAMS ((struct section_offsets *, struct objfile *));
+
+static char *
+xcoff_next_symbol_text PARAMS ((struct objfile *));
+
+static void
+record_include_begin PARAMS ((struct coff_symbol *));
+
+static void
enter_line_range PARAMS ((struct subfile *, unsigned, unsigned,
CORE_ADDR, CORE_ADDR, unsigned *));
@@ -234,17 +243,33 @@ process_xcoff_symbol PARAMS ((struct coff_symbol *, struct objfile *));
static void
read_xcoff_symtab PARAMS ((struct partial_symtab *));
+#if 0
static void
add_stab_to_list PARAMS ((char *, struct pending_stabs **));
+#endif
+
+static int
+compare_lte PARAMS ((const void *, const void *));
+
+static struct linetable *
+arrange_linetable PARAMS ((struct linetable *));
+
+static void
+record_include_end PARAMS ((struct coff_symbol *));
+
+static void
+process_linenos PARAMS ((CORE_ADDR, CORE_ADDR));
/* Translate from a COFF section number (target_index) to a SECT_OFF_*
code. */
static int secnum_to_section PARAMS ((int, struct objfile *));
+static asection * secnum_to_bfd_section PARAMS ((int, struct objfile *));
struct find_targ_sec_arg {
int targ_index;
int *resultp;
+ asection **bfd_sect;
};
static void find_targ_sec PARAMS ((bfd *, asection *, void *));
@@ -264,6 +289,7 @@ static void find_targ_sec (abfd, sect, obj)
*args->resultp = SECT_OFF_DATA;
else
*args->resultp = SECT_OFF_BSS;
+ *args->bfd_sect = sect;
}
}
@@ -274,15 +300,35 @@ secnum_to_section (secnum, objfile)
struct objfile *objfile;
{
int off = SECT_OFF_TEXT;
+ asection *sect = NULL;
struct find_targ_sec_arg args;
args.targ_index = secnum;
args.resultp = &off;
+ args.bfd_sect = &sect;
bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
return off;
}
+
+/* Return the BFD section that CS points to. */
+static asection *
+secnum_to_bfd_section (secnum, objfile)
+ int secnum;
+ struct objfile *objfile;
+{
+ int off = SECT_OFF_TEXT;
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ args.targ_index = secnum;
+ args.resultp = &off;
+ args.bfd_sect = &sect;
+ bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ return sect;
+}
/* add a given stab string into given stab vector. */
+#if 0
+
static void
add_stab_to_list (stabname, stabvector)
char *stabname;
@@ -303,6 +349,9 @@ struct pending_stabs **stabvector;
}
(*stabvector)->stab [(*stabvector)->count++] = stabname;
}
+
+#endif
+
/* Linenos are processed on a file-by-file basis.
@@ -359,14 +408,17 @@ struct pending_stabs **stabvector;
/* compare line table entry addresses. */
static int
-compare_lte (lte1, lte2)
- struct linetable_entry *lte1, *lte2;
+compare_lte (lte1p, lte2p)
+ const void *lte1p;
+ const void *lte2p;
{
+ struct linetable_entry *lte1 = (struct linetable_entry *) lte1p;
+ struct linetable_entry *lte2 = (struct linetable_entry *) lte2p;
return lte1->pc - lte2->pc;
}
-/* Give a line table with function entries are marked, arrange its functions
- in assending order and strip off function entry markers and return it in
+/* Given a line table with function entries are marked, arrange its functions
+ in ascending order and strip off function entry markers and return it in
a newly created table. If the old one is good enough, return the old one. */
/* FIXME: I think all this stuff can be replaced by just passing
sort_linevec = 1 to end_symtab. */
@@ -822,7 +874,7 @@ enter_line_range (subfile, beginoffset, endoffset, startaddr, endaddr,
namestr = (NAME); \
if (namestr[0] == '.') ++namestr; \
prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \
- (char *)NULL, (SECTION), (OBJFILE)); \
+ (char *)NULL, (SECTION), (asection *)NULL, (OBJFILE)); \
misc_func_recorded = 1; \
}
@@ -847,6 +899,7 @@ static char *raw_symbol;
/* This is the function which stabsread.c calls to get symbol
continuations. */
+
static char *
xcoff_next_symbol_text (objfile)
struct objfile *objfile;
@@ -936,6 +989,7 @@ read_xcoff_symtab (pst)
start_stabs ();
start_symtab (filestring, (char *)NULL, file_start_addr);
+ record_debugformat ("XCOFF");
symnum = ((struct symloc *)pst->read_symtab_private)->first_symnum;
max_symnum =
symnum + ((struct symloc *)pst->read_symtab_private)->numsyms;
@@ -1029,6 +1083,7 @@ read_xcoff_symtab (pst)
start_stabs ();
start_symtab ("_globals_", (char *)NULL, (CORE_ADDR)0);
+ record_debugformat ("XCOFF");
cur_src_end_addr = first_object_file_end;
/* done with all files, everything from here on is globals */
}
@@ -1093,6 +1148,7 @@ read_xcoff_symtab (pst)
/* Give all csects for this source file the same
name. */
start_symtab (filestring, NULL, (CORE_ADDR)0);
+ record_debugformat ("XCOFF");
}
/* If this is the very first csect seen,
@@ -1221,6 +1277,7 @@ read_xcoff_symtab (pst)
start_stabs ();
start_symtab (filestring, (char *)NULL, (CORE_ADDR)0);
+ record_debugformat ("XCOFF");
last_csect_name = 0;
/* reset file start and end addresses. A compilation unit with no text
@@ -1410,7 +1467,7 @@ read_xcoff_symtab (pst)
#define SYMNAME_ALLOC(NAME, ALLOCED) \
- (ALLOCED) ? (NAME) : obstack_copy0 (&objfile->symbol_obstack, (NAME), strlen (NAME));
+ (ALLOCED) ? (NAME) : obsavestring ((NAME), strlen (NAME), &objfile->symbol_obstack);
static struct type *func_symbol_type;
@@ -1554,9 +1611,8 @@ process_xcoff_symbol (cs, objfile)
return sym2;
}
-/* Extract the file name from the aux entry of a C_FILE symbol. Return
- only the last component of the name. Result is in static storage and
- is only good for temporary use. */
+/* Extract the file name from the aux entry of a C_FILE symbol.
+ Result is in static storage and is only good for temporary use. */
static char *
coff_getfilename (aux_entry, objfile)
@@ -1564,8 +1620,6 @@ coff_getfilename (aux_entry, objfile)
struct objfile *objfile;
{
static char buffer[BUFSIZ];
- register char *temp;
- char *result;
if (aux_entry->x_file.x_n.x_zeroes == 0)
strcpy (buffer,
@@ -1576,14 +1630,7 @@ coff_getfilename (aux_entry, objfile)
strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
buffer[FILNMLEN] = '\0';
}
- result = buffer;
-
- /* FIXME: We should not be throwing away the information about what
- directory. It should go into dirname of the symtab, or some such
- place. */
- if ((temp = strrchr (result, '/')) != NULL)
- result = temp + 1;
- return (result);
+ return (buffer);
}
/* Set *SYMBOL to symbol number symno in symtbl. */
@@ -1762,7 +1809,7 @@ xcoff_psymtab_to_symtab_1 (pst)
/* Init stuff necessary for reading in symbols. */
stabsread_init ();
buildsym_init ();
- old_chain = make_cleanup (really_free_pendings, 0);
+ old_chain = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
read_xcoff_symtab (pst);
sort_symtab_syms (pst->symtab);
@@ -1972,7 +2019,7 @@ xcoff_start_psymtab (objfile, section_offsets,
static struct partial_symtab *xcoff_end_psymtab
PARAMS ((struct partial_symtab *, char **, int, int,
- struct partial_symtab **, int));
+ struct partial_symtab **, int, int));
/* Close off the current usage of PST.
Returns PST, or NULL if the partial symtab was empty and thrown away.
@@ -1984,13 +2031,14 @@ static struct partial_symtab *xcoff_end_psymtab
static struct partial_symtab *
xcoff_end_psymtab (pst, include_list, num_includes, capping_symbol_number,
- dependency_list, number_dependencies)
+ dependency_list, number_dependencies, textlow_not_set)
struct partial_symtab *pst;
char **include_list;
int num_includes;
int capping_symbol_number;
struct partial_symtab **dependency_list;
int number_dependencies;
+ int textlow_not_set;
{
int i;
struct objfile *objfile = pst -> objfile;
@@ -2067,21 +2115,8 @@ xcoff_end_psymtab (pst, include_list, num_includes, capping_symbol_number,
it is on the obstack, but we can forget to chain it on the list. */
/* Empty psymtabs happen as a result of header files which don't have
any symbols in them. There can be a lot of them. */
- struct partial_symtab *prev_pst;
-
- /* First, snip it out of the psymtab chain */
-
- if (pst->objfile->psymtabs == pst)
- pst->objfile->psymtabs = pst->next;
- else
- for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
- if (prev_pst->next == pst)
- prev_pst->next = pst->next;
- /* Next, put it on a free list for recycling */
-
- pst->next = pst->objfile->free_psymtabs;
- pst->objfile->free_psymtabs = pst;
+ discard_psymtab (pst);
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *)NULL;
@@ -2154,12 +2189,13 @@ scan_xcoff_symtab (section_offsets, objfile)
struct section_offsets *section_offsets;
struct objfile *objfile;
{
- int toc_offset = 0; /* toc offset value in data section. */
+ CORE_ADDR toc_offset = 0; /* toc offset value in data section. */
char *filestring = NULL;
char *namestring;
int past_first_source_file = 0;
bfd *abfd;
+ asection *bfd_sect;
unsigned int nsyms;
/* Current partial symtab */
@@ -2183,6 +2219,7 @@ scan_xcoff_symtab (section_offsets, objfile)
CORE_ADDR last_csect_val = 0;
int last_csect_sec = 0;
int misc_func_recorded = 0; /* true if any misc. function */
+ int textlow_not_set = 1;
pst = (struct partial_symtab *) 0;
@@ -2272,10 +2309,9 @@ scan_xcoff_symtab (section_offsets, objfile)
each program csect, because their text
sections need not be adjacent. */
xcoff_end_psymtab
- (pst, psymtab_include_list,
- includes_used,
- symnum_before,
- dependency_list, dependencies_used);
+ (pst, psymtab_include_list, includes_used,
+ symnum_before, dependency_list,
+ dependencies_used, textlow_not_set);
includes_used = 0;
dependencies_used = 0;
/* Give all psymtabs for this source file the same
@@ -2315,13 +2351,18 @@ scan_xcoff_symtab (section_offsets, objfile)
(namestring, symbol.n_value,
sclass == C_HIDEXT ? mst_file_data : mst_data,
NULL, secnum_to_section (symbol.n_scnum, objfile),
- objfile);
+ NULL, objfile);
break;
case XMC_TC0:
if (toc_offset)
warning ("More than one XMC_TC0 symbol found.");
toc_offset = symbol.n_value;
+
+ /* Make TOC offset relative to start address of section. */
+ bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile);
+ if (bfd_sect)
+ toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect);
break;
case XMC_TC:
@@ -2385,7 +2426,7 @@ scan_xcoff_symtab (section_offsets, objfile)
(namestring, symbol.n_value,
sclass == C_HIDEXT ? mst_file_data : mst_data,
NULL, secnum_to_section (symbol.n_scnum, objfile),
- objfile);
+ NULL, objfile);
break;
}
break;
@@ -2402,7 +2443,7 @@ scan_xcoff_symtab (section_offsets, objfile)
(namestring, symbol.n_value,
sclass == C_HIDEXT ? mst_file_bss : mst_bss,
NULL, secnum_to_section (symbol.n_scnum, objfile),
- objfile);
+ NULL, objfile);
break;
}
break;
@@ -2437,8 +2478,8 @@ scan_xcoff_symtab (section_offsets, objfile)
if (pst)
{
xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
- symnum_before,
- dependency_list, dependencies_used);
+ symnum_before, dependency_list,
+ dependencies_used, textlow_not_set);
includes_used = 0;
dependencies_used = 0;
}
@@ -2550,7 +2591,7 @@ scan_xcoff_symtab (section_offsets, objfile)
called from DBXREAD_ONLY or N_SO code. Likewise for the symnum
variable. */
#define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms) 0
-#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)\
+#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set)\
do {} while (0)
/* We have already set the namestring. */
#define SET_NAMESTRING() /* */
@@ -2562,17 +2603,26 @@ scan_xcoff_symtab (section_offsets, objfile)
if (pst)
{
xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
- ssymnum,
- dependency_list, dependencies_used);
+ ssymnum, dependency_list,
+ dependencies_used, textlow_not_set);
}
- /* Record the toc offset value of this symbol table into ldinfo structure.
+ /* Record the toc offset value of this symbol table into objfile structure.
If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain
this information would be file auxiliary header. */
-#ifndef FAKING_RS6000
- xcoff_add_toc_to_loadinfo (toc_offset);
-#endif
+ ((struct coff_symfile_info *) objfile->sym_private)->toc_offset = toc_offset;
+}
+
+/* Return the toc offset value for a given objfile. */
+
+CORE_ADDR
+get_toc_offset (objfile)
+ struct objfile *objfile;
+{
+ if (objfile)
+ return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset;
+ return 0;
}
/* Scan and build partial symbols for a symbol file.
@@ -2601,12 +2651,6 @@ xcoff_initial_scan (objfile, section_offsets, mainline)
char *name;
unsigned int size;
-#ifndef FAKING_RS6000
- /* Initialize load info structure. */
- if (mainline)
- xcoff_init_loadinfo ();
-#endif
-
info = (struct coff_symfile_info *) objfile -> sym_private;
symfile_bfd = abfd = objfile->obfd;
name = objfile->name;
@@ -2680,11 +2724,11 @@ xcoff_initial_scan (objfile, section_offsets, mainline)
include N_SLINE. */
init_psymbol_list (objfile, num_symbols);
- pending_blocks = 0;
- back_to = make_cleanup (really_free_pendings, 0);
+ free_pending_blocks ();
+ back_to = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
init_minimal_symbol_collection ();
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
/* Now that the symbol table data of the executable file are all in core,
process them and define symbols accordingly. */
diff --git a/contrib/gdb/gdb/xcoffsolib.c b/contrib/gdb/gdb/xcoffsolib.c
index edcfda1..13d8065 100644
--- a/contrib/gdb/gdb/xcoffsolib.c
+++ b/contrib/gdb/gdb/xcoffsolib.c
@@ -27,6 +27,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "xcoffsolib.h"
#include "inferior.h"
+#include "command.h"
+
+/* Hook to relocate symbols at runtime. If gdb is build natively, this
+ hook is initialized in by rs6000-nat.c. If not, it is currently left
+ NULL and never called. */
+
+void (*xcoff_relocate_symtab_hook) PARAMS ((unsigned int)) = NULL;
#ifdef SOLIB_SYMBOLS_MANUAL
@@ -159,7 +166,8 @@ solib_info (args, from_tty)
struct vmap *vp = vmap;
/* Check for new shared libraries loaded with load (). */
- xcoff_relocate_symtab (inferior_pid);
+ if (xcoff_relocate_symtab_hook != NULL)
+ (*xcoff_relocate_symtab_hook) (inferior_pid);
if (vp == NULL || vp->nxt == NULL)
{
@@ -194,7 +202,8 @@ sharedlibrary_command (args, from_tty)
dont_repeat ();
/* Check for new shared libraries loaded with load (). */
- xcoff_relocate_symtab (inferior_pid);
+ if (xcoff_relocate_symtab_hook != NULL)
+ (*xcoff_relocate_symtab_hook) (inferior_pid);
#ifdef SOLIB_SYMBOLS_MANUAL
solib_add (args, from_tty, (struct target_ops *)0);
diff --git a/contrib/gdb/gdb/xcoffsolib.h b/contrib/gdb/gdb/xcoffsolib.h
index 9d10b2e5..77d691b 100644
--- a/contrib/gdb/gdb/xcoffsolib.h
+++ b/contrib/gdb/gdb/xcoffsolib.h
@@ -1,5 +1,5 @@
/* Data structures for RS/6000 shared libraries, for GDB.
- Copyright 1991, 1992, 1994 Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1994, 1997 Free Software Foundation, Inc.
This file is part of GDB.
@@ -32,9 +32,11 @@ struct vmap {
char *member; /* ptr 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 tvma; /* virtual addr of text section in object file */
+ CORE_ADDR toffs; /* offset of text section in object file */
CORE_ADDR dstart; /* virtual address of data start */
- CORE_ADDR dend; /* vitrual address of data end */
+ CORE_ADDR dend; /* virtual address of data end */
+ CORE_ADDR dvma; /* virtual addr of data section in object file */
/* This is NULL for the exec-file. */
struct objfile *objfile;
@@ -51,6 +53,6 @@ struct vmap_and_bfd {
extern struct vmap *vmap;
-void
-add_text_to_loadinfo PARAMS ((CORE_ADDR textaddr, CORE_ADDR dataaddr));
+/* Hook for symbol table relocation at runtime. */
+extern void (*xcoff_relocate_symtab_hook) PARAMS ((unsigned int));
diff --git a/contrib/gdb/move-if-change b/contrib/gdb/move-if-change
index ee9e355..ee1b348 100755
--- a/contrib/gdb/move-if-change
+++ b/contrib/gdb/move-if-change
@@ -1,4 +1,21 @@
#!/bin/sh
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
if
test -r $2
then
OpenPOWER on IntegriCloud